eigen 2.1.0 → 2.1.1
raw patch · 1126 files changed
+142019/−1452 lines, 1126 filesdep +transformersdep ~primitivedep ~vectorbinary-added
Dependencies added: transformers
Dependency ranges changed: primitive, vector
Files
- Data/Eigen/Internal.hsc +103/−84
- Data/Eigen/LA.hs +1/−1
- Data/Eigen/SparseLA.hs +286/−0
- Data/Eigen/SparseMatrix.hs +22/−34
- cbits/eigen-dense.cpp +125/−0
- cbits/eigen-dense.h +27/−0
- cbits/eigen-la.cpp +122/−0
- cbits/eigen-la.h +37/−0
- cbits/eigen-proxy.cpp +0/−437
- cbits/eigen-proxy.h +0/−110
- cbits/eigen-runtime.cpp +38/−0
- cbits/eigen-runtime.h +40/−0
- cbits/eigen-sparse-la.cpp +180/−0
- cbits/eigen-sparse-la.h +50/−0
- cbits/eigen-sparse.cpp +168/−0
- cbits/eigen-sparse.h +45/−0
- eigen.cabal +1444/−378
- eigen3/.hg_archival.txt +4/−0
- eigen3/.hgeol +8/−0
- eigen3/.hgignore +32/−0
- eigen3/.hgtags +30/−0
- eigen3/CMakeLists.txt +420/−0
- eigen3/CTestConfig.cmake +13/−0
- eigen3/CTestCustom.cmake.in +3/−0
- eigen3/Eigen/Core +1/−1
- eigen3/Eigen/src/Cholesky/LDLT.h +7/−0
- eigen3/Eigen/src/Cholesky/LLT.h +8/−0
- eigen3/Eigen/src/Cholesky/LLT_MKL.h +1/−1
- eigen3/Eigen/src/Core/Assign.h +11/−4
- eigen3/Eigen/src/Core/Block.h +3/−2
- eigen3/Eigen/src/Core/DenseBase.h +5/−3
- eigen3/Eigen/src/Core/DiagonalProduct.h +1/−1
- eigen3/Eigen/src/Core/Functors.h +41/−0
- eigen3/Eigen/src/Core/MapBase.h +1/−1
- eigen3/Eigen/src/Core/MatrixBase.h +0/−2
- eigen3/Eigen/src/Core/PermutationMatrix.h +29/−0
- eigen3/Eigen/src/Core/PlainObjectBase.h +2/−0
- eigen3/Eigen/src/Core/Ref.h +11/−5
- eigen3/Eigen/src/Core/ReturnByValue.h +11/−0
- eigen3/Eigen/src/Core/products/CoeffBasedProduct.h +55/−18
- eigen3/Eigen/src/Core/products/Parallelizer.h +10/−7
- eigen3/Eigen/src/Core/util/Constants.h +13/−0
- eigen3/Eigen/src/Core/util/Macros.h +8/−4
- eigen3/Eigen/src/Core/util/Memory.h +1/−1
- eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h +8/−0
- eigen3/Eigen/src/Eigenvalues/EigenSolver.h +9/−0
- eigen3/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h +9/−0
- eigen3/Eigen/src/Eigenvalues/RealQZ.h +6/−6
- eigen3/Eigen/src/Eigenvalues/RealSchur.h +4/−8
- eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +95/−109
- eigen3/Eigen/src/Geometry/AlignedBox.h +50/−33
- eigen3/Eigen/src/Geometry/Homogeneous.h +1/−1
- eigen3/Eigen/src/Geometry/Quaternion.h +10/−12
- eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +1/−14
- eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +10/−20
- eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +3/−1
- eigen3/Eigen/src/LU/FullPivLU.h +8/−0
- eigen3/Eigen/src/LU/PartialPivLU.h +8/−0
- eigen3/Eigen/src/OrderingMethods/Amd.h +14/−2
- eigen3/Eigen/src/QR/ColPivHouseholderQR.h +16/−16
- eigen3/Eigen/src/QR/FullPivHouseholderQR.h +8/−0
- eigen3/Eigen/src/QR/HouseholderQR.h +54/−40
- eigen3/Eigen/src/QR/HouseholderQR_MKL.h +16/−14
- eigen3/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h +42/−18
- eigen3/Eigen/src/SVD/JacobiSVD.h +7/−0
- eigen3/Eigen/src/SparseCore/SparseBlock.h +42/−4
- eigen3/Eigen/src/SparseCore/SparseDenseProduct.h +1/−1
- eigen3/Eigen/src/SparseCore/SparseMatrixBase.h +4/−2
- eigen3/Eigen/src/SparseCore/TriangularSolver.h +1/−1
- eigen3/Eigen/src/SparseLU/SparseLU.h +65/−16
- eigen3/Eigen/src/SparseLU/SparseLU_pivotL.h +4/−2
- eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h +48/−6
- eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h +0/−16
- eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h +17/−0
- eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h +0/−15
- eigen3/INSTALL +35/−0
- eigen3/bench/BenchSparseUtil.h +149/−0
- eigen3/bench/BenchTimer.h +187/−0
- eigen3/bench/BenchUtil.h +92/−0
- eigen3/bench/README.txt +55/−0
- eigen3/bench/basicbench.cxxlist +28/−0
- eigen3/bench/basicbenchmark.cpp +35/−0
- eigen3/bench/basicbenchmark.h +63/−0
- eigen3/bench/benchBlasGemm.cpp +219/−0
- eigen3/bench/benchCholesky.cpp +142/−0
- eigen3/bench/benchEigenSolver.cpp +212/−0
- eigen3/bench/benchFFT.cpp +115/−0
- eigen3/bench/benchGeometry.cpp +134/−0
- eigen3/bench/benchVecAdd.cpp +135/−0
- eigen3/bench/bench_gemm.cpp +271/−0
- eigen3/bench/bench_multi_compilers.sh +28/−0
- eigen3/bench/bench_norm.cpp +345/−0
- eigen3/bench/bench_reverse.cpp +84/−0
- eigen3/bench/bench_sum.cpp +18/−0
- eigen3/bench/bench_unrolling +12/−0
- eigen3/bench/benchmark.cpp +39/−0
- eigen3/bench/benchmarkSlice.cpp +38/−0
- eigen3/bench/benchmarkX.cpp +36/−0
- eigen3/bench/benchmarkXcwise.cpp +35/−0
- eigen3/bench/benchmark_suite +18/−0
- eigen3/bench/btl/CMakeLists.txt +104/−0
- eigen3/bench/btl/COPYING +340/−0
- eigen3/bench/btl/README +154/−0
- eigen3/bench/btl/actions/action_aat_product.hh +145/−0
- eigen3/bench/btl/actions/action_ata_product.hh +145/−0
- eigen3/bench/btl/actions/action_atv_product.hh +134/−0
- eigen3/bench/btl/actions/action_axpby.hh +127/−0
- eigen3/bench/btl/actions/action_axpy.hh +139/−0
- eigen3/bench/btl/actions/action_cholesky.hh +128/−0
- eigen3/bench/btl/actions/action_ger.hh +128/−0
- eigen3/bench/btl/actions/action_hessenberg.hh +233/−0
- eigen3/bench/btl/actions/action_lu_decomp.hh +124/−0
- eigen3/bench/btl/actions/action_lu_solve.hh +136/−0
- eigen3/bench/btl/actions/action_matrix_matrix_product.hh +150/−0
- eigen3/bench/btl/actions/action_matrix_matrix_product_bis.hh +152/−0
- eigen3/bench/btl/actions/action_matrix_vector_product.hh +153/−0
- eigen3/bench/btl/actions/action_partial_lu.hh +125/−0
- eigen3/bench/btl/actions/action_rot.hh +116/−0
- eigen3/bench/btl/actions/action_symv.hh +139/−0
- eigen3/bench/btl/actions/action_syr2.hh +133/−0
- eigen3/bench/btl/actions/action_trisolve.hh +137/−0
- eigen3/bench/btl/actions/action_trisolve_matrix.hh +165/−0
- eigen3/bench/btl/actions/action_trmm.hh +165/−0
- eigen3/bench/btl/actions/basic_actions.hh +21/−0
- eigen3/bench/btl/cmake/FindACML.cmake +49/−0
- eigen3/bench/btl/cmake/FindATLAS.cmake +39/−0
- eigen3/bench/btl/cmake/FindBlitz.cmake +40/−0
- eigen3/bench/btl/cmake/FindCBLAS.cmake +34/−0
- eigen3/bench/btl/cmake/FindGMM.cmake +17/−0
- eigen3/bench/btl/cmake/FindGOTO.cmake +15/−0
- eigen3/bench/btl/cmake/FindGOTO2.cmake +25/−0
- eigen3/bench/btl/cmake/FindMKL.cmake +65/−0
- eigen3/bench/btl/cmake/FindMTL4.cmake +31/−0
- eigen3/bench/btl/cmake/FindPackageHandleStandardArgs.cmake +60/−0
- eigen3/bench/btl/cmake/FindTvmet.cmake +32/−0
- eigen3/bench/btl/cmake/MacroOptionalAddSubdirectory.cmake +31/−0
- eigen3/bench/btl/data/CMakeLists.txt +32/−0
- eigen3/bench/btl/data/action_settings.txt +19/−0
- eigen3/bench/btl/data/gnuplot_common_settings.hh +87/−0
- eigen3/bench/btl/data/go_mean +58/−0
- eigen3/bench/btl/data/mean.cxx +182/−0
- eigen3/bench/btl/data/mk_gnuplot_script.sh +68/−0
- eigen3/bench/btl/data/mk_mean_script.sh +52/−0
- eigen3/bench/btl/data/mk_new_gnuplot.sh +54/−0
- eigen3/bench/btl/data/perlib_plot_settings.txt +16/−0
- eigen3/bench/btl/data/regularize.cxx +131/−0
- eigen3/bench/btl/data/smooth.cxx +198/−0
- eigen3/bench/btl/data/smooth_all.sh +68/−0
- eigen3/bench/btl/generic_bench/bench.hh +168/−0
- eigen3/bench/btl/generic_bench/bench_parameter.hh +53/−0
- eigen3/bench/btl/generic_bench/btl.hh +247/−0
- eigen3/bench/btl/generic_bench/init/init_function.hh +54/−0
- eigen3/bench/btl/generic_bench/init/init_matrix.hh +64/−0
- eigen3/bench/btl/generic_bench/init/init_vector.hh +37/−0
- eigen3/bench/btl/generic_bench/static/bench_static.hh +80/−0
- eigen3/bench/btl/generic_bench/static/intel_bench_fixed_size.hh +66/−0
- eigen3/bench/btl/generic_bench/static/static_size_generator.hh +57/−0
- eigen3/bench/btl/generic_bench/timers/STL_perf_analyzer.hh +82/−0
- eigen3/bench/btl/generic_bench/timers/STL_timer.hh +78/−0
- eigen3/bench/btl/generic_bench/timers/mixed_perf_analyzer.hh +73/−0
- eigen3/bench/btl/generic_bench/timers/portable_perf_analyzer.hh +103/−0
- eigen3/bench/btl/generic_bench/timers/portable_perf_analyzer_old.hh +134/−0
- eigen3/bench/btl/generic_bench/timers/portable_timer.hh +145/−0
- eigen3/bench/btl/generic_bench/timers/x86_perf_analyzer.hh +108/−0
- eigen3/bench/btl/generic_bench/timers/x86_timer.hh +246/−0
- eigen3/bench/btl/generic_bench/utils/size_lin_log.hh +70/−0
- eigen3/bench/btl/generic_bench/utils/size_log.hh +54/−0
- eigen3/bench/btl/generic_bench/utils/utilities.h +90/−0
- eigen3/bench/btl/generic_bench/utils/xy_file.hh +75/−0
- eigen3/bench/btl/libs/BLAS/CMakeLists.txt +60/−0
- eigen3/bench/btl/libs/BLAS/blas.h +675/−0
- eigen3/bench/btl/libs/BLAS/blas_interface.hh +83/−0
- eigen3/bench/btl/libs/BLAS/blas_interface_impl.hh +151/−0
- eigen3/bench/btl/libs/BLAS/c_interface_base.h +73/−0
- eigen3/bench/btl/libs/BLAS/main.cpp +73/−0
- eigen3/bench/btl/libs/STL/CMakeLists.txt +2/−0
- eigen3/bench/btl/libs/STL/STL_interface.hh +244/−0
- eigen3/bench/btl/libs/STL/main.cpp +42/−0
- eigen3/bench/btl/libs/blitz/CMakeLists.txt +17/−0
- eigen3/bench/btl/libs/blitz/blitz_LU_solve_interface.hh +192/−0
- eigen3/bench/btl/libs/blitz/blitz_interface.hh +147/−0
- eigen3/bench/btl/libs/blitz/btl_blitz.cpp +51/−0
- eigen3/bench/btl/libs/blitz/btl_tiny_blitz.cpp +38/−0
- eigen3/bench/btl/libs/blitz/tiny_blitz_interface.hh +106/−0
- eigen3/bench/btl/libs/eigen2/CMakeLists.txt +19/−0
- eigen3/bench/btl/libs/eigen2/btl_tiny_eigen2.cpp +46/−0
- eigen3/bench/btl/libs/eigen2/eigen2_interface.hh +168/−0
- eigen3/bench/btl/libs/eigen2/main_adv.cpp +44/−0
- eigen3/bench/btl/libs/eigen2/main_linear.cpp +34/−0
- eigen3/bench/btl/libs/eigen2/main_matmat.cpp +35/−0
- eigen3/bench/btl/libs/eigen2/main_vecmat.cpp +36/−0
- eigen3/bench/btl/libs/eigen3/CMakeLists.txt +65/−0
- eigen3/bench/btl/libs/eigen3/btl_tiny_eigen3.cpp +46/−0
- eigen3/bench/btl/libs/eigen3/eigen3_interface.hh +240/−0
- eigen3/bench/btl/libs/eigen3/main_adv.cpp +44/−0
- eigen3/bench/btl/libs/eigen3/main_linear.cpp +35/−0
- eigen3/bench/btl/libs/eigen3/main_matmat.cpp +35/−0
- eigen3/bench/btl/libs/eigen3/main_vecmat.cpp +36/−0
- eigen3/bench/btl/libs/gmm/CMakeLists.txt +6/−0
- eigen3/bench/btl/libs/gmm/gmm_LU_solve_interface.hh +192/−0
- eigen3/bench/btl/libs/gmm/gmm_interface.hh +144/−0
- eigen3/bench/btl/libs/gmm/main.cpp +51/−0
- eigen3/bench/btl/libs/mtl4/.kdbgrc.main +12/−0
- eigen3/bench/btl/libs/mtl4/CMakeLists.txt +6/−0
- eigen3/bench/btl/libs/mtl4/main.cpp +46/−0
- eigen3/bench/btl/libs/mtl4/mtl4_LU_solve_interface.hh +192/−0
- eigen3/bench/btl/libs/mtl4/mtl4_interface.hh +144/−0
- eigen3/bench/btl/libs/tvmet/CMakeLists.txt +6/−0
- eigen3/bench/btl/libs/tvmet/main.cpp +40/−0
- eigen3/bench/btl/libs/tvmet/tvmet_interface.hh +104/−0
- eigen3/bench/btl/libs/ublas/CMakeLists.txt +7/−0
- eigen3/bench/btl/libs/ublas/main.cpp +44/−0
- eigen3/bench/btl/libs/ublas/ublas_interface.hh +141/−0
- eigen3/bench/check_cache_queries.cpp +101/−0
- eigen3/bench/eig33.cpp +196/−0
- eigen3/bench/geometry.cpp +126/−0
- eigen3/bench/product_threshold.cpp +143/−0
- eigen3/bench/quat_slerp.cpp +247/−0
- eigen3/bench/quatmul.cpp +47/−0
- eigen3/bench/sparse_cholesky.cpp +216/−0
- eigen3/bench/sparse_dense_product.cpp +187/−0
- eigen3/bench/sparse_lu.cpp +132/−0
- eigen3/bench/sparse_product.cpp +323/−0
- eigen3/bench/sparse_randomsetter.cpp +125/−0
- eigen3/bench/sparse_setter.cpp +485/−0
- eigen3/bench/sparse_transpose.cpp +104/−0
- eigen3/bench/sparse_trisolver.cpp +220/−0
- eigen3/bench/spbench/CMakeLists.txt +78/−0
- eigen3/bench/spbench/sp_solver.cpp +125/−0
- eigen3/bench/spbench/spbench.dtd +31/−0
- eigen3/bench/spbench/spbenchsolver.cpp +87/−0
- eigen3/bench/spbench/spbenchsolver.h +554/−0
- eigen3/bench/spbench/spbenchstyle.h +94/−0
- eigen3/bench/spbench/test_sparseLU.cpp +93/−0
- eigen3/bench/spmv.cpp +233/−0
- eigen3/bench/vdw_new.cpp +56/−0
- eigen3/blas/BandTriangularSolver.h +97/−0
- eigen3/blas/CMakeLists.txt +60/−0
- eigen3/blas/GeneralRank1Update.h +44/−0
- eigen3/blas/PackedSelfadjointProduct.h +53/−0
- eigen3/blas/PackedTriangularMatrixVector.h +79/−0
- eigen3/blas/PackedTriangularSolverVector.h +88/−0
- eigen3/blas/README.txt +6/−0
- eigen3/blas/Rank2Update.h +57/−0
- eigen3/blas/chbmv.f +310/−0
- eigen3/blas/chpmv.f +272/−0
- eigen3/blas/common.h +145/−0
- eigen3/blas/complex_double.cpp +20/−0
- eigen3/blas/complex_single.cpp +20/−0
- eigen3/blas/complexdots.f +43/−0
- eigen3/blas/ctbmv.f +366/−0
- eigen3/blas/double.cpp +33/−0
- eigen3/blas/drotm.f +147/−0
- eigen3/blas/drotmg.f +206/−0
- eigen3/blas/dsbmv.f +304/−0
- eigen3/blas/dspmv.f +265/−0
- eigen3/blas/dtbmv.f +335/−0
- eigen3/blas/level1_cplx_impl.h +127/−0
- eigen3/blas/level1_impl.h +167/−0
- eigen3/blas/level1_real_impl.h +100/−0
- eigen3/blas/level2_cplx_impl.h +394/−0
- eigen3/blas/level2_impl.h +524/−0
- eigen3/blas/level2_real_impl.h +370/−0
- eigen3/blas/level3_impl.h +634/−0
- eigen3/blas/lsame.f +85/−0
- eigen3/blas/single.cpp +22/−0
- eigen3/blas/srotm.f +148/−0
- eigen3/blas/srotmg.f +208/−0
- eigen3/blas/ssbmv.f +306/−0
- eigen3/blas/sspmv.f +265/−0
- eigen3/blas/stbmv.f +335/−0
- eigen3/blas/testing/CMakeLists.txt +40/−0
- eigen3/blas/testing/cblat1.f +681/−0
- eigen3/blas/testing/cblat2.dat +35/−0
- eigen3/blas/testing/cblat2.f +3241/−0
- eigen3/blas/testing/cblat3.dat +23/−0
- eigen3/blas/testing/cblat3.f +3439/−0
- eigen3/blas/testing/dblat1.f +1065/−0
- eigen3/blas/testing/dblat2.dat +34/−0
- eigen3/blas/testing/dblat2.f +3138/−0
- eigen3/blas/testing/dblat3.dat +20/−0
- eigen3/blas/testing/dblat3.f +2823/−0
- eigen3/blas/testing/runblastest.sh +45/−0
- eigen3/blas/testing/sblat1.f +1021/−0
- eigen3/blas/testing/sblat2.dat +34/−0
- eigen3/blas/testing/sblat2.f +3138/−0
- eigen3/blas/testing/sblat3.dat +20/−0
- eigen3/blas/testing/sblat3.f +2823/−0
- eigen3/blas/testing/zblat1.f +681/−0
- eigen3/blas/testing/zblat2.dat +35/−0
- eigen3/blas/testing/zblat2.f +3249/−0
- eigen3/blas/testing/zblat3.dat +23/−0
- eigen3/blas/testing/zblat3.f +3445/−0
- eigen3/blas/xerbla.cpp +23/−0
- eigen3/blas/zhbmv.f +310/−0
- eigen3/blas/zhpmv.f +272/−0
- eigen3/blas/ztbmv.f +366/−0
- eigen3/cmake/EigenConfigureTesting.cmake +81/−0
- eigen3/cmake/EigenDetermineOSVersion.cmake +46/−0
- eigen3/cmake/EigenDetermineVSServicePack.cmake +27/−0
- eigen3/cmake/EigenTesting.cmake +497/−0
- eigen3/cmake/FindAdolc.cmake +20/−0
- eigen3/cmake/FindBLAS.cmake +419/−0
- eigen3/cmake/FindCholmod.cmake +89/−0
- eigen3/cmake/FindEigen2.cmake +80/−0
- eigen3/cmake/FindEigen3.cmake +81/−0
- eigen3/cmake/FindFFTW.cmake +119/−0
- eigen3/cmake/FindGLEW.cmake +105/−0
- eigen3/cmake/FindGMP.cmake +21/−0
- eigen3/cmake/FindGSL.cmake +170/−0
- eigen3/cmake/FindGoogleHash.cmake +23/−0
- eigen3/cmake/FindLAPACK.cmake +273/−0
- eigen3/cmake/FindMPFR.cmake +83/−0
- eigen3/cmake/FindMetis.cmake +59/−0
- eigen3/cmake/FindPastix.cmake +25/−0
- eigen3/cmake/FindSPQR.cmake +36/−0
- eigen3/cmake/FindScotch.cmake +24/−0
- eigen3/cmake/FindStandardMathLibrary.cmake +64/−0
- eigen3/cmake/FindSuperLU.cmake +26/−0
- eigen3/cmake/FindUmfpack.cmake +48/−0
- eigen3/cmake/RegexUtils.cmake +19/−0
- eigen3/cmake/language_support.cmake +66/−0
- eigen3/debug/gdb/__init__.py +1/−0
- eigen3/debug/gdb/printers.py +208/−0
- eigen3/debug/msvc/eigen.natvis +235/−0
- eigen3/debug/msvc/eigen_autoexp_part.dat +295/−0
- eigen3/demos/CMakeLists.txt +13/−0
- eigen3/demos/mandelbrot/CMakeLists.txt +21/−0
- eigen3/demos/mandelbrot/README +10/−0
- eigen3/demos/mandelbrot/mandelbrot.cpp +213/−0
- eigen3/demos/mandelbrot/mandelbrot.h +71/−0
- eigen3/demos/mix_eigen_and_c/README +9/−0
- eigen3/demos/mix_eigen_and_c/binary_library.cpp +185/−0
- eigen3/demos/mix_eigen_and_c/binary_library.h +71/−0
- eigen3/demos/mix_eigen_and_c/example.c +65/−0
- eigen3/demos/opengl/CMakeLists.txt +28/−0
- eigen3/demos/opengl/README +13/−0
- eigen3/demos/opengl/camera.cpp +264/−0
- eigen3/demos/opengl/camera.h +118/−0
- eigen3/demos/opengl/gpuhelper.cpp +126/−0
- eigen3/demos/opengl/gpuhelper.h +207/−0
- eigen3/demos/opengl/icosphere.cpp +120/−0
- eigen3/demos/opengl/icosphere.h +30/−0
- eigen3/demos/opengl/quaternion_demo.cpp +656/−0
- eigen3/demos/opengl/quaternion_demo.h +114/−0
- eigen3/demos/opengl/trackball.cpp +59/−0
- eigen3/demos/opengl/trackball.h +42/−0
- eigen3/doc/A05_PortingFrom2To3.dox +304/−0
- eigen3/doc/A10_Eigen2SupportModes.dox +95/−0
- eigen3/doc/AsciiQuickReference.txt +207/−0
- eigen3/doc/B01_Experimental.dox +52/−0
- eigen3/doc/CMakeLists.txt +99/−0
- eigen3/doc/ClassHierarchy.dox +129/−0
- eigen3/doc/CustomizingEigen.dox +188/−0
- eigen3/doc/Doxyfile.in +1875/−0
- eigen3/doc/Eigen_Silly_Professor_64x64.png binary
- eigen3/doc/FixedSizeVectorizable.dox +38/−0
- eigen3/doc/FunctionsTakingEigenTypes.dox +217/−0
- eigen3/doc/HiPerformance.dox +128/−0
- eigen3/doc/InsideEigenExample.dox +495/−0
- eigen3/doc/Manual.dox +159/−0
- eigen3/doc/Overview.dox +28/−0
- eigen3/doc/PassingByValue.dox +40/−0
- eigen3/doc/PreprocessorDirectives.dox +119/−0
- eigen3/doc/QuickReference.dox +727/−0
- eigen3/doc/QuickStartGuide.dox +100/−0
- eigen3/doc/SparseLinearSystems.dox +183/−0
- eigen3/doc/SparseQuickReference.dox +248/−0
- eigen3/doc/StlContainers.dox +62/−0
- eigen3/doc/StorageOrders.dox +86/−0
- eigen3/doc/StructHavingEigenMembers.dox +190/−0
- eigen3/doc/TemplateKeyword.dox +132/−0
- eigen3/doc/TopicAliasing.dox +215/−0
- eigen3/doc/TopicAssertions.dox +108/−0
- eigen3/doc/TopicEigenExpressionTemplates.dox +12/−0
- eigen3/doc/TopicLazyEvaluation.dox +65/−0
- eigen3/doc/TopicLinearAlgebraDecompositions.dox +261/−0
- eigen3/doc/TopicMultithreading.dox +46/−0
- eigen3/doc/TopicResizing.dox +11/−0
- eigen3/doc/TopicScalarTypes.dox +12/−0
- eigen3/doc/TopicVectorization.dox +9/−0
- eigen3/doc/TutorialAdvancedInitialization.dox +162/−0
- eigen3/doc/TutorialArrayClass.dox +192/−0
- eigen3/doc/TutorialBlockOperations.dox +228/−0
- eigen3/doc/TutorialGeometry.dox +241/−0
- eigen3/doc/TutorialLinearAlgebra.dox +255/−0
- eigen3/doc/TutorialMapClass.dox +86/−0
- eigen3/doc/TutorialMatrixArithmetic.dox +214/−0
- eigen3/doc/TutorialMatrixClass.dox +265/−0
- eigen3/doc/TutorialReductionsVisitorsBroadcasting.dox +257/−0
- eigen3/doc/TutorialSparse.dox +341/−0
- eigen3/doc/TutorialSparse_example_details.dox +4/−0
- eigen3/doc/UnalignedArrayAssert.dox +114/−0
- eigen3/doc/UsingIntelMKL.dox +168/−0
- eigen3/doc/WrongStackAlignment.dox +56/−0
- eigen3/doc/eigen_navtree_hacks.js +240/−0
- eigen3/doc/eigendoxy.css +211/−0
- eigen3/doc/eigendoxy_footer.html.in +36/−0
- eigen3/doc/eigendoxy_header.html.in +61/−0
- eigen3/doc/eigendoxy_layout.xml.in +178/−0
- eigen3/doc/eigendoxy_tabs.css +59/−0
- eigen3/doc/examples/.krazy +2/−0
- eigen3/doc/examples/CMakeLists.txt +16/−0
- eigen3/doc/examples/DenseBase_middleCols_int.cpp +15/−0
- eigen3/doc/examples/DenseBase_middleRows_int.cpp +15/−0
- eigen3/doc/examples/DenseBase_template_int_middleCols.cpp +15/−0
- eigen3/doc/examples/DenseBase_template_int_middleRows.cpp +15/−0
- eigen3/doc/examples/MatrixBase_cwise_const.cpp +18/−0
- eigen3/doc/examples/QuickStart_example.cpp +14/−0
- eigen3/doc/examples/QuickStart_example2_dynamic.cpp +15/−0
- eigen3/doc/examples/QuickStart_example2_fixed.cpp +15/−0
- eigen3/doc/examples/TemplateKeyword_flexible.cpp +22/−0
- eigen3/doc/examples/TemplateKeyword_simple.cpp +20/−0
- eigen3/doc/examples/TutorialLinAlgComputeTwice.cpp +23/−0
- eigen3/doc/examples/TutorialLinAlgExComputeSolveError.cpp +14/−0
- eigen3/doc/examples/TutorialLinAlgExSolveColPivHouseholderQR.cpp +17/−0
- eigen3/doc/examples/TutorialLinAlgExSolveLDLT.cpp +16/−0
- eigen3/doc/examples/TutorialLinAlgInverseDeterminant.cpp +16/−0
- eigen3/doc/examples/TutorialLinAlgRankRevealing.cpp +20/−0
- eigen3/doc/examples/TutorialLinAlgSVDSolve.cpp +15/−0
- eigen3/doc/examples/TutorialLinAlgSelfAdjointEigenSolver.cpp +18/−0
- eigen3/doc/examples/TutorialLinAlgSetThreshold.cpp +16/−0
- eigen3/doc/examples/Tutorial_ArrayClass_accessors.cpp +24/−0
- eigen3/doc/examples/Tutorial_ArrayClass_addition.cpp +23/−0
- eigen3/doc/examples/Tutorial_ArrayClass_cwise_other.cpp +19/−0
- eigen3/doc/examples/Tutorial_ArrayClass_interop.cpp +22/−0
- eigen3/doc/examples/Tutorial_ArrayClass_interop_matrix.cpp +26/−0
- eigen3/doc/examples/Tutorial_ArrayClass_mult.cpp +16/−0
- eigen3/doc/examples/Tutorial_BlockOperations_block_assignment.cpp +18/−0
- eigen3/doc/examples/Tutorial_BlockOperations_colrow.cpp +17/−0
- eigen3/doc/examples/Tutorial_BlockOperations_corner.cpp +17/−0
- eigen3/doc/examples/Tutorial_BlockOperations_print_block.cpp +20/−0
- eigen3/doc/examples/Tutorial_BlockOperations_vector.cpp +14/−0
- eigen3/doc/examples/Tutorial_PartialLU_solve.cpp +18/−0
- eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_broadcast_1nn.cpp +24/−0
- eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple.cpp +21/−0
- eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple_rowwise.cpp +20/−0
- eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_colwise.cpp +13/−0
- eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_maxnorm.cpp +20/−0
- eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_reductions_bool.cpp +21/−0
- eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_reductions_norm.cpp +28/−0
- eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_rowwise.cpp +13/−0
- eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_visitors.cpp +26/−0
- eigen3/doc/examples/Tutorial_simple_example_dynamic_size.cpp +22/−0
- eigen3/doc/examples/Tutorial_simple_example_fixed_size.cpp +15/−0
- eigen3/doc/examples/class_Block.cpp +27/−0
- eigen3/doc/examples/class_CwiseBinaryOp.cpp +18/−0
- eigen3/doc/examples/class_CwiseUnaryOp.cpp +19/−0
- eigen3/doc/examples/class_CwiseUnaryOp_ptrfun.cpp +20/−0
- eigen3/doc/examples/class_FixedBlock.cpp +27/−0
- eigen3/doc/examples/class_FixedVectorBlock.cpp +27/−0
- eigen3/doc/examples/class_VectorBlock.cpp +27/−0
- eigen3/doc/examples/function_taking_eigenbase.cpp +18/−0
- eigen3/doc/examples/function_taking_ref.cpp +19/−0
- eigen3/doc/examples/tut_arithmetic_add_sub.cpp +22/−0
- eigen3/doc/examples/tut_arithmetic_dot_cross.cpp +15/−0
- eigen3/doc/examples/tut_arithmetic_matrix_mul.cpp +19/−0
- eigen3/doc/examples/tut_arithmetic_redux_basic.cpp +16/−0
- eigen3/doc/examples/tut_arithmetic_scalar_mul_div.cpp +17/−0
- eigen3/doc/examples/tut_matrix_coefficient_accessors.cpp +18/−0
- eigen3/doc/examples/tut_matrix_resize.cpp +18/−0
- eigen3/doc/examples/tut_matrix_resize_fixed_size.cpp +12/−0
- eigen3/doc/snippets/.krazy +2/−0
- eigen3/doc/snippets/AngleAxis_mimic_euler.cpp +5/−0
- eigen3/doc/snippets/CMakeLists.txt +28/−0
- eigen3/doc/snippets/ColPivHouseholderQR_solve.cpp +8/−0
- eigen3/doc/snippets/ComplexEigenSolver_compute.cpp +16/−0
- eigen3/doc/snippets/ComplexEigenSolver_eigenvalues.cpp +4/−0
- eigen3/doc/snippets/ComplexEigenSolver_eigenvectors.cpp +4/−0
- eigen3/doc/snippets/ComplexSchur_compute.cpp +6/−0
- eigen3/doc/snippets/ComplexSchur_matrixT.cpp +4/−0
- eigen3/doc/snippets/ComplexSchur_matrixU.cpp +4/−0
- eigen3/doc/snippets/Cwise_abs.cpp +2/−0
- eigen3/doc/snippets/Cwise_abs2.cpp +2/−0
- eigen3/doc/snippets/Cwise_acos.cpp +2/−0
- eigen3/doc/snippets/Cwise_asin.cpp +2/−0
- eigen3/doc/snippets/Cwise_boolean_and.cpp +2/−0
- eigen3/doc/snippets/Cwise_boolean_or.cpp +2/−0
- eigen3/doc/snippets/Cwise_cos.cpp +2/−0
- eigen3/doc/snippets/Cwise_cube.cpp +2/−0
- eigen3/doc/snippets/Cwise_equal_equal.cpp +2/−0
- eigen3/doc/snippets/Cwise_exp.cpp +2/−0
- eigen3/doc/snippets/Cwise_greater.cpp +2/−0
- eigen3/doc/snippets/Cwise_greater_equal.cpp +2/−0
- eigen3/doc/snippets/Cwise_inverse.cpp +2/−0
- eigen3/doc/snippets/Cwise_less.cpp +2/−0
- eigen3/doc/snippets/Cwise_less_equal.cpp +2/−0
- eigen3/doc/snippets/Cwise_log.cpp +2/−0
- eigen3/doc/snippets/Cwise_max.cpp +2/−0
- eigen3/doc/snippets/Cwise_min.cpp +2/−0
- eigen3/doc/snippets/Cwise_minus.cpp +2/−0
- eigen3/doc/snippets/Cwise_minus_equal.cpp +3/−0
- eigen3/doc/snippets/Cwise_not_equal.cpp +2/−0
- eigen3/doc/snippets/Cwise_plus.cpp +2/−0
- eigen3/doc/snippets/Cwise_plus_equal.cpp +3/−0
- eigen3/doc/snippets/Cwise_pow.cpp +2/−0
- eigen3/doc/snippets/Cwise_product.cpp +4/−0
- eigen3/doc/snippets/Cwise_quotient.cpp +2/−0
- eigen3/doc/snippets/Cwise_sin.cpp +2/−0
- eigen3/doc/snippets/Cwise_slash_equal.cpp +3/−0
- eigen3/doc/snippets/Cwise_sqrt.cpp +2/−0
- eigen3/doc/snippets/Cwise_square.cpp +2/−0
- eigen3/doc/snippets/Cwise_tan.cpp +2/−0
- eigen3/doc/snippets/Cwise_times_equal.cpp +3/−0
- eigen3/doc/snippets/DenseBase_LinSpaced.cpp +2/−0
- eigen3/doc/snippets/DenseBase_LinSpaced_seq.cpp +2/−0
- eigen3/doc/snippets/DenseBase_setLinSpaced.cpp +3/−0
- eigen3/doc/snippets/DirectionWise_replicate.cpp +4/−0
- eigen3/doc/snippets/DirectionWise_replicate_int.cpp +4/−0
- eigen3/doc/snippets/EigenSolver_EigenSolver_MatrixType.cpp +16/−0
- eigen3/doc/snippets/EigenSolver_compute.cpp +6/−0
- eigen3/doc/snippets/EigenSolver_eigenvalues.cpp +4/−0
- eigen3/doc/snippets/EigenSolver_eigenvectors.cpp +4/−0
- eigen3/doc/snippets/EigenSolver_pseudoEigenvectors.cpp +9/−0
- eigen3/doc/snippets/FullPivHouseholderQR_solve.cpp +8/−0
- eigen3/doc/snippets/FullPivLU_image.cpp +9/−0
- eigen3/doc/snippets/FullPivLU_kernel.cpp +7/−0
- eigen3/doc/snippets/FullPivLU_solve.cpp +11/−0
- eigen3/doc/snippets/GeneralizedEigenSolver.cpp +7/−0
- eigen3/doc/snippets/HessenbergDecomposition_compute.cpp +6/−0
- eigen3/doc/snippets/HessenbergDecomposition_matrixH.cpp +8/−0
- eigen3/doc/snippets/HessenbergDecomposition_packedMatrix.cpp +9/−0
- eigen3/doc/snippets/HouseholderQR_householderQ.cpp +7/−0
- eigen3/doc/snippets/HouseholderQR_solve.cpp +9/−0
- eigen3/doc/snippets/HouseholderSequence_HouseholderSequence.cpp +31/−0
- eigen3/doc/snippets/IOFormat.cpp +14/−0
- eigen3/doc/snippets/JacobiSVD_basic.cpp +9/−0
- eigen3/doc/snippets/Jacobi_makeGivens.cpp +6/−0
- eigen3/doc/snippets/Jacobi_makeJacobi.cpp +8/−0
- eigen3/doc/snippets/LLT_example.cpp +12/−0
- eigen3/doc/snippets/LLT_solve.cpp +8/−0
- eigen3/doc/snippets/Map_general_stride.cpp +5/−0
- eigen3/doc/snippets/Map_inner_stride.cpp +5/−0
- eigen3/doc/snippets/Map_outer_stride.cpp +3/−0
- eigen3/doc/snippets/Map_placement_new.cpp +5/−0
- eigen3/doc/snippets/Map_simple.cpp +3/−0
- eigen3/doc/snippets/MatrixBase_adjoint.cpp +3/−0
- eigen3/doc/snippets/MatrixBase_all.cpp +7/−0
- eigen3/doc/snippets/MatrixBase_applyOnTheLeft.cpp +7/−0
- eigen3/doc/snippets/MatrixBase_applyOnTheRight.cpp +9/−0
- eigen3/doc/snippets/MatrixBase_array.cpp +4/−0
- eigen3/doc/snippets/MatrixBase_array_const.cpp +4/−0
- eigen3/doc/snippets/MatrixBase_asDiagonal.cpp +1/−0
- eigen3/doc/snippets/MatrixBase_block_int_int.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_block_int_int_int_int.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_bottomLeftCorner_int_int.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_bottomRightCorner_int_int.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_bottomRows_int.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_cast.cpp +3/−0
- eigen3/doc/snippets/MatrixBase_col.cpp +3/−0
- eigen3/doc/snippets/MatrixBase_colwise.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_computeInverseAndDetWithCheck.cpp +13/−0
- eigen3/doc/snippets/MatrixBase_computeInverseWithCheck.cpp +11/−0
- eigen3/doc/snippets/MatrixBase_cwiseAbs.cpp +4/−0
- eigen3/doc/snippets/MatrixBase_cwiseAbs2.cpp +4/−0
- eigen3/doc/snippets/MatrixBase_cwiseEqual.cpp +7/−0
- eigen3/doc/snippets/MatrixBase_cwiseInverse.cpp +4/−0
- eigen3/doc/snippets/MatrixBase_cwiseMax.cpp +2/−0
- eigen3/doc/snippets/MatrixBase_cwiseMin.cpp +2/−0
- eigen3/doc/snippets/MatrixBase_cwiseNotEqual.cpp +7/−0
- eigen3/doc/snippets/MatrixBase_cwiseProduct.cpp +4/−0
- eigen3/doc/snippets/MatrixBase_cwiseQuotient.cpp +2/−0
- eigen3/doc/snippets/MatrixBase_cwiseSqrt.cpp +2/−0
- eigen3/doc/snippets/MatrixBase_diagonal.cpp +4/−0
- eigen3/doc/snippets/MatrixBase_diagonal_int.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_diagonal_template_int.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_eigenvalues.cpp +3/−0
- eigen3/doc/snippets/MatrixBase_end_int.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_eval.cpp +12/−0
- eigen3/doc/snippets/MatrixBase_extract.cpp +13/−0
- eigen3/doc/snippets/MatrixBase_fixedBlock_int_int.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_identity.cpp +1/−0
- eigen3/doc/snippets/MatrixBase_identity_int_int.cpp +1/−0
- eigen3/doc/snippets/MatrixBase_inverse.cpp +3/−0
- eigen3/doc/snippets/MatrixBase_isDiagonal.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_isIdentity.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_isOnes.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_isOrthogonal.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_isUnitary.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_isZero.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_leftCols_int.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_marked.cpp +14/−0
- eigen3/doc/snippets/MatrixBase_noalias.cpp +3/−0
- eigen3/doc/snippets/MatrixBase_ones.cpp +2/−0
- eigen3/doc/snippets/MatrixBase_ones_int.cpp +2/−0
- eigen3/doc/snippets/MatrixBase_ones_int_int.cpp +1/−0
- eigen3/doc/snippets/MatrixBase_operatorNorm.cpp +3/−0
- eigen3/doc/snippets/MatrixBase_part.cpp +13/−0
- eigen3/doc/snippets/MatrixBase_prod.cpp +3/−0
- eigen3/doc/snippets/MatrixBase_random.cpp +1/−0
- eigen3/doc/snippets/MatrixBase_random_int.cpp +1/−0
- eigen3/doc/snippets/MatrixBase_random_int_int.cpp +1/−0
- eigen3/doc/snippets/MatrixBase_replicate.cpp +4/−0
- eigen3/doc/snippets/MatrixBase_replicate_int_int.cpp +4/−0
- eigen3/doc/snippets/MatrixBase_reverse.cpp +8/−0
- eigen3/doc/snippets/MatrixBase_rightCols_int.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_row.cpp +3/−0
- eigen3/doc/snippets/MatrixBase_rowwise.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_segment_int_int.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_select.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_set.cpp +13/−0
- eigen3/doc/snippets/MatrixBase_setIdentity.cpp +3/−0
- eigen3/doc/snippets/MatrixBase_setOnes.cpp +3/−0
- eigen3/doc/snippets/MatrixBase_setRandom.cpp +3/−0
- eigen3/doc/snippets/MatrixBase_setZero.cpp +3/−0
- eigen3/doc/snippets/MatrixBase_start_int.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_template_int_bottomRows.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_template_int_end.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_template_int_int_block_int_int_int_int.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_template_int_int_bottomLeftCorner.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_template_int_int_bottomLeftCorner_int_int.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_template_int_int_bottomRightCorner.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_template_int_int_bottomRightCorner_int_int.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_template_int_int_topLeftCorner.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_template_int_int_topLeftCorner_int_int.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_template_int_int_topRightCorner.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_template_int_int_topRightCorner_int_int.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_template_int_leftCols.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_template_int_rightCols.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_template_int_segment.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_template_int_start.cpp +5/−0
- eigen3/doc/snippets/MatrixBase_template_int_topRows.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_topLeftCorner_int_int.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_topRightCorner_int_int.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_topRows_int.cpp +6/−0
- eigen3/doc/snippets/MatrixBase_transpose.cpp +8/−0
- eigen3/doc/snippets/MatrixBase_zero.cpp +2/−0
- eigen3/doc/snippets/MatrixBase_zero_int.cpp +2/−0
- eigen3/doc/snippets/MatrixBase_zero_int_int.cpp +1/−0
- eigen3/doc/snippets/Matrix_resize_NoChange_int.cpp +3/−0
- eigen3/doc/snippets/Matrix_resize_int.cpp +6/−0
- eigen3/doc/snippets/Matrix_resize_int_NoChange.cpp +3/−0
- eigen3/doc/snippets/Matrix_resize_int_int.cpp +9/−0
- eigen3/doc/snippets/Matrix_setConstant_int.cpp +3/−0
- eigen3/doc/snippets/Matrix_setConstant_int_int.cpp +3/−0
- eigen3/doc/snippets/Matrix_setIdentity_int_int.cpp +3/−0
- eigen3/doc/snippets/Matrix_setOnes_int.cpp +3/−0
- eigen3/doc/snippets/Matrix_setOnes_int_int.cpp +3/−0
- eigen3/doc/snippets/Matrix_setRandom_int.cpp +3/−0
- eigen3/doc/snippets/Matrix_setRandom_int_int.cpp +3/−0
- eigen3/doc/snippets/Matrix_setZero_int.cpp +3/−0
- eigen3/doc/snippets/Matrix_setZero_int_int.cpp +3/−0
- eigen3/doc/snippets/PartialPivLU_solve.cpp +7/−0
- eigen3/doc/snippets/PartialRedux_count.cpp +3/−0
- eigen3/doc/snippets/PartialRedux_maxCoeff.cpp +3/−0
- eigen3/doc/snippets/PartialRedux_minCoeff.cpp +3/−0
- eigen3/doc/snippets/PartialRedux_norm.cpp +3/−0
- eigen3/doc/snippets/PartialRedux_prod.cpp +3/−0
- eigen3/doc/snippets/PartialRedux_squaredNorm.cpp +3/−0
- eigen3/doc/snippets/PartialRedux_sum.cpp +3/−0
- eigen3/doc/snippets/RealQZ_compute.cpp +17/−0
- eigen3/doc/snippets/RealSchur_RealSchur_MatrixType.cpp +10/−0
- eigen3/doc/snippets/RealSchur_compute.cpp +6/−0
- eigen3/doc/snippets/SelfAdjointEigenSolver_SelfAdjointEigenSolver.cpp +7/−0
- eigen3/doc/snippets/SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType.cpp +17/−0
- eigen3/doc/snippets/SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType2.cpp +16/−0
- eigen3/doc/snippets/SelfAdjointEigenSolver_compute_MatrixType.cpp +7/−0
- eigen3/doc/snippets/SelfAdjointEigenSolver_compute_MatrixType2.cpp +9/−0
- eigen3/doc/snippets/SelfAdjointEigenSolver_eigenvalues.cpp +4/−0
- eigen3/doc/snippets/SelfAdjointEigenSolver_eigenvectors.cpp +4/−0
- eigen3/doc/snippets/SelfAdjointEigenSolver_operatorInverseSqrt.cpp +9/−0
- eigen3/doc/snippets/SelfAdjointEigenSolver_operatorSqrt.cpp +8/−0
- eigen3/doc/snippets/SelfAdjointView_eigenvalues.cpp +3/−0
- eigen3/doc/snippets/SelfAdjointView_operatorNorm.cpp +3/−0
- eigen3/doc/snippets/TopicAliasing_block.cpp +7/−0
- eigen3/doc/snippets/TopicAliasing_block_correct.cpp +7/−0
- eigen3/doc/snippets/TopicAliasing_cwise.cpp +20/−0
- eigen3/doc/snippets/TopicAliasing_mult1.cpp +4/−0
- eigen3/doc/snippets/TopicAliasing_mult2.cpp +10/−0
- eigen3/doc/snippets/TopicAliasing_mult3.cpp +4/−0
- eigen3/doc/snippets/TopicStorageOrders_example.cpp +18/−0
- eigen3/doc/snippets/Tridiagonalization_Tridiagonalization_MatrixType.cpp +9/−0
- eigen3/doc/snippets/Tridiagonalization_compute.cpp +9/−0
- eigen3/doc/snippets/Tridiagonalization_decomposeInPlace.cpp +10/−0
- eigen3/doc/snippets/Tridiagonalization_diagonal.cpp +13/−0
- eigen3/doc/snippets/Tridiagonalization_householderCoefficients.cpp +6/−0
- eigen3/doc/snippets/Tridiagonalization_packedMatrix.cpp +8/−0
- eigen3/doc/snippets/Tutorial_AdvancedInitialization_Block.cpp +5/−0
- eigen3/doc/snippets/Tutorial_AdvancedInitialization_CommaTemporary.cpp +4/−0
- eigen3/doc/snippets/Tutorial_AdvancedInitialization_Join.cpp +11/−0
- eigen3/doc/snippets/Tutorial_AdvancedInitialization_LinSpaced.cpp +7/−0
- eigen3/doc/snippets/Tutorial_AdvancedInitialization_ThreeWays.cpp +20/−0
- eigen3/doc/snippets/Tutorial_AdvancedInitialization_Zero.cpp +13/−0
- eigen3/doc/snippets/Tutorial_Map_rowmajor.cpp +7/−0
- eigen3/doc/snippets/Tutorial_Map_using.cpp +21/−0
- eigen3/doc/snippets/Tutorial_commainit_01.cpp +5/−0
- eigen3/doc/snippets/Tutorial_commainit_01b.cpp +5/−0
- eigen3/doc/snippets/Tutorial_commainit_02.cpp +7/−0
- eigen3/doc/snippets/Tutorial_solve_matrix_inverse.cpp +6/−0
- eigen3/doc/snippets/Tutorial_solve_multiple_rhs.cpp +10/−0
- eigen3/doc/snippets/Tutorial_solve_reuse_decomposition.cpp +13/−0
- eigen3/doc/snippets/Tutorial_solve_singular.cpp +9/−0
- eigen3/doc/snippets/Tutorial_solve_triangular.cpp +8/−0
- eigen3/doc/snippets/Tutorial_solve_triangular_inplace.cpp +6/−0
- eigen3/doc/snippets/Vectorwise_reverse.cpp +10/−0
- eigen3/doc/snippets/class_FullPivLU.cpp +16/−0
- eigen3/doc/snippets/compile_snippet.cpp.in +12/−0
- eigen3/doc/snippets/tut_arithmetic_redux_minmax.cpp +12/−0
- eigen3/doc/snippets/tut_arithmetic_transpose_aliasing.cpp +5/−0
- eigen3/doc/snippets/tut_arithmetic_transpose_conjugate.cpp +12/−0
- eigen3/doc/snippets/tut_arithmetic_transpose_inplace.cpp +6/−0
- eigen3/doc/snippets/tut_matrix_assignment_resizing.cpp +5/−0
- eigen3/doc/special_examples/CMakeLists.txt +21/−0
- eigen3/doc/special_examples/Tutorial_sparse_example.cpp +32/−0
- eigen3/doc/special_examples/Tutorial_sparse_example_details.cpp +44/−0
- eigen3/doc/tutorial.cpp +62/−0
- eigen3/eigen3.pc.in +6/−0
- eigen3/failtest/CMakeLists.txt +54/−0
- eigen3/failtest/block_nonconst_ctor_on_const_xpr_0.cpp +15/−0
- eigen3/failtest/block_nonconst_ctor_on_const_xpr_1.cpp +15/−0
- eigen3/failtest/block_nonconst_ctor_on_const_xpr_2.cpp +16/−0
- eigen3/failtest/block_on_const_type_actually_const_0.cpp +16/−0
- eigen3/failtest/block_on_const_type_actually_const_1.cpp +16/−0
- eigen3/failtest/colpivqr_int.cpp +14/−0
- eigen3/failtest/const_qualified_block_method_retval_0.cpp +15/−0
- eigen3/failtest/const_qualified_block_method_retval_1.cpp +15/−0
- eigen3/failtest/const_qualified_diagonal_method_retval.cpp +15/−0
- eigen3/failtest/const_qualified_transpose_method_retval.cpp +15/−0
- eigen3/failtest/diagonal_nonconst_ctor_on_const_xpr.cpp +15/−0
- eigen3/failtest/diagonal_on_const_type_actually_const.cpp +16/−0
- eigen3/failtest/eigensolver_cplx.cpp +14/−0
- eigen3/failtest/eigensolver_int.cpp +14/−0
- eigen3/failtest/failtest_sanity_check.cpp +5/−0
- eigen3/failtest/fullpivlu_int.cpp +14/−0
- eigen3/failtest/fullpivqr_int.cpp +14/−0
- eigen3/failtest/jacobisvd_int.cpp +14/−0
- eigen3/failtest/ldlt_int.cpp +14/−0
- eigen3/failtest/llt_int.cpp +14/−0
- eigen3/failtest/map_nonconst_ctor_on_const_ptr_0.cpp +15/−0
- eigen3/failtest/map_nonconst_ctor_on_const_ptr_1.cpp +15/−0
- eigen3/failtest/map_nonconst_ctor_on_const_ptr_2.cpp +15/−0
- eigen3/failtest/map_nonconst_ctor_on_const_ptr_3.cpp +15/−0
- eigen3/failtest/map_nonconst_ctor_on_const_ptr_4.cpp +15/−0
- eigen3/failtest/map_on_const_type_actually_const_0.cpp +15/−0
- eigen3/failtest/map_on_const_type_actually_const_1.cpp +15/−0
- eigen3/failtest/partialpivlu_int.cpp +14/−0
- eigen3/failtest/qr_int.cpp +14/−0
- eigen3/failtest/ref_1.cpp +18/−0
- eigen3/failtest/ref_2.cpp +15/−0
- eigen3/failtest/ref_3.cpp +15/−0
- eigen3/failtest/ref_4.cpp +15/−0
- eigen3/failtest/ref_5.cpp +16/−0
- eigen3/failtest/transpose_nonconst_ctor_on_const_xpr.cpp +15/−0
- eigen3/failtest/transpose_on_const_type_actually_const.cpp +16/−0
- eigen3/lapack/CMakeLists.txt +449/−0
- eigen3/lapack/cholesky.cpp +72/−0
- eigen3/lapack/clacgv.f +116/−0
- eigen3/lapack/cladiv.f +97/−0
- eigen3/lapack/clarf.f +232/−0
- eigen3/lapack/clarfb.f +771/−0
- eigen3/lapack/clarfg.f +203/−0
- eigen3/lapack/clarft.f +328/−0
- eigen3/lapack/complex_double.cpp +17/−0
- eigen3/lapack/complex_single.cpp +17/−0
- eigen3/lapack/dladiv.f +128/−0
- eigen3/lapack/dlamch.f +189/−0
- eigen3/lapack/dlapy2.f +104/−0
- eigen3/lapack/dlapy3.f +111/−0
- eigen3/lapack/dlarf.f +227/−0
- eigen3/lapack/dlarfb.f +762/−0
- eigen3/lapack/dlarfg.f +196/−0
- eigen3/lapack/dlarft.f +326/−0
- eigen3/lapack/double.cpp +17/−0
- eigen3/lapack/dsecnd_NONE.f +52/−0
- eigen3/lapack/eigenvalues.cpp +79/−0
- eigen3/lapack/ilaclc.f +118/−0
- eigen3/lapack/ilaclr.f +121/−0
- eigen3/lapack/iladlc.f +118/−0
- eigen3/lapack/iladlr.f +121/−0
- eigen3/lapack/ilaslc.f +118/−0
- eigen3/lapack/ilaslr.f +121/−0
- eigen3/lapack/ilazlc.f +118/−0
- eigen3/lapack/ilazlr.f +121/−0
- eigen3/lapack/lapack_common.h +23/−0
- eigen3/lapack/lu.cpp +89/−0
- eigen3/lapack/second_NONE.f +52/−0
- eigen3/lapack/single.cpp +17/−0
- eigen3/lapack/sladiv.f +128/−0
- eigen3/lapack/slamch.f +192/−0
- eigen3/lapack/slapy2.f +104/−0
- eigen3/lapack/slapy3.f +111/−0
- eigen3/lapack/slarf.f +227/−0
- eigen3/lapack/slarfb.f +763/−0
- eigen3/lapack/slarfg.f +196/−0
- eigen3/lapack/slarft.f +326/−0
- eigen3/lapack/zlacgv.f +116/−0
- eigen3/lapack/zladiv.f +97/−0
- eigen3/lapack/zlarf.f +232/−0
- eigen3/lapack/zlarfb.f +774/−0
- eigen3/lapack/zlarfg.f +203/−0
- eigen3/lapack/zlarft.f +327/−0
- eigen3/scripts/CMakeLists.txt +6/−0
- eigen3/scripts/buildtests.in +22/−0
- eigen3/scripts/cdashtesting.cmake.in +49/−0
- eigen3/scripts/check.in +21/−0
- eigen3/scripts/debug.in +3/−0
- eigen3/scripts/eigen_gen_credits.cpp +232/−0
- eigen3/scripts/eigen_gen_docs +24/−0
- eigen3/scripts/release.in +3/−0
- eigen3/scripts/relicense.py +69/−0
- eigen3/signature_of_eigen3_matrix_library +1/−0
- eigen3/test/CMakeLists.txt +291/−0
- eigen3/test/adjoint.cpp +160/−0
- eigen3/test/array.cpp +308/−0
- eigen3/test/array_for_matrix.cpp +254/−0
- eigen3/test/array_replicate.cpp +69/−0
- eigen3/test/array_reverse.cpp +128/−0
- eigen3/test/bandmatrix.cpp +74/−0
- eigen3/test/basicstuff.cpp +214/−0
- eigen3/test/bicgstab.cpp +30/−0
- eigen3/test/block.cpp +251/−0
- eigen3/test/cholesky.cpp +404/−0
- eigen3/test/cholmod_support.cpp +56/−0
- eigen3/test/commainitializer.cpp +46/−0
- eigen3/test/conjugate_gradient.cpp +32/−0
- eigen3/test/conservative_resize.cpp +134/−0
- eigen3/test/corners.cpp +118/−0
- eigen3/test/cwiseop.cpp +184/−0
- eigen3/test/denseLM.cpp +190/−0
- eigen3/test/determinant.cpp +67/−0
- eigen3/test/diagonal.cpp +77/−0
- eigen3/test/diagonalmatrices.cpp +102/−0
- eigen3/test/dontalign.cpp +63/−0
- eigen3/test/dynalloc.cpp +134/−0
- eigen3/test/eigen2/CMakeLists.txt +61/−0
- eigen3/test/eigen2/eigen2_adjoint.cpp +99/−0
- eigen3/test/eigen2/eigen2_alignedbox.cpp +60/−0
- eigen3/test/eigen2/eigen2_array.cpp +142/−0
- eigen3/test/eigen2/eigen2_basicstuff.cpp +105/−0
- eigen3/test/eigen2/eigen2_bug_132.cpp +26/−0
- eigen3/test/eigen2/eigen2_cholesky.cpp +113/−0
- eigen3/test/eigen2/eigen2_commainitializer.cpp +46/−0
- eigen3/test/eigen2/eigen2_cwiseop.cpp +155/−0
- eigen3/test/eigen2/eigen2_determinant.cpp +61/−0
- eigen3/test/eigen2/eigen2_dynalloc.cpp +131/−0
- eigen3/test/eigen2/eigen2_eigensolver.cpp +146/−0
- eigen3/test/eigen2/eigen2_first_aligned.cpp +49/−0
- eigen3/test/eigen2/eigen2_geometry.cpp +432/−0
- eigen3/test/eigen2/eigen2_geometry_with_eigen2_prefix.cpp +435/−0
- eigen3/test/eigen2/eigen2_hyperplane.cpp +126/−0
- eigen3/test/eigen2/eigen2_inverse.cpp +62/−0
- eigen3/test/eigen2/eigen2_linearstructure.cpp +83/−0
- eigen3/test/eigen2/eigen2_lu.cpp +122/−0
- eigen3/test/eigen2/eigen2_map.cpp +114/−0
- eigen3/test/eigen2/eigen2_meta.cpp +60/−0
- eigen3/test/eigen2/eigen2_miscmatrices.cpp +48/−0
- eigen3/test/eigen2/eigen2_mixingtypes.cpp +77/−0
- eigen3/test/eigen2/eigen2_newstdvector.cpp +149/−0
- eigen3/test/eigen2/eigen2_nomalloc.cpp +53/−0
- eigen3/test/eigen2/eigen2_packetmath.cpp +132/−0
- eigen3/test/eigen2/eigen2_parametrizedline.cpp +62/−0
- eigen3/test/eigen2/eigen2_prec_inverse_4x4.cpp +84/−0
- eigen3/test/eigen2/eigen2_product_large.cpp +45/−0
- eigen3/test/eigen2/eigen2_product_small.cpp +22/−0
- eigen3/test/eigen2/eigen2_qr.cpp +69/−0
- eigen3/test/eigen2/eigen2_qtvector.cpp +158/−0
- eigen3/test/eigen2/eigen2_regression.cpp +136/−0
- eigen3/test/eigen2/eigen2_sizeof.cpp +31/−0
- eigen3/test/eigen2/eigen2_smallvectors.cpp +42/−0
- eigen3/test/eigen2/eigen2_sparse_basic.cpp +317/−0
- eigen3/test/eigen2/eigen2_sparse_product.cpp +115/−0
- eigen3/test/eigen2/eigen2_sparse_solvers.cpp +200/−0
- eigen3/test/eigen2/eigen2_sparse_vector.cpp +84/−0
- eigen3/test/eigen2/eigen2_stdvector.cpp +148/−0
- eigen3/test/eigen2/eigen2_submatrices.cpp +142/−0
- eigen3/test/eigen2/eigen2_sum.cpp +71/−0
- eigen3/test/eigen2/eigen2_svd.cpp +87/−0
- eigen3/test/eigen2/eigen2_swap.cpp +83/−0
- eigen3/test/eigen2/eigen2_triangular.cpp +148/−0
- eigen3/test/eigen2/eigen2_unalignedassert.cpp +116/−0
- eigen3/test/eigen2/eigen2_visitor.cpp +116/−0
- eigen3/test/eigen2/gsl_helper.h +175/−0
- eigen3/test/eigen2/main.h +399/−0
- eigen3/test/eigen2/product.h +129/−0
- eigen3/test/eigen2/runtest.sh +28/−0
- eigen3/test/eigen2/sparse.h +154/−0
- eigen3/test/eigen2/testsuite.cmake +197/−0
- eigen3/test/eigen2support.cpp +67/−0
- eigen3/test/eigensolver_complex.cpp +122/−0
- eigen3/test/eigensolver_generalized_real.cpp +59/−0
- eigen3/test/eigensolver_generic.cpp +125/−0
- eigen3/test/eigensolver_selfadjoint.cpp +160/−0
- eigen3/test/exceptions.cpp +113/−0
- eigen3/test/first_aligned.cpp +51/−0
- eigen3/test/geo_alignedbox.cpp +178/−0
- eigen3/test/geo_eulerangles.cpp +112/−0
- eigen3/test/geo_homogeneous.cpp +103/−0
- eigen3/test/geo_hyperplane.cpp +185/−0
- eigen3/test/geo_orthomethods.cpp +121/−0
- eigen3/test/geo_parametrizedline.cpp +104/−0
- eigen3/test/geo_quaternion.cpp +284/−0
- eigen3/test/geo_transformations.cpp +521/−0
- eigen3/test/hessenberg.cpp +62/−0
- eigen3/test/householder.cpp +138/−0
- eigen3/test/integer_types.cpp +161/−0
- eigen3/test/inverse.cpp +104/−0
- eigen3/test/jacobi.cpp +81/−0
- eigen3/test/jacobisvd.cpp +462/−0
- eigen3/test/linearstructure.cpp +84/−0
- eigen3/test/lu.cpp +210/−0
- eigen3/test/main.h +552/−0
- eigen3/test/mapped_matrix.cpp +165/−0
- eigen3/test/mapstaticmethods.cpp +173/−0
- eigen3/test/mapstride.cpp +148/−0
- eigen3/test/meta.cpp +73/−0
- eigen3/test/metis_support.cpp +39/−0
- eigen3/test/miscmatrices.cpp +47/−0
- eigen3/test/mixingtypes.cpp +132/−0
- eigen3/test/nesting_ops.cpp +33/−0
- eigen3/test/nomalloc.cpp +212/−0
- eigen3/test/nullary.cpp +131/−0
- eigen3/test/packetmath.cpp +385/−0
- eigen3/test/pardiso_support.cpp +29/−0
- eigen3/test/pastix_support.cpp +44/−0
- eigen3/test/permutationmatrices.cpp +116/−0
- eigen3/test/prec_inverse_4x4.cpp +68/−0
- eigen3/test/product.h +150/−0
- eigen3/test/product_extra.cpp +237/−0
- eigen3/test/product_large.cpp +64/−0
- eigen3/test/product_mmtr.cpp +63/−0
- eigen3/test/product_notemporary.cpp +141/−0
- eigen3/test/product_selfadjoint.cpp +80/−0
- eigen3/test/product_small.cpp +50/−0
- eigen3/test/product_symm.cpp +94/−0
- eigen3/test/product_syrk.cpp +135/−0
- eigen3/test/product_trmm.cpp +107/−0
- eigen3/test/product_trmv.cpp +89/−0
- eigen3/test/product_trsolve.cpp +93/−0
- eigen3/test/qr.cpp +127/−0
- eigen3/test/qr_colpivoting.cpp +150/−0
- eigen3/test/qr_fullpivoting.cpp +137/−0
- eigen3/test/qtvector.cpp +158/−0
- eigen3/test/real_qz.cpp +81/−0
- eigen3/test/redux.cpp +159/−0
- eigen3/test/ref.cpp +276/−0
- eigen3/test/resize.cpp +41/−0
- eigen3/test/runtest.sh +20/−0
- eigen3/test/schur_complex.cpp +91/−0
- eigen3/test/schur_real.cpp +112/−0
- eigen3/test/selfadjoint.cpp +61/−0
- eigen3/test/simplicial_cholesky.cpp +45/−0
- eigen3/test/sizeof.cpp +34/−0
- eigen3/test/sizeoverflow.cpp +66/−0
- eigen3/test/smallvectors.cpp +67/−0
- eigen3/test/sparse.h +207/−0
- eigen3/test/sparseLM.cpp +176/−0
- eigen3/test/sparse_basic.cpp +550/−0
- eigen3/test/sparse_permutations.cpp +187/−0
- eigen3/test/sparse_product.cpp +252/−0
- eigen3/test/sparse_solver.h +362/−0
- eigen3/test/sparse_solvers.cpp +112/−0
- eigen3/test/sparse_vector.cpp +110/−0
- eigen3/test/sparselu.cpp +61/−0
- eigen3/test/sparseqr.cpp +100/−0
- eigen3/test/special_numbers.cpp +58/−0
- eigen3/test/spqr_support.cpp +62/−0
- eigen3/test/stable_norm.cpp +115/−0
- eigen3/test/stddeque.cpp +132/−0
- eigen3/test/stdlist.cpp +132/−0
- eigen3/test/stdvector.cpp +148/−0
- eigen3/test/stdvector_overload.cpp +161/−0
- eigen3/test/superlu_support.cpp +22/−0
- eigen3/test/swap.cpp +83/−0
- eigen3/test/testsuite.cmake +229/−0
- eigen3/test/triangular.cpp +232/−0
- eigen3/test/umeyama.cpp +183/−0
- eigen3/test/umfpack_support.cpp +31/−0
- eigen3/test/unalignedassert.cpp +127/−0
- eigen3/test/unalignedcount.cpp +46/−0
- eigen3/test/upperbidiagonalization.cpp +43/−0
- eigen3/test/vectorization_logic.cpp +235/−0
- eigen3/test/vectorwiseop.cpp +205/−0
- eigen3/test/visitor.cpp +130/−0
- eigen3/test/zerosized.cpp +84/−0
- eigen3/unsupported/CMakeLists.txt +7/−0
- eigen3/unsupported/Eigen/AdolcForward +156/−0
- eigen3/unsupported/Eigen/AlignedVector3 +190/−0
- eigen3/unsupported/Eigen/ArpackSupport +31/−0
- eigen3/unsupported/Eigen/AutoDiff +40/−0
- eigen3/unsupported/Eigen/BVH +95/−0
- eigen3/unsupported/Eigen/CMakeLists.txt +11/−0
- eigen3/unsupported/Eigen/FFT +418/−0
- eigen3/unsupported/Eigen/IterativeSolvers +45/−0
- eigen3/unsupported/Eigen/KroneckerProduct +34/−0
- eigen3/unsupported/Eigen/LevenbergMarquardt +45/−0
- eigen3/unsupported/Eigen/MPRealSupport +203/−0
- eigen3/unsupported/Eigen/MatrixFunctions +447/−0
- eigen3/unsupported/Eigen/MoreVectorization +24/−0
- eigen3/unsupported/Eigen/NonLinearOptimization +134/−0
- eigen3/unsupported/Eigen/NumericalDiff +56/−0
- eigen3/unsupported/Eigen/OpenGLSupport +322/−0
- eigen3/unsupported/Eigen/Polynomials +138/−0
- eigen3/unsupported/Eigen/SVD +39/−0
- eigen3/unsupported/Eigen/Skyline +39/−0
- eigen3/unsupported/Eigen/SparseExtra +56/−0
- eigen3/unsupported/Eigen/Splines +31/−0
- eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h +83/−0
- eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h +642/−0
- eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h +220/−0
- eigen3/unsupported/Eigen/src/AutoDiff/CMakeLists.txt +6/−0
- eigen3/unsupported/Eigen/src/BVH/BVAlgorithms.h +293/−0
- eigen3/unsupported/Eigen/src/BVH/CMakeLists.txt +6/−0
- eigen3/unsupported/Eigen/src/BVH/KdBVH.h +222/−0
- eigen3/unsupported/Eigen/src/CMakeLists.txt +14/−0
- eigen3/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h +805/−0
- eigen3/unsupported/Eigen/src/FFT/CMakeLists.txt +6/−0
- eigen3/unsupported/Eigen/src/FFT/ei_fftw_impl.h +261/−0
- eigen3/unsupported/Eigen/src/FFT/ei_kissfft_impl.h +420/−0
- eigen3/unsupported/Eigen/src/IterativeSolvers/CMakeLists.txt +6/−0
- eigen3/unsupported/Eigen/src/IterativeSolvers/ConstrainedConjGrad.h +189/−0
- eigen3/unsupported/Eigen/src/IterativeSolvers/DGMRES.h +542/−0
- eigen3/unsupported/Eigen/src/IterativeSolvers/GMRES.h +370/−0
- eigen3/unsupported/Eigen/src/IterativeSolvers/IncompleteCholesky.h +278/−0
- eigen3/unsupported/Eigen/src/IterativeSolvers/IncompleteLU.h +113/−0
- eigen3/unsupported/Eigen/src/IterativeSolvers/IterationController.h +154/−0
- eigen3/unsupported/Eigen/src/IterativeSolvers/MINRES.h +310/−0
- eigen3/unsupported/Eigen/src/IterativeSolvers/Scaling.h +185/−0
- eigen3/unsupported/Eigen/src/KroneckerProduct/CMakeLists.txt +6/−0
- eigen3/unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h +244/−0
- eigen3/unsupported/Eigen/src/LevenbergMarquardt/CMakeLists.txt +6/−0
- eigen3/unsupported/Eigen/src/LevenbergMarquardt/CopyrightMINPACK.txt +52/−0
- eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMcovar.h +85/−0
- eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h +202/−0
- eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMpar.h +160/−0
- eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMqrsolv.h +189/−0
- eigen3/unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h +377/−0
- eigen3/unsupported/Eigen/src/MatrixFunctions/CMakeLists.txt +6/−0
- eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h +451/−0
- eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h +591/−0
- eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixFunctionAtomic.h +131/−0
- eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h +486/−0
- eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h +508/−0
- eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h +466/−0
- eigen3/unsupported/Eigen/src/MatrixFunctions/StemFunction.h +105/−0
- eigen3/unsupported/Eigen/src/MoreVectorization/CMakeLists.txt +6/−0
- eigen3/unsupported/Eigen/src/MoreVectorization/MathFunctions.h +95/−0
- eigen3/unsupported/Eigen/src/NonLinearOptimization/CMakeLists.txt +6/−0
- eigen3/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h +601/−0
- eigen3/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h +650/−0
- eigen3/unsupported/Eigen/src/NonLinearOptimization/chkder.h +66/−0
- eigen3/unsupported/Eigen/src/NonLinearOptimization/covar.h +70/−0
- eigen3/unsupported/Eigen/src/NonLinearOptimization/dogleg.h +107/−0
- eigen3/unsupported/Eigen/src/NonLinearOptimization/fdjac1.h +79/−0
- eigen3/unsupported/Eigen/src/NonLinearOptimization/lmpar.h +298/−0
- eigen3/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h +91/−0
- eigen3/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h +30/−0
- eigen3/unsupported/Eigen/src/NonLinearOptimization/r1updt.h +99/−0
- eigen3/unsupported/Eigen/src/NonLinearOptimization/rwupdt.h +49/−0
- eigen3/unsupported/Eigen/src/NumericalDiff/CMakeLists.txt +6/−0
- eigen3/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h +130/−0
- eigen3/unsupported/Eigen/src/Polynomials/CMakeLists.txt +6/−0
- eigen3/unsupported/Eigen/src/Polynomials/Companion.h +276/−0
- eigen3/unsupported/Eigen/src/Polynomials/PolynomialSolver.h +389/−0
- eigen3/unsupported/Eigen/src/Polynomials/PolynomialUtils.h +143/−0
- eigen3/unsupported/Eigen/src/SVD/BDCSVD.h +748/−0
- eigen3/unsupported/Eigen/src/SVD/CMakeLists.txt +6/−0
- eigen3/unsupported/Eigen/src/SVD/JacobiSVD.h +782/−0
- eigen3/unsupported/Eigen/src/SVD/SVDBase.h +236/−0
- eigen3/unsupported/Eigen/src/SVD/TODOBdcsvd.txt +29/−0
- eigen3/unsupported/Eigen/src/SVD/doneInBDCSVD.txt +21/−0
- eigen3/unsupported/Eigen/src/Skyline/CMakeLists.txt +6/−0
- eigen3/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h +352/−0
- eigen3/unsupported/Eigen/src/Skyline/SkylineMatrix.h +862/−0
- eigen3/unsupported/Eigen/src/Skyline/SkylineMatrixBase.h +212/−0
- eigen3/unsupported/Eigen/src/Skyline/SkylineProduct.h +295/−0
- eigen3/unsupported/Eigen/src/Skyline/SkylineStorage.h +259/−0
- eigen3/unsupported/Eigen/src/Skyline/SkylineUtil.h +89/−0
- eigen3/unsupported/Eigen/src/SparseExtra/BlockOfDynamicSparseMatrix.h +122/−0
- eigen3/unsupported/Eigen/src/SparseExtra/CMakeLists.txt +6/−0
- eigen3/unsupported/Eigen/src/SparseExtra/DynamicSparseMatrix.h +357/−0
- eigen3/unsupported/Eigen/src/SparseExtra/MarketIO.h +273/−0
- eigen3/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h +232/−0
- eigen3/unsupported/Eigen/src/SparseExtra/RandomSetter.h +327/−0
- eigen3/unsupported/Eigen/src/Splines/CMakeLists.txt +6/−0
- eigen3/unsupported/Eigen/src/Splines/Spline.h +474/−0
- eigen3/unsupported/Eigen/src/Splines/SplineFitting.h +156/−0
- eigen3/unsupported/Eigen/src/Splines/SplineFwd.h +86/−0
- eigen3/unsupported/README.txt +50/−0
- eigen3/unsupported/bench/bench_svd.cpp +123/−0
- eigen3/unsupported/doc/CMakeLists.txt +4/−0
- eigen3/unsupported/doc/Overview.dox +25/−0
- eigen3/unsupported/doc/eigendoxy_layout.xml.in +177/−0
- eigen3/unsupported/doc/examples/BVH_Example.cpp +52/−0
- eigen3/unsupported/doc/examples/CMakeLists.txt +20/−0
- eigen3/unsupported/doc/examples/FFT.cpp +118/−0
- eigen3/unsupported/doc/examples/MatrixExponential.cpp +16/−0
- eigen3/unsupported/doc/examples/MatrixFunction.cpp +23/−0
- eigen3/unsupported/doc/examples/MatrixLogarithm.cpp +15/−0
- eigen3/unsupported/doc/examples/MatrixPower.cpp +16/−0
- eigen3/unsupported/doc/examples/MatrixPower_optimal.cpp +17/−0
- eigen3/unsupported/doc/examples/MatrixSine.cpp +20/−0
- eigen3/unsupported/doc/examples/MatrixSinh.cpp +20/−0
- eigen3/unsupported/doc/examples/MatrixSquareRoot.cpp +16/−0
- eigen3/unsupported/doc/examples/PolynomialSolver1.cpp +53/−0
- eigen3/unsupported/doc/examples/PolynomialUtils1.cpp +20/−0
- eigen3/unsupported/doc/snippets/CMakeLists.txt +26/−0
- eigen3/unsupported/test/BVH.cpp +222/−0
- eigen3/unsupported/test/CMakeLists.txt +90/−0
- eigen3/unsupported/test/FFT.cpp +2/−0
- eigen3/unsupported/test/FFTW.cpp +262/−0
- eigen3/unsupported/test/NonLinearOptimization.cpp +1870/−0
- eigen3/unsupported/test/NumericalDiff.cpp +114/−0
- eigen3/unsupported/test/alignedvector3.cpp +59/−0
- eigen3/unsupported/test/autodiff.cpp +173/−0
- eigen3/unsupported/test/bdcsvd.cpp +213/−0
- eigen3/unsupported/test/dgmres.cpp +31/−0
- eigen3/unsupported/test/forward_adolc.cpp +143/−0
- eigen3/unsupported/test/gmres.cpp +31/−0
- eigen3/unsupported/test/jacobisvd.cpp +198/−0
- eigen3/unsupported/test/kronecker_product.cpp +181/−0
- eigen3/unsupported/test/levenberg_marquardt.cpp +1448/−0
- eigen3/unsupported/test/matrix_exponential.cpp +141/−0
- eigen3/unsupported/test/matrix_function.cpp +193/−0
- eigen3/unsupported/test/matrix_functions.h +47/−0
- eigen3/unsupported/test/matrix_power.cpp +133/−0
- eigen3/unsupported/test/matrix_square_root.cpp +31/−0
- eigen3/unsupported/test/minres.cpp +49/−0
- eigen3/unsupported/test/mpreal/mpreal.h +3074/−0
- eigen3/unsupported/test/mpreal_support.cpp +57/−0
- eigen3/unsupported/test/openglsupport.cpp +337/−0
- eigen3/unsupported/test/polynomialsolver.cpp +213/−0
- eigen3/unsupported/test/polynomialutils.cpp +113/−0
- eigen3/unsupported/test/sparse_extra.cpp +148/−0
- eigen3/unsupported/test/splines.cpp +244/−0
- eigen3/unsupported/test/svd_common.h +261/−0
- test/regression.hs +1/−1
Data/Eigen/Internal.hsc view
@@ -25,34 +25,34 @@ instance Elem (Complex Double) (CComplex CDouble) where class Cast a b where- cast :: a -> b+ cast :: a -> b -- | Complex number for FFI with the same memory layout as std::complex\<T\> data CComplex a = CComplex !a !a instance Storable a => Storable (CComplex a) where- sizeOf _ = sizeOf (undefined :: a) * 2- alignment _ = alignment (undefined :: a)- poke p (CComplex x y) = do- pokeElemOff (castPtr p) 0 x- pokeElemOff (castPtr p) 1 y- peek p = CComplex- <$> peekElemOff (castPtr p) 0- <*> peekElemOff (castPtr p) 1+ sizeOf _ = sizeOf (undefined :: a) * 2+ alignment _ = alignment (undefined :: a)+ poke p (CComplex x y) = do+ pokeElemOff (castPtr p) 0 x+ pokeElemOff (castPtr p) 1 y+ peek p = CComplex+ <$> peekElemOff (castPtr p) 0+ <*> peekElemOff (castPtr p) 1 data CTriplet a = CTriplet !CInt !CInt !a instance Storable a => Storable (CTriplet a) where- sizeOf _ = sizeOf (undefined :: a) + sizeOf (undefined :: CInt) * 2- alignment _ = alignment (undefined :: CInt)- poke p (CTriplet row col val) = do- pokeElemOff (castPtr p) 0 row- pokeElemOff (castPtr p) 1 col- pokeByteOff p (sizeOf (undefined :: CInt) * 2) val- peek p = CTriplet- <$> peekElemOff (castPtr p) 0- <*> peekElemOff (castPtr p) 1- <*> peekByteOff p (sizeOf (undefined :: CInt) * 2)+ sizeOf _ = sizeOf (undefined :: a) + sizeOf (undefined :: CInt) * 2+ alignment _ = alignment (undefined :: CInt)+ poke p (CTriplet row col val) = do+ pokeElemOff (castPtr p) 0 row+ pokeElemOff (castPtr p) 1 col+ pokeByteOff p (sizeOf (undefined :: CInt) * 2) val+ peek p = CTriplet+ <$> peekElemOff (castPtr p) 0+ <*> peekElemOff (castPtr p) 1+ <*> peekByteOff p (sizeOf (undefined :: CInt) * 2) instance Cast CInt Int where; cast = fromIntegral instance Cast Int CInt where; cast = fromIntegral@@ -73,27 +73,30 @@ decodeInt :: BS.ByteString -> CInt decodeInt (BSI.PS fp fo fs)- | fs == sizeOf x = x- | otherwise = error "decodeInt: wrong buffer size"- where x = performIO $ withForeignPtr fp $ peek . (`plusPtr` fo)+ | fs == sizeOf x = x+ | otherwise = error "decodeInt: wrong buffer size"+ where x = performIO $ withForeignPtr fp $ peek . (`plusPtr` fo) data CSparseMatrix a b type CSparseMatrixPtr a b = Ptr (CSparseMatrix a b) +data CSolver a b+type CSolverPtr a b = Ptr (CSolver a b)+ performIO :: IO a -> a performIO = unsafeDupablePerformIO plusForeignPtr :: ForeignPtr a -> Int -> ForeignPtr b plusForeignPtr fp fo = castForeignPtr fp' where- vs :: VS.Vector CChar- vs = VS.unsafeFromForeignPtr (castForeignPtr fp) fo 0- (fp', _) = VS.unsafeToForeignPtr0 vs+ vs :: VS.Vector CChar+ vs = VS.unsafeFromForeignPtr (castForeignPtr fp) fo 0+ (fp', _) = VS.unsafeToForeignPtr0 vs foreign import ccall "eigen-proxy.h free" c_freeString :: CString -> IO () call :: IO CString -> IO () call func = func >>= \c_str -> when (c_str /= nullPtr) $- peekCString c_str >>= \str -> c_freeString c_str >> fail str+ peekCString c_str >>= \str -> c_freeString c_str >> fail str foreign import ccall "eigen-proxy.h free" free :: Ptr a -> IO () @@ -111,74 +114,90 @@ #let api name, args = "foreign import ccall \"eigen_%s\" c_%s :: CInt -> %s\n%s :: forall b . Code b => %s\n%s = c_%s (code (undefined :: b))", #name, #name, args, #name, args, #name, #name -#api random, "Ptr b -> CInt -> CInt -> IO CString"-#api identity, "Ptr b -> CInt -> CInt -> IO CString"-#api add, "Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString"-#api sub, "Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString"-#api mul, "Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString"-#api diagonal, "Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString"-#api transpose, "Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString"-#api inverse, "Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString"-#api adjoint, "Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString"-#api conjugate, "Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString"-#api normalize, "Ptr b -> CInt -> CInt -> IO CString"-#api sum, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"-#api prod, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"-#api mean, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"-#api norm, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"-#api trace, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"-#api squaredNorm, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"-#api blueNorm, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"-#api hypotNorm, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"-#api determinant, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"-#api rank, "CInt -> Ptr CInt -> Ptr b -> CInt -> CInt -> IO CString"-#api image, "CInt -> Ptr (Ptr b) -> Ptr CInt -> Ptr CInt -> Ptr b -> CInt -> CInt -> IO CString"-#api kernel, "CInt -> Ptr (Ptr b) -> Ptr CInt -> Ptr CInt -> Ptr b -> CInt -> CInt -> IO CString"-#api solve, "CInt -> Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString"+#api random, "Ptr b -> CInt -> CInt -> IO CString"+#api identity, "Ptr b -> CInt -> CInt -> IO CString"+#api add, "Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString"+#api sub, "Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString"+#api mul, "Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString"+#api diagonal, "Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString"+#api transpose, "Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString"+#api inverse, "Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString"+#api adjoint, "Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString"+#api conjugate, "Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString"+#api normalize, "Ptr b -> CInt -> CInt -> IO CString"+#api sum, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"+#api prod, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"+#api mean, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"+#api norm, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"+#api trace, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"+#api squaredNorm, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"+#api blueNorm, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"+#api hypotNorm, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"+#api determinant, "Ptr b -> Ptr b -> CInt -> CInt -> IO CString"+#api rank, "CInt -> Ptr CInt -> Ptr b -> CInt -> CInt -> IO CString"+#api image, "CInt -> Ptr (Ptr b) -> Ptr CInt -> Ptr CInt -> Ptr b -> CInt -> CInt -> IO CString"+#api kernel, "CInt -> Ptr (Ptr b) -> Ptr CInt -> Ptr CInt -> Ptr b -> CInt -> CInt -> IO CString"+#api solve, "CInt -> Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString" #api relativeError, "Ptr b -> Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> Ptr b -> CInt -> CInt -> IO CString" #let api2 name, args = "foreign import ccall \"eigen_%s\" c_%s :: CInt -> %s\n%s :: forall a b . Code b => %s\n%s = c_%s (code (undefined :: b))", #name, #name, args, #name, args, #name, #name -#api2 sparse_fromList, "CInt -> CInt -> Ptr (CTriplet b) -> CInt -> Ptr (CSparseMatrixPtr a b) -> IO CString"-#api2 sparse_toList, "CSparseMatrixPtr a b -> Ptr (CTriplet b) -> CInt -> IO CString"-#api2 sparse_free, "CSparseMatrixPtr a b -> IO CString"-#api2 sparse_compress, "CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"-#api2 sparse_uncompress, "CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"-#api2 sparse_isCompressed, "CSparseMatrixPtr a b -> Ptr CInt -> IO CString"-#api2 sparse_transpose, "CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"-#api2 sparse_adjoint, "CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"-#api2 sparse_pruned, "CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"-#api2 sparse_prunedRef, "CSparseMatrixPtr a b -> Ptr b -> Ptr (CSparseMatrixPtr a b) -> IO CString"-#api2 sparse_scale, "CSparseMatrixPtr a b -> Ptr b -> Ptr (CSparseMatrixPtr a b) -> IO CString"-#api2 sparse_lowerTriangle, "CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"-#api2 sparse_upperTriangle, "CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"-#api2 sparse_nonZeros, "CSparseMatrixPtr a b -> Ptr CInt -> IO CString"-#api2 sparse_innerSize, "CSparseMatrixPtr a b -> Ptr CInt -> IO CString"-#api2 sparse_outerSize, "CSparseMatrixPtr a b -> Ptr CInt -> IO CString"-#api2 sparse_coeff, "CSparseMatrixPtr a b -> CInt -> CInt -> Ptr b -> IO CString"-#api2 sparse_cols, "CSparseMatrixPtr a b -> Ptr CInt -> IO CString"-#api2 sparse_rows, "CSparseMatrixPtr a b -> Ptr CInt -> IO CString"-#api2 sparse_norm, "CSparseMatrixPtr a b -> Ptr b -> IO CString"-#api2 sparse_squaredNorm, "CSparseMatrixPtr a b -> Ptr b -> IO CString"-#api2 sparse_blueNorm, "CSparseMatrixPtr a b -> Ptr b -> IO CString"-#api2 sparse_add, "CSparseMatrixPtr a b -> CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"-#api2 sparse_sub, "CSparseMatrixPtr a b -> CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"-#api2 sparse_mul, "CSparseMatrixPtr a b -> CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"-#api2 sparse_block, "CSparseMatrixPtr a b -> CInt -> CInt -> CInt -> CInt -> Ptr (CSparseMatrixPtr a b) -> IO CString"-#api2 sparse_fromMatrix, "Ptr b -> CInt -> CInt -> Ptr (CSparseMatrixPtr a b) -> IO CString"-#api2 sparse_toMatrix, "CSparseMatrixPtr a b -> Ptr b -> CInt -> CInt -> IO CString"+#api2 sparse_fromList, "CInt -> CInt -> Ptr (CTriplet b) -> CInt -> Ptr (CSparseMatrixPtr a b) -> IO CString"+#api2 sparse_toList, "CSparseMatrixPtr a b -> Ptr (CTriplet b) -> CInt -> IO CString"+#api2 sparse_free, "CSparseMatrixPtr a b -> IO CString"+#api2 sparse_makeCompressed,"CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"+#api2 sparse_uncompress, "CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"+#api2 sparse_isCompressed, "CSparseMatrixPtr a b -> Ptr CInt -> IO CString"+#api2 sparse_transpose, "CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"+#api2 sparse_adjoint, "CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"+#api2 sparse_pruned, "CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"+#api2 sparse_prunedRef, "CSparseMatrixPtr a b -> Ptr b -> Ptr (CSparseMatrixPtr a b) -> IO CString"+#api2 sparse_scale, "CSparseMatrixPtr a b -> Ptr b -> Ptr (CSparseMatrixPtr a b) -> IO CString"+#api2 sparse_diagonal, "CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"+#api2 sparse_nonZeros, "CSparseMatrixPtr a b -> Ptr CInt -> IO CString"+#api2 sparse_innerSize, "CSparseMatrixPtr a b -> Ptr CInt -> IO CString"+#api2 sparse_outerSize, "CSparseMatrixPtr a b -> Ptr CInt -> IO CString"+#api2 sparse_coeff, "CSparseMatrixPtr a b -> CInt -> CInt -> Ptr b -> IO CString"+#api2 sparse_cols, "CSparseMatrixPtr a b -> Ptr CInt -> IO CString"+#api2 sparse_rows, "CSparseMatrixPtr a b -> Ptr CInt -> IO CString"+#api2 sparse_norm, "CSparseMatrixPtr a b -> Ptr b -> IO CString"+#api2 sparse_squaredNorm, "CSparseMatrixPtr a b -> Ptr b -> IO CString"+#api2 sparse_blueNorm, "CSparseMatrixPtr a b -> Ptr b -> IO CString"+#api2 sparse_add, "CSparseMatrixPtr a b -> CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"+#api2 sparse_sub, "CSparseMatrixPtr a b -> CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"+#api2 sparse_mul, "CSparseMatrixPtr a b -> CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"+#api2 sparse_block, "CSparseMatrixPtr a b -> CInt -> CInt -> CInt -> CInt -> Ptr (CSparseMatrixPtr a b) -> IO CString"+#api2 sparse_fromMatrix, "Ptr b -> CInt -> CInt -> Ptr (CSparseMatrixPtr a b) -> IO CString"+#api2 sparse_toMatrix, "CSparseMatrixPtr a b -> Ptr b -> CInt -> CInt -> IO CString" +#let api3 name, args = "foreign import ccall \"eigen_%s\" c_%s :: CInt -> CInt -> %s\n%s :: forall s a b . (Enum s, Code b) => s -> %s\n%s s = c_%s (code (undefined :: b)) (cast (fromEnum s))", #name, #name, args, #name, args, #name, #name++#api3 sparse_la_newSolver, "Ptr (CSolverPtr a b) -> IO CString"+#api3 sparse_la_freeSolver, "CSolverPtr a b -> IO CString"+#api3 sparse_la_factorize, "CSolverPtr a b -> CSparseMatrixPtr a b -> IO CString"+#api3 sparse_la_analyzePattern, "CSolverPtr a b -> CSparseMatrixPtr a b -> IO CString"+#api3 sparse_la_compute, "CSolverPtr a b -> CSparseMatrixPtr a b -> IO CString"+#api3 sparse_la_tolerance, "CSolverPtr a b -> Ptr CDouble -> IO CString"+#api3 sparse_la_setTolerance, "CSolverPtr a b -> CDouble -> IO CString"+#api3 sparse_la_maxIterations, "CSolverPtr a b -> Ptr CInt -> IO CString"+#api3 sparse_la_setMaxIterations, "CSolverPtr a b -> CInt -> IO CString"+#api3 sparse_la_info, "CSolverPtr a b -> Ptr CInt -> IO CString"+#api3 sparse_la_error, "CSolverPtr a b -> Ptr CDouble -> IO CString"+#api3 sparse_la_iterations, "CSolverPtr a b -> Ptr CInt -> IO CString"+#api3 sparse_la_solve, "CSolverPtr a b -> CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"+-- #api3 sparse_la_solveWithGuess, "CSolverPtr a b -> CSparseMatrixPtr a b -> CSparseMatrixPtr a b -> Ptr (CSparseMatrixPtr a b) -> IO CString"+ openStream :: BSL.ByteString -> IO (IORef BSL.ByteString) openStream = newIORef readStream :: IORef BSL.ByteString -> Int -> IO BS.ByteString readStream ref size = readIORef ref >>= \a ->- let (b,c) = BSL.splitAt (fromIntegral size) a- in if BSL.length b /= fromIntegral size- then error "readStream: stream exhausted"- else do- writeIORef ref c- return . BS.concat . BSL.toChunks $ b+ let (b,c) = BSL.splitAt (fromIntegral size) a+ in if BSL.length b /= fromIntegral size+ then error "readStream: stream exhausted"+ else do+ writeIORef ref c+ return . BS.concat . BSL.toChunks $ b closeStream :: IORef BSL.ByteString -> IO () closeStream ref = BSL.null <$> readIORef ref >>= (`unless` fail "closeStream: stream underrun")
Data/Eigen/LA.hs view
@@ -148,7 +148,7 @@ -- | Robust Cholesky decomposition of a matrix with pivoting. | LDLT -- | Two-sided Jacobi SVD decomposition of a rectangular matrix.- | JacobiSVD deriving (Show, Enum)+ | JacobiSVD deriving (Eq, Enum, Show, Read) -- | [x = solve d a b] finds a solution @x@ of @ax = b@ equation using decomposition @d@
+ Data/Eigen/SparseLA.hs view
@@ -0,0 +1,286 @@+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE FlexibleInstances #-}++{- |++This documentation is based on original Eigen page <http://eigen.tuxfamily.org/dox/group__TopicSparseSystems.html Solving Sparse Linear Systems>++Eigen currently provides a limited set of built-in MPL2 compatible solvers.+hey are summarized in the following table:++@+Sparse solver Solver kind Matrix kind Notes++ConjugateGradient Classic iterative CG SPD Recommended for large symmetric+ problems (e.g., 3D Poisson eq.)+BiCGSTAB Iterative stabilized Square+ bi-conjugate gradient+SparseLU LU factorization Square Optimized for small and large problems+ with irregular patterns+SparseQR QR factorization Any, rectangular Recommended for least-square problems,+ has a basic rank-revealing feature+@++All these solvers follow the same general concept. Here is a typical and general example:++@+let+ a :: SparseMatrixXd+ a = ... -- fill a++ b :: SparseMatrixXd+ b = ... -- fill b++ validate msg = info >>= (`when` fail msg) . (/= Success)++// solve Ax = b+runSolverT solver $ do+ compute a+ validate "decomposition failed"++ x <- solve b+ validate "solving failed"++ // solve for another right hand side+ x1 <- solve b1+@++In the case where multiple problems with the same sparsity pattern have to be solved, then the "compute" step can be decomposed as follow:++@+runSolverT solver $ do+ analyzePattern a1+ factorize a1+ x1 <- solve b1+ x2 <- solve b2++ factorize a2+ x1 <- solve b1+ x2 <- solve b2+@++Finally, each solver provides some specific features, such as determinant, access to the factors, controls of the iterations, and so on.++= The Compute Step++In the `compute` function, the matrix is generally factorized: LLT for self-adjoint matrices, LDLT for general hermitian matrices,+LU for non hermitian matrices and QR for rectangular matrices. These are the results of using direct solvers.+For this class of solvers precisely, the compute step is further subdivided into `analyzePattern` and `factorize`.++The goal of `analyzePattern` is to reorder the nonzero elements of the matrix, such that the factorization step creates less fill-in.+This step exploits only the structure of the matrix. Hence, the results of this step can be used for other linear systems where the+matrix has the same structure.++In `factorize`, the factors of the coefficient matrix are computed. This step should be called each time the values of the matrix change.+However, the structural pattern of the matrix should not change between multiple calls.++For iterative solvers, the `compute` step is used to eventually setup a preconditioner.+Remember that, basically, the goal of the preconditioner is to speedup the convergence of an iterative method by solving a modified linear+system where the coefficient matrix has more clustered eigenvalues.+For real problems, an iterative solver should always be used with a preconditioner.++= The Solve Step++The `solve` function computes the solution of the linear systems with one or many right hand sides.++@+x <- solve b+@++Here, @b@ can be a vector or a matrix where the columns form the different right hand sides.+The `solve` function can be called several times as well, for instance when all the right hand sides are not available at once.++@+x1 <- solve b1+-- Get the second right hand side b2+x2 <- solve b2+-- ...+@++For direct methods, the solution are computed at the machine precision. Sometimes, the solution need not be too accurate.+In this case, the iterative methods are more suitable and the desired accuracy can be set before the solve step using `setTolerance`.+-}++module Data.Eigen.SparseLA (+ SolverInfo(..),+ ComputationInfo(..),+ SolverT,+ runSolverT,+ -- * The Compute step+ analyzePattern,+ factorize,+ compute,+ -- * The Solve step+ solve,+ tolerance,+ setTolerance,+ maxIterations,+ setMaxIterations,+ --solveWithGuess,+ info,+ Data.Eigen.SparseLA.error,+ iterations,+) where++import Prelude as P+import Foreign.Ptr+import Foreign.ForeignPtr+import Foreign.Storable+import Foreign.C.String+import Foreign.Marshal.Alloc+import Control.Monad.IO.Class+import Control.Monad.Trans.Reader+import qualified Foreign.Concurrent as FC+import Control.Applicative+import qualified Data.Eigen.Internal as I+import qualified Data.Eigen.SparseMatrix as SM++data SolverInfo+ {- | A conjugate gradient solver for sparse self-adjoint problems.++ This class allows to solve for @A.x = b@ sparse linear problems using a conjugate gradient algorithm. The sparse matrix @A@ must be selfadjoint.++ The maximal number of iterations and tolerance value can be controlled via the `setMaxIterations` and `setTolerance` methods.+ The defaults are the size of the problem for the maximal number of iterations and @epsilon@ for the tolerance+ -}+ = ConjugateGradient+ {- | A bi conjugate gradient stabilized solver for sparse square problems.++ This class allows to solve for @A.x = b@ sparse linear problems using a bi conjugate gradient stabilized algorithm.+ The vectors @x@ and @b@ can be either dense or sparse.++ The maximal number of iterations and tolerance value can be controlled via the `setMaxIterations` and `setTolerance` methods.+ The defaults are the size of the problem for the maximal number of iterations and @epsilon@ for the tolerance+ -}+ | BiCGSTAB+ {- | Sparse supernodal LU factorization for general matrices.++ This class implements the supernodal LU factorization for general matrices. It uses the main techniques from the sequential+ <http://crd-legacy.lbl.gov/~xiaoye/SuperLU/ SuperLU package>. It handles transparently real and complex arithmetics with+ single and double precision, depending on the scalar type of your input matrix. The code has been optimized to provide BLAS-3+ operations during supernode-panel updates. It benefits directly from the built-in high-performant Eigen BLAS routines.+ Moreover, when the size of a supernode is very small, the BLAS calls are avoided to enable a better optimization from the compiler.+ For best performance, you should compile it with NDEBUG flag to avoid the numerous bounds checking on vectors.+ -}+ | SparseLU+ {- | Sparse left-looking rank-revealing QR factorization.++ This class implements a left-looking rank-revealing QR decomposition of sparse matrices. When a column has a norm less than a given+ tolerance it is implicitly permuted to the end. The QR factorization thus obtained is given by @A*P = Q*R@ where @R@ is upper triangular or trapezoidal.++ @P@ is the column permutation which is the product of the fill-reducing and the rank-revealing permutations.++ @Q@ is the orthogonal matrix represented as products of Householder reflectors.++ @R@ is the sparse triangular or trapezoidal matrix. The later occurs when @A@ is rank-deficient.+ -}+ | SparseQR+ deriving (Eq, Enum, Show, Read)++data ComputationInfo+ -- | Computation was successful.+ = Success+ -- | The provided data did not satisfy the prerequisites.+ | NumericalIssue+ -- | Iterative procedure did not converge.+ | NoConvergence+ -- | The inputs are invalid, or the algorithm has been improperly called. When assertions are enabled, such errors trigger an error.+ | InvalidInput+ deriving (Eq, Enum, Show, Read)++type SolverT a b m = ReaderT (SolverInfo, ForeignPtr (I.CSolver a b)) m++runSolverT :: (MonadIO m, I.Elem a b) => SolverInfo -> SolverT a b m c -> m c+runSolverT i f = do+ fs <- liftIO $ alloca $ \ps -> do+ I.call $ I.sparse_la_newSolver i ps+ s <- peek ps+ FC.newForeignPtr s (I.call $ I.sparse_la_freeSolver i s)+ runReaderT f (i,fs)++-- | Initializes the iterative solver for the sparsity pattern of the matrix @A@ for further solving @Ax=b@ problems.+analyzePattern :: (MonadIO m, I.Elem a b) => SM.SparseMatrix a b -> SolverT a b m ()+analyzePattern (SM.SparseMatrix fa) = ask >>= \(i,fs) -> liftIO $+ withForeignPtr fs $ \s ->+ withForeignPtr fa $ \a ->+ I.call $ I.sparse_la_analyzePattern i s a++-- | nitializes the iterative solver with the numerical values of the matrix @A@ for further solving @Ax=b@ problems.+factorize :: (MonadIO m, I.Elem a b) => SM.SparseMatrix a b -> SolverT a b m ()+factorize (SM.SparseMatrix fa) = ask >>= \(i,fs) -> liftIO $+ withForeignPtr fs $ \s ->+ withForeignPtr fa $ \a ->+ I.call $ I.sparse_la_factorize i s a++-- | Initializes the iterative solver with the matrix @A@ for further solving @Ax=b@ problems.+-- +-- The `compute` method is equivalent to calling both `analyzePattern` and `factorize`.+compute :: (MonadIO m, I.Elem a b) => SM.SparseMatrix a b -> SolverT a b m ()+compute (SM.SparseMatrix fa) = ask >>= \(i,fs) -> liftIO $+ withForeignPtr fs $ \s ->+ withForeignPtr fa $ \a ->+ I.call $ I.sparse_la_compute i s a++-- | The tolerance threshold used by the stopping criteria.+tolerance :: (MonadIO m, I.Elem a b) => SolverT a b m Double+tolerance = _get_prop I.sparse_la_tolerance++-- | Sets the tolerance threshold used by the stopping criteria.+-- | This value is used as an upper bound to the relative residual error: @|Ax-b|/|b|@. The default value is the machine precision given by epsilon+setTolerance :: (MonadIO m, I.Elem a b) => Double -> SolverT a b m ()+setTolerance = _set_prop I.sparse_la_setTolerance++-- | The max number of iterations. It is either the value setted by setMaxIterations or, by default, twice the number of columns of the matrix.+maxIterations :: (MonadIO m, I.Elem a b) => SolverT a b m Int+maxIterations = _get_prop I.sparse_la_maxIterations++-- | Sets the max number of iterations. Default is twice the number of columns of the matrix.+setMaxIterations :: (MonadIO m, I.Elem a b) => Int -> SolverT a b m ()+setMaxIterations = _set_prop I.sparse_la_setMaxIterations++-- | An expression of the solution x of @A x = b@ using the current decomposition of @A@.+solve :: (MonadIO m, I.Elem a b) => SM.SparseMatrix a b -> SolverT a b m (SM.SparseMatrix a b)+solve (SM.SparseMatrix fb) = ask >>= \(i,fs) -> liftIO $+ withForeignPtr fs $ \s ->+ withForeignPtr fb $ \b ->+ alloca $ \px -> do+ I.call $ I.sparse_la_solve i s b px+ x <- peek px+ SM.SparseMatrix <$> FC.newForeignPtr x (I.call $ I.sparse_free x)++{-+-- | The solution @x@ of @A x = b@ using the current decomposition of @A@ and @x0@ as an initial solution.+solveWithGuess :: (MonadIO m, I.Elem a b) => SM.SparseMatrix a b -> SM.SparseMatrix a b -> SolverT a b m (SM.SparseMatrix a b)+solveWithGuess (SM.SparseMatrix fb) (SM.SparseMatrix fx0) = ask >>= \(i,fs) -> liftIO $+ withForeignPtr fs $ \s ->+ withForeignPtr fb $ \b ->+ withForeignPtr fx0 $ \x0 ->+ alloca $ \px -> do+ I.call $ I.sparse_la_solveWithGuess i s b x0 px+ x <- peek px+ SM.SparseMatrix <$> FC.newForeignPtr x (I.call $ I.sparse_free x)+-}++info :: (MonadIO m, I.Elem a b) => SolverT a b m ComputationInfo+info = _get_prop I.sparse_la_info >>= \x -> return (toEnum x)++-- | The tolerance error reached during the last solve. It is a close approximation of the true relative residual error @|Ax-b|/|b|@.+error :: (MonadIO m, I.Elem a b) => SolverT a b m Double+error = _get_prop I.sparse_la_error++-- | The number of iterations performed during the last solve+iterations :: (MonadIO m, I.Elem a b) => SolverT a b m Int+iterations = _get_prop I.sparse_la_iterations++_get_prop :: (I.Cast c d, MonadIO m, Storable c) => (SolverInfo -> I.CSolverPtr a b -> Ptr c -> IO CString) -> SolverT a b m d+_get_prop f = ask >>= \(i,fs) -> liftIO $+ withForeignPtr fs $ \s -> alloca $ \px -> do+ I.call $ f i s px+ I.cast <$> peek px++_set_prop :: (I.Cast c d, MonadIO m, Storable c) => (SolverInfo -> I.CSolverPtr a b -> d -> IO CString) -> c -> SolverT a b m ()+_set_prop f x = ask >>= \(i,fs) -> liftIO $+ withForeignPtr fs $ \s -> I.call $ f i s (I.cast x)
Data/Eigen/SparseMatrix.hs view
@@ -1,8 +1,11 @@-{-# LANGUAGE GADTs, ScopedTypeVariables #-}+{-# LANGUAGE GADTs #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE FlexibleContexts #-}+ module Data.Eigen.SparseMatrix ( -- * SparseMatrix type -- | SparseMatrix aliases follows Eigen naming convention- SparseMatrix,+ SparseMatrix(..), SparseMatrixXf, SparseMatrixXd, SparseMatrixXcf,@@ -24,12 +27,12 @@ squaredNorm, blueNorm, block,- --compress,- --uncompress,- --compressed,+ compress,+ uncompress,+ compressed, nonZeros,- --innerSize,- --outerSize,+ innerSize,+ outerSize, -- * Basic matrix algebra add, sub,@@ -39,8 +42,6 @@ scale, transpose, adjoint,- --lowerTriangle,- --upperTriangle, -- * Matrix serialization encode, decode,@@ -76,8 +77,10 @@ Unlike the compressed format, there might be extra space inbetween the nonzeros of two successive colmuns (resp. rows) such that insertion of new non-zero can be done with limited memory reallocation and copies. -A call to the function 'makeCompressed' turns the matrix into the standard compressed format compatible with many library.+The results of Eigen's operations always produces compressed sparse matrices. On the other hand, the insertion of a new element into a SparseMatrix converts this later to the uncompressed mode. +A call to the function 'compress' turns the matrix into the standard compressed format compatible with many library.+ Implementation deails of SparseMatrix are intentionally hidden behind ForeignPtr bacause Eigen doesn't provide mapping over plain data for sparse matricies. For more infomration please see Eigen documentation page: <http://eigen.tuxfamily.org/dox/classEigen_1_1SparseMatrix.html>@@ -159,11 +162,9 @@ nonZeros :: I.Elem a b => SparseMatrix a b -> Int nonZeros = _unop I.sparse_nonZeros (return . I.cast) -{----- | not exposed currently+-- | Turns the matrix into the compressed format compress :: I.Elem a b => SparseMatrix a b -> SparseMatrix a b-compress = _unop I.sparse_compress mk+compress = _unop I.sparse_makeCompressed mk -- | not exposed currently uncompress :: I.Elem a b => SparseMatrix a b -> SparseMatrix a b@@ -173,17 +174,14 @@ compressed :: I.Elem a b => SparseMatrix a b -> Bool compressed = _unop I.sparse_isCompressed (return . (/=0)) ---- | not exposed currently+-- | Minor dimension with respect to the storage order innerSize :: I.Elem a b => SparseMatrix a b -> Int innerSize = _unop I.sparse_innerSize (return . I.cast) --- | not exposed currently+-- | Major dimension with respect to the storage order outerSize :: I.Elem a b => SparseMatrix a b -> Int outerSize = _unop I.sparse_outerSize (return . I.cast) --}- -- | Suppresses all nonzeros which are much smaller than reference under the tolerence epsilon pruned :: I.Elem a b => a -> SparseMatrix a b -> SparseMatrix a b pruned r = _unop (\p pq -> alloca $ \pr -> poke pr (I.cast r) >> I.sparse_prunedRef p pr pq) mk@@ -200,16 +198,6 @@ adjoint :: I.Elem a b => SparseMatrix a b -> SparseMatrix a b adjoint = _unop I.sparse_adjoint mk -{---- | not exposed currently-lowerTriangle :: I.Elem a b => SparseMatrix a b -> SparseMatrix a b-lowerTriangle = _unop I.sparse_lowerTriangle mk---- | not exposed currently-upperTriangle :: I.Elem a b => SparseMatrix a b -> SparseMatrix a b-upperTriangle = _unop I.sparse_upperTriangle mk--}- -- | Adding two sparse matrices by adding the corresponding entries together. You can use @(+)@ function as well. add :: I.Elem a b => SparseMatrix a b -> SparseMatrix a b -> SparseMatrix a b add = _binop I.sparse_add mk@@ -280,7 +268,7 @@ VSM.unsafeWith tris $ \q -> I.call $ I.sparse_toList p q (I.cast size) tris <- VS.unsafeFreeze tris- let + let tri@(I.CTriplet _ _ val) = VS.head tris return $ BSL.fromChunks [@@ -293,8 +281,8 @@ where encodeInt :: CInt -> BS.ByteString encodeInt x = BSI.unsafeCreate (sizeOf x) $ (`poke` x) . castPtr- + -- | Decode sparse matrix from the lazy byte string decode :: forall a b . I.Elem a b => BSL.ByteString -> SparseMatrix a b decode st = I.performIO $ do@@ -308,17 +296,17 @@ code <- I.decodeInt <$> I.readStream st I.intSize when (code /= I.magicCode val) $ fail "SparseMatrix.decode: wrong matrix type"- + rows <- I.readInt st cols <- I.readInt st size <- I.readInt st- + BSI.PS fp fo _ <- I.readStream st (I.cast size * triSize) I.closeStream st let tris = VS.unsafeFromForeignPtr0 (I.plusForeignPtr fp fo) (I.cast size)- + VS.unsafeWith tris $ \p -> alloca $ \pq -> do I.call $ I.sparse_fromList rows cols p size pq peek pq >>= mk
+ cbits/eigen-dense.cpp view
@@ -0,0 +1,125 @@+#include "eigen-dense.h"+#include <Eigen/Core>+#include <Eigen/LeastSquares>++using namespace Eigen;++template <class T>+Map< Matrix<T,Dynamic,Dynamic> > matrix(void* p, int r, int c) {+ return Map< Matrix<T,Dynamic,Dynamic> >((T*)p, r, c);+}++template <class T>+Map< Matrix<T,Dynamic,Dynamic> > matrix(const void* p, int r, int c) {+ return Map< Matrix<T,Dynamic,Dynamic> >((const T*)p, r, c);+}++#define RET const char*++#define API(name,args,call) \+extern "C" RET eigen_##name args {\+ GUARD_START\+ switch (code) {\+ case 0: return name<T0>call;\+ case 1: return name<T1>call;\+ case 2: return name<T2>call;\+ case 3: return name<T3>call;\+ }\+ GUARD_END\+}+++#define BINOP(name,op) \+template <class T>\+RET name(void* p, int r, int c,\+ const void* p1, int r1, int c1,\+ const void* p2, int r2, int c2)\+{\+ matrix<T>(p,r,c) = matrix<T>(p1,r1,c1) op matrix<T>(p2,r2,c2);\+ return 0;\+}\+API(name, (int code,\+ void* p, int r, int c,\+ const void* p1, int r1, int c1,\+ const void* p2, int r2, int c2), (p,r,c,p1,r1,c1,p2,r2,c2));++BINOP(add,+);+BINOP(sub,-);+BINOP(mul,*);++#define PROP(name) \+extern "C" RET eigen_##name(int code, void* q, const void* p, int r, int c) {\+ GUARD_START\+ switch (code) {\+ case 0: *(T0*)q = matrix<T0>(p,r,c).name(); break;\+ case 1: *(T1*)q = matrix<T1>(p,r,c).name(); break;\+ case 2: *(T2*)q = matrix<T2>(p,r,c).name(); break;\+ case 3: *(T3*)q = matrix<T3>(p,r,c).name(); break;\+ }\+ GUARD_END\+ }++PROP(norm);+PROP(squaredNorm);+PROP(blueNorm);+PROP(hypotNorm);+PROP(sum);+PROP(prod);+PROP(mean);+PROP(trace);+PROP(determinant);++#define UNOP(name) \+extern "C" RET eigen_##name(int code, void* p, int r, int c, const void* p1, int r1, int c1) {\+ GUARD_START\+ switch (code) {\+ case 0: matrix<T0>(p,r,c) = matrix<T0>(p1,r1,c1).name(); break;\+ case 1: matrix<T1>(p,r,c) = matrix<T1>(p1,r1,c1).name(); break;\+ case 2: matrix<T2>(p,r,c) = matrix<T2>(p1,r1,c1).name(); break;\+ case 3: matrix<T3>(p,r,c) = matrix<T3>(p1,r1,c1).name(); break;\+ }\+ GUARD_END\+ }++UNOP(inverse);+UNOP(adjoint);+UNOP(conjugate);+UNOP(diagonal);+UNOP(transpose);++extern "C" RET eigen_normalize(int code, void* p, int r, int c)+{+ GUARD_START+ switch (code) {+ case 0: matrix<T0>(p,r,c).normalize(); break;+ case 1: matrix<T1>(p,r,c).normalize(); break;+ case 2: matrix<T2>(p,r,c).normalize(); break;+ case 3: matrix<T3>(p,r,c).normalize(); break;+ }+ GUARD_END+}++extern "C" RET eigen_random(int code, void* p, int r, int c)+{+ GUARD_START+ switch (code) {+ case 0: matrix<T0>(p,r,c) = MatrixXf::Random(r,c); break;+ case 1: matrix<T1>(p,r,c) = MatrixXd::Random(r,c); break;+ case 2: matrix<T2>(p,r,c) = MatrixXcf::Random(r,c); break;+ case 3: matrix<T3>(p,r,c) = MatrixXcd::Random(r,c); break;+ }+ GUARD_END+}++extern "C" RET eigen_identity(int code, void* p, int r, int c)+{+ GUARD_START+ switch (code) {+ case 0: matrix<T0>(p,r,c) = MatrixXf::Identity(r,c); break;+ case 1: matrix<T1>(p,r,c) = MatrixXd::Identity(r,c); break;+ case 2: matrix<T2>(p,r,c) = MatrixXcf::Identity(r,c); break;+ case 3: matrix<T3>(p,r,c) = MatrixXcd::Identity(r,c); break;+ }+ GUARD_END+}+
+ cbits/eigen-dense.h view
@@ -0,0 +1,27 @@+#include "eigen-runtime.h"++extern "C" {++const char* eigen_add(int, void*, int, int, const void*, int, int, const void*, int, int);+const char* eigen_sub(int, void*, int, int, const void*, int, int, const void*, int, int);+const char* eigen_mul(int, void*, int, int, const void*, int, int, const void*, int, int);+const char* eigen_norm(int, void*, const void*, int, int);+const char* eigen_squaredNorm(int, void*, const void*, int, int);+const char* eigen_blueNorm(int, void*, const void*, int, int);+const char* eigen_hypotNorm(int, void*, const void*, int, int);+const char* eigen_sum(int, void*, const void*, int, int);+const char* eigen_prod(int, void*, const void*, int, int);+const char* eigen_mean(int, void*, const void*, int, int);+const char* eigen_trace(int, void*, const void*, int, int);+const char* eigen_determinant(int, void*, const void*, int, int);+const char* eigen_diagonal(int, void*, int, int, const void*, int, int);+const char* eigen_transpose(int, void*, int, int, const void*, int, int);+const char* eigen_normalize(int, void*, int, int);+const char* eigen_random(int, void*, int, int);+const char* eigen_identity(int, void*, int, int);+const char* eigen_inverse(int, void*, int, int, const void*, int, int);+const char* eigen_conjugate(int, void*, int, int, const void*, int, int);+const char* eigen_adjoint(int, void*, int, int, const void*, int, int);++} // end extern "C"+
+ cbits/eigen-la.cpp view
@@ -0,0 +1,122 @@+#include "eigen-la.h"+#include <Eigen/Core>+#include <Eigen/LU>+#include <Eigen/LeastSquares>++using namespace Eigen;++template <class T>+RET rank(Decomposition d, int* v, const void* p, int r, int c) {+ typedef Map< Matrix<T,Dynamic,Dynamic> > MapMatrix;+ MapMatrix A((const T*)p,r,c);+ switch (d) {+ case ::FullPivLU:+ *v = A.fullPivLu().rank();+ break;+ case ::ColPivHouseholderQR:+ *v = A.colPivHouseholderQr().rank();+ break;+ case ::FullPivHouseholderQR:+ *v = A.fullPivHouseholderQr().rank();+ break;+ case ::JacobiSVD:+ *v = A.jacobiSvd(ComputeThinU | ComputeThinV).rank();+ break;+ default:+ return strdup("Selected decomposition doesn't support rank revealing.");+ }+ return 0;+}+API(rank, (int code, Decomposition d, int* v, const void* p, int r, int c), (d,v,p,r,c));++template <class T>+RET kernel(Decomposition d, void** p0, int* r0, int* c0, const void* p1, int r1, int c1) {+ typedef Map< Matrix<T,Dynamic,Dynamic> > MapMatrix;+ if (d != ::FullPivLU)+ return strdup("Selected decomposition doesn't support kernel revealing.");+ MapMatrix A((const T*)p1,r1,c1);+ Matrix<T,Dynamic,Dynamic> B = A.fullPivLu().kernel();+ *r0 = B.rows();+ *c0 = B.cols();+ *p0 = malloc(*r0 * *c0 * sizeof(T));+ MapMatrix((T*)*p0, *r0, *c0) = B;+ return 0;+}+API(kernel, (int code, Decomposition d, void** p0, int* r0, int* c0, const void* p1, int r1, int c1), (d,p0,r0,c0,p1,r1,c1));++template <class T>+RET image(Decomposition d, void** p0, int* r0, int* c0, const void* p1, int r1, int c1) {+ typedef Map< Matrix<T,Dynamic,Dynamic> > MapMatrix;+ if (d != ::FullPivLU)+ return strdup("Selected decomposition doesn't support image revealing.");+ MapMatrix A((const T*)p1,r1,c1);+ Matrix<T,Dynamic,Dynamic> B = A.fullPivLu().image(A);+ *r0 = B.rows();+ *c0 = B.cols();+ *p0 = malloc(*r0 * *c0 * sizeof(T));+ MapMatrix((T*)*p0, *r0, *c0) = B;+ return 0;+}+API(image, (int code, Decomposition d, void** p0, int* r0, int* c0, const void* p1, int r1, int c1), (d,p0,r0,c0,p1,r1,c1));++template <class T>+RET solve(Decomposition d,+ void* px, int rx, int cx,+ const void* pa, int ra, int ca,+ const void* pb, int rb, int cb)+{+ typedef Map< Matrix<T,Dynamic,Dynamic> > MapMatrix;+ MapMatrix x((T*)px, rx, cx);+ MapMatrix A((const T*)pa, ra, ca);+ MapMatrix b((const T*)pb, rb, cb);+ switch (d) {+ case ::PartialPivLU:+ x = A.partialPivLu().solve(b);+ break;+ case ::FullPivLU:+ x = A.fullPivLu().solve(b);+ break;+ case ::HouseholderQR:+ x = A.householderQr().solve(b);+ break;+ case ::ColPivHouseholderQR:+ x = A.colPivHouseholderQr().solve(b);+ break;+ case ::FullPivHouseholderQR:+ x = A.fullPivHouseholderQr().solve(b);+ break;+ case ::LLT:+ x = A.llt().solve(b);+ break;+ case ::LDLT:+ x = A.ldlt().solve(b);+ break;+ case ::JacobiSVD:+ x = A.jacobiSvd(ComputeThinU | ComputeThinV).solve(b);+ break;+ }+ return 0;+}+API(solve, (int code, Decomposition d,+ void* px, int rx, int cx,+ const void* pa, int ra, int ca,+ const void* pb, int rb, int cb), (d,px,rx,cx,pa,ra,ca,pb,rb,cb));++template <class T>+RET relativeError(void* e,+ const void* px, int rx, int cx,+ const void* pa, int ra, int ca,+ const void* pb, int rb, int cb)+{+ typedef Map< Matrix<T,Dynamic,Dynamic> > MapMatrix;+ MapMatrix x((const T*)px, rx, cx);+ MapMatrix A((const T*)pa, ra, ca);+ MapMatrix b((const T*)pb, rb, cb);+ *(T*)e = (A*x - b).norm() / b.norm();+ return 0;+}+API(relativeError, (int code, void* e,+ const void* px, int rx, int cx,+ const void* pa, int ra, int ca,+ const void* pb, int rb, int cb), (e,px,rx,cx,pa,ra,ca,pb,rb,cb));+
+ cbits/eigen-la.h view
@@ -0,0 +1,37 @@+#include "eigen-runtime.h"++extern "C" {++enum Decomposition {+ PartialPivLU,+ FullPivLU,+ HouseholderQR,+ ColPivHouseholderQR,+ FullPivHouseholderQR,+ LLT,+ LDLT,+ JacobiSVD,+ // SelfAdjointEigenSolver,+ // ComplexEigenSolver,+ // EigenSolver,+ // GeneralizedSelfAdjointEigenSolver+};++const char* eigen_rank(int, Decomposition d, int*, const void*, int, int);+const char* eigen_kernel(int, Decomposition d, void**, int*, int*, const void*, int, int);+const char* eigen_image(int, Decomposition d, void**, int*, int*, const void*, int, int);++const char* eigen_solve(int, Decomposition d, // Ax=b + void*, int, int, // x+ const void*, int, int, // A+ const void*, int, int); // b+++const char* eigen_relativeError(int, void* e, + const void*, int, int, // x+ const void*, int, int, // A+ const void*, int, int); // b;+++} // end extern "C"+
− cbits/eigen-proxy.cpp
@@ -1,437 +0,0 @@-#include "eigen-proxy.h"-#include <Eigen/LU>-#include <Eigen/LeastSquares>-#include <stdio.h>-#include <sstream>--static bool inited = eigen_initParallel();--class eigen_assert_exception : public std::exception {- std::string _what;-public:- eigen_assert_exception(const std::string& what) : _what(what) {}- ~eigen_assert_exception() throw() {}- const char* what() const throw () { return _what.c_str(); }-};--void eigen_assert_fail(const char* condition, const char* function, const char* file, int line) {- std::ostringstream os;- os << "assertion failed: " << condition << " in function " << function << " at " << file << ":" << line << std::endl;- throw eigen_assert_exception(os.str());-}--typedef float T0;-typedef double T1;-typedef std::complex<float> T2;-typedef std::complex<double> T3;--template <class T>-Map< Matrix<T,Dynamic,Dynamic> > matrix(void* p, int r, int c) {- return Map< Matrix<T,Dynamic,Dynamic> >((T*)p, r, c);-}--template <class T>-Map< Matrix<T,Dynamic,Dynamic> > matrix(const void* p, int r, int c) {- return Map< Matrix<T,Dynamic,Dynamic> >((const T*)p, r, c);-}--#define RET const char* --#define API(name,args,call) \-extern "C" RET eigen_##name args {\- GUARD_START\- switch (code) {\- case 0: return name<T0>call;\- case 1: return name<T1>call;\- case 2: return name<T2>call;\- case 3: return name<T3>call;\- }\- GUARD_END\-}---#define BINOP(name,op) \-template <class T>\-RET name(void* p, int r, int c,\- const void* p1, int r1, int c1,\- const void* p2, int r2, int c2)\-{\- matrix<T>(p,r,c) = matrix<T>(p1,r1,c1) op matrix<T>(p2,r2,c2);\- return 0;\-}\-API(name, (int code,\- void* p, int r, int c,\- const void* p1, int r1, int c1,\- const void* p2, int r2, int c2), (p,r,c,p1,r1,c1,p2,r2,c2));--BINOP(add,+);-BINOP(sub,-);-BINOP(mul,*);--#define PROP(name) \-extern "C" RET eigen_##name(int code, void* q, const void* p, int r, int c) {\- GUARD_START\- switch (code) {\- case 0: *(T0*)q = matrix<T0>(p,r,c).name(); break;\- case 1: *(T1*)q = matrix<T1>(p,r,c).name(); break;\- case 2: *(T2*)q = matrix<T2>(p,r,c).name(); break;\- case 3: *(T3*)q = matrix<T3>(p,r,c).name(); break;\- }\- GUARD_END\- }--PROP(norm);-PROP(squaredNorm);-PROP(blueNorm);-PROP(hypotNorm);-PROP(sum);-PROP(prod);-PROP(mean);-PROP(trace);-PROP(determinant);--#define UNOP(name) \-extern "C" RET eigen_##name(int code, void* p, int r, int c, const void* p1, int r1, int c1) {\- GUARD_START\- switch (code) {\- case 0: matrix<T0>(p,r,c) = matrix<T0>(p1,r1,c1).name(); break;\- case 1: matrix<T1>(p,r,c) = matrix<T1>(p1,r1,c1).name(); break;\- case 2: matrix<T2>(p,r,c) = matrix<T2>(p1,r1,c1).name(); break;\- case 3: matrix<T3>(p,r,c) = matrix<T3>(p1,r1,c1).name(); break;\- }\- GUARD_END\- }--UNOP(inverse);-UNOP(adjoint);-UNOP(conjugate);-UNOP(diagonal);-UNOP(transpose);--extern "C" RET eigen_normalize(int code, void* p, int r, int c)-{- GUARD_START- switch (code) {- case 0: matrix<T0>(p,r,c).normalize(); break;- case 1: matrix<T1>(p,r,c).normalize(); break;- case 2: matrix<T2>(p,r,c).normalize(); break;- case 3: matrix<T3>(p,r,c).normalize(); break;- }- GUARD_END-}--extern "C" RET eigen_random(int code, void* p, int r, int c)-{- GUARD_START- switch (code) {- case 0: matrix<T0>(p,r,c) = MatrixXf::Random(r,c); break;- case 1: matrix<T1>(p,r,c) = MatrixXd::Random(r,c); break;- case 2: matrix<T2>(p,r,c) = MatrixXcf::Random(r,c); break;- case 3: matrix<T3>(p,r,c) = MatrixXcd::Random(r,c); break;- }- GUARD_END-}--extern "C" RET eigen_identity(int code, void* p, int r, int c)-{- GUARD_START- switch (code) {- case 0: matrix<T0>(p,r,c) = MatrixXf::Identity(r,c); break;- case 1: matrix<T1>(p,r,c) = MatrixXd::Identity(r,c); break;- case 2: matrix<T2>(p,r,c) = MatrixXcf::Identity(r,c); break;- case 3: matrix<T3>(p,r,c) = MatrixXcd::Identity(r,c); break;- }- GUARD_END-}--template <class T>-RET rank(Decomposition d, int* v, const void* p, int r, int c) {- typedef Map< Matrix<T,Dynamic,Dynamic> > MapMatrix;- MapMatrix A((const T*)p,r,c);- switch (d) {- case ::FullPivLU:- *v = A.fullPivLu().rank();- break;- case ::ColPivHouseholderQR:- *v = A.colPivHouseholderQr().rank();- break;- case ::FullPivHouseholderQR:- *v = A.fullPivHouseholderQr().rank();- break;- case ::JacobiSVD:- *v = A.jacobiSvd(ComputeThinU | ComputeThinV).rank();- break;- default:- return strdup("Selected decomposition doesn't support rank revealing.");- }- return 0;-}-API(rank, (int code, Decomposition d, int* v, const void* p, int r, int c), (d,v,p,r,c));--template <class T>-RET kernel(Decomposition d, void** p0, int* r0, int* c0, const void* p1, int r1, int c1) {- typedef Map< Matrix<T,Dynamic,Dynamic> > MapMatrix;- if (d != ::FullPivLU)- return strdup("Selected decomposition doesn't support kernel revealing.");- MapMatrix A((const T*)p1,r1,c1);- Matrix<T,Dynamic,Dynamic> B = A.fullPivLu().kernel();- *r0 = B.rows();- *c0 = B.cols();- *p0 = malloc(*r0 * *c0 * sizeof(T));- MapMatrix((T*)*p0, *r0, *c0) = B;- return 0;-}-API(kernel, (int code, Decomposition d, void** p0, int* r0, int* c0, const void* p1, int r1, int c1), (d,p0,r0,c0,p1,r1,c1));--template <class T>-RET image(Decomposition d, void** p0, int* r0, int* c0, const void* p1, int r1, int c1) {- typedef Map< Matrix<T,Dynamic,Dynamic> > MapMatrix;- if (d != ::FullPivLU)- return strdup("Selected decomposition doesn't support image revealing.");- MapMatrix A((const T*)p1,r1,c1);- Matrix<T,Dynamic,Dynamic> B = A.fullPivLu().image(A);- *r0 = B.rows();- *c0 = B.cols();- *p0 = malloc(*r0 * *c0 * sizeof(T));- MapMatrix((T*)*p0, *r0, *c0) = B;- return 0;-}-API(image, (int code, Decomposition d, void** p0, int* r0, int* c0, const void* p1, int r1, int c1), (d,p0,r0,c0,p1,r1,c1));--template <class T>-RET solve(Decomposition d,- void* px, int rx, int cx,- const void* pa, int ra, int ca,- const void* pb, int rb, int cb)-{- typedef Map< Matrix<T,Dynamic,Dynamic> > MapMatrix;- MapMatrix x((T*)px, rx, cx);- MapMatrix A((const T*)pa, ra, ca);- MapMatrix b((const T*)pb, rb, cb);- switch (d) {- case ::PartialPivLU:- x = A.partialPivLu().solve(b);- break;- case ::FullPivLU:- x = A.fullPivLu().solve(b);- break;- case ::HouseholderQR:- x = A.householderQr().solve(b);- break;- case ::ColPivHouseholderQR:- x = A.colPivHouseholderQr().solve(b);- break;- case ::FullPivHouseholderQR:- x = A.fullPivHouseholderQr().solve(b);- break;- case ::LLT:- x = A.llt().solve(b);- break;- case ::LDLT:- x = A.ldlt().solve(b);- break;- case ::JacobiSVD:- x = A.jacobiSvd(ComputeThinU | ComputeThinV).solve(b);- break;- }- return 0;-}-API(solve, (int code, Decomposition d,- void* px, int rx, int cx,- const void* pa, int ra, int ca,- const void* pb, int rb, int cb), (d,px,rx,cx,pa,ra,ca,pb,rb,cb));--template <class T>-RET relativeError(void* e,- const void* px, int rx, int cx,- const void* pa, int ra, int ca,- const void* pb, int rb, int cb)-{- typedef Map< Matrix<T,Dynamic,Dynamic> > MapMatrix;- MapMatrix x((const T*)px, rx, cx);- MapMatrix A((const T*)pa, ra, ca);- MapMatrix b((const T*)pb, rb, cb);- *(T*)e = (A*x - b).norm() / b.norm();- return 0;-}-API(relativeError, (int code, void* e,- const void* px, int rx, int cx,- const void* pa, int ra, int ca,- const void* pb, int rb, int cb), (e,px,rx,cx,pa,ra,ca,pb,rb,cb));--extern "C" bool eigen_initParallel() {- initParallel();- return true;-}--extern "C" void eigen_setNbThreads(int n) {- setNbThreads(n);-}--extern "C" int eigen_getNbThreads() {- return nbThreads();-}--template <class T>-RET sparse_fromList(int rows, int cols, void* data, int size, void** pr) {- typedef SparseMatrix<T> M;- typedef Triplet<T> E;- std::auto_ptr<M> a(new M(rows, cols));- a->setFromTriplets((E*)data, (E*)data + size);- *(M**)pr = a.release();- return 0;-}-API(sparse_fromList, (int code, int rows, int cols, void* data, int size, void** pr), (rows,cols,data,size,pr));--template <class T>-RET sparse_toList(void* p, void* q, int s) {- int n = 0;- typedef SparseMatrix<T> M;- typedef Triplet<T> E;- M* m = (M*)p;- for (int k = 0; k < m->outerSize(); ++k) {- for (typename M::InnerIterator i(*m, k); i; ++i) {- if (n >= s)- return strdup("sparse_toList: buffer overrun detected");- ((E*)q)[n++] = E(i.row(), i.col(), i.value());- }- }- return n < s ? strdup("sparse_toList: buffer underrun detected") : 0;-}-API(sparse_toList, (int code, void* p, void* q, int s), (p,q,s));--template <class T>-RET sparse_free(void* p) {- delete (SparseMatrix<T>*)p;- return 0;-}-API(sparse_free, (int code, void* p), (p));--#define SPARSE_UNOP_INPLACE(name)\-template <class T>\-RET sparse_##name(void* p, void** pr) {\- typedef SparseMatrix<T> M;\- std::auto_ptr<M> a(new M(*(M*)p));\- a->name();\- *(M**)pr = a.release();\- return 0;\-}\-API(sparse_##name, (int code, void* p, void** pr), (p, pr));--SPARSE_UNOP_INPLACE(makeCompressed);-SPARSE_UNOP_INPLACE(uncompress);--#define SPARSE_UNOP(name)\-template <class T>\-RET sparse_##name(void* p, void** pr) {\- typedef SparseMatrix<T> M;\- *(M**)pr = new M(((M*)p)->name());\- return 0;\-}\-API(sparse_##name, (int code, void* p, void** pr), (p, pr));--SPARSE_UNOP(adjoint);-SPARSE_UNOP(transpose);--template <class T>-RET sparse_pruned(void* p, void** pr) {- typedef SparseMatrix<T> M;- std::auto_ptr<M> a(new M(*(M*)p));- a->prune(T(1));- *(M**)pr = a.release();- return 0;-}-API(sparse_pruned, (int code, void* p, void** pr), (p, pr));--template <class T>-RET sparse_prunedRef(void* p, void* q, void** pr) {- typedef SparseMatrix<T> M;- std::auto_ptr<M> a(new M(*(M*)p));- a->prune(*(T*)q);- *(M**)pr = a.release();- return 0;-}-API(sparse_prunedRef, (int code, void* p, void* q, void** pr), (p, q, pr));--template <class T>-RET sparse_scale(void* p, void* q, void** pr) {- typedef SparseMatrix<T> M;- *(M**)pr = new M(*(T*)q * *(M*)p);- return 0;-}-API(sparse_scale, (int code, void* p, void* q, void** pr), (p, q, pr));--template <class T>-RET sparse_coeff(void* p, int row, int col, void* pr) {- *(T*)pr = ((SparseMatrix<T>*)p)->coeff(row, col);- return 0;-}-API(sparse_coeff, (int code, void* p, int row, int col, void* pr), (p, row, col, pr));--#define SPARSE_PROP(name,type)\-template <class T>\-RET sparse_##name(void* p, void* pr) {\- *(type*)pr = ((SparseMatrix<T>*)p)->name();\- return 0;\-}\-API(sparse_##name, (int code, void* p, void* pr), (p, pr));--SPARSE_PROP(cols, int);-SPARSE_PROP(rows, int);-SPARSE_PROP(innerSize, int);-SPARSE_PROP(outerSize, int);-SPARSE_PROP(nonZeros, int);-SPARSE_PROP(isCompressed, int);-SPARSE_PROP(norm, T);-SPARSE_PROP(squaredNorm, T);-SPARSE_PROP(blueNorm, T);--#define SPARSE_BINOP(name,op)\-template <class T>\-RET sparse_##name(void* p, void* q, void** pr) {\- typedef SparseMatrix<T> M;\- *(M**)pr = new M(*(M*)p op *(M*)q);\- return 0;\-}\-API(sparse_##name, (int code, void* p, void* q, void** pr), (p, q, pr));--SPARSE_BINOP(add, +);-SPARSE_BINOP(sub, -);-SPARSE_BINOP(mul, *);--template <class T>-RET sparse_block(void* p, int row, int col, int rows, int cols, void** pr) {- typedef SparseMatrix<T> M;- *(M**)pr = new M(((M*)p)->block(row,col,rows,cols));- return 0;-}-API(sparse_block, (int code, void* p, int row, int col, int rows, int cols, void** pr), (p, row, col, rows, cols, pr));--template <class T> bool isZero(T x) { return x == 0; }-template <class T> bool isZero(std::complex<T> x) { return x.real() == 0 && x.imag() == 0; }--template <class T>-RET sparse_fromMatrix(void* p, int rows, int cols, void** pq) {- typedef SparseMatrix<T> M;- typedef Map< Matrix<T,Dynamic,Dynamic> > MapMatrix;- MapMatrix src((const T*)p, rows, cols);- std::auto_ptr<M> dst(new M(rows, cols));- for (int row = 0; row < rows; ++row) {- for (int col = 0; col < cols; ++col) {- T val = src.coeff(row,col);- if (!isZero(val))- dst->insert(row, col) = val;- }- }- *(M**)pq = dst.release();- return 0;-}-API(sparse_fromMatrix, (int code, void* p, int rows, int cols, void** pq), (p,rows,cols,pq));--template <class T>-RET sparse_toMatrix(void* p, void* q, int rows, int cols) {- typedef Map< Matrix<T,Dynamic,Dynamic> > MapMatrix;- MapMatrix((T*)q, rows, cols) = *(SparseMatrix<T>*)p;- return 0;-}-API(sparse_toMatrix, (int code, void* p, void* q, int rows, int cols), (p,q,rows,cols));
− cbits/eigen-proxy.h
@@ -1,110 +0,0 @@-#define EIGEN_MPL2_ONLY-#define EIGEN2_SUPPORT-#define EIGEN_NO_EIGEN2_DEPRECATED_WARNING-#define EIGEN_INITIALIZE_MATRICES_BY_ZERO-void eigen_assert_fail(const char* condition, const char* function, const char* file, int line);-#define eigen_assert(x) do {\- if (!(x)) eigen_assert_fail(#x, __PRETTY_FUNCTION__, __FILE__, __LINE__);\-} while(false)-#include <Eigen/Core>-#include <Eigen/SparseCore>--using namespace Eigen;--extern "C" {--const char* eigen_add(int, void*, int, int, const void*, int, int, const void*, int, int);-const char* eigen_sub(int, void*, int, int, const void*, int, int, const void*, int, int);-const char* eigen_mul(int, void*, int, int, const void*, int, int, const void*, int, int);-const char* eigen_norm(int, void*, const void*, int, int);-const char* eigen_squaredNorm(int, void*, const void*, int, int);-const char* eigen_blueNorm(int, void*, const void*, int, int);-const char* eigen_hypotNorm(int, void*, const void*, int, int);-const char* eigen_sum(int, void*, const void*, int, int);-const char* eigen_prod(int, void*, const void*, int, int);-const char* eigen_mean(int, void*, const void*, int, int);-const char* eigen_trace(int, void*, const void*, int, int);-const char* eigen_determinant(int, void*, const void*, int, int);-const char* eigen_diagonal(int, void*, int, int, const void*, int, int);-const char* eigen_transpose(int, void*, int, int, const void*, int, int);-const char* eigen_normalize(int, void*, int, int);-const char* eigen_random(int, void*, int, int);-const char* eigen_identity(int, void*, int, int);-const char* eigen_inverse(int, void*, int, int, const void*, int, int);-const char* eigen_conjugate(int, void*, int, int, const void*, int, int);-const char* eigen_adjoint(int, void*, int, int, const void*, int, int);-bool eigen_initParallel();-int eigen_getNbThreads();-void eigen_setNbThreads(int);--#define SPARSE_PROP(name) const char* eigen_sparse_##name(int, void*, void*)-SPARSE_PROP(cols);-SPARSE_PROP(rows);-SPARSE_PROP(innerSize);-SPARSE_PROP(outerSize);-SPARSE_PROP(nonZeros);-SPARSE_PROP(isCompressed);-SPARSE_PROP(norm);-SPARSE_PROP(squaredNorm);-SPARSE_PROP(blueNorm);-#undef SPARSE_PROP--#define SPARSE_BINOP(name) const char* eigen_sparse_##name(int, void*, void*, void**);-SPARSE_BINOP(add);-SPARSE_BINOP(sub);-SPARSE_BINOP(mul);-SPARSE_BINOP(prunedRef);-SPARSE_BINOP(scale);-#undef SPARSE_BINOP--#define SPARSE_UNOP(name) const char* eigen_sparse_##name(int, void*, void**);-SPARSE_UNOP(makeCompressed);-SPARSE_UNOP(uncompress);-SPARSE_UNOP(adjont);-SPARSE_UNOP(transponse);-SPARSE_UNOP(pruned);-#undef SPARSE_UNOP--const char* eigen_sparse_fromList(int, int, int, void*, int, void**);-const char* eigen_sparse_toList(int, void*, void*, int);-const char* eigen_sparse_free(int, void*);-const char* eigen_sparse_coeff(int, void*, int, int, void*);-const char* eigen_sparse_block(int, void*, int, int, int, int, void**);-const char* eigen_sparse_fromMatrix(int, void*, int, int, void**);-const char* eigen_sparse_toMatrix(int, void*, void*, int, int);--enum Decomposition {- PartialPivLU,- FullPivLU,- HouseholderQR,- ColPivHouseholderQR,- FullPivHouseholderQR,- LLT,- LDLT,- JacobiSVD,- // SelfAdjointEigenSolver,- // ComplexEigenSolver,- // EigenSolver,- // GeneralizedSelfAdjointEigenSolver-};--const char* eigen_rank(int, Decomposition d, int*, const void*, int, int);-const char* eigen_kernel(int, Decomposition d, void**, int*, int*, const void*, int, int);-const char* eigen_image(int, Decomposition d, void**, int*, int*, const void*, int, int);--const char* eigen_solve(int, Decomposition d, // Ax=b - void*, int, int, // x- const void*, int, int, // A- const void*, int, int); // b---const char* eigen_relativeError(int, void* e, - const void*, int, int, // x- const void*, int, int, // A- const void*, int, int); // b;---} // end extern "C"--#define GUARD_START try { assert(inited); do {-#define GUARD_END } while(false); return 0; } catch (const std::exception& ex) { return strdup(ex.what()); }
+ cbits/eigen-runtime.cpp view
@@ -0,0 +1,38 @@+#include "eigen-runtime.h"+#include <sstream>+#include <Eigen/Core>++using namespace Eigen;++class eigen_assert_exception : public std::exception {+ std::string _what;+public:+ eigen_assert_exception(const std::string& what) : _what(what) {}+ ~eigen_assert_exception() throw() {}+ const char* what() const throw () { return _what.c_str(); }+};++void eigen_assert_fail(const char* condition, const char* function, const char* file, int line) {+ std::ostringstream os;+ os << "assertion failed: " << condition << " in function " << function << " at " << file << ":" << line << std::endl;+ throw eigen_assert_exception(os.str());+}++extern "C" {++bool eigen_initParallel() {+ initParallel();+ return true;+}++void eigen_setNbThreads(int n) {+ setNbThreads(n);+}++int eigen_getNbThreads() {+ return nbThreads();+}++bool eigen_inited = eigen_initParallel();++} // extern "C"
+ cbits/eigen-runtime.h view
@@ -0,0 +1,40 @@+#define EIGEN_MPL2_ONLY+#define EIGEN2_SUPPORT+#define EIGEN_NO_EIGEN2_DEPRECATED_WARNING+#define EIGEN_INITIALIZE_MATRICES_BY_ZERO+void eigen_assert_fail(const char* condition, const char* function, const char* file, int line);+#define eigen_assert(x) do {\+ if (!(x)) eigen_assert_fail(#x, __PRETTY_FUNCTION__, __FILE__, __LINE__);\+} while(false)++extern "C" {++bool eigen_initParallel();+int eigen_getNbThreads();+void eigen_setNbThreads(int);+extern bool eigen_inited;++} // end extern "C"++#define GUARD_START try { assert(eigen_inited); do {+#define GUARD_END } while(false); return 0; } catch (const std::exception& ex) { return strdup(ex.what()); }++#define RET const char*++#define API(name,args,call) \+extern "C" RET eigen_##name args {\+ GUARD_START\+ switch (code) {\+ case 0: return name<T0>call;\+ case 1: return name<T1>call;\+ case 2: return name<T2>call;\+ case 3: return name<T3>call;\+ }\+ GUARD_END\+}++#include <complex>+typedef float T0;+typedef double T1;+typedef std::complex<float> T2;+typedef std::complex<double> T3;
+ cbits/eigen-sparse-la.cpp view
@@ -0,0 +1,180 @@+#include "eigen-sparse-la.h"++using namespace Eigen;++typedef SparseMatrix <T0> M0;+typedef SparseMatrix <T1> M1;+typedef SparseMatrix <T2> M2;+typedef SparseMatrix <T3> M3;++template <class T> struct S0 { typedef ConjugateGradient< SparseMatrix <T> > type; };+template <class T> struct S1 { typedef BiCGSTAB< SparseMatrix <T> > type; };+template <class T> struct S2 { typedef SparseLU< SparseMatrix <T> > type; };+template <class T> struct S3 { typedef SparseQR< SparseMatrix <T>, COLAMDOrdering<typename SparseMatrix<T>::Index> > type; };++#define API_ALL(name,args,call) \+extern "C" RET eigen_##name args {\+ GUARD_START\+ switch (code) {\+ case 0: switch(s) {\+ case 0: return name<T0, M0, S0<T0>::type >call;\+ case 1: return name<T0, M0, S1<T0>::type >call;\+ case 2: return name<T0, M0, S2<T0>::type >call;\+ case 3: return name<T0, M0, S3<T0>::type >call;\+ }\+ case 1: switch(s) {\+ case 0: return name<T1, M1 ,S0<T1>::type >call;\+ case 1: return name<T1, M1 ,S1<T1>::type >call;\+ case 2: return name<T1, M1 ,S2<T1>::type >call;\+ case 3: return name<T1, M1 ,S3<T1>::type >call;\+ }\+ case 2: switch(s) {\+ case 0: return name<T2, M2, S0<T2>::type >call;\+ case 1: return name<T2, M2, S1<T2>::type >call;\+ case 2: return name<T2, M2, S2<T2>::type >call;\+ case 3: return name<T2, M2, S3<T2>::type >call;\+ }\+ case 3: switch(s) {\+ case 0: return name<T3, M3, S0<T3>::type >call;\+ case 1: return name<T3, M3, S1<T3>::type >call;\+ case 2: return name<T3, M3, S2<T3>::type >call;\+ case 3: return name<T3, M3, S3<T3>::type >call;\+ }\+ }\+ GUARD_END\+}++#define API_ITERATIVE(name,args,call) \+extern "C" RET eigen_##name args {\+ GUARD_START\+ switch (code) {\+ case 0: switch(s) {\+ case 0: return name<T0, M0, S0<T0>::type >call;\+ case 1: return name<T0, M0, S1<T0>::type >call;\+ }\+ case 1: switch(s) {\+ case 0: return name<T1, M1 ,S0<T1>::type >call;\+ case 1: return name<T1, M1 ,S1<T1>::type >call;\+ }\+ case 2: switch(s) {\+ case 0: return name<T2, M2, S0<T2>::type >call;\+ case 1: return name<T2, M2, S1<T2>::type >call;\+ }\+ case 3: switch(s) {\+ case 0: return name<T3, M3, S0<T3>::type >call;\+ case 1: return name<T3, M3, S1<T3>::type >call;\+ }\+ }\+ return strdup("supported for iterative solver only");\+ GUARD_END\+}++template <class T, class M, class S>+RET sparse_la_newSolver(void** p) {+ *(S**)p = new S;+ return 0;+}+API_ALL(sparse_la_newSolver, (int code, int s, void** p), (p));++template <class T, class M, class S>+RET sparse_la_freeSolver(void* p) {+ delete (S*)p;+ return 0;+}+API_ALL(sparse_la_freeSolver, (int code, int s, void* p), (p));++template <class T, class M, class S>+RET sparse_la_factorize(void* p, void* a) {+ ((S*)p)->factorize(*(M*)a);+ return 0;+}+API_ALL(sparse_la_factorize, (int code, int s, void* p, void* a), (p,a));++template <class T, class M, class S>+RET sparse_la_analyzePattern(void* p, void* a) {+ ((S*)p)->analyzePattern(*(M*)a);+ return 0;+}+API_ALL(sparse_la_analyzePattern, (int code, int s, void* p, void* a), (p,a));++template <class T, class M, class S>+RET sparse_la_compute(void* p, void* a) {+ ((S*)p)->compute(*(M*)a);+ return 0;+}+API_ALL(sparse_la_compute, (int code, int s, void* p, void* a), (p,a));++template <class T, class M, class S>+RET sparse_la_tolerance(void* p, double* x) {+ *x = ((S*)p)->tolerance();+ return 0;+}+API_ITERATIVE(sparse_la_tolerance, (int code, int s, void* p, double* x), (p,x));++template <class T, class M, class S>+RET sparse_la_setTolerance(void* p, double x) {+ ((S*)p)->setTolerance(x);+ return 0;+}+API_ITERATIVE(sparse_la_setTolerance, (int code, int s, void* p, double x), (p,x));++template <class T, class M, class S>+RET sparse_la_maxIterations(void* p, int* x) {+ *x = ((S*)p)->maxIterations();+ return 0;+}+API_ITERATIVE(sparse_la_maxIterations, (int code, int s, void* p, int* x), (p,x));++template <class T, class M, class S>+RET sparse_la_setMaxIterations(void* p, int x) {+ ((S*)p)->setMaxIterations(x);+ return 0;+}+API_ITERATIVE(sparse_la_setMaxIterations, (int code, int s, void* p, int x), (p,x));++template <class T, class M, class S>+RET sparse_la_info(void* p, int* x) {+ *x = ((S*)p)->info();+ return 0;+}+API_ALL(sparse_la_info, (int code, int s, void* p, int* x), (p,x));++template <class T, class M, class S>+RET sparse_la_error(void* p, double* x) {+ *x = ((S*)p)->error();+ return 0;+}+API_ITERATIVE(sparse_la_error, (int code, int s, void* p, double* x), (p,x));++template <class T, class M, class S>+RET sparse_la_iterations(void* p, int* x) {+ *x = ((S*)p)->iterations();+ return 0;+}+API_ITERATIVE(sparse_la_iterations, (int code, int s, void* p, int* x), (p,x));++template <class T, class M, class S>+RET sparse_la_solve(void* p, void* b, void** x) {+ *x = new M(((S*)p)->solve(*(M*)b));+ return 0;+}+API_ALL(sparse_la_solve, (int code, int s, void* p, void* b, void** x), (p,b,x));++// template <class T, class M, class S>+// RET sparse_la_solveWithGuess(void* p, void* b, void* x0, void** x) {+// *x = new M(((S*)p)->solveWithGuess(Matrix<T,Dynamic,Dynamic>(*(M*)b), Matrix<T,Dynamic,Dynamic>(*(M*)x0)));+// return 0;+// }+// API_ALL(sparse_la_solveWithGuess, (int code, int s, void* p, void* b, void* x0, void** x), (p,b,x0,x));++++++++++++
+ cbits/eigen-sparse-la.h view
@@ -0,0 +1,50 @@+#include "eigen-runtime.h"++#include "Eigen/Core"+#include "Eigen/SparseCore"+#include "Eigen/OrderingMethods"++#include "Eigen/src/Core/util/DisableStupidWarnings.h"++#include "Eigen/src/misc/Solve.h"+#include "Eigen/src/misc/SparseSolve.h"++#include "Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h"+#include "Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h"+#include "Eigen/src/IterativeLinearSolvers/ConjugateGradient.h"+#include "Eigen/src/IterativeLinearSolvers/BiCGSTAB.h"+// #include "Eigen/src/IterativeLinearSolvers/IncompleteLUT.h" is not MPL2 compliant++#include "Eigen/src/Core/util/ReenableStupidWarnings.h"++#include "Eigen/SparseLU"+#include "Eigen/SparseQR"++using namespace Eigen;++extern "C" {++enum Solver {+ ConjugateGradient,+ BiCGSTAB,+ SparseLU,+ SparseQR+};++const char* eigen_sparse_la_newSolver(int, int, void**);+const char* eigen_sparse_la_freeSolver(int, int, void*);+const char* eigen_sparse_la_factorize(int, int, void*, void*);+const char* eigen_sparse_la_analyzePattern(int, int, void*, void*);+const char* eigen_sparse_la_compute(int, int, void*, void*);+const char* eigen_sparse_la_tolerance(int, int, void*, double*);+const char* eigen_sparse_la_setTolerance(int, int, void*, double);+const char* eigen_sparse_la_maxIterations(int, int, void*, int*);+const char* eigen_sparse_la_setMaxIterations(int, int, void*, int);+const char* eigen_sparse_la_info(int, int, void*, int*);+const char* eigen_sparse_la_error(int, int, void*, double*);+const char* eigen_sparse_la_iterations(int, int, void*, int*);+const char* eigen_sparse_la_solve(int, int, void*, void*, void**);+// const char* eigen_sparse_la_solveWithGuess(int, int, void*, void*, void*, void**);++} // end extern "C"+
+ cbits/eigen-sparse.cpp view
@@ -0,0 +1,168 @@+#include "eigen-sparse.h"+#include <Eigen/LU>+#include <Eigen/LeastSquares>+#include <stdio.h>++template <class T>+RET sparse_fromList(int rows, int cols, void* data, int size, void** pr) {+ typedef SparseMatrix<T> M;+ typedef Triplet<T> E;+ std::auto_ptr<M> a(new M(rows, cols));+ a->setFromTriplets((E*)data, (E*)data + size);+ *(M**)pr = a.release();+ return 0;+}+API(sparse_fromList, (int code, int rows, int cols, void* data, int size, void** pr), (rows,cols,data,size,pr));++template <class T>+RET sparse_toList(void* p, void* q, int s) {+ int n = 0;+ typedef SparseMatrix<T> M;+ typedef Triplet<T> E;+ M* m = (M*)p;+ for (int k = 0; k < m->outerSize(); ++k) {+ for (typename M::InnerIterator i(*m, k); i; ++i) {+ if (n >= s)+ return strdup("sparse_toList: buffer overrun detected");+ ((E*)q)[n++] = E(i.row(), i.col(), i.value());+ }+ }+ return n < s ? strdup("sparse_toList: buffer underrun detected") : 0;+}+API(sparse_toList, (int code, void* p, void* q, int s), (p,q,s));++template <class T>+RET sparse_free(void* p) {+ delete (SparseMatrix<T>*)p;+ return 0;+}+API(sparse_free, (int code, void* p), (p));++#define SPARSE_UNOP_INPLACE(name)\+template <class T>\+RET sparse_##name(void* p, void** pr) {\+ typedef SparseMatrix<T> M;\+ std::auto_ptr<M> a(new M(*(M*)p));\+ a->name();\+ *(M**)pr = a.release();\+ return 0;\+}\+API(sparse_##name, (int code, void* p, void** pr), (p, pr));++SPARSE_UNOP_INPLACE(makeCompressed);+SPARSE_UNOP_INPLACE(uncompress);++#define SPARSE_UNOP(name)\+template <class T>\+RET sparse_##name(void* p, void** pr) {\+ typedef SparseMatrix<T> M;\+ *(M**)pr = new M(((M*)p)->name());\+ return 0;\+}\+API(sparse_##name, (int code, void* p, void** pr), (p, pr));++SPARSE_UNOP(adjoint);+SPARSE_UNOP(transpose);++template <class T>+RET sparse_pruned(void* p, void** pr) {+ typedef SparseMatrix<T> M;+ std::auto_ptr<M> a(new M(*(M*)p));+ a->prune(T(1));+ *(M**)pr = a.release();+ return 0;+}+API(sparse_pruned, (int code, void* p, void** pr), (p, pr));++template <class T>+RET sparse_prunedRef(void* p, void* q, void** pr) {+ typedef SparseMatrix<T> M;+ std::auto_ptr<M> a(new M(*(M*)p));+ a->prune(*(T*)q);+ *(M**)pr = a.release();+ return 0;+}+API(sparse_prunedRef, (int code, void* p, void* q, void** pr), (p, q, pr));++template <class T>+RET sparse_scale(void* p, void* q, void** pr) {+ typedef SparseMatrix<T> M;+ *(M**)pr = new M(*(T*)q * *(M*)p);+ return 0;+}+API(sparse_scale, (int code, void* p, void* q, void** pr), (p, q, pr));++template <class T>+RET sparse_coeff(void* p, int row, int col, void* pr) {+ *(T*)pr = ((SparseMatrix<T>*)p)->coeff(row, col);+ return 0;+}+API(sparse_coeff, (int code, void* p, int row, int col, void* pr), (p, row, col, pr));++#define SPARSE_PROP(name,type)\+template <class T>\+RET sparse_##name(void* p, void* pr) {\+ *(type*)pr = ((SparseMatrix<T>*)p)->name();\+ return 0;\+}\+API(sparse_##name, (int code, void* p, void* pr), (p, pr));++SPARSE_PROP(cols, int);+SPARSE_PROP(rows, int);+SPARSE_PROP(innerSize, int);+SPARSE_PROP(outerSize, int);+SPARSE_PROP(nonZeros, int);+SPARSE_PROP(isCompressed, int);+SPARSE_PROP(norm, T);+SPARSE_PROP(squaredNorm, T);+SPARSE_PROP(blueNorm, T);++#define SPARSE_BINOP(name,op)\+template <class T>\+RET sparse_##name(void* p, void* q, void** pr) {\+ typedef SparseMatrix<T> M;\+ *(M**)pr = new M(*(M*)p op *(M*)q);\+ return 0;\+}\+API(sparse_##name, (int code, void* p, void* q, void** pr), (p, q, pr));++SPARSE_BINOP(add, +);+SPARSE_BINOP(sub, -);+SPARSE_BINOP(mul, *);++template <class T>+RET sparse_block(void* p, int row, int col, int rows, int cols, void** pr) {+ typedef SparseMatrix<T> M;+ *(M**)pr = new M(((M*)p)->block(row,col,rows,cols));+ return 0;+}+API(sparse_block, (int code, void* p, int row, int col, int rows, int cols, void** pr), (p, row, col, rows, cols, pr));++template <class T> bool isZero(T x) { return x == 0; }+template <class T> bool isZero(std::complex<T> x) { return x.real() == 0 && x.imag() == 0; }++template <class T>+RET sparse_fromMatrix(void* p, int rows, int cols, void** pq) {+ typedef SparseMatrix<T> M;+ typedef Map< Matrix<T,Dynamic,Dynamic> > MapMatrix;+ MapMatrix src((const T*)p, rows, cols);+ std::auto_ptr<M> dst(new M(rows, cols));+ for (int row = 0; row < rows; ++row) {+ for (int col = 0; col < cols; ++col) {+ T val = src.coeff(row,col);+ if (!isZero(val))+ dst->insert(row, col) = val;+ }+ }+ *(M**)pq = dst.release();+ return 0;+}+API(sparse_fromMatrix, (int code, void* p, int rows, int cols, void** pq), (p,rows,cols,pq));++template <class T>+RET sparse_toMatrix(void* p, void* q, int rows, int cols) {+ typedef Map< Matrix<T,Dynamic,Dynamic> > MapMatrix;+ MapMatrix((T*)q, rows, cols) = *(SparseMatrix<T>*)p;+ return 0;+}+API(sparse_toMatrix, (int code, void* p, void* q, int rows, int cols), (p,q,rows,cols));
+ cbits/eigen-sparse.h view
@@ -0,0 +1,45 @@+#include "eigen-runtime.h"+#include <Eigen/SparseCore>++using namespace Eigen;++extern "C" {++#define SPARSE_PROP(name) const char* eigen_sparse_##name(int, void*, void*)+SPARSE_PROP(cols);+SPARSE_PROP(rows);+SPARSE_PROP(innerSize);+SPARSE_PROP(outerSize);+SPARSE_PROP(nonZeros);+SPARSE_PROP(isCompressed);+SPARSE_PROP(norm);+SPARSE_PROP(squaredNorm);+SPARSE_PROP(blueNorm);+#undef SPARSE_PROP++#define SPARSE_BINOP(name) const char* eigen_sparse_##name(int, void*, void*, void**);+SPARSE_BINOP(add);+SPARSE_BINOP(sub);+SPARSE_BINOP(mul);+SPARSE_BINOP(prunedRef);+SPARSE_BINOP(scale);+#undef SPARSE_BINOP++#define SPARSE_UNOP(name) const char* eigen_sparse_##name(int, void*, void**);+SPARSE_UNOP(makeCompressed);+SPARSE_UNOP(uncompress);+SPARSE_UNOP(adjont);+SPARSE_UNOP(transponse);+SPARSE_UNOP(pruned);+#undef SPARSE_UNOP++const char* eigen_sparse_fromList(int, int, int, void*, int, void**);+const char* eigen_sparse_toList(int, void*, void*, int);+const char* eigen_sparse_free(int, void*);+const char* eigen_sparse_coeff(int, void*, int, int, void*);+const char* eigen_sparse_block(int, void*, int, int, int, int, void**);+const char* eigen_sparse_fromMatrix(int, void*, int, int, void**);+const char* eigen_sparse_toMatrix(int, void*, void*, int, int);++} // end extern "C"+
eigen.cabal view
@@ -1,382 +1,1448 @@ name: eigen-version: 2.1.0-homepage: https://github.com/osidorkin/haskell-eigen-synopsis: Eigen C++ library (linear algebra: matrices, vectors, numerical solvers).-description: This module provides Haskell binding for Eigen C++ library.- Eigen is a C++ template library for linear algebra: matrices, vectors, numerical solvers, and related algorithms.- Eigen home page is <http://eigen.tuxfamily.org/>.- .- Eigen is licensed under the MPL2, which is a simple weak copyleft license. Common questions about the MPL2 are answered in the official MPL2 FAQ at <http://www.mozilla.org/MPL/2.0/FAQ.html>.- .- Note that currently, a few features in Eigen rely on third-party code licensed under the LGPL: SimplicialCholesky, AMD ordering, and constrained_cg. Such features are explicitly disabled by compiling Eigen with the EIGEN_MPL2_ONLY preprocessor symbol defined.- .- Virtually any software may use Eigen. For example, closed-source software may use Eigen without having to disclose its own source code. Many proprietary and closed-source software projects are using Eigen right now, as well as many BSD-licensed projects.- .- Some parts of documentation strings are based or replicate original Eigen documentation which is available at <http://eigen.tuxfamily.org/dox/>.-category: Data, Math, Algebra, Statistics, Algorithms, Numeric-license: BSD3-license-file: LICENSE-copyright: (c) 2013-2015, Oleg Sidorkin-author: Oleg Sidorkin <oleg.sidorkin@gmail.com>-maintainer: Oleg Sidorkin <oleg.sidorkin@gmail.com>-cabal-version: >= 1.8-build-type: Simple-tested-with: GHC ==7.8.3-extra-source-files: cbits/eigen-proxy.h- eigen3/COPYING.BSD- eigen3/COPYING.GPL- eigen3/COPYING.LGPL- eigen3/COPYING.MINPACK- eigen3/COPYING.MPL2- eigen3/COPYING.README- eigen3/Eigen/Array- eigen3/Eigen/Cholesky- eigen3/Eigen/CholmodSupport- eigen3/Eigen/CMakeLists.txt- eigen3/Eigen/Core- eigen3/Eigen/Dense- eigen3/Eigen/Eigen- eigen3/Eigen/Eigen2Support- eigen3/Eigen/Eigenvalues- eigen3/Eigen/Geometry- eigen3/Eigen/Householder- eigen3/Eigen/IterativeLinearSolvers- eigen3/Eigen/Jacobi- eigen3/Eigen/LeastSquares- eigen3/Eigen/LU- eigen3/Eigen/MetisSupport- eigen3/Eigen/OrderingMethods- eigen3/Eigen/PardisoSupport- eigen3/Eigen/PaStiXSupport- eigen3/Eigen/QR- eigen3/Eigen/QtAlignedMalloc- eigen3/Eigen/Sparse- eigen3/Eigen/SparseCholesky- eigen3/Eigen/SparseCore- eigen3/Eigen/SparseLU- eigen3/Eigen/SparseQR- eigen3/Eigen/SPQRSupport- eigen3/Eigen/src/Cholesky/CMakeLists.txt- eigen3/Eigen/src/Cholesky/LDLT.h- eigen3/Eigen/src/Cholesky/LLT.h- eigen3/Eigen/src/Cholesky/LLT_MKL.h- eigen3/Eigen/src/CholmodSupport/CholmodSupport.h- eigen3/Eigen/src/CholmodSupport/CMakeLists.txt- eigen3/Eigen/src/CMakeLists.txt- eigen3/Eigen/src/Core/arch/AltiVec/CMakeLists.txt- eigen3/Eigen/src/Core/arch/AltiVec/Complex.h- eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h- eigen3/Eigen/src/Core/arch/CMakeLists.txt- eigen3/Eigen/src/Core/arch/Default/CMakeLists.txt- eigen3/Eigen/src/Core/arch/Default/Settings.h- eigen3/Eigen/src/Core/arch/NEON/CMakeLists.txt- eigen3/Eigen/src/Core/arch/NEON/Complex.h- eigen3/Eigen/src/Core/arch/NEON/PacketMath.h- eigen3/Eigen/src/Core/arch/SSE/CMakeLists.txt- eigen3/Eigen/src/Core/arch/SSE/Complex.h- eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h- eigen3/Eigen/src/Core/arch/SSE/PacketMath.h- eigen3/Eigen/src/Core/Array.h- eigen3/Eigen/src/Core/ArrayBase.h- eigen3/Eigen/src/Core/ArrayWrapper.h- eigen3/Eigen/src/Core/Assign.h- eigen3/Eigen/src/Core/Assign_MKL.h- eigen3/Eigen/src/Core/BandMatrix.h- eigen3/Eigen/src/Core/Block.h- eigen3/Eigen/src/Core/BooleanRedux.h- eigen3/Eigen/src/Core/CMakeLists.txt- eigen3/Eigen/src/Core/CommaInitializer.h- eigen3/Eigen/src/Core/CoreIterators.h- eigen3/Eigen/src/Core/CwiseBinaryOp.h- eigen3/Eigen/src/Core/CwiseNullaryOp.h- eigen3/Eigen/src/Core/CwiseUnaryOp.h- eigen3/Eigen/src/Core/CwiseUnaryView.h- eigen3/Eigen/src/Core/DenseBase.h- eigen3/Eigen/src/Core/DenseCoeffsBase.h- eigen3/Eigen/src/Core/DenseStorage.h- eigen3/Eigen/src/Core/Diagonal.h- eigen3/Eigen/src/Core/DiagonalMatrix.h- eigen3/Eigen/src/Core/DiagonalProduct.h- eigen3/Eigen/src/Core/Dot.h- eigen3/Eigen/src/Core/EigenBase.h- eigen3/Eigen/src/Core/Flagged.h- eigen3/Eigen/src/Core/ForceAlignedAccess.h- eigen3/Eigen/src/Core/Functors.h- eigen3/Eigen/src/Core/Fuzzy.h- eigen3/Eigen/src/Core/GeneralProduct.h- eigen3/Eigen/src/Core/GenericPacketMath.h- eigen3/Eigen/src/Core/GlobalFunctions.h- eigen3/Eigen/src/Core/IO.h- eigen3/Eigen/src/Core/Map.h- eigen3/Eigen/src/Core/MapBase.h- eigen3/Eigen/src/Core/MathFunctions.h- eigen3/Eigen/src/Core/Matrix.h- eigen3/Eigen/src/Core/MatrixBase.h- eigen3/Eigen/src/Core/NestByValue.h- eigen3/Eigen/src/Core/NoAlias.h- eigen3/Eigen/src/Core/NumTraits.h- eigen3/Eigen/src/Core/PermutationMatrix.h- eigen3/Eigen/src/Core/PlainObjectBase.h- eigen3/Eigen/src/Core/ProductBase.h- eigen3/Eigen/src/Core/products/CMakeLists.txt- eigen3/Eigen/src/Core/products/CoeffBasedProduct.h- eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h- eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h- eigen3/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h- eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h- eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h- eigen3/Eigen/src/Core/products/GeneralMatrixVector.h- eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h- eigen3/Eigen/src/Core/products/Parallelizer.h- eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h- eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h- eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h- eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h- eigen3/Eigen/src/Core/products/SelfadjointProduct.h- eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h- eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h- eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h- eigen3/Eigen/src/Core/products/TriangularMatrixVector.h- eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h- eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h- eigen3/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h- eigen3/Eigen/src/Core/products/TriangularSolverVector.h- eigen3/Eigen/src/Core/Random.h- eigen3/Eigen/src/Core/Redux.h- eigen3/Eigen/src/Core/Ref.h- eigen3/Eigen/src/Core/Replicate.h- eigen3/Eigen/src/Core/ReturnByValue.h- eigen3/Eigen/src/Core/Reverse.h- eigen3/Eigen/src/Core/Select.h- eigen3/Eigen/src/Core/SelfAdjointView.h- eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h- eigen3/Eigen/src/Core/SolveTriangular.h- eigen3/Eigen/src/Core/StableNorm.h- eigen3/Eigen/src/Core/Stride.h- eigen3/Eigen/src/Core/Swap.h- eigen3/Eigen/src/Core/Transpose.h- eigen3/Eigen/src/Core/Transpositions.h- eigen3/Eigen/src/Core/TriangularMatrix.h- eigen3/Eigen/src/Core/util/BlasUtil.h- eigen3/Eigen/src/Core/util/CMakeLists.txt- eigen3/Eigen/src/Core/util/Constants.h- eigen3/Eigen/src/Core/util/DisableStupidWarnings.h- eigen3/Eigen/src/Core/util/ForwardDeclarations.h- eigen3/Eigen/src/Core/util/Macros.h- eigen3/Eigen/src/Core/util/Memory.h- eigen3/Eigen/src/Core/util/Meta.h- eigen3/Eigen/src/Core/util/MKL_support.h- eigen3/Eigen/src/Core/util/NonMPL2.h- eigen3/Eigen/src/Core/util/ReenableStupidWarnings.h- eigen3/Eigen/src/Core/util/StaticAssert.h- eigen3/Eigen/src/Core/util/XprHelper.h- eigen3/Eigen/src/Core/VectorBlock.h- eigen3/Eigen/src/Core/VectorwiseOp.h- eigen3/Eigen/src/Core/Visitor.h- eigen3/Eigen/src/Eigen2Support/Block.h- eigen3/Eigen/src/Eigen2Support/CMakeLists.txt- eigen3/Eigen/src/Eigen2Support/Cwise.h- eigen3/Eigen/src/Eigen2Support/CwiseOperators.h- eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h- eigen3/Eigen/src/Eigen2Support/Geometry/All.h- eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h- eigen3/Eigen/src/Eigen2Support/Geometry/CMakeLists.txt- eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h- eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h- eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h- eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h- eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h- eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h- eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h- eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h- eigen3/Eigen/src/Eigen2Support/Lazy.h- eigen3/Eigen/src/Eigen2Support/LeastSquares.h- eigen3/Eigen/src/Eigen2Support/LU.h- eigen3/Eigen/src/Eigen2Support/Macros.h- eigen3/Eigen/src/Eigen2Support/MathFunctions.h- eigen3/Eigen/src/Eigen2Support/Memory.h- eigen3/Eigen/src/Eigen2Support/Meta.h- eigen3/Eigen/src/Eigen2Support/Minor.h- eigen3/Eigen/src/Eigen2Support/QR.h- eigen3/Eigen/src/Eigen2Support/SVD.h- eigen3/Eigen/src/Eigen2Support/TriangularSolver.h- eigen3/Eigen/src/Eigen2Support/VectorBlock.h- eigen3/Eigen/src/Eigenvalues/CMakeLists.txt- eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h- eigen3/Eigen/src/Eigenvalues/ComplexSchur.h- eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h- eigen3/Eigen/src/Eigenvalues/EigenSolver.h- eigen3/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h- eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h- eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h- eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h- eigen3/Eigen/src/Eigenvalues/RealQZ.h- eigen3/Eigen/src/Eigenvalues/RealSchur.h- eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h- eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h- eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h- eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h- eigen3/Eigen/src/Geometry/AlignedBox.h- eigen3/Eigen/src/Geometry/AngleAxis.h- eigen3/Eigen/src/Geometry/arch/CMakeLists.txt- eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h- eigen3/Eigen/src/Geometry/CMakeLists.txt- eigen3/Eigen/src/Geometry/EulerAngles.h- eigen3/Eigen/src/Geometry/Homogeneous.h- eigen3/Eigen/src/Geometry/Hyperplane.h- eigen3/Eigen/src/Geometry/OrthoMethods.h- eigen3/Eigen/src/Geometry/ParametrizedLine.h- eigen3/Eigen/src/Geometry/Quaternion.h- eigen3/Eigen/src/Geometry/Rotation2D.h- eigen3/Eigen/src/Geometry/RotationBase.h- eigen3/Eigen/src/Geometry/Scaling.h- eigen3/Eigen/src/Geometry/Transform.h- eigen3/Eigen/src/Geometry/Translation.h- eigen3/Eigen/src/Geometry/Umeyama.h- eigen3/Eigen/src/Householder/BlockHouseholder.h- eigen3/Eigen/src/Householder/CMakeLists.txt- eigen3/Eigen/src/Householder/Householder.h- eigen3/Eigen/src/Householder/HouseholderSequence.h- eigen3/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h- eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h- eigen3/Eigen/src/IterativeLinearSolvers/CMakeLists.txt- eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h- eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h- eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h- eigen3/Eigen/src/Jacobi/CMakeLists.txt- eigen3/Eigen/src/Jacobi/Jacobi.h- eigen3/Eigen/src/LU/arch/CMakeLists.txt- eigen3/Eigen/src/LU/arch/Inverse_SSE.h- eigen3/Eigen/src/LU/CMakeLists.txt- eigen3/Eigen/src/LU/Determinant.h- eigen3/Eigen/src/LU/FullPivLU.h- eigen3/Eigen/src/LU/Inverse.h- eigen3/Eigen/src/LU/PartialPivLU.h- eigen3/Eigen/src/LU/PartialPivLU_MKL.h- eigen3/Eigen/src/MetisSupport/CMakeLists.txt- eigen3/Eigen/src/MetisSupport/MetisSupport.h- eigen3/Eigen/src/misc/blas.h- eigen3/Eigen/src/misc/CMakeLists.txt- eigen3/Eigen/src/misc/Image.h- eigen3/Eigen/src/misc/Kernel.h- eigen3/Eigen/src/misc/Solve.h- eigen3/Eigen/src/misc/SparseSolve.h- eigen3/Eigen/src/OrderingMethods/Amd.h- eigen3/Eigen/src/OrderingMethods/CMakeLists.txt- eigen3/Eigen/src/OrderingMethods/Eigen_Colamd.h- eigen3/Eigen/src/OrderingMethods/Ordering.h- eigen3/Eigen/src/PardisoSupport/CMakeLists.txt- eigen3/Eigen/src/PardisoSupport/PardisoSupport.h- eigen3/Eigen/src/PaStiXSupport/CMakeLists.txt- eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h- eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h- eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h- eigen3/Eigen/src/plugins/BlockMethods.h- eigen3/Eigen/src/plugins/CMakeLists.txt- eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h- eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h- eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h- eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h- eigen3/Eigen/src/QR/CMakeLists.txt- eigen3/Eigen/src/QR/ColPivHouseholderQR.h- eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h- eigen3/Eigen/src/QR/FullPivHouseholderQR.h- eigen3/Eigen/src/QR/HouseholderQR.h- eigen3/Eigen/src/QR/HouseholderQR_MKL.h- eigen3/Eigen/src/SparseCholesky/CMakeLists.txt- eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h- eigen3/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h- eigen3/Eigen/src/SparseCore/AmbiVector.h- eigen3/Eigen/src/SparseCore/CMakeLists.txt- eigen3/Eigen/src/SparseCore/CompressedStorage.h- eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h- eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h- eigen3/Eigen/src/SparseCore/SparseBlock.h- eigen3/Eigen/src/SparseCore/SparseColEtree.h- eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h- eigen3/Eigen/src/SparseCore/SparseCwiseUnaryOp.h- eigen3/Eigen/src/SparseCore/SparseDenseProduct.h- eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h- eigen3/Eigen/src/SparseCore/SparseDot.h- eigen3/Eigen/src/SparseCore/SparseFuzzy.h- eigen3/Eigen/src/SparseCore/SparseMatrix.h- eigen3/Eigen/src/SparseCore/SparseMatrixBase.h- eigen3/Eigen/src/SparseCore/SparsePermutation.h- eigen3/Eigen/src/SparseCore/SparseProduct.h- eigen3/Eigen/src/SparseCore/SparseRedux.h- eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h- eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h- eigen3/Eigen/src/SparseCore/SparseTranspose.h- eigen3/Eigen/src/SparseCore/SparseTriangularView.h- eigen3/Eigen/src/SparseCore/SparseUtil.h- eigen3/Eigen/src/SparseCore/SparseVector.h- eigen3/Eigen/src/SparseCore/SparseView.h- eigen3/Eigen/src/SparseCore/TriangularSolver.h- eigen3/Eigen/src/SparseLU/CMakeLists.txt- eigen3/Eigen/src/SparseLU/SparseLU.h- eigen3/Eigen/src/SparseLU/SparseLU_column_bmod.h- eigen3/Eigen/src/SparseLU/SparseLU_column_dfs.h- eigen3/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h- eigen3/Eigen/src/SparseLU/SparseLU_gemm_kernel.h- eigen3/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h- eigen3/Eigen/src/SparseLU/SparseLU_kernel_bmod.h- eigen3/Eigen/src/SparseLU/SparseLU_Memory.h- eigen3/Eigen/src/SparseLU/SparseLU_panel_bmod.h- eigen3/Eigen/src/SparseLU/SparseLU_panel_dfs.h- eigen3/Eigen/src/SparseLU/SparseLU_pivotL.h- eigen3/Eigen/src/SparseLU/SparseLU_pruneL.h- eigen3/Eigen/src/SparseLU/SparseLU_relax_snode.h- eigen3/Eigen/src/SparseLU/SparseLU_Structs.h- eigen3/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h- eigen3/Eigen/src/SparseLU/SparseLU_Utils.h- eigen3/Eigen/src/SparseLU/SparseLUImpl.h- eigen3/Eigen/src/SparseQR/CMakeLists.txt- eigen3/Eigen/src/SparseQR/SparseQR.h- eigen3/Eigen/src/SPQRSupport/CMakeLists.txt- eigen3/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h- eigen3/Eigen/src/StlSupport/CMakeLists.txt- eigen3/Eigen/src/StlSupport/details.h- eigen3/Eigen/src/StlSupport/StdDeque.h- eigen3/Eigen/src/StlSupport/StdList.h- eigen3/Eigen/src/StlSupport/StdVector.h- eigen3/Eigen/src/SuperLUSupport/CMakeLists.txt- eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h- eigen3/Eigen/src/SVD/CMakeLists.txt- eigen3/Eigen/src/SVD/JacobiSVD.h- eigen3/Eigen/src/SVD/JacobiSVD_MKL.h- eigen3/Eigen/src/SVD/UpperBidiagonalization.h- eigen3/Eigen/src/UmfPackSupport/CMakeLists.txt- eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h- eigen3/Eigen/StdDeque- eigen3/Eigen/StdList- eigen3/Eigen/StdVector- eigen3/Eigen/SuperLUSupport- eigen3/Eigen/SVD- eigen3/Eigen/UmfPackSupport---source-repository head- type: git- location: git://github.com/osidorkin/haskell-eigen.git---library- exposed-modules: Data.Eigen.LA- Data.Eigen.Matrix- Data.Eigen.Matrix.Mutable- Data.Eigen.SparseMatrix- Data.Eigen.Parallel-- other-modules: Data.Eigen.Internal-- ghc-options: -Wall -fno-warn-name-shadowing- build-depends: base >= 3 && < 5,- vector >= 0.5 && < 0.11,- primitive >= 0.1 && < 0.6,- bytestring-- include-dirs: eigen3, cbits- c-sources: cbits/eigen-proxy.cpp+version: 2.1.1+homepage: https://github.com/osidorkin/haskell-eigen+synopsis: Eigen C++ library (linear algebra: matrices, vectors, numerical solvers).+description: This module provides Haskell binding for Eigen C++ library.+ Eigen is a C++ template library for linear algebra: matrices, vectors, numerical solvers, and related algorithms.+ Eigen home page is <http://eigen.tuxfamily.org/>.+ .+ Eigen is licensed under the MPL2, which is a simple weak copyleft license. Common questions about the MPL2 are answered in the official MPL2 FAQ at <http://www.mozilla.org/MPL/2.0/FAQ.html>.+ .+ Note that currently, a few features in Eigen rely on third-party code licensed under the LGPL: SimplicialCholesky, AMD ordering, and constrained_cg. Such features are explicitly disabled by compiling Eigen with the EIGEN_MPL2_ONLY preprocessor symbol defined.+ .+ Virtually any software may use Eigen. For example, closed-source software may use Eigen without having to disclose its own source code. Many proprietary and closed-source software projects are using Eigen right now, as well as many BSD-licensed projects.+ .+ Some parts of documentation strings are based or replicate original Eigen documentation which is available at <http://eigen.tuxfamily.org/dox/>.+category: Data, Math, Algebra, Statistics, Algorithms, Numeric+license: BSD3+license-file: LICENSE+copyright: (c) 2013-2015, Oleg Sidorkin+author: Oleg Sidorkin <oleg.sidorkin@gmail.com>+maintainer: Oleg Sidorkin <oleg.sidorkin@gmail.com>+cabal-version: >= 1.8+build-type: Simple+tested-with: GHC ==7.8.3+extra-source-files: cbits/eigen-runtime.h+ cbits/eigen-dense.h+ cbits/eigen-la.h+ cbits/eigen-sparse.h+ cbits/eigen-sparse-la.h+ eigen3/.hg_archival.txt+ eigen3/.hgeol+ eigen3/.hgignore+ eigen3/.hgtags+ eigen3/bench/basicbench.cxxlist+ eigen3/bench/basicbenchmark.cpp+ eigen3/bench/basicbenchmark.h+ eigen3/bench/bench_gemm.cpp+ eigen3/bench/bench_multi_compilers.sh+ eigen3/bench/bench_norm.cpp+ eigen3/bench/bench_reverse.cpp+ eigen3/bench/bench_sum.cpp+ eigen3/bench/bench_unrolling+ eigen3/bench/benchBlasGemm.cpp+ eigen3/bench/benchCholesky.cpp+ eigen3/bench/benchEigenSolver.cpp+ eigen3/bench/benchFFT.cpp+ eigen3/bench/benchGeometry.cpp+ eigen3/bench/benchmark.cpp+ eigen3/bench/benchmark_suite+ eigen3/bench/benchmarkSlice.cpp+ eigen3/bench/benchmarkX.cpp+ eigen3/bench/benchmarkXcwise.cpp+ eigen3/bench/BenchSparseUtil.h+ eigen3/bench/BenchTimer.h+ eigen3/bench/BenchUtil.h+ eigen3/bench/benchVecAdd.cpp+ eigen3/bench/btl/actions/action_aat_product.hh+ eigen3/bench/btl/actions/action_ata_product.hh+ eigen3/bench/btl/actions/action_atv_product.hh+ eigen3/bench/btl/actions/action_axpby.hh+ eigen3/bench/btl/actions/action_axpy.hh+ eigen3/bench/btl/actions/action_cholesky.hh+ eigen3/bench/btl/actions/action_ger.hh+ eigen3/bench/btl/actions/action_hessenberg.hh+ eigen3/bench/btl/actions/action_lu_decomp.hh+ eigen3/bench/btl/actions/action_lu_solve.hh+ eigen3/bench/btl/actions/action_matrix_matrix_product.hh+ eigen3/bench/btl/actions/action_matrix_matrix_product_bis.hh+ eigen3/bench/btl/actions/action_matrix_vector_product.hh+ eigen3/bench/btl/actions/action_partial_lu.hh+ eigen3/bench/btl/actions/action_rot.hh+ eigen3/bench/btl/actions/action_symv.hh+ eigen3/bench/btl/actions/action_syr2.hh+ eigen3/bench/btl/actions/action_trisolve.hh+ eigen3/bench/btl/actions/action_trisolve_matrix.hh+ eigen3/bench/btl/actions/action_trmm.hh+ eigen3/bench/btl/actions/basic_actions.hh+ eigen3/bench/btl/cmake/FindACML.cmake+ eigen3/bench/btl/cmake/FindATLAS.cmake+ eigen3/bench/btl/cmake/FindBlitz.cmake+ eigen3/bench/btl/cmake/FindCBLAS.cmake+ eigen3/bench/btl/cmake/FindGMM.cmake+ eigen3/bench/btl/cmake/FindGOTO.cmake+ eigen3/bench/btl/cmake/FindGOTO2.cmake+ eigen3/bench/btl/cmake/FindMKL.cmake+ eigen3/bench/btl/cmake/FindMTL4.cmake+ eigen3/bench/btl/cmake/FindPackageHandleStandardArgs.cmake+ eigen3/bench/btl/cmake/FindTvmet.cmake+ eigen3/bench/btl/cmake/MacroOptionalAddSubdirectory.cmake+ eigen3/bench/btl/CMakeLists.txt+ eigen3/bench/btl/COPYING+ eigen3/bench/btl/data/action_settings.txt+ eigen3/bench/btl/data/CMakeLists.txt+ eigen3/bench/btl/data/gnuplot_common_settings.hh+ eigen3/bench/btl/data/go_mean+ eigen3/bench/btl/data/mean.cxx+ eigen3/bench/btl/data/mk_gnuplot_script.sh+ eigen3/bench/btl/data/mk_mean_script.sh+ eigen3/bench/btl/data/mk_new_gnuplot.sh+ eigen3/bench/btl/data/perlib_plot_settings.txt+ eigen3/bench/btl/data/regularize.cxx+ eigen3/bench/btl/data/smooth.cxx+ eigen3/bench/btl/data/smooth_all.sh+ eigen3/bench/btl/generic_bench/bench.hh+ eigen3/bench/btl/generic_bench/bench_parameter.hh+ eigen3/bench/btl/generic_bench/btl.hh+ eigen3/bench/btl/generic_bench/init/init_function.hh+ eigen3/bench/btl/generic_bench/init/init_matrix.hh+ eigen3/bench/btl/generic_bench/init/init_vector.hh+ eigen3/bench/btl/generic_bench/static/bench_static.hh+ eigen3/bench/btl/generic_bench/static/intel_bench_fixed_size.hh+ eigen3/bench/btl/generic_bench/static/static_size_generator.hh+ eigen3/bench/btl/generic_bench/timers/mixed_perf_analyzer.hh+ eigen3/bench/btl/generic_bench/timers/portable_perf_analyzer.hh+ eigen3/bench/btl/generic_bench/timers/portable_perf_analyzer_old.hh+ eigen3/bench/btl/generic_bench/timers/portable_timer.hh+ eigen3/bench/btl/generic_bench/timers/STL_perf_analyzer.hh+ eigen3/bench/btl/generic_bench/timers/STL_timer.hh+ eigen3/bench/btl/generic_bench/timers/x86_perf_analyzer.hh+ eigen3/bench/btl/generic_bench/timers/x86_timer.hh+ eigen3/bench/btl/generic_bench/utils/size_lin_log.hh+ eigen3/bench/btl/generic_bench/utils/size_log.hh+ eigen3/bench/btl/generic_bench/utils/utilities.h+ eigen3/bench/btl/generic_bench/utils/xy_file.hh+ eigen3/bench/btl/libs/BLAS/blas.h+ eigen3/bench/btl/libs/BLAS/blas_interface.hh+ eigen3/bench/btl/libs/BLAS/blas_interface_impl.hh+ eigen3/bench/btl/libs/BLAS/c_interface_base.h+ eigen3/bench/btl/libs/BLAS/CMakeLists.txt+ eigen3/bench/btl/libs/BLAS/main.cpp+ eigen3/bench/btl/libs/blitz/blitz_interface.hh+ eigen3/bench/btl/libs/blitz/blitz_LU_solve_interface.hh+ eigen3/bench/btl/libs/blitz/btl_blitz.cpp+ eigen3/bench/btl/libs/blitz/btl_tiny_blitz.cpp+ eigen3/bench/btl/libs/blitz/CMakeLists.txt+ eigen3/bench/btl/libs/blitz/tiny_blitz_interface.hh+ eigen3/bench/btl/libs/eigen2/btl_tiny_eigen2.cpp+ eigen3/bench/btl/libs/eigen2/CMakeLists.txt+ eigen3/bench/btl/libs/eigen2/eigen2_interface.hh+ eigen3/bench/btl/libs/eigen2/main_adv.cpp+ eigen3/bench/btl/libs/eigen2/main_linear.cpp+ eigen3/bench/btl/libs/eigen2/main_matmat.cpp+ eigen3/bench/btl/libs/eigen2/main_vecmat.cpp+ eigen3/bench/btl/libs/eigen3/btl_tiny_eigen3.cpp+ eigen3/bench/btl/libs/eigen3/CMakeLists.txt+ eigen3/bench/btl/libs/eigen3/eigen3_interface.hh+ eigen3/bench/btl/libs/eigen3/main_adv.cpp+ eigen3/bench/btl/libs/eigen3/main_linear.cpp+ eigen3/bench/btl/libs/eigen3/main_matmat.cpp+ eigen3/bench/btl/libs/eigen3/main_vecmat.cpp+ eigen3/bench/btl/libs/gmm/CMakeLists.txt+ eigen3/bench/btl/libs/gmm/gmm_interface.hh+ eigen3/bench/btl/libs/gmm/gmm_LU_solve_interface.hh+ eigen3/bench/btl/libs/gmm/main.cpp+ eigen3/bench/btl/libs/mtl4/.kdbgrc.main+ eigen3/bench/btl/libs/mtl4/CMakeLists.txt+ eigen3/bench/btl/libs/mtl4/main.cpp+ eigen3/bench/btl/libs/mtl4/mtl4_interface.hh+ eigen3/bench/btl/libs/mtl4/mtl4_LU_solve_interface.hh+ eigen3/bench/btl/libs/STL/CMakeLists.txt+ eigen3/bench/btl/libs/STL/main.cpp+ eigen3/bench/btl/libs/STL/STL_interface.hh+ eigen3/bench/btl/libs/tvmet/CMakeLists.txt+ eigen3/bench/btl/libs/tvmet/main.cpp+ eigen3/bench/btl/libs/tvmet/tvmet_interface.hh+ eigen3/bench/btl/libs/ublas/CMakeLists.txt+ eigen3/bench/btl/libs/ublas/main.cpp+ eigen3/bench/btl/libs/ublas/ublas_interface.hh+ eigen3/bench/btl/README+ eigen3/bench/check_cache_queries.cpp+ eigen3/bench/eig33.cpp+ eigen3/bench/geometry.cpp+ eigen3/bench/product_threshold.cpp+ eigen3/bench/quat_slerp.cpp+ eigen3/bench/quatmul.cpp+ eigen3/bench/README.txt+ eigen3/bench/sparse_cholesky.cpp+ eigen3/bench/sparse_dense_product.cpp+ eigen3/bench/sparse_lu.cpp+ eigen3/bench/sparse_product.cpp+ eigen3/bench/sparse_randomsetter.cpp+ eigen3/bench/sparse_setter.cpp+ eigen3/bench/sparse_transpose.cpp+ eigen3/bench/sparse_trisolver.cpp+ eigen3/bench/spbench/CMakeLists.txt+ eigen3/bench/spbench/sp_solver.cpp+ eigen3/bench/spbench/spbench.dtd+ eigen3/bench/spbench/spbenchsolver.cpp+ eigen3/bench/spbench/spbenchsolver.h+ eigen3/bench/spbench/spbenchstyle.h+ eigen3/bench/spbench/test_sparseLU.cpp+ eigen3/bench/spmv.cpp+ eigen3/bench/vdw_new.cpp+ eigen3/blas/BandTriangularSolver.h+ eigen3/blas/chbmv.f+ eigen3/blas/chpmv.f+ eigen3/blas/CMakeLists.txt+ eigen3/blas/common.h+ eigen3/blas/complex_double.cpp+ eigen3/blas/complex_single.cpp+ eigen3/blas/complexdots.f+ eigen3/blas/ctbmv.f+ eigen3/blas/double.cpp+ eigen3/blas/drotm.f+ eigen3/blas/drotmg.f+ eigen3/blas/dsbmv.f+ eigen3/blas/dspmv.f+ eigen3/blas/dtbmv.f+ eigen3/blas/GeneralRank1Update.h+ eigen3/blas/level1_cplx_impl.h+ eigen3/blas/level1_impl.h+ eigen3/blas/level1_real_impl.h+ eigen3/blas/level2_cplx_impl.h+ eigen3/blas/level2_impl.h+ eigen3/blas/level2_real_impl.h+ eigen3/blas/level3_impl.h+ eigen3/blas/lsame.f+ eigen3/blas/PackedSelfadjointProduct.h+ eigen3/blas/PackedTriangularMatrixVector.h+ eigen3/blas/PackedTriangularSolverVector.h+ eigen3/blas/Rank2Update.h+ eigen3/blas/README.txt+ eigen3/blas/single.cpp+ eigen3/blas/srotm.f+ eigen3/blas/srotmg.f+ eigen3/blas/ssbmv.f+ eigen3/blas/sspmv.f+ eigen3/blas/stbmv.f+ eigen3/blas/testing/cblat1.f+ eigen3/blas/testing/cblat2.dat+ eigen3/blas/testing/cblat2.f+ eigen3/blas/testing/cblat3.dat+ eigen3/blas/testing/cblat3.f+ eigen3/blas/testing/CMakeLists.txt+ eigen3/blas/testing/dblat1.f+ eigen3/blas/testing/dblat2.dat+ eigen3/blas/testing/dblat2.f+ eigen3/blas/testing/dblat3.dat+ eigen3/blas/testing/dblat3.f+ eigen3/blas/testing/runblastest.sh+ eigen3/blas/testing/sblat1.f+ eigen3/blas/testing/sblat2.dat+ eigen3/blas/testing/sblat2.f+ eigen3/blas/testing/sblat3.dat+ eigen3/blas/testing/sblat3.f+ eigen3/blas/testing/zblat1.f+ eigen3/blas/testing/zblat2.dat+ eigen3/blas/testing/zblat2.f+ eigen3/blas/testing/zblat3.dat+ eigen3/blas/testing/zblat3.f+ eigen3/blas/xerbla.cpp+ eigen3/blas/zhbmv.f+ eigen3/blas/zhpmv.f+ eigen3/blas/ztbmv.f+ eigen3/cmake/EigenConfigureTesting.cmake+ eigen3/cmake/EigenDetermineOSVersion.cmake+ eigen3/cmake/EigenDetermineVSServicePack.cmake+ eigen3/cmake/EigenTesting.cmake+ eigen3/cmake/FindAdolc.cmake+ eigen3/cmake/FindBLAS.cmake+ eigen3/cmake/FindCholmod.cmake+ eigen3/cmake/FindEigen2.cmake+ eigen3/cmake/FindEigen3.cmake+ eigen3/cmake/FindFFTW.cmake+ eigen3/cmake/FindGLEW.cmake+ eigen3/cmake/FindGMP.cmake+ eigen3/cmake/FindGoogleHash.cmake+ eigen3/cmake/FindGSL.cmake+ eigen3/cmake/FindLAPACK.cmake+ eigen3/cmake/FindMetis.cmake+ eigen3/cmake/FindMPFR.cmake+ eigen3/cmake/FindPastix.cmake+ eigen3/cmake/FindScotch.cmake+ eigen3/cmake/FindSPQR.cmake+ eigen3/cmake/FindStandardMathLibrary.cmake+ eigen3/cmake/FindSuperLU.cmake+ eigen3/cmake/FindUmfpack.cmake+ eigen3/cmake/language_support.cmake+ eigen3/cmake/RegexUtils.cmake+ eigen3/CMakeLists.txt+ eigen3/COPYING.BSD+ eigen3/COPYING.GPL+ eigen3/COPYING.LGPL+ eigen3/COPYING.MINPACK+ eigen3/COPYING.MPL2+ eigen3/COPYING.README+ eigen3/CTestConfig.cmake+ eigen3/CTestCustom.cmake.in+ eigen3/debug/gdb/__init__.py+ eigen3/debug/gdb/printers.py+ eigen3/debug/msvc/eigen.natvis+ eigen3/debug/msvc/eigen_autoexp_part.dat+ eigen3/demos/CMakeLists.txt+ eigen3/demos/mandelbrot/CMakeLists.txt+ eigen3/demos/mandelbrot/mandelbrot.cpp+ eigen3/demos/mandelbrot/mandelbrot.h+ eigen3/demos/mandelbrot/README+ eigen3/demos/mix_eigen_and_c/binary_library.cpp+ eigen3/demos/mix_eigen_and_c/binary_library.h+ eigen3/demos/mix_eigen_and_c/example.c+ eigen3/demos/mix_eigen_and_c/README+ eigen3/demos/opengl/camera.cpp+ eigen3/demos/opengl/camera.h+ eigen3/demos/opengl/CMakeLists.txt+ eigen3/demos/opengl/gpuhelper.cpp+ eigen3/demos/opengl/gpuhelper.h+ eigen3/demos/opengl/icosphere.cpp+ eigen3/demos/opengl/icosphere.h+ eigen3/demos/opengl/quaternion_demo.cpp+ eigen3/demos/opengl/quaternion_demo.h+ eigen3/demos/opengl/README+ eigen3/demos/opengl/trackball.cpp+ eigen3/demos/opengl/trackball.h+ eigen3/doc/A05_PortingFrom2To3.dox+ eigen3/doc/A10_Eigen2SupportModes.dox+ eigen3/doc/AsciiQuickReference.txt+ eigen3/doc/B01_Experimental.dox+ eigen3/doc/ClassHierarchy.dox+ eigen3/doc/CMakeLists.txt+ eigen3/doc/CustomizingEigen.dox+ eigen3/doc/Doxyfile.in+ eigen3/doc/eigen_navtree_hacks.js+ eigen3/doc/Eigen_Silly_Professor_64x64.png+ eigen3/doc/eigendoxy.css+ eigen3/doc/eigendoxy_footer.html.in+ eigen3/doc/eigendoxy_header.html.in+ eigen3/doc/eigendoxy_layout.xml.in+ eigen3/doc/eigendoxy_tabs.css+ eigen3/doc/examples/.krazy+ eigen3/doc/examples/class_Block.cpp+ eigen3/doc/examples/class_CwiseBinaryOp.cpp+ eigen3/doc/examples/class_CwiseUnaryOp.cpp+ eigen3/doc/examples/class_CwiseUnaryOp_ptrfun.cpp+ eigen3/doc/examples/class_FixedBlock.cpp+ eigen3/doc/examples/class_FixedVectorBlock.cpp+ eigen3/doc/examples/class_VectorBlock.cpp+ eigen3/doc/examples/CMakeLists.txt+ eigen3/doc/examples/DenseBase_middleCols_int.cpp+ eigen3/doc/examples/DenseBase_middleRows_int.cpp+ eigen3/doc/examples/DenseBase_template_int_middleCols.cpp+ eigen3/doc/examples/DenseBase_template_int_middleRows.cpp+ eigen3/doc/examples/function_taking_eigenbase.cpp+ eigen3/doc/examples/function_taking_ref.cpp+ eigen3/doc/examples/MatrixBase_cwise_const.cpp+ eigen3/doc/examples/QuickStart_example.cpp+ eigen3/doc/examples/QuickStart_example2_dynamic.cpp+ eigen3/doc/examples/QuickStart_example2_fixed.cpp+ eigen3/doc/examples/TemplateKeyword_flexible.cpp+ eigen3/doc/examples/TemplateKeyword_simple.cpp+ eigen3/doc/examples/tut_arithmetic_add_sub.cpp+ eigen3/doc/examples/tut_arithmetic_dot_cross.cpp+ eigen3/doc/examples/tut_arithmetic_matrix_mul.cpp+ eigen3/doc/examples/tut_arithmetic_redux_basic.cpp+ eigen3/doc/examples/tut_arithmetic_scalar_mul_div.cpp+ eigen3/doc/examples/tut_matrix_coefficient_accessors.cpp+ eigen3/doc/examples/tut_matrix_resize.cpp+ eigen3/doc/examples/tut_matrix_resize_fixed_size.cpp+ eigen3/doc/examples/Tutorial_ArrayClass_accessors.cpp+ eigen3/doc/examples/Tutorial_ArrayClass_addition.cpp+ eigen3/doc/examples/Tutorial_ArrayClass_cwise_other.cpp+ eigen3/doc/examples/Tutorial_ArrayClass_interop.cpp+ eigen3/doc/examples/Tutorial_ArrayClass_interop_matrix.cpp+ eigen3/doc/examples/Tutorial_ArrayClass_mult.cpp+ eigen3/doc/examples/Tutorial_BlockOperations_block_assignment.cpp+ eigen3/doc/examples/Tutorial_BlockOperations_colrow.cpp+ eigen3/doc/examples/Tutorial_BlockOperations_corner.cpp+ eigen3/doc/examples/Tutorial_BlockOperations_print_block.cpp+ eigen3/doc/examples/Tutorial_BlockOperations_vector.cpp+ eigen3/doc/examples/Tutorial_PartialLU_solve.cpp+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_broadcast_1nn.cpp+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple.cpp+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple_rowwise.cpp+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_colwise.cpp+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_maxnorm.cpp+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_reductions_bool.cpp+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_reductions_norm.cpp+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_rowwise.cpp+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_visitors.cpp+ eigen3/doc/examples/Tutorial_simple_example_dynamic_size.cpp+ eigen3/doc/examples/Tutorial_simple_example_fixed_size.cpp+ eigen3/doc/examples/TutorialLinAlgComputeTwice.cpp+ eigen3/doc/examples/TutorialLinAlgExComputeSolveError.cpp+ eigen3/doc/examples/TutorialLinAlgExSolveColPivHouseholderQR.cpp+ eigen3/doc/examples/TutorialLinAlgExSolveLDLT.cpp+ eigen3/doc/examples/TutorialLinAlgInverseDeterminant.cpp+ eigen3/doc/examples/TutorialLinAlgRankRevealing.cpp+ eigen3/doc/examples/TutorialLinAlgSelfAdjointEigenSolver.cpp+ eigen3/doc/examples/TutorialLinAlgSetThreshold.cpp+ eigen3/doc/examples/TutorialLinAlgSVDSolve.cpp+ eigen3/doc/FixedSizeVectorizable.dox+ eigen3/doc/FunctionsTakingEigenTypes.dox+ eigen3/doc/HiPerformance.dox+ eigen3/doc/InsideEigenExample.dox+ eigen3/doc/Manual.dox+ eigen3/doc/Overview.dox+ eigen3/doc/PassingByValue.dox+ eigen3/doc/PreprocessorDirectives.dox+ eigen3/doc/QuickReference.dox+ eigen3/doc/QuickStartGuide.dox+ eigen3/doc/snippets/.krazy+ eigen3/doc/snippets/AngleAxis_mimic_euler.cpp+ eigen3/doc/snippets/class_FullPivLU.cpp+ eigen3/doc/snippets/CMakeLists.txt+ eigen3/doc/snippets/ColPivHouseholderQR_solve.cpp+ eigen3/doc/snippets/compile_snippet.cpp.in+ eigen3/doc/snippets/ComplexEigenSolver_compute.cpp+ eigen3/doc/snippets/ComplexEigenSolver_eigenvalues.cpp+ eigen3/doc/snippets/ComplexEigenSolver_eigenvectors.cpp+ eigen3/doc/snippets/ComplexSchur_compute.cpp+ eigen3/doc/snippets/ComplexSchur_matrixT.cpp+ eigen3/doc/snippets/ComplexSchur_matrixU.cpp+ eigen3/doc/snippets/Cwise_abs.cpp+ eigen3/doc/snippets/Cwise_abs2.cpp+ eigen3/doc/snippets/Cwise_acos.cpp+ eigen3/doc/snippets/Cwise_asin.cpp+ eigen3/doc/snippets/Cwise_boolean_and.cpp+ eigen3/doc/snippets/Cwise_boolean_or.cpp+ eigen3/doc/snippets/Cwise_cos.cpp+ eigen3/doc/snippets/Cwise_cube.cpp+ eigen3/doc/snippets/Cwise_equal_equal.cpp+ eigen3/doc/snippets/Cwise_exp.cpp+ eigen3/doc/snippets/Cwise_greater.cpp+ eigen3/doc/snippets/Cwise_greater_equal.cpp+ eigen3/doc/snippets/Cwise_inverse.cpp+ eigen3/doc/snippets/Cwise_less.cpp+ eigen3/doc/snippets/Cwise_less_equal.cpp+ eigen3/doc/snippets/Cwise_log.cpp+ eigen3/doc/snippets/Cwise_max.cpp+ eigen3/doc/snippets/Cwise_min.cpp+ eigen3/doc/snippets/Cwise_minus.cpp+ eigen3/doc/snippets/Cwise_minus_equal.cpp+ eigen3/doc/snippets/Cwise_not_equal.cpp+ eigen3/doc/snippets/Cwise_plus.cpp+ eigen3/doc/snippets/Cwise_plus_equal.cpp+ eigen3/doc/snippets/Cwise_pow.cpp+ eigen3/doc/snippets/Cwise_product.cpp+ eigen3/doc/snippets/Cwise_quotient.cpp+ eigen3/doc/snippets/Cwise_sin.cpp+ eigen3/doc/snippets/Cwise_slash_equal.cpp+ eigen3/doc/snippets/Cwise_sqrt.cpp+ eigen3/doc/snippets/Cwise_square.cpp+ eigen3/doc/snippets/Cwise_tan.cpp+ eigen3/doc/snippets/Cwise_times_equal.cpp+ eigen3/doc/snippets/DenseBase_LinSpaced.cpp+ eigen3/doc/snippets/DenseBase_LinSpaced_seq.cpp+ eigen3/doc/snippets/DenseBase_setLinSpaced.cpp+ eigen3/doc/snippets/DirectionWise_replicate.cpp+ eigen3/doc/snippets/DirectionWise_replicate_int.cpp+ eigen3/doc/snippets/EigenSolver_compute.cpp+ eigen3/doc/snippets/EigenSolver_EigenSolver_MatrixType.cpp+ eigen3/doc/snippets/EigenSolver_eigenvalues.cpp+ eigen3/doc/snippets/EigenSolver_eigenvectors.cpp+ eigen3/doc/snippets/EigenSolver_pseudoEigenvectors.cpp+ eigen3/doc/snippets/FullPivHouseholderQR_solve.cpp+ eigen3/doc/snippets/FullPivLU_image.cpp+ eigen3/doc/snippets/FullPivLU_kernel.cpp+ eigen3/doc/snippets/FullPivLU_solve.cpp+ eigen3/doc/snippets/GeneralizedEigenSolver.cpp+ eigen3/doc/snippets/HessenbergDecomposition_compute.cpp+ eigen3/doc/snippets/HessenbergDecomposition_matrixH.cpp+ eigen3/doc/snippets/HessenbergDecomposition_packedMatrix.cpp+ eigen3/doc/snippets/HouseholderQR_householderQ.cpp+ eigen3/doc/snippets/HouseholderQR_solve.cpp+ eigen3/doc/snippets/HouseholderSequence_HouseholderSequence.cpp+ eigen3/doc/snippets/IOFormat.cpp+ eigen3/doc/snippets/Jacobi_makeGivens.cpp+ eigen3/doc/snippets/Jacobi_makeJacobi.cpp+ eigen3/doc/snippets/JacobiSVD_basic.cpp+ eigen3/doc/snippets/LLT_example.cpp+ eigen3/doc/snippets/LLT_solve.cpp+ eigen3/doc/snippets/Map_general_stride.cpp+ eigen3/doc/snippets/Map_inner_stride.cpp+ eigen3/doc/snippets/Map_outer_stride.cpp+ eigen3/doc/snippets/Map_placement_new.cpp+ eigen3/doc/snippets/Map_simple.cpp+ eigen3/doc/snippets/Matrix_resize_int.cpp+ eigen3/doc/snippets/Matrix_resize_int_int.cpp+ eigen3/doc/snippets/Matrix_resize_int_NoChange.cpp+ eigen3/doc/snippets/Matrix_resize_NoChange_int.cpp+ eigen3/doc/snippets/Matrix_setConstant_int.cpp+ eigen3/doc/snippets/Matrix_setConstant_int_int.cpp+ eigen3/doc/snippets/Matrix_setIdentity_int_int.cpp+ eigen3/doc/snippets/Matrix_setOnes_int.cpp+ eigen3/doc/snippets/Matrix_setOnes_int_int.cpp+ eigen3/doc/snippets/Matrix_setRandom_int.cpp+ eigen3/doc/snippets/Matrix_setRandom_int_int.cpp+ eigen3/doc/snippets/Matrix_setZero_int.cpp+ eigen3/doc/snippets/Matrix_setZero_int_int.cpp+ eigen3/doc/snippets/MatrixBase_adjoint.cpp+ eigen3/doc/snippets/MatrixBase_all.cpp+ eigen3/doc/snippets/MatrixBase_applyOnTheLeft.cpp+ eigen3/doc/snippets/MatrixBase_applyOnTheRight.cpp+ eigen3/doc/snippets/MatrixBase_array.cpp+ eigen3/doc/snippets/MatrixBase_array_const.cpp+ eigen3/doc/snippets/MatrixBase_asDiagonal.cpp+ eigen3/doc/snippets/MatrixBase_block_int_int.cpp+ eigen3/doc/snippets/MatrixBase_block_int_int_int_int.cpp+ eigen3/doc/snippets/MatrixBase_bottomLeftCorner_int_int.cpp+ eigen3/doc/snippets/MatrixBase_bottomRightCorner_int_int.cpp+ eigen3/doc/snippets/MatrixBase_bottomRows_int.cpp+ eigen3/doc/snippets/MatrixBase_cast.cpp+ eigen3/doc/snippets/MatrixBase_col.cpp+ eigen3/doc/snippets/MatrixBase_colwise.cpp+ eigen3/doc/snippets/MatrixBase_computeInverseAndDetWithCheck.cpp+ eigen3/doc/snippets/MatrixBase_computeInverseWithCheck.cpp+ eigen3/doc/snippets/MatrixBase_cwiseAbs.cpp+ eigen3/doc/snippets/MatrixBase_cwiseAbs2.cpp+ eigen3/doc/snippets/MatrixBase_cwiseEqual.cpp+ eigen3/doc/snippets/MatrixBase_cwiseInverse.cpp+ eigen3/doc/snippets/MatrixBase_cwiseMax.cpp+ eigen3/doc/snippets/MatrixBase_cwiseMin.cpp+ eigen3/doc/snippets/MatrixBase_cwiseNotEqual.cpp+ eigen3/doc/snippets/MatrixBase_cwiseProduct.cpp+ eigen3/doc/snippets/MatrixBase_cwiseQuotient.cpp+ eigen3/doc/snippets/MatrixBase_cwiseSqrt.cpp+ eigen3/doc/snippets/MatrixBase_diagonal.cpp+ eigen3/doc/snippets/MatrixBase_diagonal_int.cpp+ eigen3/doc/snippets/MatrixBase_diagonal_template_int.cpp+ eigen3/doc/snippets/MatrixBase_eigenvalues.cpp+ eigen3/doc/snippets/MatrixBase_end_int.cpp+ eigen3/doc/snippets/MatrixBase_eval.cpp+ eigen3/doc/snippets/MatrixBase_extract.cpp+ eigen3/doc/snippets/MatrixBase_fixedBlock_int_int.cpp+ eigen3/doc/snippets/MatrixBase_identity.cpp+ eigen3/doc/snippets/MatrixBase_identity_int_int.cpp+ eigen3/doc/snippets/MatrixBase_inverse.cpp+ eigen3/doc/snippets/MatrixBase_isDiagonal.cpp+ eigen3/doc/snippets/MatrixBase_isIdentity.cpp+ eigen3/doc/snippets/MatrixBase_isOnes.cpp+ eigen3/doc/snippets/MatrixBase_isOrthogonal.cpp+ eigen3/doc/snippets/MatrixBase_isUnitary.cpp+ eigen3/doc/snippets/MatrixBase_isZero.cpp+ eigen3/doc/snippets/MatrixBase_leftCols_int.cpp+ eigen3/doc/snippets/MatrixBase_marked.cpp+ eigen3/doc/snippets/MatrixBase_noalias.cpp+ eigen3/doc/snippets/MatrixBase_ones.cpp+ eigen3/doc/snippets/MatrixBase_ones_int.cpp+ eigen3/doc/snippets/MatrixBase_ones_int_int.cpp+ eigen3/doc/snippets/MatrixBase_operatorNorm.cpp+ eigen3/doc/snippets/MatrixBase_part.cpp+ eigen3/doc/snippets/MatrixBase_prod.cpp+ eigen3/doc/snippets/MatrixBase_random.cpp+ eigen3/doc/snippets/MatrixBase_random_int.cpp+ eigen3/doc/snippets/MatrixBase_random_int_int.cpp+ eigen3/doc/snippets/MatrixBase_replicate.cpp+ eigen3/doc/snippets/MatrixBase_replicate_int_int.cpp+ eigen3/doc/snippets/MatrixBase_reverse.cpp+ eigen3/doc/snippets/MatrixBase_rightCols_int.cpp+ eigen3/doc/snippets/MatrixBase_row.cpp+ eigen3/doc/snippets/MatrixBase_rowwise.cpp+ eigen3/doc/snippets/MatrixBase_segment_int_int.cpp+ eigen3/doc/snippets/MatrixBase_select.cpp+ eigen3/doc/snippets/MatrixBase_set.cpp+ eigen3/doc/snippets/MatrixBase_setIdentity.cpp+ eigen3/doc/snippets/MatrixBase_setOnes.cpp+ eigen3/doc/snippets/MatrixBase_setRandom.cpp+ eigen3/doc/snippets/MatrixBase_setZero.cpp+ eigen3/doc/snippets/MatrixBase_start_int.cpp+ eigen3/doc/snippets/MatrixBase_template_int_bottomRows.cpp+ eigen3/doc/snippets/MatrixBase_template_int_end.cpp+ eigen3/doc/snippets/MatrixBase_template_int_int_block_int_int_int_int.cpp+ eigen3/doc/snippets/MatrixBase_template_int_int_bottomLeftCorner.cpp+ eigen3/doc/snippets/MatrixBase_template_int_int_bottomLeftCorner_int_int.cpp+ eigen3/doc/snippets/MatrixBase_template_int_int_bottomRightCorner.cpp+ eigen3/doc/snippets/MatrixBase_template_int_int_bottomRightCorner_int_int.cpp+ eigen3/doc/snippets/MatrixBase_template_int_int_topLeftCorner.cpp+ eigen3/doc/snippets/MatrixBase_template_int_int_topLeftCorner_int_int.cpp+ eigen3/doc/snippets/MatrixBase_template_int_int_topRightCorner.cpp+ eigen3/doc/snippets/MatrixBase_template_int_int_topRightCorner_int_int.cpp+ eigen3/doc/snippets/MatrixBase_template_int_leftCols.cpp+ eigen3/doc/snippets/MatrixBase_template_int_rightCols.cpp+ eigen3/doc/snippets/MatrixBase_template_int_segment.cpp+ eigen3/doc/snippets/MatrixBase_template_int_start.cpp+ eigen3/doc/snippets/MatrixBase_template_int_topRows.cpp+ eigen3/doc/snippets/MatrixBase_topLeftCorner_int_int.cpp+ eigen3/doc/snippets/MatrixBase_topRightCorner_int_int.cpp+ eigen3/doc/snippets/MatrixBase_topRows_int.cpp+ eigen3/doc/snippets/MatrixBase_transpose.cpp+ eigen3/doc/snippets/MatrixBase_zero.cpp+ eigen3/doc/snippets/MatrixBase_zero_int.cpp+ eigen3/doc/snippets/MatrixBase_zero_int_int.cpp+ eigen3/doc/snippets/PartialPivLU_solve.cpp+ eigen3/doc/snippets/PartialRedux_count.cpp+ eigen3/doc/snippets/PartialRedux_maxCoeff.cpp+ eigen3/doc/snippets/PartialRedux_minCoeff.cpp+ eigen3/doc/snippets/PartialRedux_norm.cpp+ eigen3/doc/snippets/PartialRedux_prod.cpp+ eigen3/doc/snippets/PartialRedux_squaredNorm.cpp+ eigen3/doc/snippets/PartialRedux_sum.cpp+ eigen3/doc/snippets/RealQZ_compute.cpp+ eigen3/doc/snippets/RealSchur_compute.cpp+ eigen3/doc/snippets/RealSchur_RealSchur_MatrixType.cpp+ eigen3/doc/snippets/SelfAdjointEigenSolver_compute_MatrixType.cpp+ eigen3/doc/snippets/SelfAdjointEigenSolver_compute_MatrixType2.cpp+ eigen3/doc/snippets/SelfAdjointEigenSolver_eigenvalues.cpp+ eigen3/doc/snippets/SelfAdjointEigenSolver_eigenvectors.cpp+ eigen3/doc/snippets/SelfAdjointEigenSolver_operatorInverseSqrt.cpp+ eigen3/doc/snippets/SelfAdjointEigenSolver_operatorSqrt.cpp+ eigen3/doc/snippets/SelfAdjointEigenSolver_SelfAdjointEigenSolver.cpp+ eigen3/doc/snippets/SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType.cpp+ eigen3/doc/snippets/SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType2.cpp+ eigen3/doc/snippets/SelfAdjointView_eigenvalues.cpp+ eigen3/doc/snippets/SelfAdjointView_operatorNorm.cpp+ eigen3/doc/snippets/TopicAliasing_block.cpp+ eigen3/doc/snippets/TopicAliasing_block_correct.cpp+ eigen3/doc/snippets/TopicAliasing_cwise.cpp+ eigen3/doc/snippets/TopicAliasing_mult1.cpp+ eigen3/doc/snippets/TopicAliasing_mult2.cpp+ eigen3/doc/snippets/TopicAliasing_mult3.cpp+ eigen3/doc/snippets/TopicStorageOrders_example.cpp+ eigen3/doc/snippets/Tridiagonalization_compute.cpp+ eigen3/doc/snippets/Tridiagonalization_decomposeInPlace.cpp+ eigen3/doc/snippets/Tridiagonalization_diagonal.cpp+ eigen3/doc/snippets/Tridiagonalization_householderCoefficients.cpp+ eigen3/doc/snippets/Tridiagonalization_packedMatrix.cpp+ eigen3/doc/snippets/Tridiagonalization_Tridiagonalization_MatrixType.cpp+ eigen3/doc/snippets/tut_arithmetic_redux_minmax.cpp+ eigen3/doc/snippets/tut_arithmetic_transpose_aliasing.cpp+ eigen3/doc/snippets/tut_arithmetic_transpose_conjugate.cpp+ eigen3/doc/snippets/tut_arithmetic_transpose_inplace.cpp+ eigen3/doc/snippets/tut_matrix_assignment_resizing.cpp+ eigen3/doc/snippets/Tutorial_AdvancedInitialization_Block.cpp+ eigen3/doc/snippets/Tutorial_AdvancedInitialization_CommaTemporary.cpp+ eigen3/doc/snippets/Tutorial_AdvancedInitialization_Join.cpp+ eigen3/doc/snippets/Tutorial_AdvancedInitialization_LinSpaced.cpp+ eigen3/doc/snippets/Tutorial_AdvancedInitialization_ThreeWays.cpp+ eigen3/doc/snippets/Tutorial_AdvancedInitialization_Zero.cpp+ eigen3/doc/snippets/Tutorial_commainit_01.cpp+ eigen3/doc/snippets/Tutorial_commainit_01b.cpp+ eigen3/doc/snippets/Tutorial_commainit_02.cpp+ eigen3/doc/snippets/Tutorial_Map_rowmajor.cpp+ eigen3/doc/snippets/Tutorial_Map_using.cpp+ eigen3/doc/snippets/Tutorial_solve_matrix_inverse.cpp+ eigen3/doc/snippets/Tutorial_solve_multiple_rhs.cpp+ eigen3/doc/snippets/Tutorial_solve_reuse_decomposition.cpp+ eigen3/doc/snippets/Tutorial_solve_singular.cpp+ eigen3/doc/snippets/Tutorial_solve_triangular.cpp+ eigen3/doc/snippets/Tutorial_solve_triangular_inplace.cpp+ eigen3/doc/snippets/Vectorwise_reverse.cpp+ eigen3/doc/SparseLinearSystems.dox+ eigen3/doc/SparseQuickReference.dox+ eigen3/doc/special_examples/CMakeLists.txt+ eigen3/doc/special_examples/Tutorial_sparse_example.cpp+ eigen3/doc/special_examples/Tutorial_sparse_example_details.cpp+ eigen3/doc/StlContainers.dox+ eigen3/doc/StorageOrders.dox+ eigen3/doc/StructHavingEigenMembers.dox+ eigen3/doc/TemplateKeyword.dox+ eigen3/doc/TopicAliasing.dox+ eigen3/doc/TopicAssertions.dox+ eigen3/doc/TopicEigenExpressionTemplates.dox+ eigen3/doc/TopicLazyEvaluation.dox+ eigen3/doc/TopicLinearAlgebraDecompositions.dox+ eigen3/doc/TopicMultithreading.dox+ eigen3/doc/TopicResizing.dox+ eigen3/doc/TopicScalarTypes.dox+ eigen3/doc/TopicVectorization.dox+ eigen3/doc/tutorial.cpp+ eigen3/doc/TutorialAdvancedInitialization.dox+ eigen3/doc/TutorialArrayClass.dox+ eigen3/doc/TutorialBlockOperations.dox+ eigen3/doc/TutorialGeometry.dox+ eigen3/doc/TutorialLinearAlgebra.dox+ eigen3/doc/TutorialMapClass.dox+ eigen3/doc/TutorialMatrixArithmetic.dox+ eigen3/doc/TutorialMatrixClass.dox+ eigen3/doc/TutorialReductionsVisitorsBroadcasting.dox+ eigen3/doc/TutorialSparse.dox+ eigen3/doc/TutorialSparse_example_details.dox+ eigen3/doc/UnalignedArrayAssert.dox+ eigen3/doc/UsingIntelMKL.dox+ eigen3/doc/WrongStackAlignment.dox+ eigen3/Eigen/Array+ eigen3/Eigen/Cholesky+ eigen3/Eigen/CholmodSupport+ eigen3/Eigen/CMakeLists.txt+ eigen3/Eigen/Core+ eigen3/Eigen/Dense+ eigen3/Eigen/Eigen+ eigen3/Eigen/Eigen2Support+ eigen3/Eigen/Eigenvalues+ eigen3/Eigen/Geometry+ eigen3/Eigen/Householder+ eigen3/Eigen/IterativeLinearSolvers+ eigen3/Eigen/Jacobi+ eigen3/Eigen/LeastSquares+ eigen3/Eigen/LU+ eigen3/Eigen/MetisSupport+ eigen3/Eigen/OrderingMethods+ eigen3/Eigen/PardisoSupport+ eigen3/Eigen/PaStiXSupport+ eigen3/Eigen/QR+ eigen3/Eigen/QtAlignedMalloc+ eigen3/Eigen/Sparse+ eigen3/Eigen/SparseCholesky+ eigen3/Eigen/SparseCore+ eigen3/Eigen/SparseLU+ eigen3/Eigen/SparseQR+ eigen3/Eigen/SPQRSupport+ eigen3/Eigen/src/Cholesky/CMakeLists.txt+ eigen3/Eigen/src/Cholesky/LDLT.h+ eigen3/Eigen/src/Cholesky/LLT.h+ eigen3/Eigen/src/Cholesky/LLT_MKL.h+ eigen3/Eigen/src/CholmodSupport/CholmodSupport.h+ eigen3/Eigen/src/CholmodSupport/CMakeLists.txt+ eigen3/Eigen/src/CMakeLists.txt+ eigen3/Eigen/src/Core/arch/AltiVec/CMakeLists.txt+ eigen3/Eigen/src/Core/arch/AltiVec/Complex.h+ eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h+ eigen3/Eigen/src/Core/arch/CMakeLists.txt+ eigen3/Eigen/src/Core/arch/Default/CMakeLists.txt+ eigen3/Eigen/src/Core/arch/Default/Settings.h+ eigen3/Eigen/src/Core/arch/NEON/CMakeLists.txt+ eigen3/Eigen/src/Core/arch/NEON/Complex.h+ eigen3/Eigen/src/Core/arch/NEON/PacketMath.h+ eigen3/Eigen/src/Core/arch/SSE/CMakeLists.txt+ eigen3/Eigen/src/Core/arch/SSE/Complex.h+ eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h+ eigen3/Eigen/src/Core/arch/SSE/PacketMath.h+ eigen3/Eigen/src/Core/Array.h+ eigen3/Eigen/src/Core/ArrayBase.h+ eigen3/Eigen/src/Core/ArrayWrapper.h+ eigen3/Eigen/src/Core/Assign.h+ eigen3/Eigen/src/Core/Assign_MKL.h+ eigen3/Eigen/src/Core/BandMatrix.h+ eigen3/Eigen/src/Core/Block.h+ eigen3/Eigen/src/Core/BooleanRedux.h+ eigen3/Eigen/src/Core/CMakeLists.txt+ eigen3/Eigen/src/Core/CommaInitializer.h+ eigen3/Eigen/src/Core/CoreIterators.h+ eigen3/Eigen/src/Core/CwiseBinaryOp.h+ eigen3/Eigen/src/Core/CwiseNullaryOp.h+ eigen3/Eigen/src/Core/CwiseUnaryOp.h+ eigen3/Eigen/src/Core/CwiseUnaryView.h+ eigen3/Eigen/src/Core/DenseBase.h+ eigen3/Eigen/src/Core/DenseCoeffsBase.h+ eigen3/Eigen/src/Core/DenseStorage.h+ eigen3/Eigen/src/Core/Diagonal.h+ eigen3/Eigen/src/Core/DiagonalMatrix.h+ eigen3/Eigen/src/Core/DiagonalProduct.h+ eigen3/Eigen/src/Core/Dot.h+ eigen3/Eigen/src/Core/EigenBase.h+ eigen3/Eigen/src/Core/Flagged.h+ eigen3/Eigen/src/Core/ForceAlignedAccess.h+ eigen3/Eigen/src/Core/Functors.h+ eigen3/Eigen/src/Core/Fuzzy.h+ eigen3/Eigen/src/Core/GeneralProduct.h+ eigen3/Eigen/src/Core/GenericPacketMath.h+ eigen3/Eigen/src/Core/GlobalFunctions.h+ eigen3/Eigen/src/Core/IO.h+ eigen3/Eigen/src/Core/Map.h+ eigen3/Eigen/src/Core/MapBase.h+ eigen3/Eigen/src/Core/MathFunctions.h+ eigen3/Eigen/src/Core/Matrix.h+ eigen3/Eigen/src/Core/MatrixBase.h+ eigen3/Eigen/src/Core/NestByValue.h+ eigen3/Eigen/src/Core/NoAlias.h+ eigen3/Eigen/src/Core/NumTraits.h+ eigen3/Eigen/src/Core/PermutationMatrix.h+ eigen3/Eigen/src/Core/PlainObjectBase.h+ eigen3/Eigen/src/Core/ProductBase.h+ eigen3/Eigen/src/Core/products/CMakeLists.txt+ eigen3/Eigen/src/Core/products/CoeffBasedProduct.h+ eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h+ eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h+ eigen3/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h+ eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h+ eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h+ eigen3/Eigen/src/Core/products/GeneralMatrixVector.h+ eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h+ eigen3/Eigen/src/Core/products/Parallelizer.h+ eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h+ eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h+ eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h+ eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h+ eigen3/Eigen/src/Core/products/SelfadjointProduct.h+ eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h+ eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h+ eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h+ eigen3/Eigen/src/Core/products/TriangularMatrixVector.h+ eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h+ eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h+ eigen3/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h+ eigen3/Eigen/src/Core/products/TriangularSolverVector.h+ eigen3/Eigen/src/Core/Random.h+ eigen3/Eigen/src/Core/Redux.h+ eigen3/Eigen/src/Core/Ref.h+ eigen3/Eigen/src/Core/Replicate.h+ eigen3/Eigen/src/Core/ReturnByValue.h+ eigen3/Eigen/src/Core/Reverse.h+ eigen3/Eigen/src/Core/Select.h+ eigen3/Eigen/src/Core/SelfAdjointView.h+ eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h+ eigen3/Eigen/src/Core/SolveTriangular.h+ eigen3/Eigen/src/Core/StableNorm.h+ eigen3/Eigen/src/Core/Stride.h+ eigen3/Eigen/src/Core/Swap.h+ eigen3/Eigen/src/Core/Transpose.h+ eigen3/Eigen/src/Core/Transpositions.h+ eigen3/Eigen/src/Core/TriangularMatrix.h+ eigen3/Eigen/src/Core/util/BlasUtil.h+ eigen3/Eigen/src/Core/util/CMakeLists.txt+ eigen3/Eigen/src/Core/util/Constants.h+ eigen3/Eigen/src/Core/util/DisableStupidWarnings.h+ eigen3/Eigen/src/Core/util/ForwardDeclarations.h+ eigen3/Eigen/src/Core/util/Macros.h+ eigen3/Eigen/src/Core/util/Memory.h+ eigen3/Eigen/src/Core/util/Meta.h+ eigen3/Eigen/src/Core/util/MKL_support.h+ eigen3/Eigen/src/Core/util/NonMPL2.h+ eigen3/Eigen/src/Core/util/ReenableStupidWarnings.h+ eigen3/Eigen/src/Core/util/StaticAssert.h+ eigen3/Eigen/src/Core/util/XprHelper.h+ eigen3/Eigen/src/Core/VectorBlock.h+ eigen3/Eigen/src/Core/VectorwiseOp.h+ eigen3/Eigen/src/Core/Visitor.h+ eigen3/Eigen/src/Eigen2Support/Block.h+ eigen3/Eigen/src/Eigen2Support/CMakeLists.txt+ eigen3/Eigen/src/Eigen2Support/Cwise.h+ eigen3/Eigen/src/Eigen2Support/CwiseOperators.h+ eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h+ eigen3/Eigen/src/Eigen2Support/Geometry/All.h+ eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h+ eigen3/Eigen/src/Eigen2Support/Geometry/CMakeLists.txt+ eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h+ eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h+ eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h+ eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h+ eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h+ eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h+ eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h+ eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h+ eigen3/Eigen/src/Eigen2Support/Lazy.h+ eigen3/Eigen/src/Eigen2Support/LeastSquares.h+ eigen3/Eigen/src/Eigen2Support/LU.h+ eigen3/Eigen/src/Eigen2Support/Macros.h+ eigen3/Eigen/src/Eigen2Support/MathFunctions.h+ eigen3/Eigen/src/Eigen2Support/Memory.h+ eigen3/Eigen/src/Eigen2Support/Meta.h+ eigen3/Eigen/src/Eigen2Support/Minor.h+ eigen3/Eigen/src/Eigen2Support/QR.h+ eigen3/Eigen/src/Eigen2Support/SVD.h+ eigen3/Eigen/src/Eigen2Support/TriangularSolver.h+ eigen3/Eigen/src/Eigen2Support/VectorBlock.h+ eigen3/Eigen/src/Eigenvalues/CMakeLists.txt+ eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h+ eigen3/Eigen/src/Eigenvalues/ComplexSchur.h+ eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h+ eigen3/Eigen/src/Eigenvalues/EigenSolver.h+ eigen3/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h+ eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h+ eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h+ eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h+ eigen3/Eigen/src/Eigenvalues/RealQZ.h+ eigen3/Eigen/src/Eigenvalues/RealSchur.h+ eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h+ eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h+ eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h+ eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h+ eigen3/Eigen/src/Geometry/AlignedBox.h+ eigen3/Eigen/src/Geometry/AngleAxis.h+ eigen3/Eigen/src/Geometry/arch/CMakeLists.txt+ eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h+ eigen3/Eigen/src/Geometry/CMakeLists.txt+ eigen3/Eigen/src/Geometry/EulerAngles.h+ eigen3/Eigen/src/Geometry/Homogeneous.h+ eigen3/Eigen/src/Geometry/Hyperplane.h+ eigen3/Eigen/src/Geometry/OrthoMethods.h+ eigen3/Eigen/src/Geometry/ParametrizedLine.h+ eigen3/Eigen/src/Geometry/Quaternion.h+ eigen3/Eigen/src/Geometry/Rotation2D.h+ eigen3/Eigen/src/Geometry/RotationBase.h+ eigen3/Eigen/src/Geometry/Scaling.h+ eigen3/Eigen/src/Geometry/Transform.h+ eigen3/Eigen/src/Geometry/Translation.h+ eigen3/Eigen/src/Geometry/Umeyama.h+ eigen3/Eigen/src/Householder/BlockHouseholder.h+ eigen3/Eigen/src/Householder/CMakeLists.txt+ eigen3/Eigen/src/Householder/Householder.h+ eigen3/Eigen/src/Householder/HouseholderSequence.h+ eigen3/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h+ eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h+ eigen3/Eigen/src/IterativeLinearSolvers/CMakeLists.txt+ eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h+ eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h+ eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h+ eigen3/Eigen/src/Jacobi/CMakeLists.txt+ eigen3/Eigen/src/Jacobi/Jacobi.h+ eigen3/Eigen/src/LU/arch/CMakeLists.txt+ eigen3/Eigen/src/LU/arch/Inverse_SSE.h+ eigen3/Eigen/src/LU/CMakeLists.txt+ eigen3/Eigen/src/LU/Determinant.h+ eigen3/Eigen/src/LU/FullPivLU.h+ eigen3/Eigen/src/LU/Inverse.h+ eigen3/Eigen/src/LU/PartialPivLU.h+ eigen3/Eigen/src/LU/PartialPivLU_MKL.h+ eigen3/Eigen/src/MetisSupport/CMakeLists.txt+ eigen3/Eigen/src/MetisSupport/MetisSupport.h+ eigen3/Eigen/src/misc/blas.h+ eigen3/Eigen/src/misc/CMakeLists.txt+ eigen3/Eigen/src/misc/Image.h+ eigen3/Eigen/src/misc/Kernel.h+ eigen3/Eigen/src/misc/Solve.h+ eigen3/Eigen/src/misc/SparseSolve.h+ eigen3/Eigen/src/OrderingMethods/Amd.h+ eigen3/Eigen/src/OrderingMethods/CMakeLists.txt+ eigen3/Eigen/src/OrderingMethods/Eigen_Colamd.h+ eigen3/Eigen/src/OrderingMethods/Ordering.h+ eigen3/Eigen/src/PardisoSupport/CMakeLists.txt+ eigen3/Eigen/src/PardisoSupport/PardisoSupport.h+ eigen3/Eigen/src/PaStiXSupport/CMakeLists.txt+ eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h+ eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h+ eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h+ eigen3/Eigen/src/plugins/BlockMethods.h+ eigen3/Eigen/src/plugins/CMakeLists.txt+ eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h+ eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h+ eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h+ eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h+ eigen3/Eigen/src/QR/CMakeLists.txt+ eigen3/Eigen/src/QR/ColPivHouseholderQR.h+ eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h+ eigen3/Eigen/src/QR/FullPivHouseholderQR.h+ eigen3/Eigen/src/QR/HouseholderQR.h+ eigen3/Eigen/src/QR/HouseholderQR_MKL.h+ eigen3/Eigen/src/SparseCholesky/CMakeLists.txt+ eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h+ eigen3/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h+ eigen3/Eigen/src/SparseCore/AmbiVector.h+ eigen3/Eigen/src/SparseCore/CMakeLists.txt+ eigen3/Eigen/src/SparseCore/CompressedStorage.h+ eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h+ eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h+ eigen3/Eigen/src/SparseCore/SparseBlock.h+ eigen3/Eigen/src/SparseCore/SparseColEtree.h+ eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h+ eigen3/Eigen/src/SparseCore/SparseCwiseUnaryOp.h+ eigen3/Eigen/src/SparseCore/SparseDenseProduct.h+ eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h+ eigen3/Eigen/src/SparseCore/SparseDot.h+ eigen3/Eigen/src/SparseCore/SparseFuzzy.h+ eigen3/Eigen/src/SparseCore/SparseMatrix.h+ eigen3/Eigen/src/SparseCore/SparseMatrixBase.h+ eigen3/Eigen/src/SparseCore/SparsePermutation.h+ eigen3/Eigen/src/SparseCore/SparseProduct.h+ eigen3/Eigen/src/SparseCore/SparseRedux.h+ eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h+ eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h+ eigen3/Eigen/src/SparseCore/SparseTranspose.h+ eigen3/Eigen/src/SparseCore/SparseTriangularView.h+ eigen3/Eigen/src/SparseCore/SparseUtil.h+ eigen3/Eigen/src/SparseCore/SparseVector.h+ eigen3/Eigen/src/SparseCore/SparseView.h+ eigen3/Eigen/src/SparseCore/TriangularSolver.h+ eigen3/Eigen/src/SparseLU/CMakeLists.txt+ eigen3/Eigen/src/SparseLU/SparseLU.h+ eigen3/Eigen/src/SparseLU/SparseLU_column_bmod.h+ eigen3/Eigen/src/SparseLU/SparseLU_column_dfs.h+ eigen3/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h+ eigen3/Eigen/src/SparseLU/SparseLU_gemm_kernel.h+ eigen3/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h+ eigen3/Eigen/src/SparseLU/SparseLU_kernel_bmod.h+ eigen3/Eigen/src/SparseLU/SparseLU_Memory.h+ eigen3/Eigen/src/SparseLU/SparseLU_panel_bmod.h+ eigen3/Eigen/src/SparseLU/SparseLU_panel_dfs.h+ eigen3/Eigen/src/SparseLU/SparseLU_pivotL.h+ eigen3/Eigen/src/SparseLU/SparseLU_pruneL.h+ eigen3/Eigen/src/SparseLU/SparseLU_relax_snode.h+ eigen3/Eigen/src/SparseLU/SparseLU_Structs.h+ eigen3/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h+ eigen3/Eigen/src/SparseLU/SparseLU_Utils.h+ eigen3/Eigen/src/SparseLU/SparseLUImpl.h+ eigen3/Eigen/src/SparseQR/CMakeLists.txt+ eigen3/Eigen/src/SparseQR/SparseQR.h+ eigen3/Eigen/src/SPQRSupport/CMakeLists.txt+ eigen3/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h+ eigen3/Eigen/src/StlSupport/CMakeLists.txt+ eigen3/Eigen/src/StlSupport/details.h+ eigen3/Eigen/src/StlSupport/StdDeque.h+ eigen3/Eigen/src/StlSupport/StdList.h+ eigen3/Eigen/src/StlSupport/StdVector.h+ eigen3/Eigen/src/SuperLUSupport/CMakeLists.txt+ eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h+ eigen3/Eigen/src/SVD/CMakeLists.txt+ eigen3/Eigen/src/SVD/JacobiSVD.h+ eigen3/Eigen/src/SVD/JacobiSVD_MKL.h+ eigen3/Eigen/src/SVD/UpperBidiagonalization.h+ eigen3/Eigen/src/UmfPackSupport/CMakeLists.txt+ eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h+ eigen3/Eigen/StdDeque+ eigen3/Eigen/StdList+ eigen3/Eigen/StdVector+ eigen3/Eigen/SuperLUSupport+ eigen3/Eigen/SVD+ eigen3/Eigen/UmfPackSupport+ eigen3/eigen3.pc.in+ eigen3/failtest/block_nonconst_ctor_on_const_xpr_0.cpp+ eigen3/failtest/block_nonconst_ctor_on_const_xpr_1.cpp+ eigen3/failtest/block_nonconst_ctor_on_const_xpr_2.cpp+ eigen3/failtest/block_on_const_type_actually_const_0.cpp+ eigen3/failtest/block_on_const_type_actually_const_1.cpp+ eigen3/failtest/CMakeLists.txt+ eigen3/failtest/colpivqr_int.cpp+ eigen3/failtest/const_qualified_block_method_retval_0.cpp+ eigen3/failtest/const_qualified_block_method_retval_1.cpp+ eigen3/failtest/const_qualified_diagonal_method_retval.cpp+ eigen3/failtest/const_qualified_transpose_method_retval.cpp+ eigen3/failtest/diagonal_nonconst_ctor_on_const_xpr.cpp+ eigen3/failtest/diagonal_on_const_type_actually_const.cpp+ eigen3/failtest/eigensolver_cplx.cpp+ eigen3/failtest/eigensolver_int.cpp+ eigen3/failtest/failtest_sanity_check.cpp+ eigen3/failtest/fullpivlu_int.cpp+ eigen3/failtest/fullpivqr_int.cpp+ eigen3/failtest/jacobisvd_int.cpp+ eigen3/failtest/ldlt_int.cpp+ eigen3/failtest/llt_int.cpp+ eigen3/failtest/map_nonconst_ctor_on_const_ptr_0.cpp+ eigen3/failtest/map_nonconst_ctor_on_const_ptr_1.cpp+ eigen3/failtest/map_nonconst_ctor_on_const_ptr_2.cpp+ eigen3/failtest/map_nonconst_ctor_on_const_ptr_3.cpp+ eigen3/failtest/map_nonconst_ctor_on_const_ptr_4.cpp+ eigen3/failtest/map_on_const_type_actually_const_0.cpp+ eigen3/failtest/map_on_const_type_actually_const_1.cpp+ eigen3/failtest/partialpivlu_int.cpp+ eigen3/failtest/qr_int.cpp+ eigen3/failtest/ref_1.cpp+ eigen3/failtest/ref_2.cpp+ eigen3/failtest/ref_3.cpp+ eigen3/failtest/ref_4.cpp+ eigen3/failtest/ref_5.cpp+ eigen3/failtest/transpose_nonconst_ctor_on_const_xpr.cpp+ eigen3/failtest/transpose_on_const_type_actually_const.cpp+ eigen3/INSTALL+ eigen3/lapack/cholesky.cpp+ eigen3/lapack/clacgv.f+ eigen3/lapack/cladiv.f+ eigen3/lapack/clarf.f+ eigen3/lapack/clarfb.f+ eigen3/lapack/clarfg.f+ eigen3/lapack/clarft.f+ eigen3/lapack/CMakeLists.txt+ eigen3/lapack/complex_double.cpp+ eigen3/lapack/complex_single.cpp+ eigen3/lapack/dladiv.f+ eigen3/lapack/dlamch.f+ eigen3/lapack/dlapy2.f+ eigen3/lapack/dlapy3.f+ eigen3/lapack/dlarf.f+ eigen3/lapack/dlarfb.f+ eigen3/lapack/dlarfg.f+ eigen3/lapack/dlarft.f+ eigen3/lapack/double.cpp+ eigen3/lapack/dsecnd_NONE.f+ eigen3/lapack/eigenvalues.cpp+ eigen3/lapack/ilaclc.f+ eigen3/lapack/ilaclr.f+ eigen3/lapack/iladlc.f+ eigen3/lapack/iladlr.f+ eigen3/lapack/ilaslc.f+ eigen3/lapack/ilaslr.f+ eigen3/lapack/ilazlc.f+ eigen3/lapack/ilazlr.f+ eigen3/lapack/lapack_common.h+ eigen3/lapack/lu.cpp+ eigen3/lapack/second_NONE.f+ eigen3/lapack/single.cpp+ eigen3/lapack/sladiv.f+ eigen3/lapack/slamch.f+ eigen3/lapack/slapy2.f+ eigen3/lapack/slapy3.f+ eigen3/lapack/slarf.f+ eigen3/lapack/slarfb.f+ eigen3/lapack/slarfg.f+ eigen3/lapack/slarft.f+ eigen3/lapack/zlacgv.f+ eigen3/lapack/zladiv.f+ eigen3/lapack/zlarf.f+ eigen3/lapack/zlarfb.f+ eigen3/lapack/zlarfg.f+ eigen3/lapack/zlarft.f+ eigen3/scripts/buildtests.in+ eigen3/scripts/cdashtesting.cmake.in+ eigen3/scripts/check.in+ eigen3/scripts/CMakeLists.txt+ eigen3/scripts/debug.in+ eigen3/scripts/eigen_gen_credits.cpp+ eigen3/scripts/eigen_gen_docs+ eigen3/scripts/release.in+ eigen3/scripts/relicense.py+ eigen3/signature_of_eigen3_matrix_library+ eigen3/test/adjoint.cpp+ eigen3/test/array.cpp+ eigen3/test/array_for_matrix.cpp+ eigen3/test/array_replicate.cpp+ eigen3/test/array_reverse.cpp+ eigen3/test/bandmatrix.cpp+ eigen3/test/basicstuff.cpp+ eigen3/test/bicgstab.cpp+ eigen3/test/block.cpp+ eigen3/test/cholesky.cpp+ eigen3/test/cholmod_support.cpp+ eigen3/test/CMakeLists.txt+ eigen3/test/commainitializer.cpp+ eigen3/test/conjugate_gradient.cpp+ eigen3/test/conservative_resize.cpp+ eigen3/test/corners.cpp+ eigen3/test/cwiseop.cpp+ eigen3/test/denseLM.cpp+ eigen3/test/determinant.cpp+ eigen3/test/diagonal.cpp+ eigen3/test/diagonalmatrices.cpp+ eigen3/test/dontalign.cpp+ eigen3/test/dynalloc.cpp+ eigen3/test/eigen2/CMakeLists.txt+ eigen3/test/eigen2/eigen2_adjoint.cpp+ eigen3/test/eigen2/eigen2_alignedbox.cpp+ eigen3/test/eigen2/eigen2_array.cpp+ eigen3/test/eigen2/eigen2_basicstuff.cpp+ eigen3/test/eigen2/eigen2_bug_132.cpp+ eigen3/test/eigen2/eigen2_cholesky.cpp+ eigen3/test/eigen2/eigen2_commainitializer.cpp+ eigen3/test/eigen2/eigen2_cwiseop.cpp+ eigen3/test/eigen2/eigen2_determinant.cpp+ eigen3/test/eigen2/eigen2_dynalloc.cpp+ eigen3/test/eigen2/eigen2_eigensolver.cpp+ eigen3/test/eigen2/eigen2_first_aligned.cpp+ eigen3/test/eigen2/eigen2_geometry.cpp+ eigen3/test/eigen2/eigen2_geometry_with_eigen2_prefix.cpp+ eigen3/test/eigen2/eigen2_hyperplane.cpp+ eigen3/test/eigen2/eigen2_inverse.cpp+ eigen3/test/eigen2/eigen2_linearstructure.cpp+ eigen3/test/eigen2/eigen2_lu.cpp+ eigen3/test/eigen2/eigen2_map.cpp+ eigen3/test/eigen2/eigen2_meta.cpp+ eigen3/test/eigen2/eigen2_miscmatrices.cpp+ eigen3/test/eigen2/eigen2_mixingtypes.cpp+ eigen3/test/eigen2/eigen2_newstdvector.cpp+ eigen3/test/eigen2/eigen2_nomalloc.cpp+ eigen3/test/eigen2/eigen2_packetmath.cpp+ eigen3/test/eigen2/eigen2_parametrizedline.cpp+ eigen3/test/eigen2/eigen2_prec_inverse_4x4.cpp+ eigen3/test/eigen2/eigen2_product_large.cpp+ eigen3/test/eigen2/eigen2_product_small.cpp+ eigen3/test/eigen2/eigen2_qr.cpp+ eigen3/test/eigen2/eigen2_qtvector.cpp+ eigen3/test/eigen2/eigen2_regression.cpp+ eigen3/test/eigen2/eigen2_sizeof.cpp+ eigen3/test/eigen2/eigen2_smallvectors.cpp+ eigen3/test/eigen2/eigen2_sparse_basic.cpp+ eigen3/test/eigen2/eigen2_sparse_product.cpp+ eigen3/test/eigen2/eigen2_sparse_solvers.cpp+ eigen3/test/eigen2/eigen2_sparse_vector.cpp+ eigen3/test/eigen2/eigen2_stdvector.cpp+ eigen3/test/eigen2/eigen2_submatrices.cpp+ eigen3/test/eigen2/eigen2_sum.cpp+ eigen3/test/eigen2/eigen2_svd.cpp+ eigen3/test/eigen2/eigen2_swap.cpp+ eigen3/test/eigen2/eigen2_triangular.cpp+ eigen3/test/eigen2/eigen2_unalignedassert.cpp+ eigen3/test/eigen2/eigen2_visitor.cpp+ eigen3/test/eigen2/gsl_helper.h+ eigen3/test/eigen2/main.h+ eigen3/test/eigen2/product.h+ eigen3/test/eigen2/runtest.sh+ eigen3/test/eigen2/sparse.h+ eigen3/test/eigen2/testsuite.cmake+ eigen3/test/eigen2support.cpp+ eigen3/test/eigensolver_complex.cpp+ eigen3/test/eigensolver_generalized_real.cpp+ eigen3/test/eigensolver_generic.cpp+ eigen3/test/eigensolver_selfadjoint.cpp+ eigen3/test/exceptions.cpp+ eigen3/test/first_aligned.cpp+ eigen3/test/geo_alignedbox.cpp+ eigen3/test/geo_eulerangles.cpp+ eigen3/test/geo_homogeneous.cpp+ eigen3/test/geo_hyperplane.cpp+ eigen3/test/geo_orthomethods.cpp+ eigen3/test/geo_parametrizedline.cpp+ eigen3/test/geo_quaternion.cpp+ eigen3/test/geo_transformations.cpp+ eigen3/test/hessenberg.cpp+ eigen3/test/householder.cpp+ eigen3/test/integer_types.cpp+ eigen3/test/inverse.cpp+ eigen3/test/jacobi.cpp+ eigen3/test/jacobisvd.cpp+ eigen3/test/linearstructure.cpp+ eigen3/test/lu.cpp+ eigen3/test/main.h+ eigen3/test/mapped_matrix.cpp+ eigen3/test/mapstaticmethods.cpp+ eigen3/test/mapstride.cpp+ eigen3/test/meta.cpp+ eigen3/test/metis_support.cpp+ eigen3/test/miscmatrices.cpp+ eigen3/test/mixingtypes.cpp+ eigen3/test/nesting_ops.cpp+ eigen3/test/nomalloc.cpp+ eigen3/test/nullary.cpp+ eigen3/test/packetmath.cpp+ eigen3/test/pardiso_support.cpp+ eigen3/test/pastix_support.cpp+ eigen3/test/permutationmatrices.cpp+ eigen3/test/prec_inverse_4x4.cpp+ eigen3/test/product.h+ eigen3/test/product_extra.cpp+ eigen3/test/product_large.cpp+ eigen3/test/product_mmtr.cpp+ eigen3/test/product_notemporary.cpp+ eigen3/test/product_selfadjoint.cpp+ eigen3/test/product_small.cpp+ eigen3/test/product_symm.cpp+ eigen3/test/product_syrk.cpp+ eigen3/test/product_trmm.cpp+ eigen3/test/product_trmv.cpp+ eigen3/test/product_trsolve.cpp+ eigen3/test/qr.cpp+ eigen3/test/qr_colpivoting.cpp+ eigen3/test/qr_fullpivoting.cpp+ eigen3/test/qtvector.cpp+ eigen3/test/real_qz.cpp+ eigen3/test/redux.cpp+ eigen3/test/ref.cpp+ eigen3/test/resize.cpp+ eigen3/test/runtest.sh+ eigen3/test/schur_complex.cpp+ eigen3/test/schur_real.cpp+ eigen3/test/selfadjoint.cpp+ eigen3/test/simplicial_cholesky.cpp+ eigen3/test/sizeof.cpp+ eigen3/test/sizeoverflow.cpp+ eigen3/test/smallvectors.cpp+ eigen3/test/sparse.h+ eigen3/test/sparse_basic.cpp+ eigen3/test/sparse_permutations.cpp+ eigen3/test/sparse_product.cpp+ eigen3/test/sparse_solver.h+ eigen3/test/sparse_solvers.cpp+ eigen3/test/sparse_vector.cpp+ eigen3/test/sparseLM.cpp+ eigen3/test/sparselu.cpp+ eigen3/test/sparseqr.cpp+ eigen3/test/special_numbers.cpp+ eigen3/test/spqr_support.cpp+ eigen3/test/stable_norm.cpp+ eigen3/test/stddeque.cpp+ eigen3/test/stdlist.cpp+ eigen3/test/stdvector.cpp+ eigen3/test/stdvector_overload.cpp+ eigen3/test/superlu_support.cpp+ eigen3/test/swap.cpp+ eigen3/test/testsuite.cmake+ eigen3/test/triangular.cpp+ eigen3/test/umeyama.cpp+ eigen3/test/umfpack_support.cpp+ eigen3/test/unalignedassert.cpp+ eigen3/test/unalignedcount.cpp+ eigen3/test/upperbidiagonalization.cpp+ eigen3/test/vectorization_logic.cpp+ eigen3/test/vectorwiseop.cpp+ eigen3/test/visitor.cpp+ eigen3/test/zerosized.cpp+ eigen3/unsupported/bench/bench_svd.cpp+ eigen3/unsupported/CMakeLists.txt+ eigen3/unsupported/doc/CMakeLists.txt+ eigen3/unsupported/doc/eigendoxy_layout.xml.in+ eigen3/unsupported/doc/examples/BVH_Example.cpp+ eigen3/unsupported/doc/examples/CMakeLists.txt+ eigen3/unsupported/doc/examples/FFT.cpp+ eigen3/unsupported/doc/examples/MatrixExponential.cpp+ eigen3/unsupported/doc/examples/MatrixFunction.cpp+ eigen3/unsupported/doc/examples/MatrixLogarithm.cpp+ eigen3/unsupported/doc/examples/MatrixPower.cpp+ eigen3/unsupported/doc/examples/MatrixPower_optimal.cpp+ eigen3/unsupported/doc/examples/MatrixSine.cpp+ eigen3/unsupported/doc/examples/MatrixSinh.cpp+ eigen3/unsupported/doc/examples/MatrixSquareRoot.cpp+ eigen3/unsupported/doc/examples/PolynomialSolver1.cpp+ eigen3/unsupported/doc/examples/PolynomialUtils1.cpp+ eigen3/unsupported/doc/Overview.dox+ eigen3/unsupported/doc/snippets/CMakeLists.txt+ eigen3/unsupported/Eigen/AdolcForward+ eigen3/unsupported/Eigen/AlignedVector3+ eigen3/unsupported/Eigen/ArpackSupport+ eigen3/unsupported/Eigen/AutoDiff+ eigen3/unsupported/Eigen/BVH+ eigen3/unsupported/Eigen/CMakeLists.txt+ eigen3/unsupported/Eigen/FFT+ eigen3/unsupported/Eigen/IterativeSolvers+ eigen3/unsupported/Eigen/KroneckerProduct+ eigen3/unsupported/Eigen/LevenbergMarquardt+ eigen3/unsupported/Eigen/MatrixFunctions+ eigen3/unsupported/Eigen/MoreVectorization+ eigen3/unsupported/Eigen/MPRealSupport+ eigen3/unsupported/Eigen/NonLinearOptimization+ eigen3/unsupported/Eigen/NumericalDiff+ eigen3/unsupported/Eigen/OpenGLSupport+ eigen3/unsupported/Eigen/Polynomials+ eigen3/unsupported/Eigen/Skyline+ eigen3/unsupported/Eigen/SparseExtra+ eigen3/unsupported/Eigen/Splines+ eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h+ eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h+ eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h+ eigen3/unsupported/Eigen/src/AutoDiff/CMakeLists.txt+ eigen3/unsupported/Eigen/src/BVH/BVAlgorithms.h+ eigen3/unsupported/Eigen/src/BVH/CMakeLists.txt+ eigen3/unsupported/Eigen/src/BVH/KdBVH.h+ eigen3/unsupported/Eigen/src/CMakeLists.txt+ eigen3/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h+ eigen3/unsupported/Eigen/src/FFT/CMakeLists.txt+ eigen3/unsupported/Eigen/src/FFT/ei_fftw_impl.h+ eigen3/unsupported/Eigen/src/FFT/ei_kissfft_impl.h+ eigen3/unsupported/Eigen/src/IterativeSolvers/CMakeLists.txt+ eigen3/unsupported/Eigen/src/IterativeSolvers/ConstrainedConjGrad.h+ eigen3/unsupported/Eigen/src/IterativeSolvers/DGMRES.h+ eigen3/unsupported/Eigen/src/IterativeSolvers/GMRES.h+ eigen3/unsupported/Eigen/src/IterativeSolvers/IncompleteCholesky.h+ eigen3/unsupported/Eigen/src/IterativeSolvers/IncompleteLU.h+ eigen3/unsupported/Eigen/src/IterativeSolvers/IterationController.h+ eigen3/unsupported/Eigen/src/IterativeSolvers/MINRES.h+ eigen3/unsupported/Eigen/src/IterativeSolvers/Scaling.h+ eigen3/unsupported/Eigen/src/KroneckerProduct/CMakeLists.txt+ eigen3/unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h+ eigen3/unsupported/Eigen/src/LevenbergMarquardt/CMakeLists.txt+ eigen3/unsupported/Eigen/src/LevenbergMarquardt/CopyrightMINPACK.txt+ eigen3/unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h+ eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMcovar.h+ eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h+ eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMpar.h+ eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMqrsolv.h+ eigen3/unsupported/Eigen/src/MatrixFunctions/CMakeLists.txt+ eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h+ eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h+ eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixFunctionAtomic.h+ eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h+ eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h+ eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h+ eigen3/unsupported/Eigen/src/MatrixFunctions/StemFunction.h+ eigen3/unsupported/Eigen/src/MoreVectorization/CMakeLists.txt+ eigen3/unsupported/Eigen/src/MoreVectorization/MathFunctions.h+ eigen3/unsupported/Eigen/src/NonLinearOptimization/chkder.h+ eigen3/unsupported/Eigen/src/NonLinearOptimization/CMakeLists.txt+ eigen3/unsupported/Eigen/src/NonLinearOptimization/covar.h+ eigen3/unsupported/Eigen/src/NonLinearOptimization/dogleg.h+ eigen3/unsupported/Eigen/src/NonLinearOptimization/fdjac1.h+ eigen3/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h+ eigen3/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h+ eigen3/unsupported/Eigen/src/NonLinearOptimization/lmpar.h+ eigen3/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h+ eigen3/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h+ eigen3/unsupported/Eigen/src/NonLinearOptimization/r1updt.h+ eigen3/unsupported/Eigen/src/NonLinearOptimization/rwupdt.h+ eigen3/unsupported/Eigen/src/NumericalDiff/CMakeLists.txt+ eigen3/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h+ eigen3/unsupported/Eigen/src/Polynomials/CMakeLists.txt+ eigen3/unsupported/Eigen/src/Polynomials/Companion.h+ eigen3/unsupported/Eigen/src/Polynomials/PolynomialSolver.h+ eigen3/unsupported/Eigen/src/Polynomials/PolynomialUtils.h+ eigen3/unsupported/Eigen/src/Skyline/CMakeLists.txt+ eigen3/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h+ eigen3/unsupported/Eigen/src/Skyline/SkylineMatrix.h+ eigen3/unsupported/Eigen/src/Skyline/SkylineMatrixBase.h+ eigen3/unsupported/Eigen/src/Skyline/SkylineProduct.h+ eigen3/unsupported/Eigen/src/Skyline/SkylineStorage.h+ eigen3/unsupported/Eigen/src/Skyline/SkylineUtil.h+ eigen3/unsupported/Eigen/src/SparseExtra/BlockOfDynamicSparseMatrix.h+ eigen3/unsupported/Eigen/src/SparseExtra/CMakeLists.txt+ eigen3/unsupported/Eigen/src/SparseExtra/DynamicSparseMatrix.h+ eigen3/unsupported/Eigen/src/SparseExtra/MarketIO.h+ eigen3/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h+ eigen3/unsupported/Eigen/src/SparseExtra/RandomSetter.h+ eigen3/unsupported/Eigen/src/Splines/CMakeLists.txt+ eigen3/unsupported/Eigen/src/Splines/Spline.h+ eigen3/unsupported/Eigen/src/Splines/SplineFitting.h+ eigen3/unsupported/Eigen/src/Splines/SplineFwd.h+ eigen3/unsupported/Eigen/src/SVD/BDCSVD.h+ eigen3/unsupported/Eigen/src/SVD/CMakeLists.txt+ eigen3/unsupported/Eigen/src/SVD/doneInBDCSVD.txt+ eigen3/unsupported/Eigen/src/SVD/JacobiSVD.h+ eigen3/unsupported/Eigen/src/SVD/SVDBase.h+ eigen3/unsupported/Eigen/src/SVD/TODOBdcsvd.txt+ eigen3/unsupported/Eigen/SVD+ eigen3/unsupported/README.txt+ eigen3/unsupported/test/alignedvector3.cpp+ eigen3/unsupported/test/autodiff.cpp+ eigen3/unsupported/test/bdcsvd.cpp+ eigen3/unsupported/test/BVH.cpp+ eigen3/unsupported/test/CMakeLists.txt+ eigen3/unsupported/test/dgmres.cpp+ eigen3/unsupported/test/FFT.cpp+ eigen3/unsupported/test/FFTW.cpp+ eigen3/unsupported/test/forward_adolc.cpp+ eigen3/unsupported/test/gmres.cpp+ eigen3/unsupported/test/jacobisvd.cpp+ eigen3/unsupported/test/kronecker_product.cpp+ eigen3/unsupported/test/levenberg_marquardt.cpp+ eigen3/unsupported/test/matrix_exponential.cpp+ eigen3/unsupported/test/matrix_function.cpp+ eigen3/unsupported/test/matrix_functions.h+ eigen3/unsupported/test/matrix_power.cpp+ eigen3/unsupported/test/matrix_square_root.cpp+ eigen3/unsupported/test/minres.cpp+ eigen3/unsupported/test/mpreal/mpreal.h+ eigen3/unsupported/test/mpreal_support.cpp+ eigen3/unsupported/test/NonLinearOptimization.cpp+ eigen3/unsupported/test/NumericalDiff.cpp+ eigen3/unsupported/test/openglsupport.cpp+ eigen3/unsupported/test/polynomialsolver.cpp+ eigen3/unsupported/test/polynomialutils.cpp+ eigen3/unsupported/test/sparse_extra.cpp+ eigen3/unsupported/test/splines.cpp+ eigen3/unsupported/test/svd_common.h+++source-repository head+ type: git+ location: git://github.com/osidorkin/haskell-eigen.git+++library+ exposed-modules: Data.Eigen.LA+ Data.Eigen.SparseLA+ Data.Eigen.Matrix+ Data.Eigen.Matrix.Mutable+ Data.Eigen.SparseMatrix+ Data.Eigen.Parallel+ Data.Eigen.Internal++ ghc-options: -Wall -fno-warn-name-shadowing+ build-depends: base >= 3 && < 5,+ vector >= 0.5 && < 0.12,+ primitive >= 0.1 && < 0.7,+ bytestring,+ transformers >= 0.3++ include-dirs: eigen3, cbits+ c-sources: cbits/eigen-runtime.cpp+ cbits/eigen-dense.cpp+ cbits/eigen-sparse.cpp+ cbits/eigen-la.cpp+ cbits/eigen-sparse-la.cpp extra-libraries: stdc++ Test-Suite test-solve
+ eigen3/.hg_archival.txt view
@@ -0,0 +1,4 @@+repo: 8a21fd850624c931e448cbcfb38168cb2717c790+node: bdd17ee3b1b3a166cd5ec36dcad4fc1f3faf774a+branch: 3.2+tag: 3.2.5
+ eigen3/.hgeol view
@@ -0,0 +1,8 @@+[patterns]+scripts/*.in = LF+debug/msvc/*.dat = CRLF+unsupported/test/mpreal/*.* = CRLF+** = native++[repository]+native = LF
+ eigen3/.hgignore view
@@ -0,0 +1,32 @@+syntax: glob+qrc_*cxx+*.orig+*.pyc+*.diff+diff+*.save+save+*.old+*.gmo+*.qm+core+core.*+*.bak+*~+build*+*.moc.*+*.moc+ui_*+CMakeCache.txt+tags+.*.swp+activity.png+*.out+*.php*+*.log+*.orig+*.rej+log+patch+a+a.*
+ eigen3/.hgtags view
@@ -0,0 +1,30 @@+2db9468678c6480c9633b6272ff0e3599d1e11a3 2.0-beta3+375224817dce669b6fa31d920d4c895a63fabf32 2.0-beta1+3b8120f077865e2a072e10f5be33e1d942b83a06 2.0-rc1+19dfc0e7666bcee26f7a49eb42f39a0280a3485e 2.0-beta5+7a7d8a9526f003ffa2430dfb0c2c535b5add3023 2.0-beta4+7d14ad088ac23769c349518762704f0257f6a39b 2.0.1+b9d48561579fd7d4c05b2aa42235dc9de6484bf2 2.0-beta6+e17630a40408243cb1a51ad0fe3a99beb75b7450 before-hg-migration+eda654d4cda2210ce80719addcf854773e6dec5a 2.0.0+ee9a7c468a9e73fab12f38f02bac24b07f29ed71 2.0-beta2+d49097c25d8049e730c254a2fed725a240ce4858 after-hg-migration+655348878731bcb5d9bbe0854077b052e75e5237 actual-start-from-scratch+12a658962d4e6dfdc9a1c350fe7b69e36e70675c 3.0-beta1+5c4180ad827b3f869b13b1d82f5a6ce617d6fcee 3.0-beta2+7ae24ca6f3891d5ac58ddc7db60ad413c8d6ec35 3.0-beta3+c40708b9088d622567fecc9208ad4a426621d364 3.0-beta4+b6456624eae74f49ae8683d8e7b2882a2ca0342a 3.0-rc1+a810d5dbab47acfe65b3350236efdd98f67d4d8a 3.1.0-alpha1+304c88ca3affc16dd0b008b1104873986edd77af 3.1.0-alpha2+920fc730b5930daae0a6dbe296d60ce2e3808215 3.1.0-beta1+8383e883ebcc6f14695ff0b5e20bb631abab43fb 3.1.0-rc1+bf4cb8c934fa3a79f45f1e629610f0225e93e493 3.1.0-rc2+da195914abcc1d739027cbee7c52077aab30b336 3.2-beta1+4b687cad1d23066f66863f4f87298447298443df 3.2-rc1+1eeda7b1258bcd306018c0738e2b6a8543661141 3.2-rc2+ffa86ffb557094721ca71dcea6aed2651b9fd610 3.2.0+6b38706d90a9fe182e66ab88477b3dbde34b9f66 3.2.1+1306d75b4a21891e59ff9bd96678882cf831e39f 3.2.2+36fd1ba04c120cfdd90f3e4cede47f43b21d19ad 3.2.3+10219c95fe653d4962aa9db4946f6fbea96dd740 3.2.4
+ eigen3/CMakeLists.txt view
@@ -0,0 +1,420 @@+project(Eigen)++cmake_minimum_required(VERSION 2.8.2)++# guard against in-source builds++if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})+ message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there. You may need to remove CMakeCache.txt. ")+endif()++# guard against bad build-type strings++if (NOT CMAKE_BUILD_TYPE)+ set(CMAKE_BUILD_TYPE "Release")+endif()++string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_tolower)+if( NOT cmake_build_type_tolower STREQUAL "debug"+ AND NOT cmake_build_type_tolower STREQUAL "release"+ AND NOT cmake_build_type_tolower STREQUAL "relwithdebinfo")+ message(FATAL_ERROR "Unknown build type \"${CMAKE_BUILD_TYPE}\". Allowed values are Debug, Release, RelWithDebInfo (case-insensitive).")+endif()+++#############################################################################+# retrieve version infomation #+#############################################################################++# automatically parse the version number+file(READ "${PROJECT_SOURCE_DIR}/Eigen/src/Core/util/Macros.h" _eigen_version_header)+string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen_world_version_match "${_eigen_version_header}")+set(EIGEN_WORLD_VERSION "${CMAKE_MATCH_1}")+string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen_major_version_match "${_eigen_version_header}")+set(EIGEN_MAJOR_VERSION "${CMAKE_MATCH_1}")+string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen_minor_version_match "${_eigen_version_header}")+set(EIGEN_MINOR_VERSION "${CMAKE_MATCH_1}")+set(EIGEN_VERSION_NUMBER ${EIGEN_WORLD_VERSION}.${EIGEN_MAJOR_VERSION}.${EIGEN_MINOR_VERSION})++# if the mercurial program is absent, this will leave the EIGEN_HG_CHANGESET string empty,+# but won't stop CMake.+execute_process(COMMAND hg tip -R ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE EIGEN_HGTIP_OUTPUT)+execute_process(COMMAND hg branch -R ${CMAKE_SOURCE_DIR} OUTPUT_VARIABLE EIGEN_BRANCH_OUTPUT)++# if this is the default (aka development) branch, extract the mercurial changeset number from the hg tip output...+if(EIGEN_BRANCH_OUTPUT MATCHES "default")+string(REGEX MATCH "^changeset: *[0-9]*:([0-9;a-f]+).*" EIGEN_HG_CHANGESET_MATCH "${EIGEN_HGTIP_OUTPUT}")+set(EIGEN_HG_CHANGESET "${CMAKE_MATCH_1}")+endif(EIGEN_BRANCH_OUTPUT MATCHES "default")+#...and show it next to the version number+if(EIGEN_HG_CHANGESET)+ set(EIGEN_VERSION "${EIGEN_VERSION_NUMBER} (mercurial changeset ${EIGEN_HG_CHANGESET})")+else(EIGEN_HG_CHANGESET)+ set(EIGEN_VERSION "${EIGEN_VERSION_NUMBER}")+endif(EIGEN_HG_CHANGESET)+++include(CheckCXXCompilerFlag)++set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)++#############################################################################+# find how to link to the standard libraries #+#############################################################################++find_package(StandardMathLibrary)+++set(EIGEN_TEST_CUSTOM_LINKER_FLAGS "" CACHE STRING "Additional linker flags when linking unit tests.")+set(EIGEN_TEST_CUSTOM_CXX_FLAGS "" CACHE STRING "Additional compiler flags when compiling unit tests.")++set(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO "")++if(NOT STANDARD_MATH_LIBRARY_FOUND)++ message(FATAL_ERROR+ "Can't link to the standard math library. Please report to the Eigen developers, telling them about your platform.")++else()++ if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)+ set(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO "${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO} ${STANDARD_MATH_LIBRARY}")+ else()+ set(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO "${STANDARD_MATH_LIBRARY}")+ endif()++endif()++if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)+ message(STATUS "Standard libraries to link to explicitly: ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO}")+else()+ message(STATUS "Standard libraries to link to explicitly: none")+endif()++option(EIGEN_BUILD_BTL "Build benchmark suite" OFF)+if(NOT WIN32)+ option(EIGEN_BUILD_PKGCONFIG "Build pkg-config .pc file for Eigen" ON)+endif(NOT WIN32)++set(CMAKE_INCLUDE_CURRENT_DIR ON)++option(EIGEN_SPLIT_LARGE_TESTS "Split large tests into smaller executables" ON)++option(EIGEN_DEFAULT_TO_ROW_MAJOR "Use row-major as default matrix storage order" OFF)+if(EIGEN_DEFAULT_TO_ROW_MAJOR)+ add_definitions("-DEIGEN_DEFAULT_TO_ROW_MAJOR")+endif()++set(EIGEN_TEST_MAX_SIZE "320" CACHE STRING "Maximal matrix/vector size, default is 320")++macro(ei_add_cxx_compiler_flag FLAG)+ string(REGEX REPLACE "-" "" SFLAG ${FLAG})+ check_cxx_compiler_flag(${FLAG} COMPILER_SUPPORT_${SFLAG})+ if(COMPILER_SUPPORT_${SFLAG})+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAG}")+ endif()+endmacro(ei_add_cxx_compiler_flag)++if(NOT MSVC)+ # We assume that other compilers are partly compatible with GNUCC+ + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")+ set(CMAKE_CXX_FLAGS_DEBUG "-g3")+ set(CMAKE_CXX_FLAGS_RELEASE "-g0 -O2")+ + # clang outputs some warnings for unknwon flags that are not caught by check_cxx_compiler_flag+ # adding -Werror turns such warnings into errors+ check_cxx_compiler_flag("-Werror" COMPILER_SUPPORT_WERROR)+ if(COMPILER_SUPPORT_WERROR)+ set(CMAKE_REQUIRED_FLAGS "-Werror")+ endif()+ + ei_add_cxx_compiler_flag("-pedantic")+ ei_add_cxx_compiler_flag("-Wall")+ ei_add_cxx_compiler_flag("-Wextra")+ #ei_add_cxx_compiler_flag("-Weverything") # clang+ + ei_add_cxx_compiler_flag("-Wundef")+ ei_add_cxx_compiler_flag("-Wcast-align")+ ei_add_cxx_compiler_flag("-Wchar-subscripts")+ ei_add_cxx_compiler_flag("-Wnon-virtual-dtor")+ ei_add_cxx_compiler_flag("-Wunused-local-typedefs")+ ei_add_cxx_compiler_flag("-Wpointer-arith")+ ei_add_cxx_compiler_flag("-Wwrite-strings")+ ei_add_cxx_compiler_flag("-Wformat-security")+ + ei_add_cxx_compiler_flag("-Wno-psabi")+ ei_add_cxx_compiler_flag("-Wno-variadic-macros")+ ei_add_cxx_compiler_flag("-Wno-long-long")+ + ei_add_cxx_compiler_flag("-fno-check-new")+ ei_add_cxx_compiler_flag("-fno-common")+ ei_add_cxx_compiler_flag("-fstrict-aliasing")+ ei_add_cxx_compiler_flag("-wd981") # disable ICC's "operands are evaluated in unspecified order" remark+ ei_add_cxx_compiler_flag("-wd2304") # disbale ICC's "warning #2304: non-explicit constructor with single argument may cause implicit type conversion" produced by -Wnon-virtual-dtor+ + # The -ansi flag must be added last, otherwise it is also used as a linker flag by check_cxx_compiler_flag making it fails+ # Moreover we should not set both -strict-ansi and -ansi+ check_cxx_compiler_flag("-strict-ansi" COMPILER_SUPPORT_STRICTANSI)+ ei_add_cxx_compiler_flag("-Qunused-arguments") # disable clang warning: argument unused during compilation: '-ansi'+ + if(COMPILER_SUPPORT_STRICTANSI)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -strict-ansi")+ else()+ ei_add_cxx_compiler_flag("-ansi")+ endif()+ + set(CMAKE_REQUIRED_FLAGS "")++ option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)+ if(EIGEN_TEST_SSE2)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2")+ message(STATUS "Enabling SSE2 in tests/examples")+ endif()++ option(EIGEN_TEST_SSE3 "Enable/Disable SSE3 in tests/examples" OFF)+ if(EIGEN_TEST_SSE3)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse3")+ message(STATUS "Enabling SSE3 in tests/examples")+ endif()++ option(EIGEN_TEST_SSSE3 "Enable/Disable SSSE3 in tests/examples" OFF)+ if(EIGEN_TEST_SSSE3)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mssse3")+ message(STATUS "Enabling SSSE3 in tests/examples")+ endif()++ option(EIGEN_TEST_SSE4_1 "Enable/Disable SSE4.1 in tests/examples" OFF)+ if(EIGEN_TEST_SSE4_1)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.1")+ message(STATUS "Enabling SSE4.1 in tests/examples")+ endif()++ option(EIGEN_TEST_SSE4_2 "Enable/Disable SSE4.2 in tests/examples" OFF)+ if(EIGEN_TEST_SSE4_2)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2")+ message(STATUS "Enabling SSE4.2 in tests/examples")+ endif()++ option(EIGEN_TEST_ALTIVEC "Enable/Disable AltiVec in tests/examples" OFF)+ if(EIGEN_TEST_ALTIVEC)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maltivec -mabi=altivec")+ message(STATUS "Enabling AltiVec in tests/examples")+ endif()++ option(EIGEN_TEST_NEON "Enable/Disable Neon in tests/examples" OFF)+ if(EIGEN_TEST_NEON)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon -mcpu=cortex-a8")+ message(STATUS "Enabling NEON in tests/examples")+ endif()++ check_cxx_compiler_flag("-fopenmp" COMPILER_SUPPORT_OPENMP)+ if(COMPILER_SUPPORT_OPENMP)+ option(EIGEN_TEST_OPENMP "Enable/Disable OpenMP in tests/examples" OFF)+ if(EIGEN_TEST_OPENMP)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")+ message(STATUS "Enabling OpenMP in tests/examples")+ endif()+ endif()++else(NOT MSVC)++ # C4127 - conditional expression is constant+ # C4714 - marked as __forceinline not inlined (I failed to deactivate it selectively)+ # We can disable this warning in the unit tests since it is clear that it occurs+ # because we are oftentimes returning objects that have a destructor or may+ # throw exceptions - in particular in the unit tests we are throwing extra many+ # exceptions to cover indexing errors.+ # C4505 - unreferenced local function has been removed (impossible to deactive selectively)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /wd4127 /wd4505 /wd4714")++ # replace all /Wx by /W4+ string(REGEX REPLACE "/W[0-9]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")++ check_cxx_compiler_flag("/openmp" COMPILER_SUPPORT_OPENMP)+ if(COMPILER_SUPPORT_OPENMP)+ option(EIGEN_TEST_OPENMP "Enable/Disable OpenMP in tests/examples" OFF)+ if(EIGEN_TEST_OPENMP)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /openmp")+ message(STATUS "Enabling OpenMP in tests/examples")+ endif()+ endif()++ option(EIGEN_TEST_SSE2 "Enable/Disable SSE2 in tests/examples" OFF)+ if(EIGEN_TEST_SSE2)+ if(NOT CMAKE_CL_64)+ # arch is not supported on 64 bit systems, SSE is enabled automatically.+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE2")+ endif(NOT CMAKE_CL_64)+ message(STATUS "Enabling SSE2 in tests/examples")+ endif(EIGEN_TEST_SSE2)+endif(NOT MSVC)++option(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION "Disable explicit vectorization in tests/examples" OFF)+option(EIGEN_TEST_X87 "Force using X87 instructions. Implies no vectorization." OFF)+option(EIGEN_TEST_32BIT "Force generating 32bit code." OFF)++if(EIGEN_TEST_X87)+ set(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION ON)+ if(CMAKE_COMPILER_IS_GNUCXX)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpmath=387")+ message(STATUS "Forcing use of x87 instructions in tests/examples")+ else()+ message(STATUS "EIGEN_TEST_X87 ignored on your compiler")+ endif()+endif()++if(EIGEN_TEST_32BIT)+ if(CMAKE_COMPILER_IS_GNUCXX)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")+ message(STATUS "Forcing generation of 32-bit code in tests/examples")+ else()+ message(STATUS "EIGEN_TEST_32BIT ignored on your compiler")+ endif()+endif()++if(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)+ add_definitions(-DEIGEN_DONT_VECTORIZE=1)+ message(STATUS "Disabling vectorization in tests/examples")+endif()++option(EIGEN_TEST_NO_EXPLICIT_ALIGNMENT "Disable explicit alignment (hence vectorization) in tests/examples" OFF)+if(EIGEN_TEST_NO_EXPLICIT_ALIGNMENT)+ add_definitions(-DEIGEN_DONT_ALIGN=1)+ message(STATUS "Disabling alignment in tests/examples")+endif()++option(EIGEN_TEST_C++0x "Enables all C++0x features." OFF)++include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})++# the user modifiable install path for header files+set(EIGEN_INCLUDE_INSTALL_DIR ${EIGEN_INCLUDE_INSTALL_DIR} CACHE PATH "The directory where we install the header files (optional)")++# set the internal install path for header files which depends on wether the user modifiable+# EIGEN_INCLUDE_INSTALL_DIR has been set by the user or not.+if(EIGEN_INCLUDE_INSTALL_DIR)+ set(INCLUDE_INSTALL_DIR+ ${EIGEN_INCLUDE_INSTALL_DIR}+ CACHE INTERNAL+ "The directory where we install the header files (internal)"+ )+else()+ set(INCLUDE_INSTALL_DIR+ "${CMAKE_INSTALL_PREFIX}/include/eigen3"+ CACHE INTERNAL+ "The directory where we install the header files (internal)"+ )+endif()++# similar to set_target_properties but append the property instead of overwriting it+macro(ei_add_target_property target prop value)++ get_target_property(previous ${target} ${prop})+ # if the property wasn't previously set, ${previous} is now "previous-NOTFOUND" which cmake allows catching with plain if()+ if(NOT previous)+ set(previous "")+ endif(NOT previous)+ set_target_properties(${target} PROPERTIES ${prop} "${previous} ${value}")+endmacro(ei_add_target_property)++install(FILES+ signature_of_eigen3_matrix_library+ DESTINATION ${INCLUDE_INSTALL_DIR} COMPONENT Devel+ )++if(EIGEN_BUILD_PKGCONFIG)+ SET(path_separator ":")+ STRING(REPLACE ${path_separator} ";" pkg_config_libdir_search "$ENV{PKG_CONFIG_LIBDIR}")+ message(STATUS "searching for 'pkgconfig' directory in PKG_CONFIG_LIBDIR ( $ENV{PKG_CONFIG_LIBDIR} ), ${CMAKE_INSTALL_PREFIX}/share, and ${CMAKE_INSTALL_PREFIX}/lib")+ FIND_PATH(pkg_config_libdir pkgconfig ${pkg_config_libdir_search} ${CMAKE_INSTALL_PREFIX}/share ${CMAKE_INSTALL_PREFIX}/lib ${pkg_config_libdir_search})+ if(pkg_config_libdir)+ SET(pkg_config_install_dir ${pkg_config_libdir})+ message(STATUS "found ${pkg_config_libdir}/pkgconfig" )+ else(pkg_config_libdir)+ SET(pkg_config_install_dir ${CMAKE_INSTALL_PREFIX}/share)+ message(STATUS "pkgconfig not found; installing in ${pkg_config_install_dir}" )+ endif(pkg_config_libdir)++ configure_file(eigen3.pc.in eigen3.pc)+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/eigen3.pc+ DESTINATION ${pkg_config_install_dir}/pkgconfig+ )+endif(EIGEN_BUILD_PKGCONFIG)++add_subdirectory(Eigen)++add_subdirectory(doc EXCLUDE_FROM_ALL)++include(EigenConfigureTesting)++# fixme, not sure this line is still needed:+enable_testing() # must be called from the root CMakeLists, see man page+++if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)+ add_subdirectory(test) # can't do EXCLUDE_FROM_ALL here, breaks CTest+else()+ add_subdirectory(test EXCLUDE_FROM_ALL)+endif()++if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)+ add_subdirectory(blas)+ add_subdirectory(lapack)+else()+ add_subdirectory(blas EXCLUDE_FROM_ALL)+ add_subdirectory(lapack EXCLUDE_FROM_ALL)+endif()++add_subdirectory(unsupported)++add_subdirectory(demos EXCLUDE_FROM_ALL)++# must be after test and unsupported, for configuring buildtests.in+add_subdirectory(scripts EXCLUDE_FROM_ALL)++# TODO: consider also replacing EIGEN_BUILD_BTL by a custom target "make btl"?+if(EIGEN_BUILD_BTL)+ add_subdirectory(bench/btl EXCLUDE_FROM_ALL)+endif(EIGEN_BUILD_BTL)++if(NOT WIN32)+ add_subdirectory(bench/spbench EXCLUDE_FROM_ALL)+endif(NOT WIN32)++configure_file(scripts/cdashtesting.cmake.in cdashtesting.cmake @ONLY)++ei_testing_print_summary()++message(STATUS "")+message(STATUS "Configured Eigen ${EIGEN_VERSION_NUMBER}")+message(STATUS "")++option(EIGEN_FAILTEST "Enable failtests." OFF)+if(EIGEN_FAILTEST)+ add_subdirectory(failtest)+endif()++string(TOLOWER "${CMAKE_GENERATOR}" cmake_generator_tolower)+if(cmake_generator_tolower MATCHES "makefile")+ message(STATUS "Some things you can do now:")+ message(STATUS "--------------+--------------------------------------------------------------")+ message(STATUS "Command | Description")+ message(STATUS "--------------+--------------------------------------------------------------")+ message(STATUS "make install | Install to ${CMAKE_INSTALL_PREFIX}. To change that:")+ message(STATUS " | cmake . -DCMAKE_INSTALL_PREFIX=yourpath")+ message(STATUS " | Eigen headers will then be installed to:")+ message(STATUS " | ${INCLUDE_INSTALL_DIR}")+ message(STATUS " | To install Eigen headers to a separate location, do:")+ message(STATUS " | cmake . -DEIGEN_INCLUDE_INSTALL_DIR=yourpath")+ message(STATUS "make doc | Generate the API documentation, requires Doxygen & LaTeX")+ message(STATUS "make check | Build and run the unit-tests. Read this page:")+ message(STATUS " | http://eigen.tuxfamily.org/index.php?title=Tests")+ message(STATUS "make blas | Build BLAS library (not the same thing as Eigen)")+ message(STATUS "--------------+--------------------------------------------------------------")+else()+ message(STATUS "To build/run the unit tests, read this page:")+ message(STATUS " http://eigen.tuxfamily.org/index.php?title=Tests")+endif()++message(STATUS "")
+ eigen3/CTestConfig.cmake view
@@ -0,0 +1,13 @@+## This file should be placed in the root directory of your project.+## Then modify the CMakeLists.txt file in the root directory of your+## project to incorporate the testing dashboard.+## # The following are required to uses Dart and the Cdash dashboard+## ENABLE_TESTING()+## INCLUDE(CTest)+set(CTEST_PROJECT_NAME "Eigen3.2")+set(CTEST_NIGHTLY_START_TIME "00:00:00 UTC")++set(CTEST_DROP_METHOD "http")+set(CTEST_DROP_SITE "manao.inria.fr")+set(CTEST_DROP_LOCATION "/CDash/submit.php?project=Eigen3.2")+set(CTEST_DROP_SITE_CDASH TRUE)
+ eigen3/CTestCustom.cmake.in view
@@ -0,0 +1,3 @@++set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS "2000")+set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS "2000")
eigen3/Eigen/Core view
@@ -123,7 +123,7 @@ #undef bool #undef vector #undef pixel- #elif defined __ARM_NEON__+ #elif defined __ARM_NEON #define EIGEN_VECTORIZE #define EIGEN_VECTORIZE_NEON #include <arm_neon.h>
eigen3/Eigen/src/Cholesky/LDLT.h view
@@ -235,6 +235,11 @@ } protected:+ + static void check_template_parameters()+ {+ EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);+ } /** \internal * Used to compute and store the Cholesky decomposition A = L D L^* = U^* D U.@@ -434,6 +439,8 @@ template<typename MatrixType, int _UpLo> LDLT<MatrixType,_UpLo>& LDLT<MatrixType,_UpLo>::compute(const MatrixType& a) {+ check_template_parameters();+ eigen_assert(a.rows()==a.cols()); const Index size = a.rows();
eigen3/Eigen/src/Cholesky/LLT.h view
@@ -174,6 +174,12 @@ LLT rankUpdate(const VectorType& vec, const RealScalar& sigma = 1); protected:+ + static void check_template_parameters()+ {+ EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);+ }+ /** \internal * Used to compute and store L * The strict upper part is not used and even not initialized.@@ -384,6 +390,8 @@ template<typename MatrixType, int _UpLo> LLT<MatrixType,_UpLo>& LLT<MatrixType,_UpLo>::compute(const MatrixType& a) {+ check_template_parameters();+ eigen_assert(a.rows()==a.cols()); const Index size = a.rows(); m_matrix.resize(size, size);
eigen3/Eigen/src/Cholesky/LLT_MKL.h view
@@ -60,7 +60,7 @@ lda = m.outerStride(); \ \ info = LAPACKE_##MKLPREFIX##potrf( matrix_order, uplo, size, (MKLTYPE*)a, lda ); \- info = (info==0) ? Success : NumericalIssue; \+ info = (info==0) ? -1 : info>0 ? info-1 : size; \ return info; \ } \ }; \
eigen3/Eigen/src/Core/Assign.h view
@@ -439,19 +439,26 @@ typedef typename Derived1::Index Index; static inline void run(Derived1 &dst, const Derived2 &src) {- typedef packet_traits<typename Derived1::Scalar> PacketTraits;+ typedef typename Derived1::Scalar Scalar;+ typedef packet_traits<Scalar> PacketTraits; enum { packetSize = PacketTraits::size, alignable = PacketTraits::AlignedOnScalar,- dstAlignment = alignable ? Aligned : int(assign_traits<Derived1,Derived2>::DstIsAligned) ,+ dstIsAligned = assign_traits<Derived1,Derived2>::DstIsAligned,+ dstAlignment = alignable ? Aligned : int(dstIsAligned), srcAlignment = assign_traits<Derived1,Derived2>::JointAlignment };+ const Scalar *dst_ptr = &dst.coeffRef(0,0);+ if((!bool(dstIsAligned)) && (Index(dst_ptr) % sizeof(Scalar))>0)+ {+ // the pointer is not aligend-on scalar, so alignment is not possible+ return assign_impl<Derived1,Derived2,DefaultTraversal,NoUnrolling>::run(dst, src);+ } const Index packetAlignedMask = packetSize - 1; const Index innerSize = dst.innerSize(); const Index outerSize = dst.outerSize(); const Index alignedStep = alignable ? (packetSize - dst.outerStride() % packetSize) & packetAlignedMask : 0;- Index alignedStart = ((!alignable) || assign_traits<Derived1,Derived2>::DstIsAligned) ? 0- : internal::first_aligned(&dst.coeffRef(0,0), innerSize);+ Index alignedStart = ((!alignable) || bool(dstIsAligned)) ? 0 : internal::first_aligned(dst_ptr, innerSize); for(Index outer = 0; outer < outerSize; ++outer) {
eigen3/Eigen/src/Core/Block.h view
@@ -66,8 +66,9 @@ : ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime) : int(traits<XprType>::MaxColsAtCompileTime), XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0,- IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1- : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0+ IsDense = is_same<StorageKind,Dense>::value,+ IsRowMajor = (IsDense&&MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1+ : (IsDense&&MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0 : XprTypeIsRowMajor, HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor), InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
eigen3/Eigen/src/Core/DenseBase.h view
@@ -266,11 +266,13 @@ template<typename OtherDerived> Derived& operator=(const ReturnByValue<OtherDerived>& func); -#ifndef EIGEN_PARSED_BY_DOXYGEN- /** Copies \a other into *this without evaluating other. \returns a reference to *this. */+ /** \internal Copies \a other into *this without evaluating other. \returns a reference to *this. */ template<typename OtherDerived> Derived& lazyAssign(const DenseBase<OtherDerived>& other);-#endif // not EIGEN_PARSED_BY_DOXYGEN++ /** \internal Evaluates \a other into *this. \returns a reference to *this. */+ template<typename OtherDerived>+ Derived& lazyAssign(const ReturnByValue<OtherDerived>& other); CommaInitializer<Derived> operator<< (const Scalar& s);
eigen3/Eigen/src/Core/DiagonalProduct.h view
@@ -34,7 +34,7 @@ _Vectorizable = bool(int(MatrixType::Flags)&PacketAccessBit) && _SameTypes && (_ScalarAccessOnDiag || (bool(int(DiagonalType::DiagonalVectorType::Flags)&PacketAccessBit))), _LinearAccessMask = (RowsAtCompileTime==1 || ColsAtCompileTime==1) ? LinearAccessBit : 0, - Flags = ((HereditaryBits|_LinearAccessMask) & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0) | AlignedBit,//(int(MatrixType::Flags)&int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit),+ Flags = ((HereditaryBits|_LinearAccessMask|AlignedBit) & (unsigned int)(MatrixType::Flags)) | (_Vectorizable ? PacketAccessBit : 0),//(int(MatrixType::Flags)&int(DiagonalType::DiagonalVectorType::Flags)&AlignedBit), CoeffReadCost = NumTraits<Scalar>::MulCost + MatrixType::CoeffReadCost + DiagonalType::DiagonalVectorType::CoeffReadCost }; };
eigen3/Eigen/src/Core/Functors.h view
@@ -259,6 +259,47 @@ }; }; +/** \internal+ * \brief Template functors for comparison of two scalars+ * \todo Implement packet-comparisons+ */+template<typename Scalar, ComparisonName cmp> struct scalar_cmp_op;++template<typename Scalar, ComparisonName cmp>+struct functor_traits<scalar_cmp_op<Scalar, cmp> > {+ enum {+ Cost = NumTraits<Scalar>::AddCost,+ PacketAccess = false+ };+};++template<ComparisonName Cmp, typename Scalar>+struct result_of<scalar_cmp_op<Scalar, Cmp>(Scalar,Scalar)> {+ typedef bool type;+};+++template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_EQ> {+ EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)+ EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a==b;}+};+template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_LT> {+ EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)+ EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a<b;}+};+template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_LE> {+ EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)+ EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a<=b;}+};+template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_UNORD> {+ EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)+ EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return !(a<=b || b<=a);}+};+template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_NEQ> {+ EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)+ EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a!=b;}+};+ // unary functors: /** \internal
eigen3/Eigen/src/Core/MapBase.h view
@@ -157,7 +157,7 @@ internal::inner_stride_at_compile_time<Derived>::ret==1), PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1); eigen_assert(EIGEN_IMPLIES(internal::traits<Derived>::Flags&AlignedBit, (size_t(m_data) % 16) == 0)- && "data is not aligned");+ && "input pointer is not aligned on a 16 byte boundary"); } PointerType m_data;
eigen3/Eigen/src/Core/MatrixBase.h view
@@ -159,13 +159,11 @@ template<typename OtherDerived> Derived& operator=(const ReturnByValue<OtherDerived>& other); -#ifndef EIGEN_PARSED_BY_DOXYGEN template<typename ProductDerived, typename Lhs, typename Rhs> Derived& lazyAssign(const ProductBase<ProductDerived, Lhs,Rhs>& other); template<typename MatrixPower, typename Lhs, typename Rhs> Derived& lazyAssign(const MatrixPowerProduct<MatrixPower, Lhs,Rhs>& other);-#endif // not EIGEN_PARSED_BY_DOXYGEN template<typename OtherDerived> Derived& operator+=(const MatrixBase<OtherDerived>& other);
eigen3/Eigen/src/Core/PermutationMatrix.h view
@@ -250,6 +250,35 @@ template<typename Other> friend inline PlainPermutationType operator*(const Transpose<PermutationBase<Other> >& other, const PermutationBase& perm) { return PlainPermutationType(internal::PermPermProduct, other.eval(), perm); }+ + /** \returns the determinant of the permutation matrix, which is either 1 or -1 depending on the parity of the permutation.+ *+ * This function is O(\c n) procedure allocating a buffer of \c n booleans.+ */+ Index determinant() const+ {+ Index res = 1;+ Index n = size();+ Matrix<bool,RowsAtCompileTime,1,0,MaxRowsAtCompileTime> mask(n);+ mask.fill(false);+ Index r = 0;+ while(r < n)+ {+ // search for the next seed+ while(r<n && mask[r]) r++;+ if(r>=n)+ break;+ // we got one, let's follow it until we are back to the seed+ Index k0 = r++;+ mask.coeffRef(k0) = true;+ for(Index k=indices().coeff(k0); k!=k0; k=indices().coeff(k))+ {+ mask.coeffRef(k) = true;+ res = -res;+ }+ }+ return res;+ } protected:
eigen3/Eigen/src/Core/PlainObjectBase.h view
@@ -573,6 +573,8 @@ : (rows() == other.rows() && cols() == other.cols()))) && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined"); EIGEN_ONLY_USED_FOR_DEBUG(other);+ if(this->size()==0)+ resizeLike(other); #else resizeLike(other); #endif
eigen3/Eigen/src/Core/Ref.h view
@@ -108,7 +108,8 @@ OuterStrideMatch = Derived::IsVectorAtCompileTime || int(StrideType::OuterStrideAtCompileTime)==int(Dynamic) || int(StrideType::OuterStrideAtCompileTime)==int(Derived::OuterStrideAtCompileTime), AlignmentMatch = (_Options!=Aligned) || ((PlainObjectType::Flags&AlignedBit)==0) || ((traits<Derived>::Flags&AlignedBit)==AlignedBit),- MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch+ ScalarTypeMatch = internal::is_same<typename PlainObjectType::Scalar, typename Derived::Scalar>::value,+ MatchAtCompileTime = HasDirectAccess && StorageOrderMatch && InnerStrideMatch && OuterStrideMatch && AlignmentMatch && ScalarTypeMatch }; typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type; };@@ -187,9 +188,11 @@ template<typename PlainObjectType, int Options, typename StrideType> class Ref : public RefBase<Ref<PlainObjectType, Options, StrideType> > {+ private: typedef internal::traits<Ref> Traits; template<typename Derived>- inline Ref(const PlainObjectBase<Derived>& expr);+ inline Ref(const PlainObjectBase<Derived>& expr,+ typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0); public: typedef RefBase<Ref> Base;@@ -198,13 +201,15 @@ #ifndef EIGEN_PARSED_BY_DOXYGEN template<typename Derived>- inline Ref(PlainObjectBase<Derived>& expr)+ inline Ref(PlainObjectBase<Derived>& expr,+ typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0) { EIGEN_STATIC_ASSERT(static_cast<bool>(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); Base::construct(expr.derived()); } template<typename Derived>- inline Ref(const DenseBase<Derived>& expr)+ inline Ref(const DenseBase<Derived>& expr,+ typename internal::enable_if<bool(Traits::template match<Derived>::MatchAtCompileTime),Derived>::type* = 0) #else template<typename Derived> inline Ref(DenseBase<Derived>& expr)@@ -231,7 +236,8 @@ EIGEN_DENSE_PUBLIC_INTERFACE(Ref) template<typename Derived>- inline Ref(const DenseBase<Derived>& expr)+ inline Ref(const DenseBase<Derived>& expr,+ typename internal::enable_if<bool(Traits::template match<Derived>::ScalarTypeMatch),Derived>::type* = 0) { // std::cout << match_helper<Derived>::HasDirectAccess << "," << match_helper<Derived>::OuterStrideMatch << "," << match_helper<Derived>::InnerStrideMatch << "\n"; // std::cout << int(StrideType::OuterStrideAtCompileTime) << " - " << int(Derived::OuterStrideAtCompileTime) << "\n";
eigen3/Eigen/src/Core/ReturnByValue.h view
@@ -72,6 +72,8 @@ const Unusable& coeff(Index,Index) const { return *reinterpret_cast<const Unusable*>(this); } Unusable& coeffRef(Index) { return *reinterpret_cast<Unusable*>(this); } Unusable& coeffRef(Index,Index) { return *reinterpret_cast<Unusable*>(this); }+ template<int LoadMode> Unusable& packet(Index) const;+ template<int LoadMode> Unusable& packet(Index, Index) const; #endif }; @@ -82,6 +84,15 @@ other.evalTo(derived()); return derived(); }++template<typename Derived>+template<typename OtherDerived>+Derived& DenseBase<Derived>::lazyAssign(const ReturnByValue<OtherDerived>& other)+{+ other.evalTo(derived());+ return derived();+}+ } // end namespace Eigen
eigen3/Eigen/src/Core/products/CoeffBasedProduct.h view
@@ -134,7 +134,7 @@ }; typedef internal::product_coeff_impl<CanVectorizeInner ? InnerVectorizedTraversal : DefaultTraversal,- Unroll ? (InnerSize==0 ? 0 : InnerSize-1) : Dynamic,+ Unroll ? InnerSize : Dynamic, _LhsNested, _RhsNested, Scalar> ScalarCoeffImpl; typedef CoeffBasedProduct<LhsNested,RhsNested,NestByRefBit> LazyCoeffBasedProductType;@@ -185,7 +185,7 @@ { PacketScalar res; internal::product_packet_impl<Flags&RowMajorBit ? RowMajor : ColMajor,- Unroll ? (InnerSize==0 ? 0 : InnerSize-1) : Dynamic,+ Unroll ? InnerSize : Dynamic, _LhsNested, _RhsNested, PacketScalar, LoadMode> ::run(row, col, m_lhs, m_rhs, res); return res;@@ -243,12 +243,12 @@ static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) { product_coeff_impl<DefaultTraversal, UnrollingIndex-1, Lhs, Rhs, RetScalar>::run(row, col, lhs, rhs, res);- res += lhs.coeff(row, UnrollingIndex) * rhs.coeff(UnrollingIndex, col);+ res += lhs.coeff(row, UnrollingIndex-1) * rhs.coeff(UnrollingIndex-1, col); } }; template<typename Lhs, typename Rhs, typename RetScalar>-struct product_coeff_impl<DefaultTraversal, 0, Lhs, Rhs, RetScalar>+struct product_coeff_impl<DefaultTraversal, 1, Lhs, Rhs, RetScalar> { typedef typename Lhs::Index Index; static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res)@@ -258,6 +258,16 @@ }; template<typename Lhs, typename Rhs, typename RetScalar>+struct product_coeff_impl<DefaultTraversal, 0, Lhs, Rhs, RetScalar>+{+ typedef typename Lhs::Index Index;+ static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, RetScalar &res)+ {+ res = RetScalar(0);+ }+};++template<typename Lhs, typename Rhs, typename RetScalar> struct product_coeff_impl<DefaultTraversal, Dynamic, Lhs, Rhs, RetScalar> { typedef typename Lhs::Index Index;@@ -293,6 +303,16 @@ } }; +template<typename Lhs, typename Rhs, typename RetScalar>+struct product_coeff_impl<InnerVectorizedTraversal, 0, Lhs, Rhs, RetScalar>+{+ typedef typename Lhs::Index Index;+ static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, RetScalar &res)+ {+ res = 0;+ }+};+ template<int UnrollingIndex, typename Lhs, typename Rhs, typename RetScalar> struct product_coeff_impl<InnerVectorizedTraversal, UnrollingIndex, Lhs, Rhs, RetScalar> {@@ -302,8 +322,7 @@ static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) { Packet pres;- product_coeff_vectorized_unroller<UnrollingIndex+1-PacketSize, Lhs, Rhs, Packet>::run(row, col, lhs, rhs, pres);- product_coeff_impl<DefaultTraversal,UnrollingIndex,Lhs,Rhs,RetScalar>::run(row, col, lhs, rhs, res);+ product_coeff_vectorized_unroller<UnrollingIndex-PacketSize, Lhs, Rhs, Packet>::run(row, col, lhs, rhs, pres); res = predux(pres); } };@@ -371,7 +390,7 @@ static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) { product_packet_impl<RowMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, res);- res = pmadd(pset1<Packet>(lhs.coeff(row, UnrollingIndex)), rhs.template packet<LoadMode>(UnrollingIndex, col), res);+ res = pmadd(pset1<Packet>(lhs.coeff(row, UnrollingIndex-1)), rhs.template packet<LoadMode>(UnrollingIndex-1, col), res); } }; @@ -382,12 +401,12 @@ static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res) { product_packet_impl<ColMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, res);- res = pmadd(lhs.template packet<LoadMode>(row, UnrollingIndex), pset1<Packet>(rhs.coeff(UnrollingIndex, col)), res);+ res = pmadd(lhs.template packet<LoadMode>(row, UnrollingIndex-1), pset1<Packet>(rhs.coeff(UnrollingIndex-1, col)), res); } }; template<typename Lhs, typename Rhs, typename Packet, int LoadMode>-struct product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode>+struct product_packet_impl<RowMajor, 1, Lhs, Rhs, Packet, LoadMode> { typedef typename Lhs::Index Index; static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res)@@ -397,7 +416,7 @@ }; template<typename Lhs, typename Rhs, typename Packet, int LoadMode>-struct product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode>+struct product_packet_impl<ColMajor, 1, Lhs, Rhs, Packet, LoadMode> { typedef typename Lhs::Index Index; static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet &res)@@ -407,15 +426,34 @@ }; template<typename Lhs, typename Rhs, typename Packet, int LoadMode>+struct product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode>+{+ typedef typename Lhs::Index Index;+ static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Packet &res)+ {+ res = pset1<Packet>(0);+ }+};++template<typename Lhs, typename Rhs, typename Packet, int LoadMode>+struct product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode>+{+ typedef typename Lhs::Index Index;+ static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Packet &res)+ {+ res = pset1<Packet>(0);+ }+};++template<typename Lhs, typename Rhs, typename Packet, int LoadMode> struct product_packet_impl<RowMajor, Dynamic, Lhs, Rhs, Packet, LoadMode> { typedef typename Lhs::Index Index; static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res) {- eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix");- res = pmul(pset1<Packet>(lhs.coeff(row, 0)),rhs.template packet<LoadMode>(0, col));- for(Index i = 1; i < lhs.cols(); ++i)- res = pmadd(pset1<Packet>(lhs.coeff(row, i)), rhs.template packet<LoadMode>(i, col), res);+ res = pset1<Packet>(0);+ for(Index i = 0; i < lhs.cols(); ++i)+ res = pmadd(pset1<Packet>(lhs.coeff(row, i)), rhs.template packet<LoadMode>(i, col), res); } }; @@ -425,10 +463,9 @@ typedef typename Lhs::Index Index; static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Packet& res) {- eigen_assert(lhs.cols()>0 && "you are using a non initialized matrix");- res = pmul(lhs.template packet<LoadMode>(row, 0), pset1<Packet>(rhs.coeff(0, col)));- for(Index i = 1; i < lhs.cols(); ++i)- res = pmadd(lhs.template packet<LoadMode>(row, i), pset1<Packet>(rhs.coeff(i, col)), res);+ res = pset1<Packet>(0);+ for(Index i = 0; i < lhs.cols(); ++i)+ res = pmadd(lhs.template packet<LoadMode>(row, i), pset1<Packet>(rhs.coeff(i, col)), res); } };
eigen3/Eigen/src/Core/products/Parallelizer.h view
@@ -125,19 +125,22 @@ if(transpose) std::swap(rows,cols); - Index blockCols = (cols / threads) & ~Index(0x3);- Index blockRows = (rows / threads) & ~Index(0x7);- GemmParallelInfo<Index>* info = new GemmParallelInfo<Index>[threads]; - #pragma omp parallel for schedule(static,1) num_threads(threads)- for(Index i=0; i<threads; ++i)+ #pragma omp parallel num_threads(threads) {+ Index i = omp_get_thread_num();+ // Note that the actual number of threads might be lower than the number of request ones.+ Index actual_threads = omp_get_num_threads();+ + Index blockCols = (cols / actual_threads) & ~Index(0x3);+ Index blockRows = (rows / actual_threads) & ~Index(0x7);+ Index r0 = i*blockRows;- Index actualBlockRows = (i+1==threads) ? rows-r0 : blockRows;+ Index actualBlockRows = (i+1==actual_threads) ? rows-r0 : blockRows; Index c0 = i*blockCols;- Index actualBlockCols = (i+1==threads) ? cols-c0 : blockCols;+ Index actualBlockCols = (i+1==actual_threads) ? cols-c0 : blockCols; info[i].rhs_start = c0; info[i].rhs_length = actualBlockCols;
eigen3/Eigen/src/Core/util/Constants.h view
@@ -433,6 +433,19 @@ /** The type used to identify an array expression */ struct ArrayXpr {}; +namespace internal {+ /** \internal+ * Constants for comparison functors+ */+ enum ComparisonName {+ cmp_EQ = 0,+ cmp_LT = 1,+ cmp_LE = 2,+ cmp_UNORD = 3,+ cmp_NEQ = 4+ };+}+ } // end namespace Eigen #endif // EIGEN_CONSTANTS_H
eigen3/Eigen/src/Core/util/Macros.h view
@@ -13,7 +13,7 @@ #define EIGEN_WORLD_VERSION 3 #define EIGEN_MAJOR_VERSION 2-#define EIGEN_MINOR_VERSION 4+#define EIGEN_MINOR_VERSION 5 #define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \ (EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \@@ -278,6 +278,7 @@ #error Please tell me what is the equivalent of __attribute__((aligned(n))) for your compiler #endif +#define EIGEN_ALIGN8 EIGEN_ALIGN_TO_BOUNDARY(8) #define EIGEN_ALIGN16 EIGEN_ALIGN_TO_BOUNDARY(16) #if EIGEN_ALIGN_STATICALLY@@ -313,7 +314,7 @@ // just an empty macro ! #define EIGEN_EMPTY -#if defined(_MSC_VER) && (_MSC_VER < 1900) && (!defined(__INTEL_COMPILER))+#if defined(_MSC_VER) && (_MSC_VER < 1800) && (!defined(__INTEL_COMPILER)) #define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \ using Base::operator =; #elif defined(__clang__) // workaround clang bug (see http://forum.kde.org/viewtopic.php?f=74&t=102653)@@ -332,8 +333,11 @@ } #endif -#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) \- EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived)+/** \internal+ * \brief Macro to manually inherit assignment operators.+ * This is necessary, because the implicitly defined assignment operator gets deleted when a custom operator= is defined.+ */+#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) /** * Just a side note. Commenting within defines works only by documenting
eigen3/Eigen/src/Core/util/Memory.h view
@@ -523,7 +523,7 @@ // you can overwrite Eigen's default behavior regarding alloca by defining EIGEN_ALLOCA // to the appropriate stack allocation function #ifndef EIGEN_ALLOCA- #if (defined __linux__)+ #if (defined __linux__) || (defined __APPLE__) || (defined alloca) #define EIGEN_ALLOCA alloca #elif defined(_MSC_VER) #define EIGEN_ALLOCA _alloca
eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h view
@@ -234,6 +234,12 @@ } protected:+ + static void check_template_parameters()+ {+ EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);+ }+ EigenvectorType m_eivec; EigenvalueType m_eivalues; ComplexSchur<MatrixType> m_schur;@@ -251,6 +257,8 @@ ComplexEigenSolver<MatrixType>& ComplexEigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvectors) {+ check_template_parameters();+ // this code is inspired from Jampack eigen_assert(matrix.cols() == matrix.rows());
eigen3/Eigen/src/Eigenvalues/EigenSolver.h view
@@ -298,6 +298,13 @@ void doComputeEigenvectors(); protected:+ + static void check_template_parameters()+ {+ EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);+ EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsComplex, NUMERIC_TYPE_MUST_BE_REAL);+ }+ MatrixType m_eivec; EigenvalueType m_eivalues; bool m_isInitialized;@@ -364,6 +371,8 @@ EigenSolver<MatrixType>& EigenSolver<MatrixType>::compute(const MatrixType& matrix, bool computeEigenvectors) {+ check_template_parameters();+ using std::sqrt; using std::abs; eigen_assert(matrix.cols() == matrix.rows());
eigen3/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h view
@@ -263,6 +263,13 @@ } protected:+ + static void check_template_parameters()+ {+ EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);+ EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsComplex, NUMERIC_TYPE_MUST_BE_REAL);+ }+ MatrixType m_eivec; ComplexVectorType m_alphas; VectorType m_betas;@@ -290,6 +297,8 @@ GeneralizedEigenSolver<MatrixType>& GeneralizedEigenSolver<MatrixType>::compute(const MatrixType& A, const MatrixType& B, bool computeEigenvectors) {+ check_template_parameters();+ using std::sqrt; using std::abs; eigen_assert(A.cols() == A.rows() && B.cols() == A.rows() && B.cols() == B.rows());
eigen3/Eigen/src/Eigenvalues/RealQZ.h view
@@ -240,10 +240,10 @@ m_S.coeffRef(i,j) = Scalar(0.0); m_S.rightCols(dim-j-1).applyOnTheLeft(i-1,i,G.adjoint()); m_T.rightCols(dim-i+1).applyOnTheLeft(i-1,i,G.adjoint());+ // update Q+ if (m_computeQZ)+ m_Q.applyOnTheRight(i-1,i,G); }- // update Q- if (m_computeQZ)- m_Q.applyOnTheRight(i-1,i,G); // kill T(i,i-1) if(m_T.coeff(i,i-1)!=Scalar(0)) {@@ -251,10 +251,10 @@ m_T.coeffRef(i,i-1) = Scalar(0.0); m_S.applyOnTheRight(i,i-1,G); m_T.topRows(i).applyOnTheRight(i,i-1,G);+ // update Z+ if (m_computeQZ)+ m_Z.applyOnTheLeft(i,i-1,G.adjoint()); }- // update Z- if (m_computeQZ)- m_Z.applyOnTheLeft(i,i-1,G.adjoint()); } } }
eigen3/Eigen/src/Eigenvalues/RealSchur.h view
@@ -234,7 +234,7 @@ typedef Matrix<Scalar,3,1> Vector3s; Scalar computeNormOfT();- Index findSmallSubdiagEntry(Index iu, const Scalar& norm);+ Index findSmallSubdiagEntry(Index iu); void splitOffTwoRows(Index iu, bool computeU, const Scalar& exshift); void computeShift(Index iu, Index iter, Scalar& exshift, Vector3s& shiftInfo); void initFrancisQRStep(Index il, Index iu, const Vector3s& shiftInfo, Index& im, Vector3s& firstHouseholderVector);@@ -286,7 +286,7 @@ { while (iu >= 0) {- Index il = findSmallSubdiagEntry(iu, norm);+ Index il = findSmallSubdiagEntry(iu); // Check for convergence if (il == iu) // One root found@@ -343,16 +343,14 @@ /** \internal Look for single small sub-diagonal element and returns its index */ template<typename MatrixType>-inline typename MatrixType::Index RealSchur<MatrixType>::findSmallSubdiagEntry(Index iu, const Scalar& norm)+inline typename MatrixType::Index RealSchur<MatrixType>::findSmallSubdiagEntry(Index iu) { using std::abs; Index res = iu; while (res > 0) { Scalar s = abs(m_matT.coeff(res-1,res-1)) + abs(m_matT.coeff(res,res));- if (s == 0.0)- s = norm;- if (abs(m_matT.coeff(res,res-1)) < NumTraits<Scalar>::epsilon() * s)+ if (abs(m_matT.coeff(res,res-1)) <= NumTraits<Scalar>::epsilon() * s) break; res--; }@@ -457,9 +455,7 @@ const Scalar lhs = m_matT.coeff(im,im-1) * (abs(v.coeff(1)) + abs(v.coeff(2))); const Scalar rhs = v.coeff(0) * (abs(m_matT.coeff(im-1,im-1)) + abs(Tmm) + abs(m_matT.coeff(im+1,im+1))); if (abs(lhs) < NumTraits<Scalar>::epsilon() * rhs)- { break;- } } }
eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h view
@@ -351,6 +351,11 @@ #endif // EIGEN2_SUPPORT protected:+ static void check_template_parameters()+ {+ EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);+ }+ MatrixType m_eivec; RealVectorType m_eivalues; typename TridiagonalizationType::SubDiagonalType m_subdiag;@@ -384,6 +389,8 @@ SelfAdjointEigenSolver<MatrixType>& SelfAdjointEigenSolver<MatrixType> ::compute(const MatrixType& matrix, int options) {+ check_template_parameters();+ using std::abs; eigen_assert(matrix.cols() == matrix.rows()); eigen_assert((options&~(EigVecMask|GenEigMask))==0@@ -490,7 +497,12 @@ typedef typename SolverType::MatrixType MatrixType; typedef typename SolverType::RealVectorType VectorType; typedef typename SolverType::Scalar Scalar;+ typedef typename MatrixType::Index Index; + /** \internal+ * Computes the roots of the characteristic polynomial of \a m.+ * For numerical stability m.trace() should be near zero and to avoid over- or underflow m should be normalized.+ */ static inline void computeRoots(const MatrixType& m, VectorType& roots) { using std::sqrt;@@ -510,39 +522,48 @@ // Construct the parameters used in classifying the roots of the equation // and in solving the equation for the roots in closed form. Scalar c2_over_3 = c2*s_inv3;- Scalar a_over_3 = (c1 - c2*c2_over_3)*s_inv3;- if (a_over_3 > Scalar(0))+ Scalar a_over_3 = (c2*c2_over_3 - c1)*s_inv3;+ if(a_over_3<Scalar(0)) a_over_3 = Scalar(0); Scalar half_b = Scalar(0.5)*(c0 + c2_over_3*(Scalar(2)*c2_over_3*c2_over_3 - c1)); - Scalar q = half_b*half_b + a_over_3*a_over_3*a_over_3;- if (q > Scalar(0))+ Scalar q = a_over_3*a_over_3*a_over_3 - half_b*half_b;+ if(q<Scalar(0)) q = Scalar(0); // Compute the eigenvalues by solving for the roots of the polynomial.- Scalar rho = sqrt(-a_over_3);- Scalar theta = atan2(sqrt(-q),half_b)*s_inv3;+ Scalar rho = sqrt(a_over_3);+ Scalar theta = atan2(sqrt(q),half_b)*s_inv3; // since sqrt(q) > 0, atan2 is in [0, pi] and theta is in [0, pi/3] Scalar cos_theta = cos(theta); Scalar sin_theta = sin(theta);- roots(0) = c2_over_3 + Scalar(2)*rho*cos_theta;- roots(1) = c2_over_3 - rho*(cos_theta + s_sqrt3*sin_theta);- roots(2) = c2_over_3 - rho*(cos_theta - s_sqrt3*sin_theta);+ // roots are already sorted, since cos is monotonically decreasing on [0, pi]+ roots(0) = c2_over_3 - rho*(cos_theta + s_sqrt3*sin_theta); // == 2*rho*cos(theta+2pi/3)+ roots(1) = c2_over_3 - rho*(cos_theta - s_sqrt3*sin_theta); // == 2*rho*cos(theta+ pi/3)+ roots(2) = c2_over_3 + Scalar(2)*rho*cos_theta;+ } - // Sort in increasing order.- if (roots(0) >= roots(1))- std::swap(roots(0),roots(1));- if (roots(1) >= roots(2))- {- std::swap(roots(1),roots(2));- if (roots(0) >= roots(1))- std::swap(roots(0),roots(1));- }+ static inline bool extract_kernel(MatrixType& mat, Ref<VectorType> res, Ref<VectorType> representative)+ {+ using std::abs;+ Index i0;+ // Find non-zero column i0 (by construction, there must exist a non zero coefficient on the diagonal):+ mat.diagonal().cwiseAbs().maxCoeff(&i0);+ // mat.col(i0) is a good candidate for an orthogonal vector to the current eigenvector,+ // so let's save it:+ representative = mat.col(i0);+ Scalar n0, n1;+ VectorType c0, c1;+ n0 = (c0 = representative.cross(mat.col((i0+1)%3))).squaredNorm();+ n1 = (c1 = representative.cross(mat.col((i0+2)%3))).squaredNorm();+ if(n0>n1) res = c0/std::sqrt(n0);+ else res = c1/std::sqrt(n1);++ return true; }- + static inline void run(SolverType& solver, const MatrixType& mat, int options) {- using std::sqrt; eigen_assert(mat.cols() == 3 && mat.cols() == mat.rows()); eigen_assert((options&~(EigVecMask|GenEigMask))==0 && (options&EigVecMask)!=EigVecMask@@ -552,116 +573,72 @@ MatrixType& eivecs = solver.m_eivec; VectorType& eivals = solver.m_eivalues; - // map the matrix coefficients to [-1:1] to avoid over- and underflow.- Scalar scale = mat.cwiseAbs().maxCoeff();- MatrixType scaledMat = mat / scale;+ // Shift the matrix to the mean eigenvalue and map the matrix coefficients to [-1:1] to avoid over- and underflow.+ Scalar shift = mat.trace() / Scalar(3);+ // TODO Avoid this copy. Currently it is necessary to suppress bogus values when determining maxCoeff and for computing the eigenvectors later+ MatrixType scaledMat = mat.template selfadjointView<Lower>();+ scaledMat.diagonal().array() -= shift;+ Scalar scale = scaledMat.cwiseAbs().maxCoeff();+ if(scale > 0) scaledMat /= scale; // TODO for scale==0 we could save the remaining operations // compute the eigenvalues computeRoots(scaledMat,eivals); - // compute the eigen vectors+ // compute the eigenvectors if(computeEigenvectors) {- Scalar safeNorm2 = Eigen::NumTraits<Scalar>::epsilon(); if((eivals(2)-eivals(0))<=Eigen::NumTraits<Scalar>::epsilon()) {+ // All three eigenvalues are numerically the same eivecs.setIdentity(); } else {- scaledMat = scaledMat.template selfadjointView<Lower>(); MatrixType tmp; tmp = scaledMat; + // Compute the eigenvector of the most distinct eigenvalue Scalar d0 = eivals(2) - eivals(1); Scalar d1 = eivals(1) - eivals(0);- int k = d0 > d1 ? 2 : 0;- d0 = d0 > d1 ? d0 : d1;-- tmp.diagonal().array () -= eivals(k);- VectorType cross;- Scalar n;- n = (cross = tmp.row(0).cross(tmp.row(1))).squaredNorm();-- if(n>safeNorm2)+ Index k(0), l(2);+ if(d0 > d1) {- eivecs.col(k) = cross / sqrt(n);+ std::swap(k,l);+ d0 = d1; }- else- {- n = (cross = tmp.row(0).cross(tmp.row(2))).squaredNorm(); - if(n>safeNorm2)- {- eivecs.col(k) = cross / sqrt(n);- }- else- {- n = (cross = tmp.row(1).cross(tmp.row(2))).squaredNorm();-- if(n>safeNorm2)- {- eivecs.col(k) = cross / sqrt(n);- }- else- {- // the input matrix and/or the eigenvaues probably contains some inf/NaN,- // => exit- // scale back to the original size.- eivals *= scale;-- solver.m_info = NumericalIssue;- solver.m_isInitialized = true;- solver.m_eigenvectorsOk = computeEigenvectors;- return;- }- }+ // Compute the eigenvector of index k+ {+ tmp.diagonal().array () -= eivals(k);+ // By construction, 'tmp' is of rank 2, and its kernel corresponds to the respective eigenvector.+ extract_kernel(tmp, eivecs.col(k), eivecs.col(l)); } - tmp = scaledMat;- tmp.diagonal().array() -= eivals(1);-- if(d0<=Eigen::NumTraits<Scalar>::epsilon())+ // Compute eigenvector of index l+ if(d0<=2*Eigen::NumTraits<Scalar>::epsilon()*d1) {- eivecs.col(1) = eivecs.col(k).unitOrthogonal();+ // If d0 is too small, then the two other eigenvalues are numerically the same,+ // and thus we only have to ortho-normalize the near orthogonal vector we saved above.+ eivecs.col(l) -= eivecs.col(k).dot(eivecs.col(l))*eivecs.col(l);+ eivecs.col(l).normalize(); } else {- n = (cross = eivecs.col(k).cross(tmp.row(0))).squaredNorm();- if(n>safeNorm2)- {- eivecs.col(1) = cross / sqrt(n);- }- else- {- n = (cross = eivecs.col(k).cross(tmp.row(1))).squaredNorm();- if(n>safeNorm2)- eivecs.col(1) = cross / sqrt(n);- else- {- n = (cross = eivecs.col(k).cross(tmp.row(2))).squaredNorm();- if(n>safeNorm2)- eivecs.col(1) = cross / sqrt(n);- else- {- // we should never reach this point,- // if so the last two eigenvalues are likely to be very close to each other- eivecs.col(1) = eivecs.col(k).unitOrthogonal();- }- }- }+ tmp = scaledMat;+ tmp.diagonal().array () -= eivals(l); - // make sure that eivecs[1] is orthogonal to eivecs[2]- // FIXME: this step should not be needed- Scalar d = eivecs.col(1).dot(eivecs.col(k));- eivecs.col(1) = (eivecs.col(1) - d * eivecs.col(k)).normalized();+ VectorType dummy;+ extract_kernel(tmp, eivecs.col(l), dummy); } - eivecs.col(k==2 ? 0 : 2) = eivecs.col(k).cross(eivecs.col(1)).normalized();+ // Compute last eigenvector from the other two+ eivecs.col(1) = eivecs.col(2).cross(eivecs.col(0)).normalized(); } }+ // Rescale back to the original size. eivals *= scale;+ eivals.array() += shift; solver.m_info = Success; solver.m_isInitialized = true;@@ -679,7 +656,7 @@ static inline void computeRoots(const MatrixType& m, VectorType& roots) { using std::sqrt;- const Scalar t0 = Scalar(0.5) * sqrt( numext::abs2(m(0,0)-m(1,1)) + Scalar(4)*m(1,0)*m(1,0));+ const Scalar t0 = Scalar(0.5) * sqrt( numext::abs2(m(0,0)-m(1,1)) + Scalar(4)*numext::abs2(m(1,0))); const Scalar t1 = Scalar(0.5) * (m(0,0) + m(1,1)); roots(0) = t1 - t0; roots(1) = t1 + t0;@@ -688,6 +665,8 @@ static inline void run(SolverType& solver, const MatrixType& mat, int options) { using std::sqrt;+ using std::abs;+ eigen_assert(mat.cols() == 2 && mat.cols() == mat.rows()); eigen_assert((options&~(EigVecMask|GenEigMask))==0 && (options&EigVecMask)!=EigVecMask@@ -708,22 +687,29 @@ // compute the eigen vectors if(computeEigenvectors) {- scaledMat.diagonal().array () -= eivals(1);- Scalar a2 = numext::abs2(scaledMat(0,0));- Scalar c2 = numext::abs2(scaledMat(1,1));- Scalar b2 = numext::abs2(scaledMat(1,0));- if(a2>c2)+ if((eivals(1)-eivals(0))<=abs(eivals(1))*Eigen::NumTraits<Scalar>::epsilon()) {- eivecs.col(1) << -scaledMat(1,0), scaledMat(0,0);- eivecs.col(1) /= sqrt(a2+b2);+ eivecs.setIdentity(); } else {- eivecs.col(1) << -scaledMat(1,1), scaledMat(1,0);- eivecs.col(1) /= sqrt(c2+b2);- }+ scaledMat.diagonal().array () -= eivals(1);+ Scalar a2 = numext::abs2(scaledMat(0,0));+ Scalar c2 = numext::abs2(scaledMat(1,1));+ Scalar b2 = numext::abs2(scaledMat(1,0));+ if(a2>c2)+ {+ eivecs.col(1) << -scaledMat(1,0), scaledMat(0,0);+ eivecs.col(1) /= sqrt(a2+b2);+ }+ else+ {+ eivecs.col(1) << -scaledMat(1,1), scaledMat(1,0);+ eivecs.col(1) /= sqrt(c2+b2);+ } - eivecs.col(0) << eivecs.col(1).unitOrthogonal();+ eivecs.col(0) << eivecs.col(1).unitOrthogonal();+ } } // Rescale back to the original size.
eigen3/Eigen/src/Geometry/AlignedBox.h view
@@ -19,10 +19,12 @@ * * \brief An axis aligned box *- * \param _Scalar the type of the scalar coefficients- * \param _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic.+ * \tparam _Scalar the type of the scalar coefficients+ * \tparam _AmbientDim the dimension of the ambient space, can be a compile time value or Dynamic. * * This class represents an axis aligned box as a pair of the minimal and maximal corners.+ * \warning The result of most methods is undefined when applied to an empty box. You can check for empty boxes using isEmpty().+ * \sa alignedboxtypedefs */ template <typename _Scalar, int _AmbientDim> class AlignedBox@@ -40,18 +42,21 @@ /** Define constants to name the corners of a 1D, 2D or 3D axis aligned bounding box */ enum CornerType {- /** 1D names */+ /** 1D names @{ */ Min=0, Max=1,+ /** @} */ - /** Added names for 2D */+ /** Identifier for 2D corner @{ */ BottomLeft=0, BottomRight=1, TopLeft=2, TopRight=3,+ /** @} */ - /** Added names for 3D */+ /** Identifier for 3D corner @{ */ BottomLeftFloor=0, BottomRightFloor=1, TopLeftFloor=2, TopRightFloor=3, BottomLeftCeil=4, BottomRightCeil=5, TopLeftCeil=6, TopRightCeil=7+ /** @} */ }; @@ -63,34 +68,33 @@ inline explicit AlignedBox(Index _dim) : m_min(_dim), m_max(_dim) { setEmpty(); } - /** Constructs a box with extremities \a _min and \a _max. */+ /** Constructs a box with extremities \a _min and \a _max.+ * \warning If either component of \a _min is larger than the same component of \a _max, the constructed box is empty. */ template<typename OtherVectorType1, typename OtherVectorType2> inline AlignedBox(const OtherVectorType1& _min, const OtherVectorType2& _max) : m_min(_min), m_max(_max) {} /** Constructs a box containing a single point \a p. */ template<typename Derived>- inline explicit AlignedBox(const MatrixBase<Derived>& a_p)- {- typename internal::nested<Derived,2>::type p(a_p.derived());- m_min = p;- m_max = p;- }+ inline explicit AlignedBox(const MatrixBase<Derived>& p) : m_min(p), m_max(m_min)+ { } ~AlignedBox() {} /** \returns the dimension in which the box holds */ inline Index dim() const { return AmbientDimAtCompileTime==Dynamic ? m_min.size() : Index(AmbientDimAtCompileTime); } - /** \deprecated use isEmpty */+ /** \deprecated use isEmpty() */ inline bool isNull() const { return isEmpty(); } - /** \deprecated use setEmpty */+ /** \deprecated use setEmpty() */ inline void setNull() { setEmpty(); } - /** \returns true if the box is empty. */+ /** \returns true if the box is empty.+ * \sa setEmpty */ inline bool isEmpty() const { return (m_min.array() > m_max.array()).any(); } - /** Makes \c *this an empty box. */+ /** Makes \c *this an empty box.+ * \sa isEmpty */ inline void setEmpty() { m_min.setConstant( ScalarTraits::highest() );@@ -175,27 +179,34 @@ /** \returns true if the point \a p is inside the box \c *this. */ template<typename Derived>- inline bool contains(const MatrixBase<Derived>& a_p) const+ inline bool contains(const MatrixBase<Derived>& p) const {- typename internal::nested<Derived,2>::type p(a_p.derived());- return (m_min.array()<=p.array()).all() && (p.array()<=m_max.array()).all();+ typename internal::nested<Derived,2>::type p_n(p.derived());+ return (m_min.array()<=p_n.array()).all() && (p_n.array()<=m_max.array()).all(); } /** \returns true if the box \a b is entirely inside the box \c *this. */ inline bool contains(const AlignedBox& b) const { return (m_min.array()<=(b.min)().array()).all() && ((b.max)().array()<=m_max.array()).all(); } - /** Extends \c *this such that it contains the point \a p and returns a reference to \c *this. */+ /** \returns true if the box \a b is intersecting the box \c *this.+ * \sa intersection, clamp */+ inline bool intersects(const AlignedBox& b) const+ { return (m_min.array()<=(b.max)().array()).all() && ((b.min)().array()<=m_max.array()).all(); }++ /** Extends \c *this such that it contains the point \a p and returns a reference to \c *this.+ * \sa extend(const AlignedBox&) */ template<typename Derived>- inline AlignedBox& extend(const MatrixBase<Derived>& a_p)+ inline AlignedBox& extend(const MatrixBase<Derived>& p) {- typename internal::nested<Derived,2>::type p(a_p.derived());- m_min = m_min.cwiseMin(p);- m_max = m_max.cwiseMax(p);+ typename internal::nested<Derived,2>::type p_n(p.derived());+ m_min = m_min.cwiseMin(p_n);+ m_max = m_max.cwiseMax(p_n); return *this; } - /** Extends \c *this such that it contains the box \a b and returns a reference to \c *this. */+ /** Extends \c *this such that it contains the box \a b and returns a reference to \c *this.+ * \sa merged, extend(const MatrixBase&) */ inline AlignedBox& extend(const AlignedBox& b) { m_min = m_min.cwiseMin(b.m_min);@@ -203,7 +214,9 @@ return *this; } - /** Clamps \c *this by the box \a b and returns a reference to \c *this. */+ /** Clamps \c *this by the box \a b and returns a reference to \c *this.+ * \note If the boxes don't intersect, the resulting box is empty.+ * \sa intersection(), intersects() */ inline AlignedBox& clamp(const AlignedBox& b) { m_min = m_min.cwiseMax(b.m_min);@@ -211,11 +224,15 @@ return *this; } - /** Returns an AlignedBox that is the intersection of \a b and \c *this */+ /** Returns an AlignedBox that is the intersection of \a b and \c *this+ * \note If the boxes don't intersect, the resulting box is empty.+ * \sa intersects(), clamp, contains() */ inline AlignedBox intersection(const AlignedBox& b) const {return AlignedBox(m_min.cwiseMax(b.m_min), m_max.cwiseMin(b.m_max)); } - /** Returns an AlignedBox that is the union of \a b and \c *this */+ /** Returns an AlignedBox that is the union of \a b and \c *this.+ * \note Merging with an empty box may result in a box bigger than \c *this. + * \sa extend(const AlignedBox&) */ inline AlignedBox merged(const AlignedBox& b) const { return AlignedBox(m_min.cwiseMin(b.m_min), m_max.cwiseMax(b.m_max)); } @@ -231,20 +248,20 @@ /** \returns the squared distance between the point \a p and the box \c *this, * and zero if \a p is inside the box.- * \sa exteriorDistance()+ * \sa exteriorDistance(const MatrixBase&), squaredExteriorDistance(const AlignedBox&) */ template<typename Derived>- inline Scalar squaredExteriorDistance(const MatrixBase<Derived>& a_p) const;+ inline Scalar squaredExteriorDistance(const MatrixBase<Derived>& p) const; /** \returns the squared distance between the boxes \a b and \c *this, * and zero if the boxes intersect.- * \sa exteriorDistance()+ * \sa exteriorDistance(const AlignedBox&), squaredExteriorDistance(const MatrixBase&) */ inline Scalar squaredExteriorDistance(const AlignedBox& b) const; /** \returns the distance between the point \a p and the box \c *this, * and zero if \a p is inside the box.- * \sa squaredExteriorDistance()+ * \sa squaredExteriorDistance(const MatrixBase&), exteriorDistance(const AlignedBox&) */ template<typename Derived> inline NonInteger exteriorDistance(const MatrixBase<Derived>& p) const@@ -252,7 +269,7 @@ /** \returns the distance between the boxes \a b and \c *this, * and zero if the boxes intersect.- * \sa squaredExteriorDistance()+ * \sa squaredExteriorDistance(const AlignedBox&), exteriorDistance(const MatrixBase&) */ inline NonInteger exteriorDistance(const AlignedBox& b) const { using std::sqrt; return sqrt(NonInteger(squaredExteriorDistance(b))); }
eigen3/Eigen/src/Geometry/Homogeneous.h view
@@ -79,7 +79,7 @@ { if( (int(Direction)==Vertical && row==m_matrix.rows()) || (int(Direction)==Horizontal && col==m_matrix.cols()))- return 1;+ return Scalar(1); return m_matrix.coeff(row, col); }
eigen3/Eigen/src/Geometry/Quaternion.h view
@@ -161,7 +161,7 @@ { return coeffs().isApprox(other.coeffs(), prec); } /** return the result vector of \a v through the rotation*/- EIGEN_STRONG_INLINE Vector3 _transformVector(Vector3 v) const;+ EIGEN_STRONG_INLINE Vector3 _transformVector(const Vector3& v) const; /** \returns \c *this with scalar type casted to \a NewScalarType *@@ -231,7 +231,7 @@ public: typedef _Scalar Scalar; - EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Quaternion)+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Quaternion) using Base::operator*=; typedef typename internal::traits<Quaternion>::Coefficients Coefficients;@@ -341,7 +341,7 @@ public: typedef _Scalar Scalar; typedef typename internal::traits<Map>::Coefficients Coefficients;- EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Map)+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map) using Base::operator*=; /** Constructs a Mapped Quaternion object from the pointer \a coeffs@@ -378,7 +378,7 @@ public: typedef _Scalar Scalar; typedef typename internal::traits<Map>::Coefficients Coefficients;- EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Map)+ EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Map) using Base::operator*=; /** Constructs a Mapped Quaternion object from the pointer \a coeffs@@ -461,7 +461,7 @@ */ template <class Derived> EIGEN_STRONG_INLINE typename QuaternionBase<Derived>::Vector3-QuaternionBase<Derived>::_transformVector(Vector3 v) const+QuaternionBase<Derived>::_transformVector(const Vector3& v) const { // Note that this algorithm comes from the optimization by hand // of the conversion to a Matrix followed by a Matrix/Vector product.@@ -637,7 +637,7 @@ { // FIXME should this function be called multiplicativeInverse and conjugate() be called inverse() or opposite() ?? Scalar n2 = this->squaredNorm();- if (n2 > 0)+ if (n2 > Scalar(0)) return Quaternion<Scalar>(conjugate().coeffs() / n2); else {@@ -667,12 +667,10 @@ inline typename internal::traits<Derived>::Scalar QuaternionBase<Derived>::angularDistance(const QuaternionBase<OtherDerived>& other) const {- using std::acos;+ using std::atan2; using std::abs;- Scalar d = abs(this->dot(other));- if (d>=Scalar(1))- return Scalar(0);- return Scalar(2) * acos(d);+ Quaternion<Scalar> d = (*this) * other.conjugate();+ return Scalar(2) * atan2( d.vec().norm(), abs(d.w()) ); } @@ -712,7 +710,7 @@ scale0 = sin( ( Scalar(1) - t ) * theta) / sinTheta; scale1 = sin( ( t * theta) ) / sinTheta; }- if(d<0) scale1 = -scale1;+ if(d<Scalar(0)) scale1 = -scale1; return Quaternion<Scalar>(scale0 * coeffs() + scale1 * other.coeffs()); }
eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h view
@@ -151,20 +151,7 @@ * \endcode * * By default the iterations start with x=0 as an initial guess of the solution.- * One can control the start using the solveWithGuess() method. Here is a step by- * step execution example starting with a random guess and printing the evolution- * of the estimated error:- * * \code- * x = VectorXd::Random(n);- * solver.setMaxIterations(1);- * int i = 0;- * do {- * x = solver.solveWithGuess(b,x);- * std::cout << i << " : " << solver.error() << std::endl;- * ++i;- * } while (solver.info()!=Success && i<100);- * \endcode- * Note that such a step by step excution is slightly slower.+ * One can control the start using the solveWithGuess() method. * * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner */
eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h view
@@ -112,9 +112,9 @@ * This class allows to solve for A.x = b sparse linear problems using a conjugate gradient algorithm. * The sparse matrix A must be selfadjoint. The vectors x and b can be either dense or sparse. *- * \tparam _MatrixType the type of the sparse matrix A, can be a dense or a sparse matrix.- * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower- * or Upper. Default is Lower.+ * \tparam _MatrixType the type of the matrix A, can be a dense or a sparse matrix.+ * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower,+ * Upper, or Lower|Upper in which the full matrix entries will be considered. Default is Lower. * \tparam _Preconditioner the type of the preconditioner. Default is DiagonalPreconditioner * * The maximal number of iterations and tolerance value can be controlled via the setMaxIterations()@@ -137,20 +137,7 @@ * \endcode * * By default the iterations start with x=0 as an initial guess of the solution.- * One can control the start using the solveWithGuess() method. Here is a step by- * step execution example starting with a random guess and printing the evolution- * of the estimated error:- * * \code- * x = VectorXd::Random(n);- * cg.setMaxIterations(1);- * int i = 0;- * do {- * x = cg.solveWithGuess(b,x);- * std::cout << i << " : " << cg.error() << std::endl;- * ++i;- * } while (cg.info()!=Success && i<100);- * \endcode- * Note that such a step by step excution is slightly slower.+ * One can control the start using the solveWithGuess() method. * * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner */@@ -213,6 +200,10 @@ template<typename Rhs,typename Dest> void _solveWithGuess(const Rhs& b, Dest& x) const {+ typedef typename internal::conditional<UpLo==(Lower|Upper),+ const MatrixType&,+ SparseSelfAdjointView<const MatrixType, UpLo>+ >::type MatrixWrapperType; m_iterations = Base::maxIterations(); m_error = Base::m_tolerance; @@ -222,8 +213,7 @@ m_error = Base::m_tolerance; typename Dest::ColXpr xj(x,j);- internal::conjugate_gradient(mp_matrix->template selfadjointView<UpLo>(), b.col(j), xj,- Base::m_preconditioner, m_iterations, m_error);+ internal::conjugate_gradient(MatrixWrapperType(*mp_matrix), b.col(j), xj, Base::m_preconditioner, m_iterations, m_error); } m_isInitialized = true;@@ -234,7 +224,7 @@ template<typename Rhs,typename Dest> void _solve(const Rhs& b, Dest& x) const {- x.setOnes();+ x.setZero(); _solveWithGuess(b,x); }
eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h view
@@ -150,7 +150,6 @@ { analyzePattern(amat); factorize(amat);- m_isInitialized = m_factorizationIsOk; return *this; } @@ -235,6 +234,8 @@ m_Pinv = m_P.inverse(); // ... and the inverse permutation m_analysisIsOk = true;+ m_factorizationIsOk = false;+ m_isInitialized = false; } template <typename Scalar>@@ -442,6 +443,7 @@ m_lu.makeCompressed(); m_factorizationIsOk = true;+ m_isInitialized = m_factorizationIsOk; m_info = Success; }
eigen3/Eigen/src/LU/FullPivLU.h view
@@ -374,6 +374,12 @@ inline Index cols() const { return m_lu.cols(); } protected:+ + static void check_template_parameters()+ {+ EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);+ }+ MatrixType m_lu; PermutationPType m_p; PermutationQType m_q;@@ -418,6 +424,8 @@ template<typename MatrixType> FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix) {+ check_template_parameters();+ // the permutations are stored as int indices, so just to be sure: eigen_assert(matrix.rows()<=NumTraits<int>::highest() && matrix.cols()<=NumTraits<int>::highest());
eigen3/Eigen/src/LU/PartialPivLU.h view
@@ -171,6 +171,12 @@ inline Index cols() const { return m_lu.cols(); } protected:+ + static void check_template_parameters()+ {+ EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);+ }+ MatrixType m_lu; PermutationType m_p; TranspositionType m_rowsTranspositions;@@ -386,6 +392,8 @@ template<typename MatrixType> PartialPivLU<MatrixType>& PartialPivLU<MatrixType>::compute(const MatrixType& matrix) {+ check_template_parameters();+ // the row permutation is stored as int indices, so just to be sure: eigen_assert(matrix.rows()<NumTraits<int>::highest());
eigen3/Eigen/src/OrderingMethods/Amd.h view
@@ -144,15 +144,23 @@ /* --- Initialize degree lists ------------------------------------------ */ for(i = 0; i < n; i++) {+ bool has_diag = false;+ for(p = Cp[i]; p<Cp[i+1]; ++p)+ if(Ci[p]==i)+ {+ has_diag = true;+ break;+ }+ d = degree[i];- if(d == 0) /* node i is empty */+ if(d == 1) /* node i is empty */ { elen[i] = -2; /* element i is dead */ nel++; Cp[i] = -1; /* i is a root of assembly tree */ w[i] = 0; }- else if(d > dense) /* node i is dense */+ else if(d > dense || !has_diag) /* node i is dense or has no structural diagonal element */ { nv[i] = 0; /* absorb i into element n */ elen[i] = -1; /* node i is dead */@@ -167,6 +175,10 @@ head[d] = i; } }+ + elen[n] = -2; /* n is a dead element */+ Cp[n] = -1; /* n is a root of assembly tree */+ w[n] = 0; /* n is a dead element */ while (nel < n) /* while (selecting pivots) do */ {
eigen3/Eigen/src/QR/ColPivHouseholderQR.h view
@@ -384,6 +384,12 @@ } protected:+ + static void check_template_parameters()+ {+ EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);+ }+ MatrixType m_qr; HCoeffsType m_hCoeffs; PermutationType m_colsPermutation;@@ -422,6 +428,8 @@ template<typename MatrixType> ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const MatrixType& matrix) {+ check_template_parameters();+ using std::abs; Index rows = matrix.rows(); Index cols = matrix.cols();@@ -463,20 +471,10 @@ // we store that back into our table: it can't hurt to correct our table. m_colSqNorms.coeffRef(biggest_col_index) = biggest_col_sq_norm; - // if the current biggest column is smaller than epsilon times the initial biggest column,- // terminate to avoid generating nan/inf values.- // Note that here, if we test instead for "biggest == 0", we get a failure every 1000 (or so)- // repetitions of the unit test, with the result of solve() filled with large values of the order- // of 1/(size*epsilon).- if(biggest_col_sq_norm < threshold_helper * RealScalar(rows-k))- {+ // Track the number of meaningful pivots but do not stop the decomposition to make+ // sure that the initial matrix is properly reproduced. See bug 941.+ if(m_nonzero_pivots==size && biggest_col_sq_norm < threshold_helper * RealScalar(rows-k)) m_nonzero_pivots = k;- m_hCoeffs.tail(size-k).setZero();- m_qr.bottomRightCorner(rows-k,cols-k)- .template triangularView<StrictlyLower>()- .setZero();- break;- } // apply the transposition to the columns m_colsTranspositions.coeffRef(k) = biggest_col_index;@@ -505,7 +503,7 @@ } m_colsPermutation.setIdentity(PermIndexType(cols));- for(PermIndexType k = 0; k < m_nonzero_pivots; ++k)+ for(PermIndexType k = 0; k < size/*m_nonzero_pivots*/; ++k) m_colsPermutation.applyTranspositionOnTheRight(k, PermIndexType(m_colsTranspositions.coeff(k))); m_det_pq = (number_of_transpositions%2) ? -1 : 1;@@ -555,13 +553,15 @@ } // end namespace internal -/** \returns the matrix Q as a sequence of householder transformations */+/** \returns the matrix Q as a sequence of householder transformations.+ * You can extract the meaningful part only by using:+ * \code qr.householderQ().setLength(qr.nonzeroPivots()) \endcode*/ template<typename MatrixType> typename ColPivHouseholderQR<MatrixType>::HouseholderSequenceType ColPivHouseholderQR<MatrixType> ::householderQ() const { eigen_assert(m_isInitialized && "ColPivHouseholderQR is not initialized.");- return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate()).setLength(m_nonzero_pivots);+ return HouseholderSequenceType(m_qr, m_hCoeffs.conjugate()); } /** \return the column-pivoting Householder QR decomposition of \c *this.
eigen3/Eigen/src/QR/FullPivHouseholderQR.h view
@@ -368,6 +368,12 @@ RealScalar maxPivot() const { return m_maxpivot; } protected:+ + static void check_template_parameters()+ {+ EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);+ }+ MatrixType m_qr; HCoeffsType m_hCoeffs; IntDiagSizeVectorType m_rows_transpositions;@@ -407,6 +413,8 @@ template<typename MatrixType> FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(const MatrixType& matrix) {+ check_template_parameters();+ using std::abs; Index rows = matrix.rows(); Index cols = matrix.cols();
eigen3/Eigen/src/QR/HouseholderQR.h view
@@ -189,6 +189,12 @@ const HCoeffsType& hCoeffs() const { return m_hCoeffs; } protected:+ + static void check_template_parameters()+ {+ EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);+ }+ MatrixType m_qr; HCoeffsType m_hCoeffs; RowVectorType m_temp;@@ -251,56 +257,62 @@ } /** \internal */-template<typename MatrixQR, typename HCoeffs>-void householder_qr_inplace_blocked(MatrixQR& mat, HCoeffs& hCoeffs,- typename MatrixQR::Index maxBlockSize=32,- typename MatrixQR::Scalar* tempData = 0)+template<typename MatrixQR, typename HCoeffs,+ typename MatrixQRScalar = typename MatrixQR::Scalar,+ bool InnerStrideIsOne = (MatrixQR::InnerStrideAtCompileTime == 1 && HCoeffs::InnerStrideAtCompileTime == 1)>+struct householder_qr_inplace_blocked {- typedef typename MatrixQR::Index Index;- typedef typename MatrixQR::Scalar Scalar;- typedef Block<MatrixQR,Dynamic,Dynamic> BlockType;+ // This is specialized for MKL-supported Scalar types in HouseholderQR_MKL.h+ static void run(MatrixQR& mat, HCoeffs& hCoeffs,+ typename MatrixQR::Index maxBlockSize=32,+ typename MatrixQR::Scalar* tempData = 0)+ {+ typedef typename MatrixQR::Index Index;+ typedef typename MatrixQR::Scalar Scalar;+ typedef Block<MatrixQR,Dynamic,Dynamic> BlockType; - Index rows = mat.rows();- Index cols = mat.cols();- Index size = (std::min)(rows, cols);+ Index rows = mat.rows();+ Index cols = mat.cols();+ Index size = (std::min)(rows, cols); - typedef Matrix<Scalar,Dynamic,1,ColMajor,MatrixQR::MaxColsAtCompileTime,1> TempType;- TempType tempVector;- if(tempData==0)- {- tempVector.resize(cols);- tempData = tempVector.data();- }+ typedef Matrix<Scalar,Dynamic,1,ColMajor,MatrixQR::MaxColsAtCompileTime,1> TempType;+ TempType tempVector;+ if(tempData==0)+ {+ tempVector.resize(cols);+ tempData = tempVector.data();+ } - Index blockSize = (std::min)(maxBlockSize,size);+ Index blockSize = (std::min)(maxBlockSize,size); - Index k = 0;- for (k = 0; k < size; k += blockSize)- {- Index bs = (std::min)(size-k,blockSize); // actual size of the block- Index tcols = cols - k - bs; // trailing columns- Index brows = rows-k; // rows of the block+ Index k = 0;+ for (k = 0; k < size; k += blockSize)+ {+ Index bs = (std::min)(size-k,blockSize); // actual size of the block+ Index tcols = cols - k - bs; // trailing columns+ Index brows = rows-k; // rows of the block - // partition the matrix:- // A00 | A01 | A02- // mat = A10 | A11 | A12- // A20 | A21 | A22- // and performs the qr dec of [A11^T A12^T]^T- // and update [A21^T A22^T]^T using level 3 operations.- // Finally, the algorithm continue on A22+ // partition the matrix:+ // A00 | A01 | A02+ // mat = A10 | A11 | A12+ // A20 | A21 | A22+ // and performs the qr dec of [A11^T A12^T]^T+ // and update [A21^T A22^T]^T using level 3 operations.+ // Finally, the algorithm continue on A22 - BlockType A11_21 = mat.block(k,k,brows,bs);- Block<HCoeffs,Dynamic,1> hCoeffsSegment = hCoeffs.segment(k,bs);+ BlockType A11_21 = mat.block(k,k,brows,bs);+ Block<HCoeffs,Dynamic,1> hCoeffsSegment = hCoeffs.segment(k,bs); - householder_qr_inplace_unblocked(A11_21, hCoeffsSegment, tempData);+ householder_qr_inplace_unblocked(A11_21, hCoeffsSegment, tempData); - if(tcols)- {- BlockType A21_22 = mat.block(k,k+bs,brows,tcols);- apply_block_householder_on_the_left(A21_22,A11_21,hCoeffsSegment.adjoint());+ if(tcols)+ {+ BlockType A21_22 = mat.block(k,k+bs,brows,tcols);+ apply_block_householder_on_the_left(A21_22,A11_21,hCoeffsSegment.adjoint());+ } } }-}+}; template<typename _MatrixType, typename Rhs> struct solve_retval<HouseholderQR<_MatrixType>, Rhs>@@ -343,6 +355,8 @@ template<typename MatrixType> HouseholderQR<MatrixType>& HouseholderQR<MatrixType>::compute(const MatrixType& matrix) {+ check_template_parameters();+ Index rows = matrix.rows(); Index cols = matrix.cols(); Index size = (std::min)(rows,cols);@@ -352,7 +366,7 @@ m_temp.resize(cols); - internal::householder_qr_inplace_blocked(m_qr, m_hCoeffs, 48, m_temp.data());+ internal::householder_qr_inplace_blocked<MatrixType, HCoeffsType>::run(m_qr, m_hCoeffs, 48, m_temp.data()); m_isInitialized = true; return *this;
eigen3/Eigen/src/QR/HouseholderQR_MKL.h view
@@ -34,28 +34,30 @@ #ifndef EIGEN_QR_MKL_H #define EIGEN_QR_MKL_H -#include "Eigen/src/Core/util/MKL_support.h"+#include "../Core/util/MKL_support.h" namespace Eigen { -namespace internal {+ namespace internal { -/** \internal Specialization for the data types supported by MKL */+ /** \internal Specialization for the data types supported by MKL */ #define EIGEN_MKL_QR_NOPIV(EIGTYPE, MKLTYPE, MKLPREFIX) \ template<typename MatrixQR, typename HCoeffs> \-void householder_qr_inplace_blocked(MatrixQR& mat, HCoeffs& hCoeffs, \- typename MatrixQR::Index maxBlockSize=32, \- EIGTYPE* tempData = 0) \+struct householder_qr_inplace_blocked<MatrixQR, HCoeffs, EIGTYPE, true> \ { \- lapack_int m = mat.rows(); \- lapack_int n = mat.cols(); \- lapack_int lda = mat.outerStride(); \- lapack_int matrix_order = (MatrixQR::IsRowMajor) ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR; \- LAPACKE_##MKLPREFIX##geqrf( matrix_order, m, n, (MKLTYPE*)mat.data(), lda, (MKLTYPE*)hCoeffs.data()); \- hCoeffs.adjointInPlace(); \-\-}+ static void run(MatrixQR& mat, HCoeffs& hCoeffs, \+ typename MatrixQR::Index = 32, \+ typename MatrixQR::Scalar* = 0) \+ { \+ lapack_int m = (lapack_int) mat.rows(); \+ lapack_int n = (lapack_int) mat.cols(); \+ lapack_int lda = (lapack_int) mat.outerStride(); \+ lapack_int matrix_order = (MatrixQR::IsRowMajor) ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR; \+ LAPACKE_##MKLPREFIX##geqrf( matrix_order, m, n, (MKLTYPE*)mat.data(), lda, (MKLTYPE*)hCoeffs.data()); \+ hCoeffs.adjointInPlace(); \+ } \+}; EIGEN_MKL_QR_NOPIV(double, double, d) EIGEN_MKL_QR_NOPIV(float, float, s)
eigen3/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h view
@@ -64,19 +64,13 @@ typedef PermutationMatrix<Dynamic, Dynamic> PermutationType; public: SPQR() - : m_isInitialized(false),- m_ordering(SPQR_ORDERING_DEFAULT),- m_allow_tol(SPQR_DEFAULT_TOL),- m_tolerance (NumTraits<Scalar>::epsilon())+ : m_isInitialized(false), m_ordering(SPQR_ORDERING_DEFAULT), m_allow_tol(SPQR_DEFAULT_TOL), m_tolerance (NumTraits<Scalar>::epsilon()), m_useDefaultThreshold(true) { cholmod_l_start(&m_cc); } - SPQR(const _MatrixType& matrix) - : m_isInitialized(false),- m_ordering(SPQR_ORDERING_DEFAULT),- m_allow_tol(SPQR_DEFAULT_TOL),- m_tolerance (NumTraits<Scalar>::epsilon())+ SPQR(const _MatrixType& matrix)+ : m_isInitialized(false), m_ordering(SPQR_ORDERING_DEFAULT), m_allow_tol(SPQR_DEFAULT_TOL), m_tolerance (NumTraits<Scalar>::epsilon()), m_useDefaultThreshold(true) { cholmod_l_start(&m_cc); compute(matrix);@@ -101,10 +95,26 @@ if(m_isInitialized) SPQR_free(); MatrixType mat(matrix);+ + /* Compute the default threshold as in MatLab, see:+ * Tim Davis, "Algorithm 915, SuiteSparseQR: Multifrontal Multithreaded Rank-Revealing+ * Sparse QR Factorization, ACM Trans. on Math. Soft. 38(1), 2011, Page 8:3 + */+ RealScalar pivotThreshold = m_tolerance;+ if(m_useDefaultThreshold) + {+ using std::max;+ RealScalar max2Norm = 0.0;+ for (int j = 0; j < mat.cols(); j++) max2Norm = (max)(max2Norm, mat.col(j).norm());+ if(max2Norm==RealScalar(0))+ max2Norm = RealScalar(1);+ pivotThreshold = 20 * (mat.rows() + mat.cols()) * max2Norm * NumTraits<RealScalar>::epsilon();+ }+ cholmod_sparse A; A = viewAsCholmod(mat); Index col = matrix.cols();- m_rank = SuiteSparseQR<Scalar>(m_ordering, m_tolerance, col, &A, + m_rank = SuiteSparseQR<Scalar>(m_ordering, pivotThreshold, col, &A, &m_cR, &m_E, &m_H, &m_HPinv, &m_HTau, &m_cc); if (!m_cR)@@ -120,7 +130,7 @@ /** * Get the number of rows of the input matrix and the Q matrix */- inline Index rows() const {return m_H->nrow; }+ inline Index rows() const {return m_cR->nrow; } /** * Get the number of columns of the input matrix. @@ -145,17 +155,26 @@ { eigen_assert(m_isInitialized && " The QR factorization should be computed first, call compute()"); eigen_assert(b.cols()==1 && "This method is for vectors only");- + //Compute Q^T * b- typename Dest::PlainObject y;+ typename Dest::PlainObject y, y2; y = matrixQ().transpose() * b;- // Solves with the triangular matrix R+ + // Solves with the triangular matrix R Index rk = this->rank();- y.topRows(rk) = this->matrixR().topLeftCorner(rk, rk).template triangularView<Upper>().solve(y.topRows(rk));- y.bottomRows(cols()-rk).setZero();+ y2 = y;+ y.resize((std::max)(cols(),Index(y.rows())),y.cols());+ y.topRows(rk) = this->matrixR().topLeftCorner(rk, rk).template triangularView<Upper>().solve(y2.topRows(rk));+ // Apply the column permutation - dest.topRows(cols()) = colsPermutation() * y.topRows(cols());+ // colsPermutation() performs a copy of the permutation,+ // so let's apply it manually:+ for(Index i = 0; i < rk; ++i) dest.row(m_E[i]) = y.row(i);+ for(Index i = rk; i < cols(); ++i) dest.row(m_E[i]).setZero(); +// y.bottomRows(y.rows()-rk).setZero();+// dest = colsPermutation() * y.topRows(cols());+ m_info = Success; } @@ -197,7 +216,11 @@ /// Set the fill-reducing ordering method to be used void setSPQROrdering(int ord) { m_ordering = ord;} /// Set the tolerance tol to treat columns with 2-norm < =tol as zero- void setPivotThreshold(const RealScalar& tol) { m_tolerance = tol; }+ void setPivotThreshold(const RealScalar& tol)+ {+ m_useDefaultThreshold = false;+ m_tolerance = tol;+ } /** \returns a pointer to the SPQR workspace */ cholmod_common *cholmodCommon() const { return &m_cc; }@@ -230,6 +253,7 @@ mutable cholmod_dense *m_HTau; // The Householder coefficients mutable Index m_rank; // The rank of the matrix mutable cholmod_common m_cc; // Workspace and parameters+ bool m_useDefaultThreshold; // Use default threshold template<typename ,typename > friend struct SPQR_QProduct; };
eigen3/Eigen/src/SVD/JacobiSVD.h view
@@ -742,6 +742,11 @@ private: void allocate(Index rows, Index cols, unsigned int computationOptions);+ + static void check_template_parameters()+ {+ EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar);+ } protected: MatrixUType m_matrixU;@@ -818,6 +823,8 @@ JacobiSVD<MatrixType, QRPreconditioner>& JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsigned int computationOptions) {+ check_template_parameters();+ using std::abs; allocate(matrix.rows(), matrix.cols(), computationOptions);
eigen3/Eigen/src/SparseCore/SparseBlock.h view
@@ -57,6 +57,16 @@ inline BlockImpl(const XprType& xpr, int startRow, int startCol, int blockRows, int blockCols) : m_matrix(xpr), m_outerStart(IsRowMajor ? startRow : startCol), m_outerSize(IsRowMajor ? blockRows : blockCols) {}+ + inline const Scalar coeff(int row, int col) const+ {+ return m_matrix.coeff(row + IsRowMajor ? m_outerStart : 0, col +IsRowMajor ? 0 : m_outerStart);+ }+ + inline const Scalar coeff(int index) const+ {+ return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart);+ } EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); } EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }@@ -226,6 +236,21 @@ else return Map<const Matrix<Index,OuterSize,1> >(m_matrix.innerNonZeroPtr()+m_outerStart, m_outerSize.value()).sum(); }+ + inline Scalar& coeffRef(int row, int col)+ {+ return m_matrix.const_cast_derived().coeffRef(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart));+ }+ + inline const Scalar coeff(int row, int col) const+ {+ return m_matrix.coeff(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart));+ }+ + inline const Scalar coeff(int index) const+ {+ return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart);+ } const Scalar& lastCoeff() const {@@ -313,6 +338,16 @@ else return Map<const Matrix<Index,OuterSize,1> >(m_matrix.innerNonZeroPtr()+m_outerStart, m_outerSize.value()).sum(); }+ + inline const Scalar coeff(int row, int col) const+ {+ return m_matrix.coeff(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 : m_outerStart));+ }+ + inline const Scalar coeff(int index) const+ {+ return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index : m_outerStart);+ } const Scalar& lastCoeff() const {@@ -355,7 +390,8 @@ * is col-major (resp. row-major). */ template<typename Derived>-Block<Derived,Dynamic,Dynamic,true> SparseMatrixBase<Derived>::innerVectors(Index outerStart, Index outerSize)+typename SparseMatrixBase<Derived>::InnerVectorsReturnType+SparseMatrixBase<Derived>::innerVectors(Index outerStart, Index outerSize) { return Block<Derived,Dynamic,Dynamic,true>(derived(), IsRowMajor ? outerStart : 0, IsRowMajor ? 0 : outerStart,@@ -367,7 +403,8 @@ * is col-major (resp. row-major). Read-only. */ template<typename Derived>-const Block<const Derived,Dynamic,Dynamic,true> SparseMatrixBase<Derived>::innerVectors(Index outerStart, Index outerSize) const+const typename SparseMatrixBase<Derived>::ConstInnerVectorsReturnType+SparseMatrixBase<Derived>::innerVectors(Index outerStart, Index outerSize) const { return Block<const Derived,Dynamic,Dynamic,true>(derived(), IsRowMajor ? outerStart : 0, IsRowMajor ? 0 : outerStart,@@ -394,8 +431,8 @@ : m_matrix(xpr), m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0), m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),- m_blockRows(xpr.rows()),- m_blockCols(xpr.cols())+ m_blockRows(BlockRows==1 ? 1 : xpr.rows()),+ m_blockCols(BlockCols==1 ? 1 : xpr.cols()) {} /** Dynamic-size constructor@@ -497,3 +534,4 @@ } // end namespace Eigen #endif // EIGEN_SPARSE_BLOCK_H+
eigen3/Eigen/src/SparseCore/SparseDenseProduct.h view
@@ -180,7 +180,7 @@ typename Res::Scalar tmp(0); for(LhsInnerIterator it(lhs,j); it ;++it) tmp += it.value() * rhs.coeff(it.index(),c);- res.coeffRef(j,c) = alpha * tmp;+ res.coeffRef(j,c) += alpha * tmp; } } }
eigen3/Eigen/src/SparseCore/SparseMatrixBase.h view
@@ -404,8 +404,10 @@ const ConstInnerVectorReturnType innerVector(Index outer) const; // set of inner-vectors- Block<Derived,Dynamic,Dynamic,true> innerVectors(Index outerStart, Index outerSize);- const Block<const Derived,Dynamic,Dynamic,true> innerVectors(Index outerStart, Index outerSize) const;+ typedef Block<Derived,Dynamic,Dynamic,true> InnerVectorsReturnType;+ typedef Block<const Derived,Dynamic,Dynamic,true> ConstInnerVectorsReturnType;+ InnerVectorsReturnType innerVectors(Index outerStart, Index outerSize);+ const ConstInnerVectorsReturnType innerVectors(Index outerStart, Index outerSize) const; /** \internal use operator= */ template<typename DenseDerived>
eigen3/Eigen/src/SparseCore/TriangularSolver.h view
@@ -69,7 +69,7 @@ for(int i=lhs.rows()-1 ; i>=0 ; --i) { Scalar tmp = other.coeff(i,col);- Scalar l_ii = 0;+ Scalar l_ii(0); typename Lhs::InnerIterator it(lhs, i); while(it && it.index()<i) ++it;
eigen3/Eigen/src/SparseLU/SparseLU.h view
@@ -268,7 +268,8 @@ { if(it.index() == j) {- det *= (std::abs)(it.value());+ using std::abs;+ det *= abs(it.value()); break; } }@@ -295,7 +296,8 @@ if(it.row() < j) continue; if(it.row() == j) {- det += (std::log)((std::abs)(it.value()));+ using std::log; using std::abs;+ det += log(abs(it.value())); break; } }@@ -303,21 +305,64 @@ return det; } - /** \returns A number representing the sign of the determinant- *- * \sa absDeterminant(), logAbsDeterminant()- */- Scalar signDeterminant()- {- eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");- return Scalar(m_detPermR);- }+ /** \returns A number representing the sign of the determinant+ *+ * \sa absDeterminant(), logAbsDeterminant()+ */+ Scalar signDeterminant()+ {+ eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");+ // Initialize with the determinant of the row matrix+ Index det = 1;+ // Note that the diagonal blocks of U are stored in supernodes,+ // which are available in the L part :)+ for (Index j = 0; j < this->cols(); ++j)+ {+ for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it)+ {+ if(it.index() == j)+ {+ if(it.value()<0)+ det = -det;+ else if(it.value()==0)+ return 0;+ break;+ }+ }+ }+ return det * m_detPermR * m_detPermC;+ }+ + /** \returns The determinant of the matrix.+ *+ * \sa absDeterminant(), logAbsDeterminant()+ */+ Scalar determinant()+ {+ eigen_assert(m_factorizationIsOk && "The matrix should be factorized first.");+ // Initialize with the determinant of the row matrix+ Scalar det = Scalar(1.);+ // Note that the diagonal blocks of U are stored in supernodes,+ // which are available in the L part :)+ for (Index j = 0; j < this->cols(); ++j)+ {+ for (typename SCMatrix::InnerIterator it(m_Lstore, j); it; ++it)+ {+ if(it.index() == j)+ {+ det *= it.value();+ break;+ }+ }+ }+ return det * Scalar(m_detPermR * m_detPermC);+ } protected: // Functions void initperfvalues() {- m_perfv.panel_size = 1;+ m_perfv.panel_size = 16; m_perfv.relax = 1; m_perfv.maxsuper = 128; m_perfv.rowblk = 16; @@ -345,8 +390,8 @@ // values for performance internal::perfvalues<Index> m_perfv; RealScalar m_diagpivotthresh; // Specifies the threshold used for a diagonal entry to be an acceptable pivot- Index m_nnzL, m_nnzU; // Nonzeros in L and U factors - Index m_detPermR; // Determinant of the coefficient matrix+ Index m_nnzL, m_nnzU; // Nonzeros in L and U factors+ Index m_detPermR, m_detPermC; // Determinants of the permutation matrices private: // Disable copy constructor SparseLU (const SparseLU& );@@ -622,7 +667,8 @@ } // Update the determinant of the row permutation matrix- if (pivrow != jj) m_detPermR *= -1;+ // FIXME: the following test is not correct, we should probably take iperm_c into account and pivrow is not directly the row pivot.+ if (pivrow != jj) m_detPermR = -m_detPermR; // Prune columns (0:jj-1) using column jj Base::pruneL(jj, m_perm_r.indices(), pivrow, nseg, segrep, repfnz_k, xprune, m_glu); @@ -637,10 +683,13 @@ jcol += panel_size; // Move to the next panel } // end for -- end elimination + m_detPermR = m_perm_r.determinant();+ m_detPermC = m_perm_c.determinant();+ // Count the number of nonzeros in factors Base::countnz(n, m_nnzL, m_nnzU, m_glu); // Apply permutation to the L subscripts - Base::fixupL(n, m_perm_r.indices(), m_glu); + Base::fixupL(n, m_perm_r.indices(), m_glu); // Create supernode matrix L m_Lstore.setInfos(m, n, m_glu.lusup, m_glu.xlusup, m_glu.lsub, m_glu.xlsub, m_glu.supno, m_glu.xsup);
eigen3/Eigen/src/SparseLU/SparseLU_pivotL.h view
@@ -77,7 +77,8 @@ RealScalar rtemp; Index isub, icol, itemp, k; for (isub = nsupc; isub < nsupr; ++isub) {- rtemp = std::abs(lu_col_ptr[isub]);+ using std::abs;+ rtemp = abs(lu_col_ptr[isub]); if (rtemp > pivmax) { pivmax = rtemp; pivptr = isub;@@ -101,7 +102,8 @@ if (diag >= 0 ) { // Diagonal element exists- rtemp = std::abs(lu_col_ptr[diag]);+ using std::abs;+ rtemp = abs(lu_col_ptr[diag]); if (rtemp != 0.0 && rtemp >= thresh) pivptr = diag; } pivrow = lsub_ptr[pivptr];
eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h view
@@ -70,6 +70,43 @@ return (max)(Derived::PlainObject::Constant(rows(), cols(), other)); } ++#define EIGEN_MAKE_CWISE_COMP_OP(OP, COMPARATOR) \+template<typename OtherDerived> \+EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const OtherDerived> \+OP(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \+{ \+ return CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const OtherDerived>(derived(), other.derived()); \+}\+typedef CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_ ## COMPARATOR>, const Derived, const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject> > Cmp ## COMPARATOR ## ReturnType; \+typedef CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_ ## COMPARATOR>, const CwiseNullaryOp<internal::scalar_constant_op<Scalar>, PlainObject>, const Derived > RCmp ## COMPARATOR ## ReturnType; \+EIGEN_STRONG_INLINE const Cmp ## COMPARATOR ## ReturnType \+OP(const Scalar& s) const { \+ return this->OP(Derived::PlainObject::Constant(rows(), cols(), s)); \+} \+friend EIGEN_STRONG_INLINE const RCmp ## COMPARATOR ## ReturnType \+OP(const Scalar& s, const Derived& d) { \+ return Derived::PlainObject::Constant(d.rows(), d.cols(), s).OP(d); \+}++#define EIGEN_MAKE_CWISE_COMP_R_OP(OP, R_OP, RCOMPARATOR) \+template<typename OtherDerived> \+EIGEN_STRONG_INLINE const CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_##RCOMPARATOR>, const OtherDerived, const Derived> \+OP(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \+{ \+ return CwiseBinaryOp<internal::scalar_cmp_op<Scalar, internal::cmp_##RCOMPARATOR>, const OtherDerived, const Derived>(other.derived(), derived()); \+} \+\+inline const RCmp ## RCOMPARATOR ## ReturnType \+OP(const Scalar& s) const { \+ return Derived::PlainObject::Constant(rows(), cols(), s).R_OP(*this); \+} \+friend inline const Cmp ## RCOMPARATOR ## ReturnType \+OP(const Scalar& s, const Derived& d) { \+ return d.R_OP(Derived::PlainObject::Constant(d.rows(), d.cols(), s)); \+}++ /** \returns an expression of the coefficient-wise \< operator of *this and \a other * * Example: \include Cwise_less.cpp@@ -77,7 +114,7 @@ * * \sa all(), any(), operator>(), operator<=() */-EIGEN_MAKE_CWISE_BINARY_OP(operator<,std::less)+EIGEN_MAKE_CWISE_COMP_OP(operator<, LT) /** \returns an expression of the coefficient-wise \<= operator of *this and \a other *@@ -86,7 +123,7 @@ * * \sa all(), any(), operator>=(), operator<() */-EIGEN_MAKE_CWISE_BINARY_OP(operator<=,std::less_equal)+EIGEN_MAKE_CWISE_COMP_OP(operator<=, LE) /** \returns an expression of the coefficient-wise \> operator of *this and \a other *@@ -95,7 +132,7 @@ * * \sa all(), any(), operator>=(), operator<() */-EIGEN_MAKE_CWISE_BINARY_OP(operator>,std::greater)+EIGEN_MAKE_CWISE_COMP_R_OP(operator>, operator<, LT) /** \returns an expression of the coefficient-wise \>= operator of *this and \a other *@@ -104,7 +141,7 @@ * * \sa all(), any(), operator>(), operator<=() */-EIGEN_MAKE_CWISE_BINARY_OP(operator>=,std::greater_equal)+EIGEN_MAKE_CWISE_COMP_R_OP(operator>=, operator<=, LE) /** \returns an expression of the coefficient-wise == operator of *this and \a other *@@ -118,7 +155,7 @@ * * \sa all(), any(), isApprox(), isMuchSmallerThan() */-EIGEN_MAKE_CWISE_BINARY_OP(operator==,std::equal_to)+EIGEN_MAKE_CWISE_COMP_OP(operator==, EQ) /** \returns an expression of the coefficient-wise != operator of *this and \a other *@@ -132,8 +169,11 @@ * * \sa all(), any(), isApprox(), isMuchSmallerThan() */-EIGEN_MAKE_CWISE_BINARY_OP(operator!=,std::not_equal_to)+EIGEN_MAKE_CWISE_COMP_OP(operator!=, NEQ) +#undef EIGEN_MAKE_CWISE_COMP_OP+#undef EIGEN_MAKE_CWISE_COMP_R_OP+ // scalar addition /** \returns an expression of \c *this with each coeff incremented by the constant \a scalar@@ -209,3 +249,5 @@ THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_OF_BOOL); return CwiseBinaryOp<internal::scalar_boolean_or_op, const Derived, const OtherDerived>(derived(),other.derived()); }++
eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h view
@@ -185,19 +185,3 @@ { return derived(); }--#define EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(METHOD_NAME,FUNCTOR) \- inline const CwiseUnaryOp<std::binder2nd<FUNCTOR<Scalar> >, const Derived> \- METHOD_NAME(const Scalar& s) const { \- return CwiseUnaryOp<std::binder2nd<FUNCTOR<Scalar> >, const Derived> \- (derived(), std::bind2nd(FUNCTOR<Scalar>(), s)); \- }--EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator==, std::equal_to)-EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator!=, std::not_equal_to)-EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator<, std::less)-EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator<=, std::less_equal)-EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator>, std::greater)-EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator>=, std::greater_equal)--
eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h view
@@ -124,3 +124,20 @@ { return CwiseBinaryOp<internal::scalar_quotient_op<Scalar>, const Derived, const OtherDerived>(derived(), other.derived()); }++typedef CwiseBinaryOp<internal::scalar_cmp_op<Scalar,internal::cmp_EQ>, const Derived, const ConstantReturnType> CwiseScalarEqualReturnType;++/** \returns an expression of the coefficient-wise == operator of \c *this and a scalar \a s+ *+ * \warning this performs an exact comparison, which is generally a bad idea with floating-point types.+ * In order to check for equality between two vectors or matrices with floating-point coefficients, it is+ * generally a far better idea to use a fuzzy comparison as provided by isApprox() and+ * isMuchSmallerThan().+ *+ * \sa cwiseEqual(const MatrixBase<OtherDerived> &) const+ */+inline const CwiseScalarEqualReturnType+cwiseEqual(const Scalar& s) const+{+ return CwiseScalarEqualReturnType(derived(), Derived::Constant(rows(), cols(), s), internal::scalar_cmp_op<Scalar,internal::cmp_EQ>());+}
eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h view
@@ -50,18 +50,3 @@ inline const CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const Derived> cwiseInverse() const { return derived(); } -/** \returns an expression of the coefficient-wise == operator of \c *this and a scalar \a s- *- * \warning this performs an exact comparison, which is generally a bad idea with floating-point types.- * In order to check for equality between two vectors or matrices with floating-point coefficients, it is- * generally a far better idea to use a fuzzy comparison as provided by isApprox() and- * isMuchSmallerThan().- *- * \sa cwiseEqual(const MatrixBase<OtherDerived> &) const- */-inline const CwiseUnaryOp<std::binder1st<std::equal_to<Scalar> >, const Derived>-cwiseEqual(const Scalar& s) const-{- return CwiseUnaryOp<std::binder1st<std::equal_to<Scalar> >,const Derived>- (derived(), std::bind1st(std::equal_to<Scalar>(), s));-}
+ eigen3/INSTALL view
@@ -0,0 +1,35 @@+Installation instructions for Eigen+***********************************++Explanation before starting+***************************++Eigen consists only of header files, hence there is nothing to compile+before you can use it. Moreover, these header files do not depend on your+platform, they are the same for everybody.++Method 1. Installing without using CMake+****************************************++You can use right away the headers in the Eigen/ subdirectory. In order+to install, just copy this Eigen/ subdirectory to your favorite location.+If you also want the unsupported features, copy the unsupported/+subdirectory too.++Method 2. Installing using CMake+********************************++Let's call this directory 'source_dir' (where this INSTALL file is).+Before starting, create another directory which we will call 'build_dir'.++Do:++ cd build_dir+ cmake source_dir+ make install++The "make install" step may require administrator privileges.++You can adjust the installation destination (the "prefix")+by passing the -DCMAKE_INSTALL_PREFIX=myprefix option to cmake, as is+explained in the message that cmake prints at the end.
+ eigen3/bench/BenchSparseUtil.h view
@@ -0,0 +1,149 @@++#include <Eigen/Sparse>+#include <bench/BenchTimer.h>+#include <set>++using namespace std;+using namespace Eigen;+using namespace Eigen;++#ifndef SIZE+#define SIZE 1024+#endif++#ifndef DENSITY+#define DENSITY 0.01+#endif++#ifndef SCALAR+#define SCALAR double+#endif++typedef SCALAR Scalar;+typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;+typedef Matrix<Scalar,Dynamic,1> DenseVector;+typedef SparseMatrix<Scalar> EigenSparseMatrix;++void fillMatrix(float density, int rows, int cols, EigenSparseMatrix& dst)+{+ dst.reserve(double(rows)*cols*density);+ for(int j = 0; j < cols; j++)+ {+ for(int i = 0; i < rows; i++)+ {+ Scalar v = (internal::random<float>(0,1) < density) ? internal::random<Scalar>() : 0;+ if (v!=0)+ dst.insert(i,j) = v;+ }+ }+ dst.finalize();+}++void fillMatrix2(int nnzPerCol, int rows, int cols, EigenSparseMatrix& dst)+{+// std::cout << "alloc " << nnzPerCol*cols << "\n";+ dst.reserve(nnzPerCol*cols);+ for(int j = 0; j < cols; j++)+ {+ std::set<int> aux;+ for(int i = 0; i < nnzPerCol; i++)+ {+ int k = internal::random<int>(0,rows-1);+ while (aux.find(k)!=aux.end())+ k = internal::random<int>(0,rows-1);+ aux.insert(k);++ dst.insert(k,j) = internal::random<Scalar>();+ }+ }+ dst.finalize();+}++void eiToDense(const EigenSparseMatrix& src, DenseMatrix& dst)+{+ dst.setZero();+ for (int j=0; j<src.cols(); ++j)+ for (EigenSparseMatrix::InnerIterator it(src.derived(), j); it; ++it)+ dst(it.index(),j) = it.value();+}++#ifndef NOGMM+#include "gmm/gmm.h"+typedef gmm::csc_matrix<Scalar> GmmSparse;+typedef gmm::col_matrix< gmm::wsvector<Scalar> > GmmDynSparse;+void eiToGmm(const EigenSparseMatrix& src, GmmSparse& dst)+{+ GmmDynSparse tmp(src.rows(), src.cols());+ for (int j=0; j<src.cols(); ++j)+ for (EigenSparseMatrix::InnerIterator it(src.derived(), j); it; ++it)+ tmp(it.index(),j) = it.value();+ gmm::copy(tmp, dst);+}+#endif++#ifndef NOMTL+#include <boost/numeric/mtl/mtl.hpp>+typedef mtl::compressed2D<Scalar, mtl::matrix::parameters<mtl::tag::col_major> > MtlSparse;+typedef mtl::compressed2D<Scalar, mtl::matrix::parameters<mtl::tag::row_major> > MtlSparseRowMajor;+void eiToMtl(const EigenSparseMatrix& src, MtlSparse& dst)+{+ mtl::matrix::inserter<MtlSparse> ins(dst);+ for (int j=0; j<src.cols(); ++j)+ for (EigenSparseMatrix::InnerIterator it(src.derived(), j); it; ++it)+ ins[it.index()][j] = it.value();+}+#endif++#ifdef CSPARSE+extern "C" {+#include "cs.h"+}+void eiToCSparse(const EigenSparseMatrix& src, cs* &dst)+{+ cs* aux = cs_spalloc (0, 0, 1, 1, 1);+ for (int j=0; j<src.cols(); ++j)+ for (EigenSparseMatrix::InnerIterator it(src.derived(), j); it; ++it)+ if (!cs_entry(aux, it.index(), j, it.value()))+ {+ std::cout << "cs_entry error\n";+ exit(2);+ }+ dst = cs_compress(aux);+// cs_spfree(aux);+}+#endif // CSPARSE++#ifndef NOUBLAS+#include <boost/numeric/ublas/vector.hpp>+#include <boost/numeric/ublas/matrix.hpp>+#include <boost/numeric/ublas/io.hpp>+#include <boost/numeric/ublas/triangular.hpp>+#include <boost/numeric/ublas/vector_sparse.hpp>+#include <boost/numeric/ublas/matrix_sparse.hpp>+#include <boost/numeric/ublas/vector_of_vector.hpp>+#include <boost/numeric/ublas/operation.hpp>++typedef boost::numeric::ublas::compressed_matrix<Scalar,boost::numeric::ublas::column_major> UBlasSparse;++void eiToUblas(const EigenSparseMatrix& src, UBlasSparse& dst)+{+ dst.resize(src.rows(), src.cols(), false);+ for (int j=0; j<src.cols(); ++j)+ for (EigenSparseMatrix::InnerIterator it(src.derived(), j); it; ++it)+ dst(it.index(),j) = it.value();+}++template <typename EigenType, typename UblasType>+void eiToUblasVec(const EigenType& src, UblasType& dst)+{+ dst.resize(src.size());+ for (int j=0; j<src.size(); ++j)+ dst[j] = src.coeff(j);+}+#endif++#ifdef OSKI+extern "C" {+#include <oski/oski.h>+}+#endif
+ eigen3/bench/BenchTimer.h view
@@ -0,0 +1,187 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_BENCH_TIMERR_H+#define EIGEN_BENCH_TIMERR_H++#if defined(_WIN32) || defined(__CYGWIN__)+# ifndef NOMINMAX+# define NOMINMAX+# define EIGEN_BT_UNDEF_NOMINMAX+# endif+# ifndef WIN32_LEAN_AND_MEAN+# define WIN32_LEAN_AND_MEAN+# define EIGEN_BT_UNDEF_WIN32_LEAN_AND_MEAN+# endif+# include <windows.h>+#elif defined(__APPLE__)+#include <CoreServices/CoreServices.h>+#include <mach/mach_time.h>+#else+# include <unistd.h>+#endif++#include <Eigen/Core>++namespace Eigen+{++enum {+ CPU_TIMER = 0,+ REAL_TIMER = 1+};++/** Elapsed time timer keeping the best try.+ *+ * On POSIX platforms we use clock_gettime with CLOCK_PROCESS_CPUTIME_ID.+ * On Windows we use QueryPerformanceCounter+ *+ * Important: on linux, you must link with -lrt+ */+class BenchTimer+{+public:++ BenchTimer()+ {+#if defined(_WIN32) || defined(__CYGWIN__)+ LARGE_INTEGER freq;+ QueryPerformanceFrequency(&freq);+ m_frequency = (double)freq.QuadPart;+#endif+ reset();+ }++ ~BenchTimer() {}++ inline void reset()+ {+ m_bests.fill(1e9);+ m_worsts.fill(0);+ m_totals.setZero();+ }+ inline void start()+ {+ m_starts[CPU_TIMER] = getCpuTime();+ m_starts[REAL_TIMER] = getRealTime();+ }+ inline void stop()+ {+ m_times[CPU_TIMER] = getCpuTime() - m_starts[CPU_TIMER];+ m_times[REAL_TIMER] = getRealTime() - m_starts[REAL_TIMER];+ #if EIGEN_VERSION_AT_LEAST(2,90,0)+ m_bests = m_bests.cwiseMin(m_times);+ m_worsts = m_worsts.cwiseMax(m_times);+ #else+ m_bests(0) = std::min(m_bests(0),m_times(0));+ m_bests(1) = std::min(m_bests(1),m_times(1));+ m_worsts(0) = std::max(m_worsts(0),m_times(0));+ m_worsts(1) = std::max(m_worsts(1),m_times(1));+ #endif+ m_totals += m_times;+ }++ /** Return the elapsed time in seconds between the last start/stop pair+ */+ inline double value(int TIMER = CPU_TIMER) const+ {+ return m_times[TIMER];+ }++ /** Return the best elapsed time in seconds+ */+ inline double best(int TIMER = CPU_TIMER) const+ {+ return m_bests[TIMER];+ }++ /** Return the worst elapsed time in seconds+ */+ inline double worst(int TIMER = CPU_TIMER) const+ {+ return m_worsts[TIMER];+ }++ /** Return the total elapsed time in seconds.+ */+ inline double total(int TIMER = CPU_TIMER) const+ {+ return m_totals[TIMER];+ }++ inline double getCpuTime() const+ {+#ifdef _WIN32+ LARGE_INTEGER query_ticks;+ QueryPerformanceCounter(&query_ticks);+ return query_ticks.QuadPart/m_frequency;+#elif __APPLE__+ return double(mach_absolute_time())*1e-9;+#else+ timespec ts;+ clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);+ return double(ts.tv_sec) + 1e-9 * double(ts.tv_nsec);+#endif+ }++ inline double getRealTime() const+ {+#ifdef _WIN32+ SYSTEMTIME st;+ GetSystemTime(&st);+ return (double)st.wSecond + 1.e-3 * (double)st.wMilliseconds;+#elif __APPLE__+ return double(mach_absolute_time())*1e-9;+#else+ timespec ts;+ clock_gettime(CLOCK_REALTIME, &ts);+ return double(ts.tv_sec) + 1e-9 * double(ts.tv_nsec);+#endif+ }++protected:+#if defined(_WIN32) || defined(__CYGWIN__)+ double m_frequency;+#endif+ Vector2d m_starts;+ Vector2d m_times;+ Vector2d m_bests;+ Vector2d m_worsts;+ Vector2d m_totals;++public:+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW+};++#define BENCH(TIMER,TRIES,REP,CODE) { \+ TIMER.reset(); \+ for(int uglyvarname1=0; uglyvarname1<TRIES; ++uglyvarname1){ \+ TIMER.start(); \+ for(int uglyvarname2=0; uglyvarname2<REP; ++uglyvarname2){ \+ CODE; \+ } \+ TIMER.stop(); \+ } \+ }++}++// clean #defined tokens+#ifdef EIGEN_BT_UNDEF_NOMINMAX+# undef EIGEN_BT_UNDEF_NOMINMAX+# undef NOMINMAX+#endif++#ifdef EIGEN_BT_UNDEF_WIN32_LEAN_AND_MEAN+# undef EIGEN_BT_UNDEF_WIN32_LEAN_AND_MEAN+# undef WIN32_LEAN_AND_MEAN+#endif++#endif // EIGEN_BENCH_TIMERR_H
+ eigen3/bench/BenchUtil.h view
@@ -0,0 +1,92 @@++#ifndef EIGEN_BENCH_UTIL_H+#define EIGEN_BENCH_UTIL_H++#include <Eigen/Core>+#include "BenchTimer.h"++using namespace std;+using namespace Eigen;++#include <boost/preprocessor/repetition/enum_params.hpp>+#include <boost/preprocessor/repetition.hpp>+#include <boost/preprocessor/seq.hpp>+#include <boost/preprocessor/array.hpp>+#include <boost/preprocessor/arithmetic.hpp>+#include <boost/preprocessor/comparison.hpp>+#include <boost/preprocessor/punctuation.hpp>+#include <boost/preprocessor/punctuation/comma.hpp>+#include <boost/preprocessor/stringize.hpp>++template<typename MatrixType> void initMatrix_random(MatrixType& mat) __attribute__((noinline));+template<typename MatrixType> void initMatrix_random(MatrixType& mat)+{+ mat.setRandom();// = MatrixType::random(mat.rows(), mat.cols());+}++template<typename MatrixType> void initMatrix_identity(MatrixType& mat) __attribute__((noinline));+template<typename MatrixType> void initMatrix_identity(MatrixType& mat)+{+ mat.setIdentity();+}++#ifndef __INTEL_COMPILER+#define DISABLE_SSE_EXCEPTIONS() { \+ int aux; \+ asm( \+ "stmxcsr %[aux] \n\t" \+ "orl $32832, %[aux] \n\t" \+ "ldmxcsr %[aux] \n\t" \+ : : [aux] "m" (aux)); \+}+#else+#define DISABLE_SSE_EXCEPTIONS() +#endif++#ifdef BENCH_GMM+#include <gmm/gmm.h>+template <typename EigenMatrixType, typename GmmMatrixType>+void eiToGmm(const EigenMatrixType& src, GmmMatrixType& dst)+{+ dst.resize(src.rows(),src.cols());+ for (int j=0; j<src.cols(); ++j)+ for (int i=0; i<src.rows(); ++i)+ dst(i,j) = src.coeff(i,j);+}+#endif+++#ifdef BENCH_GSL+#include <gsl/gsl_matrix.h>+#include <gsl/gsl_linalg.h>+#include <gsl/gsl_eigen.h>+template <typename EigenMatrixType>+void eiToGsl(const EigenMatrixType& src, gsl_matrix** dst)+{+ for (int j=0; j<src.cols(); ++j)+ for (int i=0; i<src.rows(); ++i)+ gsl_matrix_set(*dst, i, j, src.coeff(i,j));+}+#endif++#ifdef BENCH_UBLAS+#include <boost/numeric/ublas/matrix.hpp>+#include <boost/numeric/ublas/vector.hpp>+template <typename EigenMatrixType, typename UblasMatrixType>+void eiToUblas(const EigenMatrixType& src, UblasMatrixType& dst)+{+ dst.resize(src.rows(),src.cols());+ for (int j=0; j<src.cols(); ++j)+ for (int i=0; i<src.rows(); ++i)+ dst(i,j) = src.coeff(i,j);+}+template <typename EigenType, typename UblasType>+void eiToUblasVec(const EigenType& src, UblasType& dst)+{+ dst.resize(src.size());+ for (int j=0; j<src.size(); ++j)+ dst[j] = src.coeff(j);+}+#endif++#endif // EIGEN_BENCH_UTIL_H
+ eigen3/bench/README.txt view
@@ -0,0 +1,55 @@++This folder contains a couple of benchmark utities and Eigen benchmarks.++****************************+* bench_multi_compilers.sh *+****************************++This script allows to run a benchmark on a set of different compilers/compiler options.+It takes two arguments:+ - a file defining the list of the compilers with their options+ - the .cpp file of the benchmark++Examples:++$ ./bench_multi_compilers.sh basicbench.cxxlist basicbenchmark.cpp++ g++-4.1 -O3 -DNDEBUG -finline-limit=10000+ 3d-3x3 / 4d-4x4 / Xd-4x4 / Xd-20x20 /+ 0.271102 0.131416 0.422322 0.198633+ 0.201658 0.102436 0.397566 0.207282++ g++-4.2 -O3 -DNDEBUG -finline-limit=10000+ 3d-3x3 / 4d-4x4 / Xd-4x4 / Xd-20x20 /+ 0.107805 0.0890579 0.30265 0.161843+ 0.127157 0.0712581 0.278341 0.191029++ g++-4.3 -O3 -DNDEBUG -finline-limit=10000+ 3d-3x3 / 4d-4x4 / Xd-4x4 / Xd-20x20 /+ 0.134318 0.105291 0.3704 0.180966+ 0.137703 0.0732472 0.31225 0.202204++ icpc -fast -DNDEBUG -fno-exceptions -no-inline-max-size+ 3d-3x3 / 4d-4x4 / Xd-4x4 / Xd-20x20 /+ 0.226145 0.0941319 0.371873 0.159433+ 0.109302 0.0837538 0.328102 0.173891+++$ ./bench_multi_compilers.sh ompbench.cxxlist ompbenchmark.cpp++ g++-4.2 -O3 -DNDEBUG -finline-limit=10000 -fopenmp+ double, fixed-size 4x4: 0.00165105s 0.0778739s+ double, 32x32: 0.0654769s 0.075289s => x0.869674 (2)+ double, 128x128: 0.054148s 0.0419669s => x1.29025 (2)+ double, 512x512: 0.913799s 0.428533s => x2.13239 (2)+ double, 1024x1024: 14.5972s 9.3542s => x1.5605 (2)++ icpc -fast -DNDEBUG -fno-exceptions -no-inline-max-size -openmp+ double, fixed-size 4x4: 0.000589848s 0.019949s+ double, 32x32: 0.0682781s 0.0449722s => x1.51823 (2)+ double, 128x128: 0.0547509s 0.0435519s => x1.25714 (2)+ double, 512x512: 0.829436s 0.424438s => x1.9542 (2)+ double, 1024x1024: 14.5243s 10.7735s => x1.34815 (2)+++
+ eigen3/bench/basicbench.cxxlist view
@@ -0,0 +1,28 @@+#!/bin/bash++# CLIST[((g++))]="g++-3.4 -O3 -DNDEBUG"+# CLIST[((g++))]="g++-3.4 -O3 -DNDEBUG -finline-limit=20000"++# CLIST[((g++))]="g++-4.1 -O3 -DNDEBUG"+#CLIST[((g++))]="g++-4.1 -O3 -DNDEBUG -finline-limit=20000"++# CLIST[((g++))]="g++-4.2 -O3 -DNDEBUG"+#CLIST[((g++))]="g++-4.2 -O3 -DNDEBUG -finline-limit=20000"+# CLIST[((g++))]="g++-4.2 -O3 -DNDEBUG -finline-limit=20000 -fprofile-generate"+# CLIST[((g++))]="g++-4.2 -O3 -DNDEBUG -finline-limit=20000 -fprofile-use"++# CLIST[((g++))]="g++-4.3 -O3 -DNDEBUG"+#CLIST[((g++))]="g++-4.3 -O3 -DNDEBUG -finline-limit=20000"+# CLIST[((g++))]="g++-4.3 -O3 -DNDEBUG -finline-limit=20000 -fprofile-generate"+# CLIST[((g++))]="g++-4.3 -O3 -DNDEBUG -finline-limit=20000 -fprofile-use"++# CLIST[((g++))]="icpc -fast -DNDEBUG -fno-exceptions -no-inline-max-size -prof-genx"+# CLIST[((g++))]="icpc -fast -DNDEBUG -fno-exceptions -no-inline-max-size -prof-use"++#CLIST[((g++))]="/opt/intel/Compiler/11.1/072/bin/intel64/icpc -fast -DNDEBUG -fno-exceptions -no-inline-max-size -lrt"+CLIST[((g++))]="/home/orzel/svn/llvm/Release/bin/clang++ -O3 -DNDEBUG -DEIGEN_DONT_VECTORIZE -lrt"+CLIST[((g++))]="/home/orzel/svn/llvm/Release/bin/clang++ -O3 -DNDEBUG -lrt"+CLIST[((g++))]="g++-4.4.4 -O3 -DNDEBUG -DEIGEN_DONT_VECTORIZE -lrt"+CLIST[((g++))]="g++-4.4.4 -O3 -DNDEBUG -lrt"+CLIST[((g++))]="g++-4.5.0 -O3 -DNDEBUG -DEIGEN_DONT_VECTORIZE -lrt"+CLIST[((g++))]="g++-4.5.0 -O3 -DNDEBUG -lrt"
+ eigen3/bench/basicbenchmark.cpp view
@@ -0,0 +1,35 @@++#include <iostream>+#include "BenchUtil.h"+#include "basicbenchmark.h"++int main(int argc, char *argv[])+{+ DISABLE_SSE_EXCEPTIONS();++ // this is the list of matrix type and size we want to bench:+ // ((suffix) (matrix size) (number of iterations))+ #define MODES ((3d)(3)(4000000)) ((4d)(4)(1000000)) ((Xd)(4)(1000000)) ((Xd)(20)(10000))+// #define MODES ((Xd)(20)(10000))++ #define _GENERATE_HEADER(R,ARG,EL) << BOOST_PP_STRINGIZE(BOOST_PP_SEQ_HEAD(EL)) << "-" \+ << BOOST_PP_STRINGIZE(BOOST_PP_SEQ_ELEM(1,EL)) << "x" \+ << BOOST_PP_STRINGIZE(BOOST_PP_SEQ_ELEM(1,EL)) << " / "++ std::cout BOOST_PP_SEQ_FOR_EACH(_GENERATE_HEADER, ~, MODES ) << endl;++ const int tries = 10;++ #define _RUN_BENCH(R,ARG,EL) \+ std::cout << ARG( \+ BOOST_PP_CAT(Matrix, BOOST_PP_SEQ_HEAD(EL)) (\+ BOOST_PP_SEQ_ELEM(1,EL),BOOST_PP_SEQ_ELEM(1,EL)), BOOST_PP_SEQ_ELEM(2,EL), tries) \+ << " ";++ BOOST_PP_SEQ_FOR_EACH(_RUN_BENCH, benchBasic<LazyEval>, MODES );+ std::cout << endl;+ BOOST_PP_SEQ_FOR_EACH(_RUN_BENCH, benchBasic<EarlyEval>, MODES );+ std::cout << endl;++ return 0;+}
+ eigen3/bench/basicbenchmark.h view
@@ -0,0 +1,63 @@++#ifndef EIGEN_BENCH_BASICBENCH_H+#define EIGEN_BENCH_BASICBENCH_H++enum {LazyEval, EarlyEval, OmpEval};++template<int Mode, typename MatrixType>+void benchBasic_loop(const MatrixType& I, MatrixType& m, int iterations) __attribute__((noinline));++template<int Mode, typename MatrixType>+void benchBasic_loop(const MatrixType& I, MatrixType& m, int iterations)+{+ for(int a = 0; a < iterations; a++)+ {+ if (Mode==LazyEval)+ {+ asm("#begin_bench_loop LazyEval");+ if (MatrixType::SizeAtCompileTime!=Eigen::Dynamic) asm("#fixedsize");+ m = (I + 0.00005 * (m + m.lazy() * m)).eval();+ }+ else if (Mode==OmpEval)+ {+ asm("#begin_bench_loop OmpEval");+ if (MatrixType::SizeAtCompileTime!=Eigen::Dynamic) asm("#fixedsize");+ m = (I + 0.00005 * (m + m.lazy() * m)).evalOMP();+ }+ else+ {+ asm("#begin_bench_loop EarlyEval");+ if (MatrixType::SizeAtCompileTime!=Eigen::Dynamic) asm("#fixedsize");+ m = I + 0.00005 * (m + m * m);+ }+ asm("#end_bench_loop");+ }+}++template<int Mode, typename MatrixType>+double benchBasic(const MatrixType& mat, int size, int tries) __attribute__((noinline));++template<int Mode, typename MatrixType>+double benchBasic(const MatrixType& mat, int iterations, int tries)+{+ const int rows = mat.rows();+ const int cols = mat.cols();++ MatrixType I(rows,cols);+ MatrixType m(rows,cols);++ initMatrix_identity(I);++ Eigen::BenchTimer timer;+ for(uint t=0; t<tries; ++t)+ {+ initMatrix_random(m);+ timer.start();+ benchBasic_loop<Mode>(I, m, iterations);+ timer.stop();+ cerr << m;+ }+ return timer.value();+};++#endif // EIGEN_BENCH_BASICBENCH_H
+ eigen3/bench/benchBlasGemm.cpp view
@@ -0,0 +1,219 @@+// g++ -O3 -DNDEBUG -I.. -L /usr/lib64/atlas/ benchBlasGemm.cpp -o benchBlasGemm -lrt -lcblas+// possible options:+// -DEIGEN_DONT_VECTORIZE+// -msse2++// #define EIGEN_DEFAULT_TO_ROW_MAJOR+#define _FLOAT++#include <iostream>++#include <Eigen/Core>+#include "BenchTimer.h"++// include the BLAS headers+extern "C" {+#include <cblas.h>+}+#include <string>++#ifdef _FLOAT+typedef float Scalar;+#define CBLAS_GEMM cblas_sgemm+#else+typedef double Scalar;+#define CBLAS_GEMM cblas_dgemm+#endif+++typedef Eigen::Matrix<Scalar,Eigen::Dynamic,Eigen::Dynamic> MyMatrix;+void bench_eigengemm(MyMatrix& mc, const MyMatrix& ma, const MyMatrix& mb, int nbloops);+void check_product(int M, int N, int K);+void check_product(void);++int main(int argc, char *argv[])+{+ // disable SSE exceptions+ #ifdef __GNUC__+ {+ int aux;+ asm(+ "stmxcsr %[aux] \n\t"+ "orl $32832, %[aux] \n\t"+ "ldmxcsr %[aux] \n\t"+ : : [aux] "m" (aux));+ }+ #endif++ int nbtries=1, nbloops=1, M, N, K;++ if (argc==2)+ {+ if (std::string(argv[1])=="check")+ check_product();+ else+ M = N = K = atoi(argv[1]);+ }+ else if ((argc==3) && (std::string(argv[1])=="auto"))+ {+ M = N = K = atoi(argv[2]);+ nbloops = 1000000000/(M*M*M);+ if (nbloops<1)+ nbloops = 1;+ nbtries = 6;+ }+ else if (argc==4)+ {+ M = N = K = atoi(argv[1]);+ nbloops = atoi(argv[2]);+ nbtries = atoi(argv[3]);+ }+ else if (argc==6)+ {+ M = atoi(argv[1]);+ N = atoi(argv[2]);+ K = atoi(argv[3]);+ nbloops = atoi(argv[4]);+ nbtries = atoi(argv[5]);+ }+ else+ {+ std::cout << "Usage: " << argv[0] << " size \n";+ std::cout << "Usage: " << argv[0] << " auto size\n";+ std::cout << "Usage: " << argv[0] << " size nbloops nbtries\n";+ std::cout << "Usage: " << argv[0] << " M N K nbloops nbtries\n";+ std::cout << "Usage: " << argv[0] << " check\n";+ std::cout << "Options:\n";+ std::cout << " size unique size of the 2 matrices (integer)\n";+ std::cout << " auto automatically set the number of repetitions and tries\n";+ std::cout << " nbloops number of times the GEMM routines is executed\n";+ std::cout << " nbtries number of times the loop is benched (return the best try)\n";+ std::cout << " M N K sizes of the matrices: MxN = MxK * KxN (integers)\n";+ std::cout << " check check eigen product using cblas as a reference\n";+ exit(1);+ }++ double nbmad = double(M) * double(N) * double(K) * double(nbloops);++ if (!(std::string(argv[1])=="auto"))+ std::cout << M << " x " << N << " x " << K << "\n";++ Scalar alpha, beta;+ MyMatrix ma(M,K), mb(K,N), mc(M,N);+ ma = MyMatrix::Random(M,K);+ mb = MyMatrix::Random(K,N);+ mc = MyMatrix::Random(M,N);++ Eigen::BenchTimer timer;++ // we simply compute c += a*b, so:+ alpha = 1;+ beta = 1;++ // bench cblas+ // ROWS_A, COLS_B, COLS_A, 1.0, A, COLS_A, B, COLS_B, 0.0, C, COLS_B);+ if (!(std::string(argv[1])=="auto"))+ {+ timer.reset();+ for (uint k=0 ; k<nbtries ; ++k)+ {+ timer.start();+ for (uint j=0 ; j<nbloops ; ++j)+ #ifdef EIGEN_DEFAULT_TO_ROW_MAJOR+ CBLAS_GEMM(CblasRowMajor, CblasNoTrans, CblasNoTrans, M, N, K, alpha, ma.data(), K, mb.data(), N, beta, mc.data(), N);+ #else+ CBLAS_GEMM(CblasColMajor, CblasNoTrans, CblasNoTrans, M, N, K, alpha, ma.data(), M, mb.data(), K, beta, mc.data(), M);+ #endif+ timer.stop();+ }+ if (!(std::string(argv[1])=="auto"))+ std::cout << "cblas: " << timer.value() << " (" << 1e-3*floor(1e-6*nbmad/timer.value()) << " GFlops/s)\n";+ else+ std::cout << M << " : " << timer.value() << " ; " << 1e-3*floor(1e-6*nbmad/timer.value()) << "\n";+ }++ // clear+ ma = MyMatrix::Random(M,K);+ mb = MyMatrix::Random(K,N);+ mc = MyMatrix::Random(M,N);++ // eigen+// if (!(std::string(argv[1])=="auto"))+ {+ timer.reset();+ for (uint k=0 ; k<nbtries ; ++k)+ {+ timer.start();+ bench_eigengemm(mc, ma, mb, nbloops);+ timer.stop();+ }+ if (!(std::string(argv[1])=="auto"))+ std::cout << "eigen : " << timer.value() << " (" << 1e-3*floor(1e-6*nbmad/timer.value()) << " GFlops/s)\n";+ else+ std::cout << M << " : " << timer.value() << " ; " << 1e-3*floor(1e-6*nbmad/timer.value()) << "\n";+ }++ std::cout << "l1: " << Eigen::l1CacheSize() << std::endl;+ std::cout << "l2: " << Eigen::l2CacheSize() << std::endl;+ ++ return 0;+}++using namespace Eigen;++void bench_eigengemm(MyMatrix& mc, const MyMatrix& ma, const MyMatrix& mb, int nbloops)+{+ for (uint j=0 ; j<nbloops ; ++j)+ mc.noalias() += ma * mb;+}++#define MYVERIFY(A,M) if (!(A)) { \+ std::cout << "FAIL: " << M << "\n"; \+ }+void check_product(int M, int N, int K)+{+ MyMatrix ma(M,K), mb(K,N), mc(M,N), maT(K,M), mbT(N,K), meigen(M,N), mref(M,N);+ ma = MyMatrix::Random(M,K);+ mb = MyMatrix::Random(K,N);+ maT = ma.transpose();+ mbT = mb.transpose();+ mc = MyMatrix::Random(M,N);++ MyMatrix::Scalar eps = 1e-4;++ meigen = mref = mc;+ CBLAS_GEMM(CblasColMajor, CblasNoTrans, CblasNoTrans, M, N, K, 1, ma.data(), M, mb.data(), K, 1, mref.data(), M);+ meigen += ma * mb;+ MYVERIFY(meigen.isApprox(mref, eps),". * .");++ meigen = mref = mc;+ CBLAS_GEMM(CblasColMajor, CblasTrans, CblasNoTrans, M, N, K, 1, maT.data(), K, mb.data(), K, 1, mref.data(), M);+ meigen += maT.transpose() * mb;+ MYVERIFY(meigen.isApprox(mref, eps),"T * .");++ meigen = mref = mc;+ CBLAS_GEMM(CblasColMajor, CblasTrans, CblasTrans, M, N, K, 1, maT.data(), K, mbT.data(), N, 1, mref.data(), M);+ meigen += (maT.transpose()) * (mbT.transpose());+ MYVERIFY(meigen.isApprox(mref, eps),"T * T");++ meigen = mref = mc;+ CBLAS_GEMM(CblasColMajor, CblasNoTrans, CblasTrans, M, N, K, 1, ma.data(), M, mbT.data(), N, 1, mref.data(), M);+ meigen += ma * mbT.transpose();+ MYVERIFY(meigen.isApprox(mref, eps),". * T");+}++void check_product(void)+{+ int M, N, K;+ for (uint i=0; i<1000; ++i)+ {+ M = internal::random<int>(1,64);+ N = internal::random<int>(1,768);+ K = internal::random<int>(1,768);+ M = (0 + M) * 1;+ std::cout << M << " x " << N << " x " << K << "\n";+ check_product(M, N, K);+ }+}+
+ eigen3/bench/benchCholesky.cpp view
@@ -0,0 +1,142 @@++// g++ -DNDEBUG -O3 -I.. benchLLT.cpp -o benchLLT && ./benchLLT+// options:+// -DBENCH_GSL -lgsl /usr/lib/libcblas.so.3+// -DEIGEN_DONT_VECTORIZE+// -msse2+// -DREPEAT=100+// -DTRIES=10+// -DSCALAR=double++#include <iostream>++#include <Eigen/Core>+#include <Eigen/Cholesky>+#include <bench/BenchUtil.h>+using namespace Eigen;++#ifndef REPEAT+#define REPEAT 10000+#endif++#ifndef TRIES+#define TRIES 10+#endif++typedef float Scalar;++template <typename MatrixType>+__attribute__ ((noinline)) void benchLLT(const MatrixType& m)+{+ int rows = m.rows();+ int cols = m.cols();++ int cost = 0;+ for (int j=0; j<rows; ++j)+ {+ int r = std::max(rows - j -1,0);+ cost += 2*(r*j+r+j);+ }++ int repeats = (REPEAT*1000)/(rows*rows);++ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;++ MatrixType a = MatrixType::Random(rows,cols);+ SquareMatrixType covMat = a * a.adjoint();++ BenchTimer timerNoSqrt, timerSqrt;++ Scalar acc = 0;+ int r = internal::random<int>(0,covMat.rows()-1);+ int c = internal::random<int>(0,covMat.cols()-1);+ for (int t=0; t<TRIES; ++t)+ {+ timerNoSqrt.start();+ for (int k=0; k<repeats; ++k)+ {+ LDLT<SquareMatrixType> cholnosqrt(covMat);+ acc += cholnosqrt.matrixL().coeff(r,c);+ }+ timerNoSqrt.stop();+ }++ for (int t=0; t<TRIES; ++t)+ {+ timerSqrt.start();+ for (int k=0; k<repeats; ++k)+ {+ LLT<SquareMatrixType> chol(covMat);+ acc += chol.matrixL().coeff(r,c);+ }+ timerSqrt.stop();+ }++ if (MatrixType::RowsAtCompileTime==Dynamic)+ std::cout << "dyn ";+ else+ std::cout << "fixed ";+ std::cout << covMat.rows() << " \t"+ << (timerNoSqrt.value() * REPEAT) / repeats << "s "+ << "(" << 1e-6 * cost*repeats/timerNoSqrt.value() << " MFLOPS)\t"+ << (timerSqrt.value() * REPEAT) / repeats << "s "+ << "(" << 1e-6 * cost*repeats/timerSqrt.value() << " MFLOPS)\n";+++ #ifdef BENCH_GSL+ if (MatrixType::RowsAtCompileTime==Dynamic)+ {+ timerSqrt.reset();++ gsl_matrix* gslCovMat = gsl_matrix_alloc(covMat.rows(),covMat.cols());+ gsl_matrix* gslCopy = gsl_matrix_alloc(covMat.rows(),covMat.cols());++ eiToGsl(covMat, &gslCovMat);+ for (int t=0; t<TRIES; ++t)+ {+ timerSqrt.start();+ for (int k=0; k<repeats; ++k)+ {+ gsl_matrix_memcpy(gslCopy,gslCovMat);+ gsl_linalg_cholesky_decomp(gslCopy);+ acc += gsl_matrix_get(gslCopy,r,c);+ }+ timerSqrt.stop();+ }++ std::cout << " | \t"+ << timerSqrt.value() * REPEAT / repeats << "s";++ gsl_matrix_free(gslCovMat);+ }+ #endif+ std::cout << "\n";+ // make sure the compiler does not optimize too much+ if (acc==123)+ std::cout << acc;+}++int main(int argc, char* argv[])+{+ const int dynsizes[] = {4,6,8,16,24,32,49,64,128,256,512,900,0};+ std::cout << "size no sqrt standard";+// #ifdef BENCH_GSL+// std::cout << " GSL (standard + double + ATLAS) ";+// #endif+ std::cout << "\n";+ for (uint i=0; dynsizes[i]>0; ++i)+ benchLLT(Matrix<Scalar,Dynamic,Dynamic>(dynsizes[i],dynsizes[i]));++ benchLLT(Matrix<Scalar,2,2>());+ benchLLT(Matrix<Scalar,3,3>());+ benchLLT(Matrix<Scalar,4,4>());+ benchLLT(Matrix<Scalar,5,5>());+ benchLLT(Matrix<Scalar,6,6>());+ benchLLT(Matrix<Scalar,7,7>());+ benchLLT(Matrix<Scalar,8,8>());+ benchLLT(Matrix<Scalar,12,12>());+ benchLLT(Matrix<Scalar,16,16>());+ return 0;+}+
+ eigen3/bench/benchEigenSolver.cpp view
@@ -0,0 +1,212 @@++// g++ -DNDEBUG -O3 -I.. benchEigenSolver.cpp -o benchEigenSolver && ./benchEigenSolver+// options:+// -DBENCH_GMM+// -DBENCH_GSL -lgsl /usr/lib/libcblas.so.3+// -DEIGEN_DONT_VECTORIZE+// -msse2+// -DREPEAT=100+// -DTRIES=10+// -DSCALAR=double++#include <iostream>++#include <Eigen/Core>+#include <Eigen/QR>+#include <bench/BenchUtil.h>+using namespace Eigen;++#ifndef REPEAT+#define REPEAT 1000+#endif++#ifndef TRIES+#define TRIES 4+#endif++#ifndef SCALAR+#define SCALAR float+#endif++typedef SCALAR Scalar;++template <typename MatrixType>+__attribute__ ((noinline)) void benchEigenSolver(const MatrixType& m)+{+ int rows = m.rows();+ int cols = m.cols();++ int stdRepeats = std::max(1,int((REPEAT*1000)/(rows*rows*sqrt(rows))));+ int saRepeats = stdRepeats * 4;++ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;++ MatrixType a = MatrixType::Random(rows,cols);+ SquareMatrixType covMat = a * a.adjoint();++ BenchTimer timerSa, timerStd;++ Scalar acc = 0;+ int r = internal::random<int>(0,covMat.rows()-1);+ int c = internal::random<int>(0,covMat.cols()-1);+ {+ SelfAdjointEigenSolver<SquareMatrixType> ei(covMat);+ for (int t=0; t<TRIES; ++t)+ {+ timerSa.start();+ for (int k=0; k<saRepeats; ++k)+ {+ ei.compute(covMat);+ acc += ei.eigenvectors().coeff(r,c);+ }+ timerSa.stop();+ }+ }++ {+ EigenSolver<SquareMatrixType> ei(covMat);+ for (int t=0; t<TRIES; ++t)+ {+ timerStd.start();+ for (int k=0; k<stdRepeats; ++k)+ {+ ei.compute(covMat);+ acc += ei.eigenvectors().coeff(r,c);+ }+ timerStd.stop();+ }+ }++ if (MatrixType::RowsAtCompileTime==Dynamic)+ std::cout << "dyn ";+ else+ std::cout << "fixed ";+ std::cout << covMat.rows() << " \t"+ << timerSa.value() * REPEAT / saRepeats << "s \t"+ << timerStd.value() * REPEAT / stdRepeats << "s";++ #ifdef BENCH_GMM+ if (MatrixType::RowsAtCompileTime==Dynamic)+ {+ timerSa.reset();+ timerStd.reset();++ gmm::dense_matrix<Scalar> gmmCovMat(covMat.rows(),covMat.cols());+ gmm::dense_matrix<Scalar> eigvect(covMat.rows(),covMat.cols());+ std::vector<Scalar> eigval(covMat.rows());+ eiToGmm(covMat, gmmCovMat);+ for (int t=0; t<TRIES; ++t)+ {+ timerSa.start();+ for (int k=0; k<saRepeats; ++k)+ {+ gmm::symmetric_qr_algorithm(gmmCovMat, eigval, eigvect);+ acc += eigvect(r,c);+ }+ timerSa.stop();+ }+ // the non-selfadjoint solver does not compute the eigen vectors+// for (int t=0; t<TRIES; ++t)+// {+// timerStd.start();+// for (int k=0; k<stdRepeats; ++k)+// {+// gmm::implicit_qr_algorithm(gmmCovMat, eigval, eigvect);+// acc += eigvect(r,c);+// }+// timerStd.stop();+// }++ std::cout << " | \t"+ << timerSa.value() * REPEAT / saRepeats << "s"+ << /*timerStd.value() * REPEAT / stdRepeats << "s"*/ " na ";+ }+ #endif++ #ifdef BENCH_GSL+ if (MatrixType::RowsAtCompileTime==Dynamic)+ {+ timerSa.reset();+ timerStd.reset();++ gsl_matrix* gslCovMat = gsl_matrix_alloc(covMat.rows(),covMat.cols());+ gsl_matrix* gslCopy = gsl_matrix_alloc(covMat.rows(),covMat.cols());+ gsl_matrix* eigvect = gsl_matrix_alloc(covMat.rows(),covMat.cols());+ gsl_vector* eigval = gsl_vector_alloc(covMat.rows());+ gsl_eigen_symmv_workspace* eisymm = gsl_eigen_symmv_alloc(covMat.rows());+ + gsl_matrix_complex* eigvectz = gsl_matrix_complex_alloc(covMat.rows(),covMat.cols());+ gsl_vector_complex* eigvalz = gsl_vector_complex_alloc(covMat.rows());+ gsl_eigen_nonsymmv_workspace* einonsymm = gsl_eigen_nonsymmv_alloc(covMat.rows());+ + eiToGsl(covMat, &gslCovMat);+ for (int t=0; t<TRIES; ++t)+ {+ timerSa.start();+ for (int k=0; k<saRepeats; ++k)+ {+ gsl_matrix_memcpy(gslCopy,gslCovMat);+ gsl_eigen_symmv(gslCopy, eigval, eigvect, eisymm);+ acc += gsl_matrix_get(eigvect,r,c);+ }+ timerSa.stop();+ }+ for (int t=0; t<TRIES; ++t)+ {+ timerStd.start();+ for (int k=0; k<stdRepeats; ++k)+ {+ gsl_matrix_memcpy(gslCopy,gslCovMat);+ gsl_eigen_nonsymmv(gslCopy, eigvalz, eigvectz, einonsymm);+ acc += GSL_REAL(gsl_matrix_complex_get(eigvectz,r,c));+ }+ timerStd.stop();+ }++ std::cout << " | \t"+ << timerSa.value() * REPEAT / saRepeats << "s \t"+ << timerStd.value() * REPEAT / stdRepeats << "s";++ gsl_matrix_free(gslCovMat);+ gsl_vector_free(gslCopy);+ gsl_matrix_free(eigvect);+ gsl_vector_free(eigval);+ gsl_matrix_complex_free(eigvectz);+ gsl_vector_complex_free(eigvalz);+ gsl_eigen_symmv_free(eisymm);+ gsl_eigen_nonsymmv_free(einonsymm);+ }+ #endif++ std::cout << "\n";+ + // make sure the compiler does not optimize too much+ if (acc==123)+ std::cout << acc;+}++int main(int argc, char* argv[])+{+ const int dynsizes[] = {4,6,8,12,16,24,32,64,128,256,512,0};+ std::cout << "size selfadjoint generic";+ #ifdef BENCH_GMM+ std::cout << " GMM++ ";+ #endif+ #ifdef BENCH_GSL+ std::cout << " GSL (double + ATLAS) ";+ #endif+ std::cout << "\n";+ for (uint i=0; dynsizes[i]>0; ++i)+ benchEigenSolver(Matrix<Scalar,Dynamic,Dynamic>(dynsizes[i],dynsizes[i]));++ benchEigenSolver(Matrix<Scalar,2,2>());+ benchEigenSolver(Matrix<Scalar,3,3>());+ benchEigenSolver(Matrix<Scalar,4,4>());+ benchEigenSolver(Matrix<Scalar,6,6>());+ benchEigenSolver(Matrix<Scalar,8,8>());+ benchEigenSolver(Matrix<Scalar,12,12>());+ benchEigenSolver(Matrix<Scalar,16,16>());+ return 0;+}+
+ eigen3/bench/benchFFT.cpp view
@@ -0,0 +1,115 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Mark Borgerding mark a borgerding net+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include <iostream>++#include <bench/BenchUtil.h>+#include <complex>+#include <vector>+#include <Eigen/Core>++#include <unsupported/Eigen/FFT>++using namespace Eigen;+using namespace std;+++template <typename T>+string nameof();++template <> string nameof<float>() {return "float";}+template <> string nameof<double>() {return "double";}+template <> string nameof<long double>() {return "long double";}++#ifndef TYPE+#define TYPE float+#endif++#ifndef NFFT+#define NFFT 1024+#endif+#ifndef NDATA+#define NDATA 1000000+#endif++using namespace Eigen;++template <typename T>+void bench(int nfft,bool fwd,bool unscaled=false, bool halfspec=false)+{+ typedef typename NumTraits<T>::Real Scalar;+ typedef typename std::complex<Scalar> Complex;+ int nits = NDATA/nfft;+ vector<T> inbuf(nfft);+ vector<Complex > outbuf(nfft);+ FFT< Scalar > fft;++ if (unscaled) {+ fft.SetFlag(fft.Unscaled);+ cout << "unscaled ";+ }+ if (halfspec) {+ fft.SetFlag(fft.HalfSpectrum);+ cout << "halfspec ";+ }+++ std::fill(inbuf.begin(),inbuf.end(),0);+ fft.fwd( outbuf , inbuf);++ BenchTimer timer;+ timer.reset();+ for (int k=0;k<8;++k) {+ timer.start();+ if (fwd)+ for(int i = 0; i < nits; i++)+ fft.fwd( outbuf , inbuf);+ else+ for(int i = 0; i < nits; i++)+ fft.inv(inbuf,outbuf);+ timer.stop();+ }++ cout << nameof<Scalar>() << " ";+ double mflops = 5.*nfft*log2((double)nfft) / (1e6 * timer.value() / (double)nits );+ if ( NumTraits<T>::IsComplex ) {+ cout << "complex";+ }else{+ cout << "real ";+ mflops /= 2;+ }+++ if (fwd)+ cout << " fwd";+ else+ cout << " inv";++ cout << " NFFT=" << nfft << " " << (double(1e-6*nfft*nits)/timer.value()) << " MS/s " << mflops << "MFLOPS\n";+}++int main(int argc,char ** argv)+{+ bench<complex<float> >(NFFT,true);+ bench<complex<float> >(NFFT,false);+ bench<float>(NFFT,true);+ bench<float>(NFFT,false);+ bench<float>(NFFT,false,true);+ bench<float>(NFFT,false,true,true);++ bench<complex<double> >(NFFT,true);+ bench<complex<double> >(NFFT,false);+ bench<double>(NFFT,true);+ bench<double>(NFFT,false);+ bench<complex<long double> >(NFFT,true);+ bench<complex<long double> >(NFFT,false);+ bench<long double>(NFFT,true);+ bench<long double>(NFFT,false);+ return 0;+}
+ eigen3/bench/benchGeometry.cpp view
@@ -0,0 +1,134 @@+#include <iostream>+#include <iomanip>+#include <Eigen/Core>+#include <Eigen/Geometry>+#include <bench/BenchTimer.h>++using namespace Eigen;+using namespace std;++#ifndef REPEAT+#define REPEAT 1000000+#endif++enum func_opt+{+ TV,+ TMATV,+ TMATVMAT,+};+++template <class res, class arg1, class arg2, int opt>+struct func;++template <class res, class arg1, class arg2>+struct func<res, arg1, arg2, TV>+{+ static EIGEN_DONT_INLINE res run( arg1& a1, arg2& a2 )+ {+ asm ("");+ return a1 * a2;+ }+};++template <class res, class arg1, class arg2>+struct func<res, arg1, arg2, TMATV>+{+ static EIGEN_DONT_INLINE res run( arg1& a1, arg2& a2 )+ {+ asm ("");+ return a1.matrix() * a2;+ }+};++template <class res, class arg1, class arg2>+struct func<res, arg1, arg2, TMATVMAT>+{+ static EIGEN_DONT_INLINE res run( arg1& a1, arg2& a2 )+ {+ asm ("");+ return res(a1.matrix() * a2.matrix());+ }+};++template <class func, class arg1, class arg2>+struct test_transform+{+ static void run()+ {+ arg1 a1;+ a1.setIdentity();+ arg2 a2;+ a2.setIdentity();++ BenchTimer timer;+ timer.reset();+ for (int k=0; k<10; ++k)+ {+ timer.start();+ for (int k=0; k<REPEAT; ++k)+ a2 = func::run( a1, a2 );+ timer.stop();+ }+ cout << setprecision(4) << fixed << timer.value() << "s " << endl;;+ }+};+++#define run_vec( op, scalar, mode, option, vsize ) \+ std::cout << #scalar << "\t " << #mode << "\t " << #option << " " << #vsize " "; \+ {\+ typedef Transform<scalar, 3, mode, option> Trans;\+ typedef Matrix<scalar, vsize, 1, option> Vec;\+ typedef func<Vec,Trans,Vec,op> Func;\+ test_transform< Func, Trans, Vec >::run();\+ }++#define run_trans( op, scalar, mode, option ) \+ std::cout << #scalar << "\t " << #mode << "\t " << #option << " "; \+ {\+ typedef Transform<scalar, 3, mode, option> Trans;\+ typedef func<Trans,Trans,Trans,op> Func;\+ test_transform< Func, Trans, Trans >::run();\+ }++int main(int argc, char* argv[])+{+ cout << "vec = trans * vec" << endl;+ run_vec(TV, float, Isometry, AutoAlign, 3);+ run_vec(TV, float, Isometry, DontAlign, 3);+ run_vec(TV, float, Isometry, AutoAlign, 4);+ run_vec(TV, float, Isometry, DontAlign, 4);+ run_vec(TV, float, Projective, AutoAlign, 4);+ run_vec(TV, float, Projective, DontAlign, 4);+ run_vec(TV, double, Isometry, AutoAlign, 3);+ run_vec(TV, double, Isometry, DontAlign, 3);+ run_vec(TV, double, Isometry, AutoAlign, 4);+ run_vec(TV, double, Isometry, DontAlign, 4);+ run_vec(TV, double, Projective, AutoAlign, 4);+ run_vec(TV, double, Projective, DontAlign, 4);++ cout << "vec = trans.matrix() * vec" << endl;+ run_vec(TMATV, float, Isometry, AutoAlign, 4);+ run_vec(TMATV, float, Isometry, DontAlign, 4);+ run_vec(TMATV, double, Isometry, AutoAlign, 4);+ run_vec(TMATV, double, Isometry, DontAlign, 4);++ cout << "trans = trans1 * trans" << endl;+ run_trans(TV, float, Isometry, AutoAlign);+ run_trans(TV, float, Isometry, DontAlign);+ run_trans(TV, double, Isometry, AutoAlign);+ run_trans(TV, double, Isometry, DontAlign);+ run_trans(TV, float, Projective, AutoAlign);+ run_trans(TV, float, Projective, DontAlign);+ run_trans(TV, double, Projective, AutoAlign);+ run_trans(TV, double, Projective, DontAlign);++ cout << "trans = trans1.matrix() * trans.matrix()" << endl;+ run_trans(TMATVMAT, float, Isometry, AutoAlign);+ run_trans(TMATVMAT, float, Isometry, DontAlign);+ run_trans(TMATVMAT, double, Isometry, AutoAlign);+ run_trans(TMATVMAT, double, Isometry, DontAlign);+}+
+ eigen3/bench/benchVecAdd.cpp view
@@ -0,0 +1,135 @@++#include <iostream>+#include <Eigen/Core>+#include <bench/BenchTimer.h>+using namespace Eigen;++#ifndef SIZE+#define SIZE 50+#endif++#ifndef REPEAT+#define REPEAT 10000+#endif++typedef float Scalar;++__attribute__ ((noinline)) void benchVec(Scalar* a, Scalar* b, Scalar* c, int size);+__attribute__ ((noinline)) void benchVec(MatrixXf& a, MatrixXf& b, MatrixXf& c);+__attribute__ ((noinline)) void benchVec(VectorXf& a, VectorXf& b, VectorXf& c);++int main(int argc, char* argv[])+{+ int size = SIZE * 8;+ int size2 = size * size;+ Scalar* a = internal::aligned_new<Scalar>(size2);+ Scalar* b = internal::aligned_new<Scalar>(size2+4)+1;+ Scalar* c = internal::aligned_new<Scalar>(size2); + + for (int i=0; i<size; ++i)+ {+ a[i] = b[i] = c[i] = 0;+ }+ + BenchTimer timer;+ + timer.reset();+ for (int k=0; k<10; ++k)+ {+ timer.start();+ benchVec(a, b, c, size2);+ timer.stop();+ }+ std::cout << timer.value() << "s " << (double(size2*REPEAT)/timer.value())/(1024.*1024.*1024.) << " GFlops\n";+ return 0;+ for (int innersize = size; innersize>2 ; --innersize)+ {+ if (size2%innersize==0)+ {+ int outersize = size2/innersize;+ MatrixXf ma = Map<MatrixXf>(a, innersize, outersize );+ MatrixXf mb = Map<MatrixXf>(b, innersize, outersize );+ MatrixXf mc = Map<MatrixXf>(c, innersize, outersize );+ timer.reset();+ for (int k=0; k<3; ++k)+ {+ timer.start();+ benchVec(ma, mb, mc);+ timer.stop();+ }+ std::cout << innersize << " x " << outersize << " " << timer.value() << "s " << (double(size2*REPEAT)/timer.value())/(1024.*1024.*1024.) << " GFlops\n";+ }+ }+ + VectorXf va = Map<VectorXf>(a, size2);+ VectorXf vb = Map<VectorXf>(b, size2);+ VectorXf vc = Map<VectorXf>(c, size2);+ timer.reset();+ for (int k=0; k<3; ++k)+ {+ timer.start();+ benchVec(va, vb, vc);+ timer.stop();+ }+ std::cout << timer.value() << "s " << (double(size2*REPEAT)/timer.value())/(1024.*1024.*1024.) << " GFlops\n";++ return 0;+}++void benchVec(MatrixXf& a, MatrixXf& b, MatrixXf& c)+{+ for (int k=0; k<REPEAT; ++k)+ a = a + b;+}++void benchVec(VectorXf& a, VectorXf& b, VectorXf& c)+{+ for (int k=0; k<REPEAT; ++k)+ a = a + b;+}++void benchVec(Scalar* a, Scalar* b, Scalar* c, int size)+{+ typedef internal::packet_traits<Scalar>::type PacketScalar;+ const int PacketSize = internal::packet_traits<Scalar>::size;+ PacketScalar a0, a1, a2, a3, b0, b1, b2, b3;+ for (int k=0; k<REPEAT; ++k)+ for (int i=0; i<size; i+=PacketSize*8)+ {+// a0 = internal::pload(&a[i]);+// b0 = internal::pload(&b[i]);+// a1 = internal::pload(&a[i+1*PacketSize]);+// b1 = internal::pload(&b[i+1*PacketSize]);+// a2 = internal::pload(&a[i+2*PacketSize]);+// b2 = internal::pload(&b[i+2*PacketSize]);+// a3 = internal::pload(&a[i+3*PacketSize]);+// b3 = internal::pload(&b[i+3*PacketSize]);+// internal::pstore(&a[i], internal::padd(a0, b0));+// a0 = internal::pload(&a[i+4*PacketSize]);+// b0 = internal::pload(&b[i+4*PacketSize]);+// +// internal::pstore(&a[i+1*PacketSize], internal::padd(a1, b1));+// a1 = internal::pload(&a[i+5*PacketSize]);+// b1 = internal::pload(&b[i+5*PacketSize]);+// +// internal::pstore(&a[i+2*PacketSize], internal::padd(a2, b2));+// a2 = internal::pload(&a[i+6*PacketSize]);+// b2 = internal::pload(&b[i+6*PacketSize]);+// +// internal::pstore(&a[i+3*PacketSize], internal::padd(a3, b3));+// a3 = internal::pload(&a[i+7*PacketSize]);+// b3 = internal::pload(&b[i+7*PacketSize]);+// +// internal::pstore(&a[i+4*PacketSize], internal::padd(a0, b0));+// internal::pstore(&a[i+5*PacketSize], internal::padd(a1, b1));+// internal::pstore(&a[i+6*PacketSize], internal::padd(a2, b2));+// internal::pstore(&a[i+7*PacketSize], internal::padd(a3, b3));+ + internal::pstore(&a[i+2*PacketSize], internal::padd(internal::ploadu(&a[i+2*PacketSize]), internal::ploadu(&b[i+2*PacketSize])));+ internal::pstore(&a[i+3*PacketSize], internal::padd(internal::ploadu(&a[i+3*PacketSize]), internal::ploadu(&b[i+3*PacketSize])));+ internal::pstore(&a[i+4*PacketSize], internal::padd(internal::ploadu(&a[i+4*PacketSize]), internal::ploadu(&b[i+4*PacketSize])));+ internal::pstore(&a[i+5*PacketSize], internal::padd(internal::ploadu(&a[i+5*PacketSize]), internal::ploadu(&b[i+5*PacketSize])));+ internal::pstore(&a[i+6*PacketSize], internal::padd(internal::ploadu(&a[i+6*PacketSize]), internal::ploadu(&b[i+6*PacketSize])));+ internal::pstore(&a[i+7*PacketSize], internal::padd(internal::ploadu(&a[i+7*PacketSize]), internal::ploadu(&b[i+7*PacketSize])));+ }+}
+ eigen3/bench/bench_gemm.cpp view
@@ -0,0 +1,271 @@++// g++-4.4 bench_gemm.cpp -I .. -O2 -DNDEBUG -lrt -fopenmp && OMP_NUM_THREADS=2 ./a.out+// icpc bench_gemm.cpp -I .. -O3 -DNDEBUG -lrt -openmp && OMP_NUM_THREADS=2 ./a.out++#include <iostream>+#include <Eigen/Core>+#include <bench/BenchTimer.h>++using namespace std;+using namespace Eigen;++#ifndef SCALAR+// #define SCALAR std::complex<float>+#define SCALAR float+#endif++typedef SCALAR Scalar;+typedef NumTraits<Scalar>::Real RealScalar;+typedef Matrix<RealScalar,Dynamic,Dynamic> A;+typedef Matrix</*Real*/Scalar,Dynamic,Dynamic> B;+typedef Matrix<Scalar,Dynamic,Dynamic> C;+typedef Matrix<RealScalar,Dynamic,Dynamic> M;++#ifdef HAVE_BLAS++extern "C" {+ #include <Eigen/src/misc/blas.h>+}++static float fone = 1;+static float fzero = 0;+static double done = 1;+static double szero = 0;+static std::complex<float> cfone = 1;+static std::complex<float> cfzero = 0;+static std::complex<double> cdone = 1;+static std::complex<double> cdzero = 0;+static char notrans = 'N';+static char trans = 'T'; +static char nonunit = 'N';+static char lower = 'L';+static char right = 'R';+static int intone = 1;++void blas_gemm(const MatrixXf& a, const MatrixXf& b, MatrixXf& c)+{+ int M = c.rows(); int N = c.cols(); int K = a.cols();+ int lda = a.rows(); int ldb = b.rows(); int ldc = c.rows();++ sgemm_(¬rans,¬rans,&M,&N,&K,&fone,+ const_cast<float*>(a.data()),&lda,+ const_cast<float*>(b.data()),&ldb,&fone,+ c.data(),&ldc);+}++EIGEN_DONT_INLINE void blas_gemm(const MatrixXd& a, const MatrixXd& b, MatrixXd& c)+{+ int M = c.rows(); int N = c.cols(); int K = a.cols();+ int lda = a.rows(); int ldb = b.rows(); int ldc = c.rows();++ dgemm_(¬rans,¬rans,&M,&N,&K,&done,+ const_cast<double*>(a.data()),&lda,+ const_cast<double*>(b.data()),&ldb,&done,+ c.data(),&ldc);+}++void blas_gemm(const MatrixXcf& a, const MatrixXcf& b, MatrixXcf& c)+{+ int M = c.rows(); int N = c.cols(); int K = a.cols();+ int lda = a.rows(); int ldb = b.rows(); int ldc = c.rows();++ cgemm_(¬rans,¬rans,&M,&N,&K,(float*)&cfone,+ const_cast<float*>((const float*)a.data()),&lda,+ const_cast<float*>((const float*)b.data()),&ldb,(float*)&cfone,+ (float*)c.data(),&ldc);+}++void blas_gemm(const MatrixXcd& a, const MatrixXcd& b, MatrixXcd& c)+{+ int M = c.rows(); int N = c.cols(); int K = a.cols();+ int lda = a.rows(); int ldb = b.rows(); int ldc = c.rows();++ zgemm_(¬rans,¬rans,&M,&N,&K,(double*)&cdone,+ const_cast<double*>((const double*)a.data()),&lda,+ const_cast<double*>((const double*)b.data()),&ldb,(double*)&cdone,+ (double*)c.data(),&ldc);+}++++#endif++void matlab_cplx_cplx(const M& ar, const M& ai, const M& br, const M& bi, M& cr, M& ci)+{+ cr.noalias() += ar * br;+ cr.noalias() -= ai * bi;+ ci.noalias() += ar * bi;+ ci.noalias() += ai * br;+}++void matlab_real_cplx(const M& a, const M& br, const M& bi, M& cr, M& ci)+{+ cr.noalias() += a * br;+ ci.noalias() += a * bi;+}++void matlab_cplx_real(const M& ar, const M& ai, const M& b, M& cr, M& ci)+{+ cr.noalias() += ar * b;+ ci.noalias() += ai * b;+}++template<typename A, typename B, typename C>+EIGEN_DONT_INLINE void gemm(const A& a, const B& b, C& c)+{+ c.noalias() += a * b;+}++int main(int argc, char ** argv)+{+ std::ptrdiff_t l1 = internal::queryL1CacheSize();+ std::ptrdiff_t l2 = internal::queryTopLevelCacheSize();+ std::cout << "L1 cache size = " << (l1>0 ? l1/1024 : -1) << " KB\n";+ std::cout << "L2/L3 cache size = " << (l2>0 ? l2/1024 : -1) << " KB\n";+ typedef internal::gebp_traits<Scalar,Scalar> Traits;+ std::cout << "Register blocking = " << Traits::mr << " x " << Traits::nr << "\n";++ int rep = 1; // number of repetitions per try+ int tries = 2; // number of tries, we keep the best++ int s = 2048;+ int cache_size = -1;++ bool need_help = false;+ for (int i=1; i<argc; ++i)+ {+ if(argv[i][0]=='s')+ s = atoi(argv[i]+1);+ else if(argv[i][0]=='c')+ cache_size = atoi(argv[i]+1);+ else if(argv[i][0]=='t')+ tries = atoi(argv[i]+1);+ else if(argv[i][0]=='p')+ rep = atoi(argv[i]+1);+ else+ need_help = true;+ }++ if(need_help)+ {+ std::cout << argv[0] << " s<matrix size> c<cache size> t<nb tries> p<nb repeats>\n";+ return 1;+ }++ if(cache_size>0)+ setCpuCacheSizes(cache_size,96*cache_size);++ int m = s;+ int n = s;+ int p = s;+ A a(m,p); a.setRandom();+ B b(p,n); b.setRandom();+ C c(m,n); c.setOnes();+ C rc = c;++ std::cout << "Matrix sizes = " << m << "x" << p << " * " << p << "x" << n << "\n";+ std::ptrdiff_t mc(m), nc(n), kc(p);+ internal::computeProductBlockingSizes<Scalar,Scalar>(kc, mc, nc);+ std::cout << "blocking size (mc x kc) = " << mc << " x " << kc << "\n";++ C r = c;++ // check the parallel product is correct+ #if defined EIGEN_HAS_OPENMP+ int procs = omp_get_max_threads();+ if(procs>1)+ {+ #ifdef HAVE_BLAS+ blas_gemm(a,b,r);+ #else+ omp_set_num_threads(1);+ r.noalias() += a * b;+ omp_set_num_threads(procs);+ #endif+ c.noalias() += a * b;+ if(!r.isApprox(c)) std::cerr << "Warning, your parallel product is crap!\n\n";+ }+ #elif defined HAVE_BLAS+ blas_gemm(a,b,r);+ c.noalias() += a * b;+ if(!r.isApprox(c)) std::cerr << "Warning, your product is crap!\n\n";+ #else+ gemm(a,b,c);+ r.noalias() += a.cast<Scalar>() * b.cast<Scalar>();+ if(!r.isApprox(c)) std::cerr << "Warning, your product is crap!\n\n";+ #endif++ #ifdef HAVE_BLAS+ BenchTimer tblas;+ c = rc;+ BENCH(tblas, tries, rep, blas_gemm(a,b,c));+ std::cout << "blas cpu " << tblas.best(CPU_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/tblas.best(CPU_TIMER))*1e-9 << " GFLOPS \t(" << tblas.total(CPU_TIMER) << "s)\n";+ std::cout << "blas real " << tblas.best(REAL_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/tblas.best(REAL_TIMER))*1e-9 << " GFLOPS \t(" << tblas.total(REAL_TIMER) << "s)\n";+ #endif++ BenchTimer tmt;+ c = rc;+ BENCH(tmt, tries, rep, gemm(a,b,c));+ std::cout << "eigen cpu " << tmt.best(CPU_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/tmt.best(CPU_TIMER))*1e-9 << " GFLOPS \t(" << tmt.total(CPU_TIMER) << "s)\n";+ std::cout << "eigen real " << tmt.best(REAL_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/tmt.best(REAL_TIMER))*1e-9 << " GFLOPS \t(" << tmt.total(REAL_TIMER) << "s)\n";++ #ifdef EIGEN_HAS_OPENMP+ if(procs>1)+ {+ BenchTimer tmono;+ omp_set_num_threads(1);+ Eigen::internal::setNbThreads(1);+ c = rc;+ BENCH(tmono, tries, rep, gemm(a,b,c));+ std::cout << "eigen mono cpu " << tmono.best(CPU_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/tmono.best(CPU_TIMER))*1e-9 << " GFLOPS \t(" << tmono.total(CPU_TIMER) << "s)\n";+ std::cout << "eigen mono real " << tmono.best(REAL_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/tmono.best(REAL_TIMER))*1e-9 << " GFLOPS \t(" << tmono.total(REAL_TIMER) << "s)\n";+ std::cout << "mt speed up x" << tmono.best(CPU_TIMER) / tmt.best(REAL_TIMER) << " => " << (100.0*tmono.best(CPU_TIMER) / tmt.best(REAL_TIMER))/procs << "%\n";+ }+ #endif+ + #ifdef DECOUPLED+ if((NumTraits<A::Scalar>::IsComplex) && (NumTraits<B::Scalar>::IsComplex))+ {+ M ar(m,p); ar.setRandom();+ M ai(m,p); ai.setRandom();+ M br(p,n); br.setRandom();+ M bi(p,n); bi.setRandom();+ M cr(m,n); cr.setRandom();+ M ci(m,n); ci.setRandom();+ + BenchTimer t;+ BENCH(t, tries, rep, matlab_cplx_cplx(ar,ai,br,bi,cr,ci));+ std::cout << "\"matlab\" cpu " << t.best(CPU_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/t.best(CPU_TIMER))*1e-9 << " GFLOPS \t(" << t.total(CPU_TIMER) << "s)\n";+ std::cout << "\"matlab\" real " << t.best(REAL_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/t.best(REAL_TIMER))*1e-9 << " GFLOPS \t(" << t.total(REAL_TIMER) << "s)\n";+ }+ if((!NumTraits<A::Scalar>::IsComplex) && (NumTraits<B::Scalar>::IsComplex))+ {+ M a(m,p); a.setRandom();+ M br(p,n); br.setRandom();+ M bi(p,n); bi.setRandom();+ M cr(m,n); cr.setRandom();+ M ci(m,n); ci.setRandom();+ + BenchTimer t;+ BENCH(t, tries, rep, matlab_real_cplx(a,br,bi,cr,ci));+ std::cout << "\"matlab\" cpu " << t.best(CPU_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/t.best(CPU_TIMER))*1e-9 << " GFLOPS \t(" << t.total(CPU_TIMER) << "s)\n";+ std::cout << "\"matlab\" real " << t.best(REAL_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/t.best(REAL_TIMER))*1e-9 << " GFLOPS \t(" << t.total(REAL_TIMER) << "s)\n";+ }+ if((NumTraits<A::Scalar>::IsComplex) && (!NumTraits<B::Scalar>::IsComplex))+ {+ M ar(m,p); ar.setRandom();+ M ai(m,p); ai.setRandom();+ M b(p,n); b.setRandom();+ M cr(m,n); cr.setRandom();+ M ci(m,n); ci.setRandom();+ + BenchTimer t;+ BENCH(t, tries, rep, matlab_cplx_real(ar,ai,b,cr,ci));+ std::cout << "\"matlab\" cpu " << t.best(CPU_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/t.best(CPU_TIMER))*1e-9 << " GFLOPS \t(" << t.total(CPU_TIMER) << "s)\n";+ std::cout << "\"matlab\" real " << t.best(REAL_TIMER)/rep << "s \t" << (double(m)*n*p*rep*2/t.best(REAL_TIMER))*1e-9 << " GFLOPS \t(" << t.total(REAL_TIMER) << "s)\n";+ }+ #endif++ return 0;+}+
+ eigen3/bench/bench_multi_compilers.sh view
@@ -0,0 +1,28 @@+#!/bin/bash++if (($# < 2)); then+ echo "Usage: $0 compilerlist.txt benchfile.cpp"+else++compilerlist=$1+benchfile=$2++g=0+source $compilerlist++# for each compiler, compile benchfile and run the benchmark+for (( i=0 ; i<g ; ++i )) ; do+ # check the compiler exists+ compiler=`echo ${CLIST[$i]} | cut -d " " -f 1`+ if [ -e `which $compiler` ]; then+ echo "${CLIST[$i]}"+# echo "${CLIST[$i]} $benchfile -I.. -o bench~"+# if [ -e ./.bench ] ; then rm .bench; fi+ ${CLIST[$i]} $benchfile -I.. -o .bench && ./.bench 2> /dev/null+ echo ""+ else+ echo "compiler not found: $compiler"+ fi+done++fi
+ eigen3/bench/bench_norm.cpp view
@@ -0,0 +1,345 @@+#include <typeinfo>+#include <iostream>+#include <Eigen/Core>+#include "BenchTimer.h"+using namespace Eigen;+using namespace std;++template<typename T>+EIGEN_DONT_INLINE typename T::Scalar sqsumNorm(const T& v)+{+ return v.norm();+}++template<typename T>+EIGEN_DONT_INLINE typename T::Scalar hypotNorm(const T& v)+{+ return v.hypotNorm();+}++template<typename T>+EIGEN_DONT_INLINE typename T::Scalar blueNorm(const T& v)+{+ return v.blueNorm();+}++template<typename T>+EIGEN_DONT_INLINE typename T::Scalar lapackNorm(T& v)+{+ typedef typename T::Scalar Scalar;+ int n = v.size();+ Scalar scale = 0;+ Scalar ssq = 1;+ for (int i=0;i<n;++i)+ {+ Scalar ax = internal::abs(v.coeff(i));+ if (scale >= ax)+ {+ ssq += internal::abs2(ax/scale);+ }+ else+ {+ ssq = Scalar(1) + ssq * internal::abs2(scale/ax);+ scale = ax;+ }+ }+ return scale * internal::sqrt(ssq);+}++template<typename T>+EIGEN_DONT_INLINE typename T::Scalar twopassNorm(T& v)+{+ typedef typename T::Scalar Scalar;+ Scalar s = v.cwise().abs().maxCoeff();+ return s*(v/s).norm();+}++template<typename T>+EIGEN_DONT_INLINE typename T::Scalar bl2passNorm(T& v)+{+ return v.stableNorm();+}++template<typename T>+EIGEN_DONT_INLINE typename T::Scalar divacNorm(T& v)+{+ int n =v.size() / 2;+ for (int i=0;i<n;++i)+ v(i) = v(2*i)*v(2*i) + v(2*i+1)*v(2*i+1);+ n = n/2;+ while (n>0)+ {+ for (int i=0;i<n;++i)+ v(i) = v(2*i) + v(2*i+1);+ n = n/2;+ }+ return internal::sqrt(v(0));+}++#ifdef EIGEN_VECTORIZE+Packet4f internal::plt(const Packet4f& a, Packet4f& b) { return _mm_cmplt_ps(a,b); }+Packet2d internal::plt(const Packet2d& a, Packet2d& b) { return _mm_cmplt_pd(a,b); }++Packet4f internal::pandnot(const Packet4f& a, Packet4f& b) { return _mm_andnot_ps(a,b); }+Packet2d internal::pandnot(const Packet2d& a, Packet2d& b) { return _mm_andnot_pd(a,b); }+#endif++template<typename T>+EIGEN_DONT_INLINE typename T::Scalar pblueNorm(const T& v)+{+ #ifndef EIGEN_VECTORIZE+ return v.blueNorm();+ #else+ typedef typename T::Scalar Scalar;++ static int nmax = 0;+ static Scalar b1, b2, s1m, s2m, overfl, rbig, relerr;+ int n;++ if(nmax <= 0)+ {+ int nbig, ibeta, it, iemin, iemax, iexp;+ Scalar abig, eps;++ nbig = std::numeric_limits<int>::max(); // largest integer+ ibeta = std::numeric_limits<Scalar>::radix; //NumTraits<Scalar>::Base; // base for floating-point numbers+ it = std::numeric_limits<Scalar>::digits; //NumTraits<Scalar>::Mantissa; // number of base-beta digits in mantissa+ iemin = std::numeric_limits<Scalar>::min_exponent; // minimum exponent+ iemax = std::numeric_limits<Scalar>::max_exponent; // maximum exponent+ rbig = std::numeric_limits<Scalar>::max(); // largest floating-point number++ // Check the basic machine-dependent constants.+ if(iemin > 1 - 2*it || 1+it>iemax || (it==2 && ibeta<5)+ || (it<=4 && ibeta <= 3 ) || it<2)+ {+ eigen_assert(false && "the algorithm cannot be guaranteed on this computer");+ }+ iexp = -((1-iemin)/2);+ b1 = std::pow(ibeta, iexp); // lower boundary of midrange+ iexp = (iemax + 1 - it)/2;+ b2 = std::pow(ibeta,iexp); // upper boundary of midrange++ iexp = (2-iemin)/2;+ s1m = std::pow(ibeta,iexp); // scaling factor for lower range+ iexp = - ((iemax+it)/2);+ s2m = std::pow(ibeta,iexp); // scaling factor for upper range++ overfl = rbig*s2m; // overfow boundary for abig+ eps = std::pow(ibeta, 1-it);+ relerr = internal::sqrt(eps); // tolerance for neglecting asml+ abig = 1.0/eps - 1.0;+ if (Scalar(nbig)>abig) nmax = abig; // largest safe n+ else nmax = nbig;+ }++ typedef typename internal::packet_traits<Scalar>::type Packet;+ const int ps = internal::packet_traits<Scalar>::size;+ Packet pasml = internal::pset1(Scalar(0));+ Packet pamed = internal::pset1(Scalar(0));+ Packet pabig = internal::pset1(Scalar(0));+ Packet ps2m = internal::pset1(s2m);+ Packet ps1m = internal::pset1(s1m);+ Packet pb2 = internal::pset1(b2);+ Packet pb1 = internal::pset1(b1);+ for(int j=0; j<v.size(); j+=ps)+ {+ Packet ax = internal::pabs(v.template packet<Aligned>(j));+ Packet ax_s2m = internal::pmul(ax,ps2m);+ Packet ax_s1m = internal::pmul(ax,ps1m);+ Packet maskBig = internal::plt(pb2,ax);+ Packet maskSml = internal::plt(ax,pb1);++// Packet maskMed = internal::pand(maskSml,maskBig);+// Packet scale = internal::pset1(Scalar(0));+// scale = internal::por(scale, internal::pand(maskBig,ps2m));+// scale = internal::por(scale, internal::pand(maskSml,ps1m));+// scale = internal::por(scale, internal::pandnot(internal::pset1(Scalar(1)),maskMed));+// ax = internal::pmul(ax,scale);+// ax = internal::pmul(ax,ax);+// pabig = internal::padd(pabig, internal::pand(maskBig, ax));+// pasml = internal::padd(pasml, internal::pand(maskSml, ax));+// pamed = internal::padd(pamed, internal::pandnot(ax,maskMed));+++ pabig = internal::padd(pabig, internal::pand(maskBig, internal::pmul(ax_s2m,ax_s2m)));+ pasml = internal::padd(pasml, internal::pand(maskSml, internal::pmul(ax_s1m,ax_s1m)));+ pamed = internal::padd(pamed, internal::pandnot(internal::pmul(ax,ax),internal::pand(maskSml,maskBig)));+ }+ Scalar abig = internal::predux(pabig);+ Scalar asml = internal::predux(pasml);+ Scalar amed = internal::predux(pamed);+ if(abig > Scalar(0))+ {+ abig = internal::sqrt(abig);+ if(abig > overfl)+ {+ eigen_assert(false && "overflow");+ return rbig;+ }+ if(amed > Scalar(0))+ {+ abig = abig/s2m;+ amed = internal::sqrt(amed);+ }+ else+ {+ return abig/s2m;+ }++ }+ else if(asml > Scalar(0))+ {+ if (amed > Scalar(0))+ {+ abig = internal::sqrt(amed);+ amed = internal::sqrt(asml) / s1m;+ }+ else+ {+ return internal::sqrt(asml)/s1m;+ }+ }+ else+ {+ return internal::sqrt(amed);+ }+ asml = std::min(abig, amed);+ abig = std::max(abig, amed);+ if(asml <= abig*relerr)+ return abig;+ else+ return abig * internal::sqrt(Scalar(1) + internal::abs2(asml/abig));+ #endif+}++#define BENCH_PERF(NRM) { \+ Eigen::BenchTimer tf, td, tcf; tf.reset(); td.reset(); tcf.reset();\+ for (int k=0; k<tries; ++k) { \+ tf.start(); \+ for (int i=0; i<iters; ++i) NRM(vf); \+ tf.stop(); \+ } \+ for (int k=0; k<tries; ++k) { \+ td.start(); \+ for (int i=0; i<iters; ++i) NRM(vd); \+ td.stop(); \+ } \+ for (int k=0; k<std::max(1,tries/3); ++k) { \+ tcf.start(); \+ for (int i=0; i<iters; ++i) NRM(vcf); \+ tcf.stop(); \+ } \+ std::cout << #NRM << "\t" << tf.value() << " " << td.value() << " " << tcf.value() << "\n"; \+}++void check_accuracy(double basef, double based, int s)+{+ double yf = basef * internal::abs(internal::random<double>());+ double yd = based * internal::abs(internal::random<double>());+ VectorXf vf = VectorXf::Ones(s) * yf;+ VectorXd vd = VectorXd::Ones(s) * yd;++ std::cout << "reference\t" << internal::sqrt(double(s))*yf << "\t" << internal::sqrt(double(s))*yd << "\n";+ std::cout << "sqsumNorm\t" << sqsumNorm(vf) << "\t" << sqsumNorm(vd) << "\n";+ std::cout << "hypotNorm\t" << hypotNorm(vf) << "\t" << hypotNorm(vd) << "\n";+ std::cout << "blueNorm\t" << blueNorm(vf) << "\t" << blueNorm(vd) << "\n";+ std::cout << "pblueNorm\t" << pblueNorm(vf) << "\t" << pblueNorm(vd) << "\n";+ std::cout << "lapackNorm\t" << lapackNorm(vf) << "\t" << lapackNorm(vd) << "\n";+ std::cout << "twopassNorm\t" << twopassNorm(vf) << "\t" << twopassNorm(vd) << "\n";+ std::cout << "bl2passNorm\t" << bl2passNorm(vf) << "\t" << bl2passNorm(vd) << "\n";+}++void check_accuracy_var(int ef0, int ef1, int ed0, int ed1, int s)+{+ VectorXf vf(s);+ VectorXd vd(s);+ for (int i=0; i<s; ++i)+ {+ vf[i] = internal::abs(internal::random<double>()) * std::pow(double(10), internal::random<int>(ef0,ef1));+ vd[i] = internal::abs(internal::random<double>()) * std::pow(double(10), internal::random<int>(ed0,ed1));+ }++ //std::cout << "reference\t" << internal::sqrt(double(s))*yf << "\t" << internal::sqrt(double(s))*yd << "\n";+ std::cout << "sqsumNorm\t" << sqsumNorm(vf) << "\t" << sqsumNorm(vd) << "\t" << sqsumNorm(vf.cast<long double>()) << "\t" << sqsumNorm(vd.cast<long double>()) << "\n";+ std::cout << "hypotNorm\t" << hypotNorm(vf) << "\t" << hypotNorm(vd) << "\t" << hypotNorm(vf.cast<long double>()) << "\t" << hypotNorm(vd.cast<long double>()) << "\n";+ std::cout << "blueNorm\t" << blueNorm(vf) << "\t" << blueNorm(vd) << "\t" << blueNorm(vf.cast<long double>()) << "\t" << blueNorm(vd.cast<long double>()) << "\n";+ std::cout << "pblueNorm\t" << pblueNorm(vf) << "\t" << pblueNorm(vd) << "\t" << blueNorm(vf.cast<long double>()) << "\t" << blueNorm(vd.cast<long double>()) << "\n";+ std::cout << "lapackNorm\t" << lapackNorm(vf) << "\t" << lapackNorm(vd) << "\t" << lapackNorm(vf.cast<long double>()) << "\t" << lapackNorm(vd.cast<long double>()) << "\n";+ std::cout << "twopassNorm\t" << twopassNorm(vf) << "\t" << twopassNorm(vd) << "\t" << twopassNorm(vf.cast<long double>()) << "\t" << twopassNorm(vd.cast<long double>()) << "\n";+// std::cout << "bl2passNorm\t" << bl2passNorm(vf) << "\t" << bl2passNorm(vd) << "\t" << bl2passNorm(vf.cast<long double>()) << "\t" << bl2passNorm(vd.cast<long double>()) << "\n";+}++int main(int argc, char** argv)+{+ int tries = 10;+ int iters = 100000;+ double y = 1.1345743233455785456788e12 * internal::random<double>();+ VectorXf v = VectorXf::Ones(1024) * y;++// return 0;+ int s = 10000;+ double basef_ok = 1.1345743233455785456788e15;+ double based_ok = 1.1345743233455785456788e95;++ double basef_under = 1.1345743233455785456788e-27;+ double based_under = 1.1345743233455785456788e-303;++ double basef_over = 1.1345743233455785456788e+27;+ double based_over = 1.1345743233455785456788e+302;++ std::cout.precision(20);++ std::cerr << "\nNo under/overflow:\n";+ check_accuracy(basef_ok, based_ok, s);++ std::cerr << "\nUnderflow:\n";+ check_accuracy(basef_under, based_under, s);++ std::cerr << "\nOverflow:\n";+ check_accuracy(basef_over, based_over, s);++ std::cerr << "\nVarying (over):\n";+ for (int k=0; k<1; ++k)+ {+ check_accuracy_var(20,27,190,302,s);+ std::cout << "\n";+ }++ std::cerr << "\nVarying (under):\n";+ for (int k=0; k<1; ++k)+ {+ check_accuracy_var(-27,20,-302,-190,s);+ std::cout << "\n";+ }++ std::cout.precision(4);+ std::cerr << "Performance (out of cache):\n";+ {+ int iters = 1;+ VectorXf vf = VectorXf::Random(1024*1024*32) * y;+ VectorXd vd = VectorXd::Random(1024*1024*32) * y;+ VectorXcf vcf = VectorXcf::Random(1024*1024*32) * y;+ BENCH_PERF(sqsumNorm);+ BENCH_PERF(blueNorm);+// BENCH_PERF(pblueNorm);+// BENCH_PERF(lapackNorm);+// BENCH_PERF(hypotNorm);+// BENCH_PERF(twopassNorm);+ BENCH_PERF(bl2passNorm);+ }++ std::cerr << "\nPerformance (in cache):\n";+ {+ int iters = 100000;+ VectorXf vf = VectorXf::Random(512) * y;+ VectorXd vd = VectorXd::Random(512) * y;+ VectorXcf vcf = VectorXcf::Random(512) * y;+ BENCH_PERF(sqsumNorm);+ BENCH_PERF(blueNorm);+// BENCH_PERF(pblueNorm);+// BENCH_PERF(lapackNorm);+// BENCH_PERF(hypotNorm);+// BENCH_PERF(twopassNorm);+ BENCH_PERF(bl2passNorm);+ }+}
+ eigen3/bench/bench_reverse.cpp view
@@ -0,0 +1,84 @@++#include <iostream>+#include <Eigen/Core>+#include <bench/BenchUtil.h>+using namespace Eigen;++#ifndef REPEAT+#define REPEAT 100000+#endif++#ifndef TRIES+#define TRIES 20+#endif++typedef double Scalar;++template <typename MatrixType>+__attribute__ ((noinline)) void bench_reverse(const MatrixType& m)+{+ int rows = m.rows();+ int cols = m.cols();+ int size = m.size();++ int repeats = (REPEAT*1000)/size;+ MatrixType a = MatrixType::Random(rows,cols);+ MatrixType b = MatrixType::Random(rows,cols);++ BenchTimer timerB, timerH, timerV;++ Scalar acc = 0;+ int r = internal::random<int>(0,rows-1);+ int c = internal::random<int>(0,cols-1);+ for (int t=0; t<TRIES; ++t)+ {+ timerB.start();+ for (int k=0; k<repeats; ++k)+ {+ asm("#begin foo");+ b = a.reverse();+ asm("#end foo");+ acc += b.coeff(r,c);+ }+ timerB.stop();+ }++ if (MatrixType::RowsAtCompileTime==Dynamic)+ std::cout << "dyn ";+ else+ std::cout << "fixed ";+ std::cout << rows << " x " << cols << " \t"+ << (timerB.value() * REPEAT) / repeats << "s "+ << "(" << 1e-6 * size*repeats/timerB.value() << " MFLOPS)\t";++ std::cout << "\n";+ // make sure the compiler does not optimize too much+ if (acc==123)+ std::cout << acc;+}++int main(int argc, char* argv[])+{+ const int dynsizes[] = {4,6,8,16,24,32,49,64,128,256,512,900,0};+ std::cout << "size no sqrt standard";+// #ifdef BENCH_GSL+// std::cout << " GSL (standard + double + ATLAS) ";+// #endif+ std::cout << "\n";+ for (uint i=0; dynsizes[i]>0; ++i)+ {+ bench_reverse(Matrix<Scalar,Dynamic,Dynamic>(dynsizes[i],dynsizes[i]));+ bench_reverse(Matrix<Scalar,Dynamic,1>(dynsizes[i]*dynsizes[i]));+ }+// bench_reverse(Matrix<Scalar,2,2>());+// bench_reverse(Matrix<Scalar,3,3>());+// bench_reverse(Matrix<Scalar,4,4>());+// bench_reverse(Matrix<Scalar,5,5>());+// bench_reverse(Matrix<Scalar,6,6>());+// bench_reverse(Matrix<Scalar,7,7>());+// bench_reverse(Matrix<Scalar,8,8>());+// bench_reverse(Matrix<Scalar,12,12>());+// bench_reverse(Matrix<Scalar,16,16>());+ return 0;+}+
+ eigen3/bench/bench_sum.cpp view
@@ -0,0 +1,18 @@+#include <iostream>+#include <Eigen/Core>+using namespace Eigen;+using namespace std;++int main() +{+ typedef Matrix<SCALAR,Eigen::Dynamic,1> Vec;+ Vec v(SIZE);+ v.setZero();+ v[0] = 1;+ v[1] = 2;+ for(int i = 0; i < 1000000; i++)+ {+ v.coeffRef(0) += v.sum() * SCALAR(1e-20);+ }+ cout << v.sum() << endl;+}
+ eigen3/bench/bench_unrolling view
@@ -0,0 +1,12 @@+#!/bin/bash++# gcc : CXX="g++ -finline-limit=10000 -ftemplate-depth-2000 --param max-inline-recursive-depth=2000"+# icc : CXX="icpc -fast -no-inline-max-size -fno-exceptions"+CXX=${CXX-g++ -finline-limit=10000 -ftemplate-depth-2000 --param max-inline-recursive-depth=2000} # default value++for ((i=1; i<16; ++i)); do+ echo "Matrix size: $i x $i :"+ $CXX -O3 -I.. -DNDEBUG benchmark.cpp -DMATSIZE=$i -DEIGEN_UNROLLING_LIMIT=400 -o benchmark && time ./benchmark >/dev/null+ $CXX -O3 -I.. -DNDEBUG -finline-limit=10000 benchmark.cpp -DMATSIZE=$i -DEIGEN_DONT_USE_UNROLLED_LOOPS=1 -o benchmark && time ./benchmark >/dev/null+ echo " "+done
+ eigen3/bench/benchmark.cpp view
@@ -0,0 +1,39 @@+// g++ -O3 -DNDEBUG -DMATSIZE=<x> benchmark.cpp -o benchmark && time ./benchmark++#include <iostream>++#include <Eigen/Core>++#ifndef MATSIZE+#define MATSIZE 3+#endif++using namespace std;+using namespace Eigen;++#ifndef REPEAT+#define REPEAT 40000000+#endif++#ifndef SCALAR+#define SCALAR double+#endif++int main(int argc, char *argv[])+{+ Matrix<SCALAR,MATSIZE,MATSIZE> I = Matrix<SCALAR,MATSIZE,MATSIZE>::Ones();+ Matrix<SCALAR,MATSIZE,MATSIZE> m;+ for(int i = 0; i < MATSIZE; i++)+ for(int j = 0; j < MATSIZE; j++)+ {+ m(i,j) = (i+MATSIZE*j);+ }+ asm("#begin");+ for(int a = 0; a < REPEAT; a++)+ {+ m = Matrix<SCALAR,MATSIZE,MATSIZE>::Ones() + 0.00005 * (m + (m*m));+ }+ asm("#end");+ cout << m << endl;+ return 0;+}
+ eigen3/bench/benchmarkSlice.cpp view
@@ -0,0 +1,38 @@+// g++ -O3 -DNDEBUG benchmarkX.cpp -o benchmarkX && time ./benchmarkX++#include <iostream>++#include <Eigen/Core>++using namespace std;+using namespace Eigen;++#ifndef REPEAT+#define REPEAT 10000+#endif++#ifndef SCALAR+#define SCALAR float+#endif++int main(int argc, char *argv[])+{+ typedef Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> Mat;+ Mat m(100, 100);+ m.setRandom();++ for(int a = 0; a < REPEAT; a++)+ {+ int r, c, nr, nc;+ r = Eigen::internal::random<int>(0,10);+ c = Eigen::internal::random<int>(0,10);+ nr = Eigen::internal::random<int>(50,80);+ nc = Eigen::internal::random<int>(50,80);+ m.block(r,c,nr,nc) += Mat::Ones(nr,nc);+ m.block(r,c,nr,nc) *= SCALAR(10);+ m.block(r,c,nr,nc) -= Mat::constant(nr,nc,10);+ m.block(r,c,nr,nc) /= SCALAR(10);+ }+ cout << m[0] << endl;+ return 0;+}
+ eigen3/bench/benchmarkX.cpp view
@@ -0,0 +1,36 @@+// g++ -fopenmp -I .. -O3 -DNDEBUG -finline-limit=1000 benchmarkX.cpp -o b && time ./b++#include <iostream>++#include <Eigen/Core>++using namespace std;+using namespace Eigen;++#ifndef MATTYPE+#define MATTYPE MatrixXLd+#endif++#ifndef MATSIZE+#define MATSIZE 400+#endif++#ifndef REPEAT+#define REPEAT 100+#endif++int main(int argc, char *argv[])+{+ MATTYPE I = MATTYPE::Ones(MATSIZE,MATSIZE);+ MATTYPE m(MATSIZE,MATSIZE);+ for(int i = 0; i < MATSIZE; i++) for(int j = 0; j < MATSIZE; j++)+ {+ m(i,j) = (i+j+1)/(MATSIZE*MATSIZE);+ }+ for(int a = 0; a < REPEAT; a++)+ {+ m = I + 0.0001 * (m + m*m);+ }+ cout << m(0,0) << endl;+ return 0;+}
+ eigen3/bench/benchmarkXcwise.cpp view
@@ -0,0 +1,35 @@+// g++ -O3 -DNDEBUG benchmarkX.cpp -o benchmarkX && time ./benchmarkX++#include <iostream>+#include <Eigen/Core>++using namespace std;+using namespace Eigen;++#ifndef VECTYPE+#define VECTYPE VectorXLd+#endif++#ifndef VECSIZE+#define VECSIZE 1000000+#endif++#ifndef REPEAT+#define REPEAT 1000+#endif++int main(int argc, char *argv[])+{+ VECTYPE I = VECTYPE::Ones(VECSIZE);+ VECTYPE m(VECSIZE,1);+ for(int i = 0; i < VECSIZE; i++)+ {+ m[i] = 0.1 * i/VECSIZE;+ }+ for(int a = 0; a < REPEAT; a++)+ {+ m = VECTYPE::Ones(VECSIZE) + 0.00005 * (m.cwise().square() + m/4);+ }+ cout << m[0] << endl;+ return 0;+}
+ eigen3/bench/benchmark_suite view
@@ -0,0 +1,18 @@+#!/bin/bash+CXX=${CXX-g++} # default value unless caller has defined CXX+echo "Fixed size 3x3, column-major, -DNDEBUG"+$CXX -O3 -I .. -DNDEBUG benchmark.cpp -o benchmark && time ./benchmark >/dev/null+echo "Fixed size 3x3, column-major, with asserts"+$CXX -O3 -I .. benchmark.cpp -o benchmark && time ./benchmark >/dev/null+echo "Fixed size 3x3, row-major, -DNDEBUG"+$CXX -O3 -I .. -DEIGEN_DEFAULT_TO_ROW_MAJOR -DNDEBUG benchmark.cpp -o benchmark && time ./benchmark >/dev/null+echo "Fixed size 3x3, row-major, with asserts"+$CXX -O3 -I .. -DEIGEN_DEFAULT_TO_ROW_MAJOR benchmark.cpp -o benchmark && time ./benchmark >/dev/null+echo "Dynamic size 20x20, column-major, -DNDEBUG"+$CXX -O3 -I .. -DNDEBUG benchmarkX.cpp -o benchmarkX && time ./benchmarkX >/dev/null+echo "Dynamic size 20x20, column-major, with asserts"+$CXX -O3 -I .. benchmarkX.cpp -o benchmarkX && time ./benchmarkX >/dev/null+echo "Dynamic size 20x20, row-major, -DNDEBUG"+$CXX -O3 -I .. -DEIGEN_DEFAULT_TO_ROW_MAJOR -DNDEBUG benchmarkX.cpp -o benchmarkX && time ./benchmarkX >/dev/null+echo "Dynamic size 20x20, row-major, with asserts"+$CXX -O3 -I .. -DEIGEN_DEFAULT_TO_ROW_MAJOR benchmarkX.cpp -o benchmarkX && time ./benchmarkX >/dev/null
+ eigen3/bench/btl/CMakeLists.txt view
@@ -0,0 +1,104 @@+PROJECT(BTL)++CMAKE_MINIMUM_REQUIRED(VERSION 2.6.2)++set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake ${Eigen_SOURCE_DIR}/cmake)+include(MacroOptionalAddSubdirectory)++OPTION(BTL_NOVEC "Disable SSE/Altivec optimizations when possible" OFF)++SET(CMAKE_INCLUDE_CURRENT_DIR ON)++string(REGEX MATCH icpc IS_ICPC ${CMAKE_CXX_COMPILER})+IF(CMAKE_COMPILER_IS_GNUCXX OR IS_ICPC)+ SET(CMAKE_CXX_FLAGS "-g0 -O3 -DNDEBUG")+ SET(CMAKE_Fortran_FLAGS "-g0 -O3 -DNDEBUG")+ IF(NOT BTL_NOVEC)+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2")+ SET(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -msse2")+ ELSE(NOT BTL_NOVEC)+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEIGEN_DONT_VECTORIZE")+ ENDIF(NOT BTL_NOVEC)+ENDIF(CMAKE_COMPILER_IS_GNUCXX OR IS_ICPC)++IF(MSVC)+ SET(CMAKE_CXX_FLAGS " /O2 /Ot /GL /fp:fast -DNDEBUG")+# SET(CMAKE_Fortran_FLAGS "-g0 -O3 -DNDEBUG")+ IF(NOT BTL_NOVEC)+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:SSE2")+ ELSE(NOT BTL_NOVEC)+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DEIGEN_DONT_VECTORIZE")+ ENDIF(NOT BTL_NOVEC)+ENDIF(MSVC)++if(IS_ICPC)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fast")+ set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fast")+endif(IS_ICPC)++include_directories(+ ${PROJECT_SOURCE_DIR}/actions+ ${PROJECT_SOURCE_DIR}/generic_bench+ ${PROJECT_SOURCE_DIR}/generic_bench/utils+ ${PROJECT_SOURCE_DIR}/libs/STL)++# find_package(MKL)+# if (MKL_FOUND)+# add_definitions(-DHAVE_MKL)+# set(DEFAULT_LIBRARIES ${MKL_LIBRARIES})+# endif (MKL_FOUND)++MACRO(BTL_ADD_BENCH targetname)++ foreach(_current_var ${ARGN})+ set(_last_var ${_current_var})+ endforeach(_current_var)++ set(_sources ${ARGN})+ list(LENGTH _sources _argn_length)++ list(REMOVE_ITEM _sources ON OFF TRUE FALSE)++ list(LENGTH _sources _src_length)++ if (${_argn_length} EQUAL ${_src_length})+ set(_last_var ON)+ endif (${_argn_length} EQUAL ${_src_length})++ OPTION(BUILD_${targetname} "Build benchmark ${targetname}" ${_last_var})++ IF(BUILD_${targetname})+ ADD_EXECUTABLE(${targetname} ${_sources})+ ADD_TEST(${targetname} "${targetname}")+ target_link_libraries(${targetname} ${DEFAULT_LIBRARIES} rt)+ ENDIF(BUILD_${targetname})++ENDMACRO(BTL_ADD_BENCH)++macro(btl_add_target_property target prop value)++ if(BUILD_${target})+ get_target_property(previous ${target} ${prop})+ if(NOT previous)+ set(previous "")+ endif()+ set_target_properties(${target} PROPERTIES ${prop} "${previous} ${value}")+ endif()++endmacro(btl_add_target_property)++ENABLE_TESTING()++add_subdirectory(libs/eigen3)+add_subdirectory(libs/eigen2)+add_subdirectory(libs/BLAS)+add_subdirectory(libs/ublas)+add_subdirectory(libs/gmm)+add_subdirectory(libs/mtl4)+add_subdirectory(libs/blitz)+add_subdirectory(libs/tvmet)+add_subdirectory(libs/STL)++add_subdirectory(data)++
+ eigen3/bench/btl/COPYING view
@@ -0,0 +1,340 @@+ GNU GENERAL PUBLIC LICENSE+ Version 2, June 1991++ Copyright (C) 1989, 1991 Free Software Foundation, Inc.+ 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+ Everyone is permitted to copy and distribute verbatim copies+ of this license document, but changing it is not allowed.++ Preamble++ The licenses for most software are designed to take away your+freedom to share and change it. By contrast, the GNU General Public+License is intended to guarantee your freedom to share and change free+software--to make sure the software is free for all its users. This+General Public License applies to most of the Free Software+Foundation's software and to any other program whose authors commit to+using it. (Some other Free Software Foundation software is covered by+the GNU Library General Public License instead.) You can apply it to+your programs, too.++ When we speak of free software, we are referring to freedom, not+price. Our General Public Licenses are designed to make sure that you+have the freedom to distribute copies of free software (and charge for+this service if you wish), that you receive source code or can get it+if you want it, that you can change the software or use pieces of it+in new free programs; and that you know you can do these things.++ To protect your rights, we need to make restrictions that forbid+anyone to deny you these rights or to ask you to surrender the rights.+These restrictions translate to certain responsibilities for you if you+distribute copies of the software, or if you modify it.++ For example, if you distribute copies of such a program, whether+gratis or for a fee, you must give the recipients all the rights that+you have. You must make sure that they, too, receive or can get the+source code. And you must show them these terms so they know their+rights.++ We protect your rights with two steps: (1) copyright the software, and+(2) offer you this license which gives you legal permission to copy,+distribute and/or modify the software.++ Also, for each author's protection and ours, we want to make certain+that everyone understands that there is no warranty for this free+software. If the software is modified by someone else and passed on, we+want its recipients to know that what they have is not the original, so+that any problems introduced by others will not reflect on the original+authors' reputations.++ Finally, any free program is threatened constantly by software+patents. We wish to avoid the danger that redistributors of a free+program will individually obtain patent licenses, in effect making the+program proprietary. To prevent this, we have made it clear that any+patent must be licensed for everyone's free use or not licensed at all.++ The precise terms and conditions for copying, distribution and+modification follow.++ GNU GENERAL PUBLIC LICENSE+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION++ 0. This License applies to any program or other work which contains+a notice placed by the copyright holder saying it may be distributed+under the terms of this General Public License. The "Program", below,+refers to any such program or work, and a "work based on the Program"+means either the Program or any derivative work under copyright law:+that is to say, a work containing the Program or a portion of it,+either verbatim or with modifications and/or translated into another+language. (Hereinafter, translation is included without limitation in+the term "modification".) Each licensee is addressed as "you".++Activities other than copying, distribution and modification are not+covered by this License; they are outside its scope. The act of+running the Program is not restricted, and the output from the Program+is covered only if its contents constitute a work based on the+Program (independent of having been made by running the Program).+Whether that is true depends on what the Program does.++ 1. You may copy and distribute verbatim copies of the Program's+source code as you receive it, in any medium, provided that you+conspicuously and appropriately publish on each copy an appropriate+copyright notice and disclaimer of warranty; keep intact all the+notices that refer to this License and to the absence of any warranty;+and give any other recipients of the Program a copy of this License+along with the Program.++You may charge a fee for the physical act of transferring a copy, and+you may at your option offer warranty protection in exchange for a fee.++ 2. You may modify your copy or copies of the Program or any portion+of it, thus forming a work based on the Program, and copy and+distribute such modifications or work under the terms of Section 1+above, provided that you also meet all of these conditions:++ a) You must cause the modified files to carry prominent notices+ stating that you changed the files and the date of any change.++ b) You must cause any work that you distribute or publish, that in+ whole or in part contains or is derived from the Program or any+ part thereof, to be licensed as a whole at no charge to all third+ parties under the terms of this License.++ c) If the modified program normally reads commands interactively+ when run, you must cause it, when started running for such+ interactive use in the most ordinary way, to print or display an+ announcement including an appropriate copyright notice and a+ notice that there is no warranty (or else, saying that you provide+ a warranty) and that users may redistribute the program under+ these conditions, and telling the user how to view a copy of this+ License. (Exception: if the Program itself is interactive but+ does not normally print such an announcement, your work based on+ the Program is not required to print an announcement.)++These requirements apply to the modified work as a whole. If+identifiable sections of that work are not derived from the Program,+and can be reasonably considered independent and separate works in+themselves, then this License, and its terms, do not apply to those+sections when you distribute them as separate works. But when you+distribute the same sections as part of a whole which is a work based+on the Program, the distribution of the whole must be on the terms of+this License, whose permissions for other licensees extend to the+entire whole, and thus to each and every part regardless of who wrote it.++Thus, it is not the intent of this section to claim rights or contest+your rights to work written entirely by you; rather, the intent is to+exercise the right to control the distribution of derivative or+collective works based on the Program.++In addition, mere aggregation of another work not based on the Program+with the Program (or with a work based on the Program) on a volume of+a storage or distribution medium does not bring the other work under+the scope of this License.++ 3. You may copy and distribute the Program (or a work based on it,+under Section 2) in object code or executable form under the terms of+Sections 1 and 2 above provided that you also do one of the following:++ a) Accompany it with the complete corresponding machine-readable+ source code, which must be distributed under the terms of Sections+ 1 and 2 above on a medium customarily used for software interchange; or,++ b) Accompany it with a written offer, valid for at least three+ years, to give any third party, for a charge no more than your+ cost of physically performing source distribution, a complete+ machine-readable copy of the corresponding source code, to be+ distributed under the terms of Sections 1 and 2 above on a medium+ customarily used for software interchange; or,++ c) Accompany it with the information you received as to the offer+ to distribute corresponding source code. (This alternative is+ allowed only for noncommercial distribution and only if you+ received the program in object code or executable form with such+ an offer, in accord with Subsection b above.)++The source code for a work means the preferred form of the work for+making modifications to it. For an executable work, complete source+code means all the source code for all modules it contains, plus any+associated interface definition files, plus the scripts used to+control compilation and installation of the executable. However, as a+special exception, the source code distributed need not include+anything that is normally distributed (in either source or binary+form) with the major components (compiler, kernel, and so on) of the+operating system on which the executable runs, unless that component+itself accompanies the executable.++If distribution of executable or object code is made by offering+access to copy from a designated place, then offering equivalent+access to copy the source code from the same place counts as+distribution of the source code, even though third parties are not+compelled to copy the source along with the object code.++ 4. You may not copy, modify, sublicense, or distribute the Program+except as expressly provided under this License. Any attempt+otherwise to copy, modify, sublicense or distribute the Program is+void, and will automatically terminate your rights under this License.+However, parties who have received copies, or rights, from you under+this License will not have their licenses terminated so long as such+parties remain in full compliance.++ 5. You are not required to accept this License, since you have not+signed it. However, nothing else grants you permission to modify or+distribute the Program or its derivative works. These actions are+prohibited by law if you do not accept this License. Therefore, by+modifying or distributing the Program (or any work based on the+Program), you indicate your acceptance of this License to do so, and+all its terms and conditions for copying, distributing or modifying+the Program or works based on it.++ 6. Each time you redistribute the Program (or any work based on the+Program), the recipient automatically receives a license from the+original licensor to copy, distribute or modify the Program subject to+these terms and conditions. You may not impose any further+restrictions on the recipients' exercise of the rights granted herein.+You are not responsible for enforcing compliance by third parties to+this License.++ 7. If, as a consequence of a court judgment or allegation of patent+infringement or for any other reason (not limited to patent issues),+conditions are imposed on you (whether by court order, agreement or+otherwise) that contradict the conditions of this License, they do not+excuse you from the conditions of this License. If you cannot+distribute so as to satisfy simultaneously your obligations under this+License and any other pertinent obligations, then as a consequence you+may not distribute the Program at all. For example, if a patent+license would not permit royalty-free redistribution of the Program by+all those who receive copies directly or indirectly through you, then+the only way you could satisfy both it and this License would be to+refrain entirely from distribution of the Program.++If any portion of this section is held invalid or unenforceable under+any particular circumstance, the balance of the section is intended to+apply and the section as a whole is intended to apply in other+circumstances.++It is not the purpose of this section to induce you to infringe any+patents or other property right claims or to contest validity of any+such claims; this section has the sole purpose of protecting the+integrity of the free software distribution system, which is+implemented by public license practices. Many people have made+generous contributions to the wide range of software distributed+through that system in reliance on consistent application of that+system; it is up to the author/donor to decide if he or she is willing+to distribute software through any other system and a licensee cannot+impose that choice.++This section is intended to make thoroughly clear what is believed to+be a consequence of the rest of this License.++ 8. If the distribution and/or use of the Program is restricted in+certain countries either by patents or by copyrighted interfaces, the+original copyright holder who places the Program under this License+may add an explicit geographical distribution limitation excluding+those countries, so that distribution is permitted only in or among+countries not thus excluded. In such case, this License incorporates+the limitation as if written in the body of this License.++ 9. The Free Software Foundation may publish revised and/or new versions+of the General Public License from time to time. Such new versions will+be similar in spirit to the present version, but may differ in detail to+address new problems or concerns.++Each version is given a distinguishing version number. If the Program+specifies a version number of this License which applies to it and "any+later version", you have the option of following the terms and conditions+either of that version or of any later version published by the Free+Software Foundation. If the Program does not specify a version number of+this License, you may choose any version ever published by the Free Software+Foundation.++ 10. If you wish to incorporate parts of the Program into other free+programs whose distribution conditions are different, write to the author+to ask for permission. For software which is copyrighted by the Free+Software Foundation, write to the Free Software Foundation; we sometimes+make exceptions for this. Our decision will be guided by the two goals+of preserving the free status of all derivatives of our free software and+of promoting the sharing and reuse of software generally.++ NO WARRANTY++ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,+REPAIR OR CORRECTION.++ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE+POSSIBILITY OF SUCH DAMAGES.++ END OF TERMS AND CONDITIONS++ How to Apply These Terms to Your New Programs++ If you develop a new program, and you want it to be of the greatest+possible use to the public, the best way to achieve this is to make it+free software which everyone can redistribute and change under these terms.++ To do so, attach the following notices to the program. It is safest+to attach them to the start of each source file to most effectively+convey the exclusion of warranty; and each file should have at least+the "copyright" line and a pointer to where the full notice is found.++ <one line to give the program's name and a brief idea of what it does.>+ Copyright (C) <year> <name of author>++ This program is free software; you can redistribute it and/or modify+ it under the terms of the GNU General Public License as published by+ the Free Software Foundation; either version 2 of the License, or+ (at your option) any later version.++ This program is distributed in the hope that it will be useful,+ but WITHOUT ANY WARRANTY; without even the implied warranty of+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+ GNU General Public License for more details.++ You should have received a copy of the GNU General Public License+ along with this program; if not, write to the Free Software+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA+++Also add information on how to contact you by electronic and paper mail.++If the program is interactive, make it output a short notice like this+when it starts in an interactive mode:++ Gnomovision version 69, Copyright (C) year name of author+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.+ This is free software, and you are welcome to redistribute it+ under certain conditions; type `show c' for details.++The hypothetical commands `show w' and `show c' should show the appropriate+parts of the General Public License. Of course, the commands you use may+be called something other than `show w' and `show c'; they could even be+mouse-clicks or menu items--whatever suits your program.++You should also get your employer (if you work as a programmer) or your+school, if any, to sign a "copyright disclaimer" for the program, if+necessary. Here is a sample; alter the names:++ Yoyodyne, Inc., hereby disclaims all copyright interest in the program+ `Gnomovision' (which makes passes at compilers) written by James Hacker.++ <signature of Ty Coon>, 1 April 1989+ Ty Coon, President of Vice++This General Public License does not permit incorporating your program into+proprietary programs. If your program is a subroutine library, you may+consider it more useful to permit linking proprietary applications with the+library. If this is what you want to do, use the GNU Library General+Public License instead of this License.
+ eigen3/bench/btl/README view
@@ -0,0 +1,154 @@+Bench Template Library++****************************************+Introduction :++The aim of this project is to compare the performance+of available numerical libraries. The code is designed+as generic and modular as possible. Thus, adding new+numerical libraries or new numerical tests should+require minimal effort.+++*****************************************++Installation :++BTL uses cmake / ctest:++1 - create a build directory:++ $ mkdir build+ $ cd build++2 - configure:++ $ ccmake ..++3 - run the bench using ctest:++ $ ctest -V++You can run the benchmarks only on libraries matching a given regular expression:+ ctest -V -R <regexp>+For instance:+ ctest -V -R eigen2++You can also select a given set of actions defining the environment variable BTL_CONFIG this way:+ BTL_CONFIG="-a action1{:action2}*" ctest -V+An exemple:+ BTL_CONFIG="-a axpy:vector_matrix:trisolve:ata" ctest -V -R eigen2++Finally, if bench results already exist (the bench*.dat files) then they merges by keeping the best for each matrix size. If you want to overwrite the previous ones you can simply add the "--overwrite" option:+ BTL_CONFIG="-a axpy:vector_matrix:trisolve:ata --overwrite" ctest -V -R eigen2++4 : Analyze the result. different data files (.dat) are produced in each libs directories.+ If gnuplot is available, choose a directory name in the data directory to store the results and type:+ $ cd data+ $ mkdir my_directory+ $ cp ../libs/*/*.dat my_directory+ Build the data utilities in this (data) directory+ make+ Then you can look the raw data,+ go_mean my_directory+ or smooth the data first :+ smooth_all.sh my_directory+ go_mean my_directory_smooth+++*************************************************++Files and directories :++ generic_bench : all the bench sources common to all libraries++ actions : sources for different action wrappers (axpy, matrix-matrix product) to be tested.++ libs/* : bench sources specific to each tested libraries.++ machine_dep : directory used to store machine specific Makefile.in++ data : directory used to store gnuplot scripts and data analysis utilities++**************************************************++Principles : the code modularity is achieved by defining two concepts :++ ****** Action concept : This is a class defining which kind+ of test must be performed (e.g. a matrix_vector_product).+ An Action should define the following methods :++ *** Ctor using the size of the problem (matrix or vector size) as an argument+ Action action(size);+ *** initialize : this method initialize the calculation (e.g. initialize the matrices and vectors arguments)+ action.initialize();+ *** calculate : this method actually launch the calculation to be benchmarked+ action.calculate;+ *** nb_op_base() : this method returns the complexity of the calculate method (allowing the mflops evaluation)+ *** name() : this method returns the name of the action (std::string)++ ****** Interface concept : This is a class or namespace defining how to use a given library and+ its specific containers (matrix and vector). Up to now an interface should following types++ *** real_type : kind of float to be used (float or double)+ *** stl_vector : must correspond to std::vector<real_type>+ *** stl_matrix : must correspond to std::vector<stl_vector>+ *** gene_vector : the vector type for this interface --> e.g. (real_type *) for the C_interface+ *** gene_matrix : the matrix type for this interface --> e.g. (gene_vector *) for the C_interface++ + the following common methods++ *** free_matrix(gene_matrix & A, int N) dealocation of a N sized gene_matrix A+ *** free_vector(gene_vector & B) dealocation of a N sized gene_vector B+ *** matrix_from_stl(gene_matrix & A, stl_matrix & A_stl) copy the content of an stl_matrix A_stl into a gene_matrix A.+ The allocation of A is done in this function.+ *** vector_to_stl(gene_vector & B, stl_vector & B_stl) copy the content of an stl_vector B_stl into a gene_vector B.+ The allocation of B is done in this function.+ *** matrix_to_stl(gene_matrix & A, stl_matrix & A_stl) copy the content of an gene_matrix A into an stl_matrix A_stl.+ The size of A_STL must corresponds to the size of A.+ *** vector_to_stl(gene_vector & A, stl_vector & A_stl) copy the content of an gene_vector A into an stl_vector A_stl.+ The size of B_STL must corresponds to the size of B.+ *** copy_matrix(gene_matrix & source, gene_matrix & cible, int N) : copy the content of source in cible. Both source+ and cible must be sized NxN.+ *** copy_vector(gene_vector & source, gene_vector & cible, int N) : copy the content of source in cible. Both source+ and cible must be sized N.++ and the following method corresponding to the action one wants to be benchmarked :++ *** matrix_vector_product(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N)+ *** matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N)+ *** ata_product(const gene_matrix & A, gene_matrix & X, int N)+ *** aat_product(const gene_matrix & A, gene_matrix & X, int N)+ *** axpy(real coef, const gene_vector & X, gene_vector & Y, int N)++ The bench algorithm (generic_bench/bench.hh) is templated with an action itself templated with+ an interface. A typical main.cpp source stored in a given library directory libs/A_LIB+ looks like :++ bench< AN_ACTION < AN_INTERFACE > >( 10 , 1000 , 50 ) ;++ this function will produce XY data file containing measured mflops as a function of the size for 50+ sizes between 10 and 10000.++ This algorithm can be adapted by providing a given Perf_Analyzer object which determines how the time+ measurements must be done. For example, the X86_Perf_Analyzer use the asm rdtsc function and provides+ a very fast and accurate (but less portable) timing method. The default is the Portable_Perf_Analyzer+ so++ bench< AN_ACTION < AN_INTERFACE > >( 10 , 1000 , 50 ) ;++ is equivalent to++ bench< Portable_Perf_Analyzer,AN_ACTION < AN_INTERFACE > >( 10 , 1000 , 50 ) ;++ If your system supports it we suggest to use a mixed implementation (X86_perf_Analyzer+Portable_Perf_Analyzer).+ replace+ bench<Portable_Perf_Analyzer,Action>(size_min,size_max,nb_point);+ with+ bench<Mixed_Perf_Analyzer,Action>(size_min,size_max,nb_point);+ in generic/bench.hh++.+++
+ eigen3/bench/btl/actions/action_aat_product.hh view
@@ -0,0 +1,145 @@+//=====================================================+// File : action_aat_product.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_AAT_PRODUCT+#define ACTION_AAT_PRODUCT+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_aat_product {++public :++ // Ctor++ Action_aat_product( int size ):_size(size)+ {+ MESSAGE("Action_aat_product Ctor");++ // STL matrix and vector initialization++ init_matrix<pseudo_random>(A_stl,_size);+ init_matrix<null_function>(X_stl,_size);+ init_matrix<null_function>(resu_stl,_size);++ // generic matrix and vector initialization++ Interface::matrix_from_stl(A_ref,A_stl);+ Interface::matrix_from_stl(X_ref,X_stl);++ Interface::matrix_from_stl(A,A_stl);+ Interface::matrix_from_stl(X,X_stl);++ }++ // invalidate copy ctor++ Action_aat_product( const Action_aat_product & )+ {+ INFOS("illegal call to Action_aat_product Copy Ctor");+ exit(0);+ }++ // Dtor++ ~Action_aat_product( void ){++ MESSAGE("Action_aat_product Dtor");++ // deallocation++ Interface::free_matrix(A,_size);+ Interface::free_matrix(X,_size);++ Interface::free_matrix(A_ref,_size);+ Interface::free_matrix(X_ref,_size);++ }++ // action name++ static inline std::string name( void )+ {+ return "aat_"+Interface::name();+ }++ double nb_op_base( void ){+ return double(_size)*double(_size)*double(_size);+ }++ inline void initialize( void ){++ Interface::copy_matrix(A_ref,A,_size);+ Interface::copy_matrix(X_ref,X,_size);++ }++ inline void calculate( void ) {++ Interface::aat_product(A,X,_size);++ }++ void check_result( void ){+ if (_size>128) return;+ // calculation check++ Interface::matrix_to_stl(X,resu_stl);++ STL_interface<typename Interface::real_type>::aat_product(A_stl,X_stl,_size);++ typename Interface::real_type error=+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);++ if (error>1.e-6){+ INFOS("WRONG CALCULATION...residual=" << error);+ exit(1);+ }++ }++private :++ typename Interface::stl_matrix A_stl;+ typename Interface::stl_matrix X_stl;+ typename Interface::stl_matrix resu_stl;++ typename Interface::gene_matrix A_ref;+ typename Interface::gene_matrix X_ref;++ typename Interface::gene_matrix A;+ typename Interface::gene_matrix X;+++ int _size;++};+++#endif+++
+ eigen3/bench/btl/actions/action_ata_product.hh view
@@ -0,0 +1,145 @@+//=====================================================+// File : action_ata_product.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_ATA_PRODUCT+#define ACTION_ATA_PRODUCT+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_ata_product {++public :++ // Ctor++ Action_ata_product( int size ):_size(size)+ {+ MESSAGE("Action_ata_product Ctor");++ // STL matrix and vector initialization++ init_matrix<pseudo_random>(A_stl,_size);+ init_matrix<null_function>(X_stl,_size);+ init_matrix<null_function>(resu_stl,_size);++ // generic matrix and vector initialization++ Interface::matrix_from_stl(A_ref,A_stl);+ Interface::matrix_from_stl(X_ref,X_stl);++ Interface::matrix_from_stl(A,A_stl);+ Interface::matrix_from_stl(X,X_stl);++ }++ // invalidate copy ctor++ Action_ata_product( const Action_ata_product & )+ {+ INFOS("illegal call to Action_ata_product Copy Ctor");+ exit(0);+ }++ // Dtor++ ~Action_ata_product( void ){++ MESSAGE("Action_ata_product Dtor");++ // deallocation++ Interface::free_matrix(A,_size);+ Interface::free_matrix(X,_size);++ Interface::free_matrix(A_ref,_size);+ Interface::free_matrix(X_ref,_size);++ }++ // action name++ static inline std::string name( void )+ {+ return "ata_"+Interface::name();+ }++ double nb_op_base( void ){+ return 2.0*_size*_size*_size;+ }++ inline void initialize( void ){++ Interface::copy_matrix(A_ref,A,_size);+ Interface::copy_matrix(X_ref,X,_size);++ }++ inline void calculate( void ) {++ Interface::ata_product(A,X,_size);++ }++ void check_result( void ){+ if (_size>128) return;+ // calculation check++ Interface::matrix_to_stl(X,resu_stl);++ STL_interface<typename Interface::real_type>::ata_product(A_stl,X_stl,_size);++ typename Interface::real_type error=+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);++ if (error>1.e-6){+ INFOS("WRONG CALCULATION...residual=" << error);+ exit(1);+ }++ }++private :++ typename Interface::stl_matrix A_stl;+ typename Interface::stl_matrix X_stl;+ typename Interface::stl_matrix resu_stl;++ typename Interface::gene_matrix A_ref;+ typename Interface::gene_matrix X_ref;++ typename Interface::gene_matrix A;+ typename Interface::gene_matrix X;+++ int _size;++};+++#endif+++
+ eigen3/bench/btl/actions/action_atv_product.hh view
@@ -0,0 +1,134 @@+//=====================================================+// File : action_atv_product.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_ATV_PRODUCT+#define ACTION_ATV_PRODUCT+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_atv_product {++public :++ Action_atv_product( int size ) : _size(size)+ {+ MESSAGE("Action_atv_product Ctor");++ // STL matrix and vector initialization++ init_matrix<pseudo_random>(A_stl,_size);+ init_vector<pseudo_random>(B_stl,_size);+ init_vector<null_function>(X_stl,_size);+ init_vector<null_function>(resu_stl,_size);++ // generic matrix and vector initialization++ Interface::matrix_from_stl(A_ref,A_stl);+ Interface::vector_from_stl(B_ref,B_stl);+ Interface::vector_from_stl(X_ref,X_stl);++ Interface::matrix_from_stl(A,A_stl);+ Interface::vector_from_stl(B,B_stl);+ Interface::vector_from_stl(X,X_stl);+ }++ // invalidate copy ctor+ Action_atv_product( const Action_atv_product & )+ {+ INFOS("illegal call to Action_atv_product Copy Ctor");+ exit(1);+ }++ ~Action_atv_product( void )+ {+ MESSAGE("Action_atv_product Dtor");++ Interface::free_matrix(A,_size);+ Interface::free_vector(B);+ Interface::free_vector(X);++ Interface::free_matrix(A_ref,_size);+ Interface::free_vector(B_ref);+ Interface::free_vector(X_ref);+ }++ static inline std::string name() { return "atv_" + Interface::name(); }++ double nb_op_base( void ) { return 2.0*_size*_size; }++ inline void initialize( void ){+ Interface::copy_matrix(A_ref,A,_size);+ Interface::copy_vector(B_ref,B,_size);+ Interface::copy_vector(X_ref,X,_size);+ }++ BTL_DONT_INLINE void calculate( void ) {+ BTL_ASM_COMMENT("begin atv");+ Interface::atv_product(A,B,X,_size);+ BTL_ASM_COMMENT("end atv");+ }++ void check_result( void )+ {+ if (_size>128) return;+ Interface::vector_to_stl(X,resu_stl);++ STL_interface<typename Interface::real_type>::atv_product(A_stl,B_stl,X_stl,_size);++ typename Interface::real_type error=+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);++ if (error>1.e-6){+ INFOS("WRONG CALCULATION...residual=" << error);+ exit(1);+ }+ }++private :++ typename Interface::stl_matrix A_stl;+ typename Interface::stl_vector B_stl;+ typename Interface::stl_vector X_stl;+ typename Interface::stl_vector resu_stl;++ typename Interface::gene_matrix A_ref;+ typename Interface::gene_vector B_ref;+ typename Interface::gene_vector X_ref;++ typename Interface::gene_matrix A;+ typename Interface::gene_vector B;+ typename Interface::gene_vector X;+++ int _size;++};+++#endif+++
+ eigen3/bench/btl/actions/action_axpby.hh view
@@ -0,0 +1,127 @@+//=====================================================+// File : action_axpby.hh+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_AXPBY+#define ACTION_AXPBY+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_axpby {++public :++ // Ctor+ Action_axpby( int size ):_size(size),_alpha(0.5),_beta(0.95)+ {+ MESSAGE("Action_axpby Ctor");++ // STL vector initialization+ init_vector<pseudo_random>(X_stl,_size);+ init_vector<pseudo_random>(Y_stl,_size);+ init_vector<null_function>(resu_stl,_size);++ // generic matrix and vector initialization+ Interface::vector_from_stl(X_ref,X_stl);+ Interface::vector_from_stl(Y_ref,Y_stl);++ Interface::vector_from_stl(X,X_stl);+ Interface::vector_from_stl(Y,Y_stl);+ }++ // invalidate copy ctor+ Action_axpby( const Action_axpby & )+ {+ INFOS("illegal call to Action_axpby Copy Ctor");+ exit(1);+ }++ // Dtor+ ~Action_axpby( void ){+ MESSAGE("Action_axpby Dtor");++ // deallocation+ Interface::free_vector(X_ref);+ Interface::free_vector(Y_ref);++ Interface::free_vector(X);+ Interface::free_vector(Y);+ }++ // action name+ static inline std::string name( void )+ {+ return "axpby_"+Interface::name();+ }++ double nb_op_base( void ){+ return 3.0*_size;+ }++ inline void initialize( void ){+ Interface::copy_vector(X_ref,X,_size);+ Interface::copy_vector(Y_ref,Y,_size);+ }++ inline void calculate( void ) {+ BTL_ASM_COMMENT("mybegin axpby");+ Interface::axpby(_alpha,X,_beta,Y,_size);+ BTL_ASM_COMMENT("myend axpby");+ }++ void check_result( void ){+ if (_size>128) return;+ // calculation check+ Interface::vector_to_stl(Y,resu_stl);++ STL_interface<typename Interface::real_type>::axpby(_alpha,X_stl,_beta,Y_stl,_size);++ typename Interface::real_type error=+ STL_interface<typename Interface::real_type>::norm_diff(Y_stl,resu_stl);++ if (error>1.e-6){+ INFOS("WRONG CALCULATION...residual=" << error);+ exit(2);+ }+ }++private :++ typename Interface::stl_vector X_stl;+ typename Interface::stl_vector Y_stl;+ typename Interface::stl_vector resu_stl;++ typename Interface::gene_vector X_ref;+ typename Interface::gene_vector Y_ref;++ typename Interface::gene_vector X;+ typename Interface::gene_vector Y;++ typename Interface::real_type _alpha;+ typename Interface::real_type _beta;++ int _size;+};++#endif
+ eigen3/bench/btl/actions/action_axpy.hh view
@@ -0,0 +1,139 @@+//=====================================================+// File : action_axpy.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_AXPY+#define ACTION_AXPY+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_axpy {++public :++ // Ctor++ Action_axpy( int size ):_size(size),_coef(1.0)+ {+ MESSAGE("Action_axpy Ctor");++ // STL vector initialization++ init_vector<pseudo_random>(X_stl,_size);+ init_vector<pseudo_random>(Y_stl,_size);+ init_vector<null_function>(resu_stl,_size);++ // generic matrix and vector initialization++ Interface::vector_from_stl(X_ref,X_stl);+ Interface::vector_from_stl(Y_ref,Y_stl);++ Interface::vector_from_stl(X,X_stl);+ Interface::vector_from_stl(Y,Y_stl);+++ }++ // invalidate copy ctor++ Action_axpy( const Action_axpy & )+ {+ INFOS("illegal call to Action_axpy Copy Ctor");+ exit(1);+ }++ // Dtor++ ~Action_axpy( void ){++ MESSAGE("Action_axpy Dtor");++ // deallocation++ Interface::free_vector(X_ref);+ Interface::free_vector(Y_ref);++ Interface::free_vector(X);+ Interface::free_vector(Y);+ }++ // action name++ static inline std::string name( void )+ {+ return "axpy_"+Interface::name();+ }++ double nb_op_base( void ){+ return 2.0*_size;+ }++ inline void initialize( void ){+ Interface::copy_vector(X_ref,X,_size);+ Interface::copy_vector(Y_ref,Y,_size);+ }++ inline void calculate( void ) {+ BTL_ASM_COMMENT("mybegin axpy");+ Interface::axpy(_coef,X,Y,_size);+ BTL_ASM_COMMENT("myend axpy");+ }++ void check_result( void ){+ if (_size>128) return;+ // calculation check++ Interface::vector_to_stl(Y,resu_stl);++ STL_interface<typename Interface::real_type>::axpy(_coef,X_stl,Y_stl,_size);++ typename Interface::real_type error=+ STL_interface<typename Interface::real_type>::norm_diff(Y_stl,resu_stl);++ if (error>1.e-6){+ INFOS("WRONG CALCULATION...residual=" << error);+ exit(0);+ }++ }++private :++ typename Interface::stl_vector X_stl;+ typename Interface::stl_vector Y_stl;+ typename Interface::stl_vector resu_stl;++ typename Interface::gene_vector X_ref;+ typename Interface::gene_vector Y_ref;++ typename Interface::gene_vector X;+ typename Interface::gene_vector Y;++ typename Interface::real_type _coef;++ int _size;+};++#endif
+ eigen3/bench/btl/actions/action_cholesky.hh view
@@ -0,0 +1,128 @@+//=====================================================+// File : action_cholesky.hh+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_CHOLESKY+#define ACTION_CHOLESKY+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_cholesky {++public :++ // Ctor++ Action_cholesky( int size ):_size(size)+ {+ MESSAGE("Action_cholesky Ctor");++ // STL mat/vec initialization+ init_matrix_symm<pseudo_random>(X_stl,_size);+ init_matrix<null_function>(C_stl,_size);++ // make sure X is invertible+ for (int i=0; i<_size; ++i)+ X_stl[i][i] = std::abs(X_stl[i][i]) * 1e2 + 100;++ // generic matrix and vector initialization+ Interface::matrix_from_stl(X_ref,X_stl);+ Interface::matrix_from_stl(X,X_stl);+ Interface::matrix_from_stl(C,C_stl);++ _cost = 0;+ for (int j=0; j<_size; ++j)+ {+ double r = std::max(_size - j -1,0);+ _cost += 2*(r*j+r+j);+ }+ }++ // invalidate copy ctor++ Action_cholesky( const Action_cholesky & )+ {+ INFOS("illegal call to Action_cholesky Copy Ctor");+ exit(1);+ }++ // Dtor++ ~Action_cholesky( void ){++ MESSAGE("Action_cholesky Dtor");++ // deallocation+ Interface::free_matrix(X_ref,_size);+ Interface::free_matrix(X,_size);+ Interface::free_matrix(C,_size);+ }++ // action name++ static inline std::string name( void )+ {+ return "cholesky_"+Interface::name();+ }++ double nb_op_base( void ){+ return _cost;+ }++ inline void initialize( void ){+ Interface::copy_matrix(X_ref,X,_size);+ }++ inline void calculate( void ) {+ Interface::cholesky(X,C,_size);+ }++ void check_result( void ){+ // calculation check+// STL_interface<typename Interface::real_type>::cholesky(X_stl,C_stl,_size);+//+// typename Interface::real_type error=+// STL_interface<typename Interface::real_type>::norm_diff(C_stl,resu_stl);+//+// if (error>1.e-6){+// INFOS("WRONG CALCULATION...residual=" << error);+// exit(0);+// }++ }++private :++ typename Interface::stl_matrix X_stl;+ typename Interface::stl_matrix C_stl;++ typename Interface::gene_matrix X_ref;+ typename Interface::gene_matrix X;+ typename Interface::gene_matrix C;++ int _size;+ double _cost;+};++#endif
+ eigen3/bench/btl/actions/action_ger.hh view
@@ -0,0 +1,128 @@++// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_GER+#define ACTION_GER+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_ger {++public :++ // Ctor+ BTL_DONT_INLINE Action_ger( int size ):_size(size)+ {+ MESSAGE("Action_ger Ctor");++ // STL matrix and vector initialization+ typename Interface::stl_matrix tmp;+ init_matrix<pseudo_random>(A_stl,_size);+ init_vector<pseudo_random>(B_stl,_size);+ init_vector<pseudo_random>(X_stl,_size);+ init_vector<null_function>(resu_stl,_size);++ // generic matrix and vector initialization+ Interface::matrix_from_stl(A_ref,A_stl);+ Interface::matrix_from_stl(A,A_stl);+ Interface::vector_from_stl(B_ref,B_stl);+ Interface::vector_from_stl(B,B_stl);+ Interface::vector_from_stl(X_ref,X_stl);+ Interface::vector_from_stl(X,X_stl);+ }++ // invalidate copy ctor+ Action_ger( const Action_ger & )+ {+ INFOS("illegal call to Action_ger Copy Ctor");+ exit(1);+ }++ // Dtor+ BTL_DONT_INLINE ~Action_ger( void ){+ MESSAGE("Action_ger Dtor");+ Interface::free_matrix(A,_size);+ Interface::free_vector(B);+ Interface::free_vector(X);+ Interface::free_matrix(A_ref,_size);+ Interface::free_vector(B_ref);+ Interface::free_vector(X_ref);++ }++ // action name+ static inline std::string name( void )+ {+ return "ger_" + Interface::name();+ }++ double nb_op_base( void ){+ return 2.0*_size*_size;+ }++ BTL_DONT_INLINE void initialize( void ){+ Interface::copy_matrix(A_ref,A,_size);+ Interface::copy_vector(B_ref,B,_size);+ Interface::copy_vector(X_ref,X,_size);+ }++ BTL_DONT_INLINE void calculate( void ) {+ BTL_ASM_COMMENT("#begin ger");+ Interface::ger(A,B,X,_size);+ BTL_ASM_COMMENT("end ger");+ }++ BTL_DONT_INLINE void check_result( void ){+ // calculation check+ Interface::vector_to_stl(X,resu_stl);++ STL_interface<typename Interface::real_type>::ger(A_stl,B_stl,X_stl,_size);++ typename Interface::real_type error=+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);++ if (error>1.e-3){+ INFOS("WRONG CALCULATION...residual=" << error);+// exit(0);+ }++ }++private :++ typename Interface::stl_matrix A_stl;+ typename Interface::stl_vector B_stl;+ typename Interface::stl_vector X_stl;+ typename Interface::stl_vector resu_stl;++ typename Interface::gene_matrix A_ref;+ typename Interface::gene_vector B_ref;+ typename Interface::gene_vector X_ref;++ typename Interface::gene_matrix A;+ typename Interface::gene_vector B;+ typename Interface::gene_vector X;++ int _size;+};+++#endif
+ eigen3/bench/btl/actions/action_hessenberg.hh view
@@ -0,0 +1,233 @@+//=====================================================+// File : action_hessenberg.hh+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_HESSENBERG+#define ACTION_HESSENBERG+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_hessenberg {++public :++ // Ctor++ Action_hessenberg( int size ):_size(size)+ {+ MESSAGE("Action_hessenberg Ctor");++ // STL vector initialization+ init_matrix<pseudo_random>(X_stl,_size);++ init_matrix<null_function>(C_stl,_size);+ init_matrix<null_function>(resu_stl,_size);++ // generic matrix and vector initialization+ Interface::matrix_from_stl(X_ref,X_stl);+ Interface::matrix_from_stl(X,X_stl);+ Interface::matrix_from_stl(C,C_stl);++ _cost = 0;+ for (int j=0; j<_size-2; ++j)+ {+ double r = std::max(0,_size-j-1);+ double b = std::max(0,_size-j-2);+ _cost += 6 + 3*b + r*r*4 + r*_size*4;+ }+ }++ // invalidate copy ctor++ Action_hessenberg( const Action_hessenberg & )+ {+ INFOS("illegal call to Action_hessenberg Copy Ctor");+ exit(1);+ }++ // Dtor++ ~Action_hessenberg( void ){++ MESSAGE("Action_hessenberg Dtor");++ // deallocation+ Interface::free_matrix(X_ref,_size);+ Interface::free_matrix(X,_size);+ Interface::free_matrix(C,_size);+ }++ // action name++ static inline std::string name( void )+ {+ return "hessenberg_"+Interface::name();+ }++ double nb_op_base( void ){+ return _cost;+ }++ inline void initialize( void ){+ Interface::copy_matrix(X_ref,X,_size);+ }++ inline void calculate( void ) {+ Interface::hessenberg(X,C,_size);+ }++ void check_result( void ){+ // calculation check+ Interface::matrix_to_stl(C,resu_stl);++// STL_interface<typename Interface::real_type>::hessenberg(X_stl,C_stl,_size);+//+// typename Interface::real_type error=+// STL_interface<typename Interface::real_type>::norm_diff(C_stl,resu_stl);+//+// if (error>1.e-6){+// INFOS("WRONG CALCULATION...residual=" << error);+// exit(0);+// }++ }++private :++ typename Interface::stl_matrix X_stl;+ typename Interface::stl_matrix C_stl;+ typename Interface::stl_matrix resu_stl;++ typename Interface::gene_matrix X_ref;+ typename Interface::gene_matrix X;+ typename Interface::gene_matrix C;++ int _size;+ double _cost;+};++template<class Interface>+class Action_tridiagonalization {++public :++ // Ctor++ Action_tridiagonalization( int size ):_size(size)+ {+ MESSAGE("Action_tridiagonalization Ctor");++ // STL vector initialization+ init_matrix<pseudo_random>(X_stl,_size);+ + for(int i=0; i<_size; ++i)+ {+ for(int j=0; j<i; ++j)+ X_stl[i][j] = X_stl[j][i];+ }+ + init_matrix<null_function>(C_stl,_size);+ init_matrix<null_function>(resu_stl,_size);++ // generic matrix and vector initialization+ Interface::matrix_from_stl(X_ref,X_stl);+ Interface::matrix_from_stl(X,X_stl);+ Interface::matrix_from_stl(C,C_stl);++ _cost = 0;+ for (int j=0; j<_size-2; ++j)+ {+ double r = std::max(0,_size-j-1);+ double b = std::max(0,_size-j-2);+ _cost += 6. + 3.*b + r*r*8.;+ }+ }++ // invalidate copy ctor++ Action_tridiagonalization( const Action_tridiagonalization & )+ {+ INFOS("illegal call to Action_tridiagonalization Copy Ctor");+ exit(1);+ }++ // Dtor++ ~Action_tridiagonalization( void ){++ MESSAGE("Action_tridiagonalization Dtor");++ // deallocation+ Interface::free_matrix(X_ref,_size);+ Interface::free_matrix(X,_size);+ Interface::free_matrix(C,_size);+ }++ // action name++ static inline std::string name( void ) { return "tridiagonalization_"+Interface::name(); }++ double nb_op_base( void ){+ return _cost;+ }++ inline void initialize( void ){+ Interface::copy_matrix(X_ref,X,_size);+ }++ inline void calculate( void ) {+ Interface::tridiagonalization(X,C,_size);+ }++ void check_result( void ){+ // calculation check+ Interface::matrix_to_stl(C,resu_stl);++// STL_interface<typename Interface::real_type>::tridiagonalization(X_stl,C_stl,_size);+//+// typename Interface::real_type error=+// STL_interface<typename Interface::real_type>::norm_diff(C_stl,resu_stl);+//+// if (error>1.e-6){+// INFOS("WRONG CALCULATION...residual=" << error);+// exit(0);+// }++ }++private :++ typename Interface::stl_matrix X_stl;+ typename Interface::stl_matrix C_stl;+ typename Interface::stl_matrix resu_stl;++ typename Interface::gene_matrix X_ref;+ typename Interface::gene_matrix X;+ typename Interface::gene_matrix C;++ int _size;+ double _cost;+};++#endif
+ eigen3/bench/btl/actions/action_lu_decomp.hh view
@@ -0,0 +1,124 @@+//=====================================================+// File : action_lu_decomp.hh+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_LU_DECOMP+#define ACTION_LU_DECOMP+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_lu_decomp {++public :++ // Ctor++ Action_lu_decomp( int size ):_size(size)+ {+ MESSAGE("Action_lu_decomp Ctor");++ // STL vector initialization+ init_matrix<pseudo_random>(X_stl,_size);++ init_matrix<null_function>(C_stl,_size);+ init_matrix<null_function>(resu_stl,_size);++ // generic matrix and vector initialization+ Interface::matrix_from_stl(X_ref,X_stl);+ Interface::matrix_from_stl(X,X_stl);+ Interface::matrix_from_stl(C,C_stl);++ _cost = 2.0*size*size*size/3.0 + size*size;+ }++ // invalidate copy ctor++ Action_lu_decomp( const Action_lu_decomp & )+ {+ INFOS("illegal call to Action_lu_decomp Copy Ctor");+ exit(1);+ }++ // Dtor++ ~Action_lu_decomp( void ){++ MESSAGE("Action_lu_decomp Dtor");++ // deallocation+ Interface::free_matrix(X_ref,_size);+ Interface::free_matrix(X,_size);+ Interface::free_matrix(C,_size);+ }++ // action name++ static inline std::string name( void )+ {+ return "complete_lu_decomp_"+Interface::name();+ }++ double nb_op_base( void ){+ return _cost;+ }++ inline void initialize( void ){+ Interface::copy_matrix(X_ref,X,_size);+ }++ inline void calculate( void ) {+ Interface::lu_decomp(X,C,_size);+ }++ void check_result( void ){+ // calculation check+ Interface::matrix_to_stl(C,resu_stl);++// STL_interface<typename Interface::real_type>::lu_decomp(X_stl,C_stl,_size);+//+// typename Interface::real_type error=+// STL_interface<typename Interface::real_type>::norm_diff(C_stl,resu_stl);+//+// if (error>1.e-6){+// INFOS("WRONG CALCULATION...residual=" << error);+// exit(0);+// }++ }++private :++ typename Interface::stl_matrix X_stl;+ typename Interface::stl_matrix C_stl;+ typename Interface::stl_matrix resu_stl;++ typename Interface::gene_matrix X_ref;+ typename Interface::gene_matrix X;+ typename Interface::gene_matrix C;++ int _size;+ double _cost;+};++#endif
+ eigen3/bench/btl/actions/action_lu_solve.hh view
@@ -0,0 +1,136 @@+//=====================================================+// File : action_lu_solve.hh+// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002+//=====================================================+// +// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+// +// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+// +#ifndef ACTION_LU_SOLVE+#define ACTION_LU_SOLVE+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_lu_solve +{++public :++ static inline std::string name( void )+ {+ return "lu_solve_"+Interface::name();+ }+ + static double nb_op_base(int size){+ return 2.0*size*size*size/3.0; // questionable but not really important+ }+++ static double calculate( int nb_calc, int size ) {++ // STL matrix and vector initialization+ + typename Interface::stl_matrix A_stl;+ typename Interface::stl_vector B_stl;+ typename Interface::stl_vector X_stl;++ init_matrix<pseudo_random>(A_stl,size);+ init_vector<pseudo_random>(B_stl,size);+ init_vector<null_function>(X_stl,size);++ // generic matrix and vector initialization++ typename Interface::gene_matrix A;+ typename Interface::gene_vector B;+ typename Interface::gene_vector X;++ typename Interface::gene_matrix LU; ++ Interface::matrix_from_stl(A,A_stl);+ Interface::vector_from_stl(B,B_stl);+ Interface::vector_from_stl(X,X_stl);+ Interface::matrix_from_stl(LU,A_stl);+ + // local variable :++ typename Interface::Pivot_Vector pivot; // pivot vector+ Interface::new_Pivot_Vector(pivot,size);+ + // timer utilities++ Portable_Timer chronos;++ // time measurement++ chronos.start();+ + for (int ii=0;ii<nb_calc;ii++){++ // LU factorization+ Interface::copy_matrix(A,LU,size);+ Interface::LU_factor(LU,pivot,size);+ + // LU solve++ Interface::LU_solve(LU,pivot,B,X,size);++ }++ // Time stop++ chronos.stop();++ double time=chronos.user_time();+ + // check result :++ typename Interface::stl_vector B_new_stl(size);+ Interface::vector_to_stl(X,X_stl);++ STL_interface<typename Interface::real_type>::matrix_vector_product(A_stl,X_stl,B_new_stl,size); + + typename Interface::real_type error=+ STL_interface<typename Interface::real_type>::norm_diff(B_stl,B_new_stl);+ + if (error>1.e-5){+ INFOS("WRONG CALCULATION...residual=" << error);+ STL_interface<typename Interface::real_type>::display_vector(B_stl);+ STL_interface<typename Interface::real_type>::display_vector(B_new_stl);+ exit(0);+ }+ + // deallocation and return time+ + Interface::free_matrix(A,size);+ Interface::free_vector(B);+ Interface::free_vector(X);+ Interface::free_Pivot_Vector(pivot);++ return time;+ }++};+ ++#endif+++
+ eigen3/bench/btl/actions/action_matrix_matrix_product.hh view
@@ -0,0 +1,150 @@+//=====================================================+// File : action_matrix_matrix_product.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_MATRIX_MATRIX_PRODUCT+#define ACTION_MATRIX_MATRIX_PRODUCT+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_matrix_matrix_product {++public :++ // Ctor++ Action_matrix_matrix_product( int size ):_size(size)+ {+ MESSAGE("Action_matrix_matrix_product Ctor");++ // STL matrix and vector initialization++ init_matrix<pseudo_random>(A_stl,_size);+ init_matrix<pseudo_random>(B_stl,_size);+ init_matrix<null_function>(X_stl,_size);+ init_matrix<null_function>(resu_stl,_size);++ // generic matrix and vector initialization++ Interface::matrix_from_stl(A_ref,A_stl);+ Interface::matrix_from_stl(B_ref,B_stl);+ Interface::matrix_from_stl(X_ref,X_stl);++ Interface::matrix_from_stl(A,A_stl);+ Interface::matrix_from_stl(B,B_stl);+ Interface::matrix_from_stl(X,X_stl);++ }++ // invalidate copy ctor++ Action_matrix_matrix_product( const Action_matrix_matrix_product & )+ {+ INFOS("illegal call to Action_matrix_matrix_product Copy Ctor");+ exit(0);+ }++ // Dtor++ ~Action_matrix_matrix_product( void ){++ MESSAGE("Action_matrix_matrix_product Dtor");++ // deallocation++ Interface::free_matrix(A,_size);+ Interface::free_matrix(B,_size);+ Interface::free_matrix(X,_size);++ Interface::free_matrix(A_ref,_size);+ Interface::free_matrix(B_ref,_size);+ Interface::free_matrix(X_ref,_size);++ }++ // action name++ static inline std::string name( void )+ {+ return "matrix_matrix_"+Interface::name();+ }++ double nb_op_base( void ){+ return 2.0*_size*_size*_size;+ }++ inline void initialize( void ){++ Interface::copy_matrix(A_ref,A,_size);+ Interface::copy_matrix(B_ref,B,_size);+ Interface::copy_matrix(X_ref,X,_size);++ }++ inline void calculate( void ) {+ Interface::matrix_matrix_product(A,B,X,_size);+ }++ void check_result( void ){++ // calculation check+ if (_size<200)+ {+ Interface::matrix_to_stl(X,resu_stl);+ STL_interface<typename Interface::real_type>::matrix_matrix_product(A_stl,B_stl,X_stl,_size);+ typename Interface::real_type error=+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);+ if (error>1.e-6){+ INFOS("WRONG CALCULATION...residual=" << error);+ exit(1);+ }+ }+ }++private :++ typename Interface::stl_matrix A_stl;+ typename Interface::stl_matrix B_stl;+ typename Interface::stl_matrix X_stl;+ typename Interface::stl_matrix resu_stl;++ typename Interface::gene_matrix A_ref;+ typename Interface::gene_matrix B_ref;+ typename Interface::gene_matrix X_ref;++ typename Interface::gene_matrix A;+ typename Interface::gene_matrix B;+ typename Interface::gene_matrix X;+++ int _size;++};+++#endif+++
+ eigen3/bench/btl/actions/action_matrix_matrix_product_bis.hh view
@@ -0,0 +1,152 @@+//=====================================================+// File : action_matrix_matrix_product_bis.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_MATRIX_MATRIX_PRODUCT_BIS+#define ACTION_MATRIX_MATRIX_PRODUCT_BIS+#include "utilities.h"+#include "STL_interface.hh"+#include "STL_timer.hh"+#include <string>+#include "init_function.hh"+#include "init_vector.hh"+#include "init_matrix.hh"++using namespace std;++template<class Interface>+class Action_matrix_matrix_product_bis {++public :++ static inline std::string name( void )+ {+ return "matrix_matrix_"+Interface::name();+ }++ static double nb_op_base(int size){+ return 2.0*size*size*size;+ }++ static double calculate( int nb_calc, int size ) {++ // STL matrix and vector initialization++ typename Interface::stl_matrix A_stl;+ typename Interface::stl_matrix B_stl;+ typename Interface::stl_matrix X_stl;++ init_matrix<pseudo_random>(A_stl,size);+ init_matrix<pseudo_random>(B_stl,size);+ init_matrix<null_function>(X_stl,size);++ // generic matrix and vector initialization++ typename Interface::gene_matrix A_ref;+ typename Interface::gene_matrix B_ref;+ typename Interface::gene_matrix X_ref;++ typename Interface::gene_matrix A;+ typename Interface::gene_matrix B;+ typename Interface::gene_matrix X;+++ Interface::matrix_from_stl(A_ref,A_stl);+ Interface::matrix_from_stl(B_ref,B_stl);+ Interface::matrix_from_stl(X_ref,X_stl);++ Interface::matrix_from_stl(A,A_stl);+ Interface::matrix_from_stl(B,B_stl);+ Interface::matrix_from_stl(X,X_stl);+++ // STL_timer utilities++ STL_timer chronos;++ // Baseline evaluation++ chronos.start_baseline(nb_calc);++ do {++ Interface::copy_matrix(A_ref,A,size);+ Interface::copy_matrix(B_ref,B,size);+ Interface::copy_matrix(X_ref,X,size);+++ // Interface::matrix_matrix_product(A,B,X,size); This line must be commented !!!!+ }+ while(chronos.check());++ chronos.report(true);++ // Time measurement++ chronos.start(nb_calc);++ do {++ Interface::copy_matrix(A_ref,A,size);+ Interface::copy_matrix(B_ref,B,size);+ Interface::copy_matrix(X_ref,X,size);++ Interface::matrix_matrix_product(A,B,X,size); // here it is not commented !!!!+ }+ while(chronos.check());++ chronos.report(true);++ double time=chronos.calculated_time/2000.0;++ // calculation check++ typename Interface::stl_matrix resu_stl(size);++ Interface::matrix_to_stl(X,resu_stl);++ STL_interface<typename Interface::real_type>::matrix_matrix_product(A_stl,B_stl,X_stl,size);++ typename Interface::real_type error=+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);++ if (error>1.e-6){+ INFOS("WRONG CALCULATION...residual=" << error);+ exit(1);+ }++ // deallocation and return time++ Interface::free_matrix(A,size);+ Interface::free_matrix(B,size);+ Interface::free_matrix(X,size);++ Interface::free_matrix(A_ref,size);+ Interface::free_matrix(B_ref,size);+ Interface::free_matrix(X_ref,size);++ return time;+ }++};+++#endif+++
+ eigen3/bench/btl/actions/action_matrix_vector_product.hh view
@@ -0,0 +1,153 @@+//=====================================================+// File : action_matrix_vector_product.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_MATRIX_VECTOR_PRODUCT+#define ACTION_MATRIX_VECTOR_PRODUCT+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_matrix_vector_product {++public :++ // Ctor++ BTL_DONT_INLINE Action_matrix_vector_product( int size ):_size(size)+ {+ MESSAGE("Action_matrix_vector_product Ctor");++ // STL matrix and vector initialization++ init_matrix<pseudo_random>(A_stl,_size);+ init_vector<pseudo_random>(B_stl,_size);+ init_vector<null_function>(X_stl,_size);+ init_vector<null_function>(resu_stl,_size);++ // generic matrix and vector initialization++ Interface::matrix_from_stl(A_ref,A_stl);+ Interface::matrix_from_stl(A,A_stl);+ Interface::vector_from_stl(B_ref,B_stl);+ Interface::vector_from_stl(B,B_stl);+ Interface::vector_from_stl(X_ref,X_stl);+ Interface::vector_from_stl(X,X_stl);++ }++ // invalidate copy ctor++ Action_matrix_vector_product( const Action_matrix_vector_product & )+ {+ INFOS("illegal call to Action_matrix_vector_product Copy Ctor");+ exit(1);+ }++ // Dtor++ BTL_DONT_INLINE ~Action_matrix_vector_product( void ){++ MESSAGE("Action_matrix_vector_product Dtor");++ // deallocation++ Interface::free_matrix(A,_size);+ Interface::free_vector(B);+ Interface::free_vector(X);++ Interface::free_matrix(A_ref,_size);+ Interface::free_vector(B_ref);+ Interface::free_vector(X_ref);++ }++ // action name++ static inline std::string name( void )+ {+ return "matrix_vector_" + Interface::name();+ }++ double nb_op_base( void ){+ return 2.0*_size*_size;+ }++ BTL_DONT_INLINE void initialize( void ){++ Interface::copy_matrix(A_ref,A,_size);+ Interface::copy_vector(B_ref,B,_size);+ Interface::copy_vector(X_ref,X,_size);++ }++ BTL_DONT_INLINE void calculate( void ) {+ BTL_ASM_COMMENT("#begin matrix_vector_product");+ Interface::matrix_vector_product(A,B,X,_size);+ BTL_ASM_COMMENT("end matrix_vector_product");+ }++ BTL_DONT_INLINE void check_result( void ){++ // calculation check++ Interface::vector_to_stl(X,resu_stl);++ STL_interface<typename Interface::real_type>::matrix_vector_product(A_stl,B_stl,X_stl,_size);++ typename Interface::real_type error=+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);++ if (error>1.e-5){+ INFOS("WRONG CALCULATION...residual=" << error);+ exit(0);+ }++ }++private :++ typename Interface::stl_matrix A_stl;+ typename Interface::stl_vector B_stl;+ typename Interface::stl_vector X_stl;+ typename Interface::stl_vector resu_stl;++ typename Interface::gene_matrix A_ref;+ typename Interface::gene_vector B_ref;+ typename Interface::gene_vector X_ref;++ typename Interface::gene_matrix A;+ typename Interface::gene_vector B;+ typename Interface::gene_vector X;+++ int _size;++};+++#endif+++
+ eigen3/bench/btl/actions/action_partial_lu.hh view
@@ -0,0 +1,125 @@+//=====================================================+// File : action_lu_decomp.hh+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_PARTIAL_LU+#define ACTION_PARTIAL_LU+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_partial_lu {++public :++ // Ctor++ Action_partial_lu( int size ):_size(size)+ {+ MESSAGE("Action_partial_lu Ctor");++ // STL vector initialization+ init_matrix<pseudo_random>(X_stl,_size);+ init_matrix<null_function>(C_stl,_size);++ // make sure X is invertible+ for (int i=0; i<_size; ++i)+ X_stl[i][i] = X_stl[i][i] * 1e2 + 1;++ // generic matrix and vector initialization+ Interface::matrix_from_stl(X_ref,X_stl);+ Interface::matrix_from_stl(X,X_stl);+ Interface::matrix_from_stl(C,C_stl);++ _cost = 2.0*size*size*size/3.0 + size*size;+ }++ // invalidate copy ctor++ Action_partial_lu( const Action_partial_lu & )+ {+ INFOS("illegal call to Action_partial_lu Copy Ctor");+ exit(1);+ }++ // Dtor++ ~Action_partial_lu( void ){++ MESSAGE("Action_partial_lu Dtor");++ // deallocation+ Interface::free_matrix(X_ref,_size);+ Interface::free_matrix(X,_size);+ Interface::free_matrix(C,_size);+ }++ // action name++ static inline std::string name( void )+ {+ return "partial_lu_decomp_"+Interface::name();+ }++ double nb_op_base( void ){+ return _cost;+ }++ inline void initialize( void ){+ Interface::copy_matrix(X_ref,X,_size);+ }++ inline void calculate( void ) {+ Interface::partial_lu_decomp(X,C,_size);+ }++ void check_result( void ){+ // calculation check+// Interface::matrix_to_stl(C,resu_stl);++// STL_interface<typename Interface::real_type>::lu_decomp(X_stl,C_stl,_size);+//+// typename Interface::real_type error=+// STL_interface<typename Interface::real_type>::norm_diff(C_stl,resu_stl);+//+// if (error>1.e-6){+// INFOS("WRONG CALCULATION...residual=" << error);+// exit(0);+// }++ }++private :++ typename Interface::stl_matrix X_stl;+ typename Interface::stl_matrix C_stl;++ typename Interface::gene_matrix X_ref;+ typename Interface::gene_matrix X;+ typename Interface::gene_matrix C;++ int _size;+ double _cost;+};++#endif
+ eigen3/bench/btl/actions/action_rot.hh view
@@ -0,0 +1,116 @@++// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_ROT+#define ACTION_ROT+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_rot {++public :++ // Ctor+ BTL_DONT_INLINE Action_rot( int size ):_size(size)+ {+ MESSAGE("Action_rot Ctor");++ // STL matrix and vector initialization+ typename Interface::stl_matrix tmp;+ init_vector<pseudo_random>(A_stl,_size);+ init_vector<pseudo_random>(B_stl,_size);++ // generic matrix and vector initialization+ Interface::vector_from_stl(A_ref,A_stl);+ Interface::vector_from_stl(A,A_stl);+ Interface::vector_from_stl(B_ref,B_stl);+ Interface::vector_from_stl(B,B_stl);+ }++ // invalidate copy ctor+ Action_rot( const Action_rot & )+ {+ INFOS("illegal call to Action_rot Copy Ctor");+ exit(1);+ }++ // Dtor+ BTL_DONT_INLINE ~Action_rot( void ){+ MESSAGE("Action_rot Dtor");+ Interface::free_vector(A);+ Interface::free_vector(B);+ Interface::free_vector(A_ref);+ Interface::free_vector(B_ref);+ }++ // action name+ static inline std::string name( void )+ {+ return "rot_" + Interface::name();+ }++ double nb_op_base( void ){+ return 6.0*_size;+ }++ BTL_DONT_INLINE void initialize( void ){+ Interface::copy_vector(A_ref,A,_size);+ Interface::copy_vector(B_ref,B,_size);+ }++ BTL_DONT_INLINE void calculate( void ) {+ BTL_ASM_COMMENT("#begin rot");+ Interface::rot(A,B,0.5,0.6,_size);+ BTL_ASM_COMMENT("end rot");+ }++ BTL_DONT_INLINE void check_result( void ){+ // calculation check+// Interface::vector_to_stl(X,resu_stl);++// STL_interface<typename Interface::real_type>::rot(A_stl,B_stl,X_stl,_size);++// typename Interface::real_type error=+// STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);++// if (error>1.e-3){+// INFOS("WRONG CALCULATION...residual=" << error);+// exit(0);+// }++ }++private :++ typename Interface::stl_vector A_stl;+ typename Interface::stl_vector B_stl;++ typename Interface::gene_vector A_ref;+ typename Interface::gene_vector B_ref;++ typename Interface::gene_vector A;+ typename Interface::gene_vector B;++ int _size;+};+++#endif
+ eigen3/bench/btl/actions/action_symv.hh view
@@ -0,0 +1,139 @@+//=====================================================+// File : action_symv.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_SYMV+#define ACTION_SYMV+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_symv {++public :++ // Ctor++ BTL_DONT_INLINE Action_symv( int size ):_size(size)+ {+ MESSAGE("Action_symv Ctor");++ // STL matrix and vector initialization+ init_matrix_symm<pseudo_random>(A_stl,_size);+ init_vector<pseudo_random>(B_stl,_size);+ init_vector<null_function>(X_stl,_size);+ init_vector<null_function>(resu_stl,_size);++ // generic matrix and vector initialization+ Interface::matrix_from_stl(A_ref,A_stl);+ Interface::matrix_from_stl(A,A_stl);+ Interface::vector_from_stl(B_ref,B_stl);+ Interface::vector_from_stl(B,B_stl);+ Interface::vector_from_stl(X_ref,X_stl);+ Interface::vector_from_stl(X,X_stl);++ }++ // invalidate copy ctor++ Action_symv( const Action_symv & )+ {+ INFOS("illegal call to Action_symv Copy Ctor");+ exit(1);+ }++ // Dtor+ BTL_DONT_INLINE ~Action_symv( void ){+ Interface::free_matrix(A,_size);+ Interface::free_vector(B);+ Interface::free_vector(X);+ Interface::free_matrix(A_ref,_size);+ Interface::free_vector(B_ref);+ Interface::free_vector(X_ref);+ }++ // action name++ static inline std::string name( void )+ {+ return "symv_" + Interface::name();+ }++ double nb_op_base( void ){+ return 2.0*_size*_size;+ }++ BTL_DONT_INLINE void initialize( void ){++ Interface::copy_matrix(A_ref,A,_size);+ Interface::copy_vector(B_ref,B,_size);+ Interface::copy_vector(X_ref,X,_size);++ }++ BTL_DONT_INLINE void calculate( void ) {+ BTL_ASM_COMMENT("#begin symv");+ Interface::symv(A,B,X,_size);+ BTL_ASM_COMMENT("end symv");+ }++ BTL_DONT_INLINE void check_result( void ){+ if (_size>128) return;+ // calculation check+ Interface::vector_to_stl(X,resu_stl);++ STL_interface<typename Interface::real_type>::symv(A_stl,B_stl,X_stl,_size);++ typename Interface::real_type error=+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);++ if (error>1.e-5){+ INFOS("WRONG CALCULATION...residual=" << error);+ exit(0);+ }++ }++private :++ typename Interface::stl_matrix A_stl;+ typename Interface::stl_vector B_stl;+ typename Interface::stl_vector X_stl;+ typename Interface::stl_vector resu_stl;++ typename Interface::gene_matrix A_ref;+ typename Interface::gene_vector B_ref;+ typename Interface::gene_vector X_ref;++ typename Interface::gene_matrix A;+ typename Interface::gene_vector B;+ typename Interface::gene_vector X;+++ int _size;++};+++#endif
+ eigen3/bench/btl/actions/action_syr2.hh view
@@ -0,0 +1,133 @@+//=====================================================+// File : action_syr2.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_SYR2+#define ACTION_SYR2+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_syr2 {++public :++ // Ctor++ BTL_DONT_INLINE Action_syr2( int size ):_size(size)+ {+ // STL matrix and vector initialization+ typename Interface::stl_matrix tmp;+ init_matrix<pseudo_random>(A_stl,_size);+ init_vector<pseudo_random>(B_stl,_size);+ init_vector<pseudo_random>(X_stl,_size);+ init_vector<null_function>(resu_stl,_size);++ // generic matrix and vector initialization+ Interface::matrix_from_stl(A_ref,A_stl);+ Interface::matrix_from_stl(A,A_stl);+ Interface::vector_from_stl(B_ref,B_stl);+ Interface::vector_from_stl(B,B_stl);+ Interface::vector_from_stl(X_ref,X_stl);+ Interface::vector_from_stl(X,X_stl);+ }++ // invalidate copy ctor+ Action_syr2( const Action_syr2 & )+ {+ INFOS("illegal call to Action_syr2 Copy Ctor");+ exit(1);+ }++ // Dtor+ BTL_DONT_INLINE ~Action_syr2( void ){+ Interface::free_matrix(A,_size);+ Interface::free_vector(B);+ Interface::free_vector(X);+ Interface::free_matrix(A_ref,_size);+ Interface::free_vector(B_ref);+ Interface::free_vector(X_ref);+ }++ // action name++ static inline std::string name( void )+ {+ return "syr2_" + Interface::name();+ }++ double nb_op_base( void ){+ return 2.0*_size*_size;+ }++ BTL_DONT_INLINE void initialize( void ){+ Interface::copy_matrix(A_ref,A,_size);+ Interface::copy_vector(B_ref,B,_size);+ Interface::copy_vector(X_ref,X,_size);+ }++ BTL_DONT_INLINE void calculate( void ) {+ BTL_ASM_COMMENT("#begin syr2");+ Interface::syr2(A,B,X,_size);+ BTL_ASM_COMMENT("end syr2");+ }++ BTL_DONT_INLINE void check_result( void ){+ // calculation check+ Interface::vector_to_stl(X,resu_stl);++ STL_interface<typename Interface::real_type>::syr2(A_stl,B_stl,X_stl,_size);++ typename Interface::real_type error=+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);++ if (error>1.e-3){+ INFOS("WRONG CALCULATION...residual=" << error);+// exit(0);+ }++ }++private :++ typename Interface::stl_matrix A_stl;+ typename Interface::stl_vector B_stl;+ typename Interface::stl_vector X_stl;+ typename Interface::stl_vector resu_stl;++ typename Interface::gene_matrix A_ref;+ typename Interface::gene_vector B_ref;+ typename Interface::gene_vector X_ref;++ typename Interface::gene_matrix A;+ typename Interface::gene_vector B;+ typename Interface::gene_vector X;+++ int _size;++};+++#endif
+ eigen3/bench/btl/actions/action_trisolve.hh view
@@ -0,0 +1,137 @@+//=====================================================+// File : action_trisolve.hh+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_TRISOLVE+#define ACTION_TRISOLVE+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_trisolve {++public :++ // Ctor++ Action_trisolve( int size ):_size(size)+ {+ MESSAGE("Action_trisolve Ctor");++ // STL vector initialization+ init_matrix<pseudo_random>(L_stl,_size);+ init_vector<pseudo_random>(B_stl,_size);+ init_vector<null_function>(X_stl,_size);+ for (int j=0; j<_size; ++j)+ {+ for (int i=0; i<j; ++i)+ L_stl[j][i] = 0;+ L_stl[j][j] += 3;+ }++ init_vector<null_function>(resu_stl,_size);++ // generic matrix and vector initialization+ Interface::matrix_from_stl(L,L_stl);+ Interface::vector_from_stl(X,X_stl);+ Interface::vector_from_stl(B,B_stl);++ _cost = 0;+ for (int j=0; j<_size; ++j)+ {+ _cost += 2*j + 1;+ }+ }++ // invalidate copy ctor++ Action_trisolve( const Action_trisolve & )+ {+ INFOS("illegal call to Action_trisolve Copy Ctor");+ exit(1);+ }++ // Dtor++ ~Action_trisolve( void ){++ MESSAGE("Action_trisolve Dtor");++ // deallocation+ Interface::free_matrix(L,_size);+ Interface::free_vector(B);+ Interface::free_vector(X);+ }++ // action name++ static inline std::string name( void )+ {+ return "trisolve_vector_"+Interface::name();+ }++ double nb_op_base( void ){+ return _cost;+ }++ inline void initialize( void ){+ //Interface::copy_vector(X_ref,X,_size);+ }++ inline void calculate( void ) {+ Interface::trisolve_lower(L,B,X,_size);+ }++ void check_result(){+ if (_size>128) return;+ // calculation check+ Interface::vector_to_stl(X,resu_stl);++ STL_interface<typename Interface::real_type>::trisolve_lower(L_stl,B_stl,X_stl,_size);++ typename Interface::real_type error=+ STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);++ if (error>1.e-4){+ INFOS("WRONG CALCULATION...residual=" << error);+ exit(2);+ } //else INFOS("CALCULATION OK...residual=" << error);++ }++private :++ typename Interface::stl_matrix L_stl;+ typename Interface::stl_vector X_stl;+ typename Interface::stl_vector B_stl;+ typename Interface::stl_vector resu_stl;++ typename Interface::gene_matrix L;+ typename Interface::gene_vector X;+ typename Interface::gene_vector B;++ int _size;+ double _cost;+};++#endif
+ eigen3/bench/btl/actions/action_trisolve_matrix.hh view
@@ -0,0 +1,165 @@+//=====================================================+// File : action_matrix_matrix_product.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_TRISOLVE_MATRIX_PRODUCT+#define ACTION_TRISOLVE_MATRIX_PRODUCT+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_trisolve_matrix {++public :++ // Ctor++ Action_trisolve_matrix( int size ):_size(size)+ {+ MESSAGE("Action_trisolve_matrix Ctor");++ // STL matrix and vector initialization++ init_matrix<pseudo_random>(A_stl,_size);+ init_matrix<pseudo_random>(B_stl,_size);+ init_matrix<null_function>(X_stl,_size);+ init_matrix<null_function>(resu_stl,_size);++ for (int j=0; j<_size; ++j)+ {+ for (int i=0; i<j; ++i)+ A_stl[j][i] = 0;+ A_stl[j][j] += 3;+ }++ // generic matrix and vector initialization++ Interface::matrix_from_stl(A_ref,A_stl);+ Interface::matrix_from_stl(B_ref,B_stl);+ Interface::matrix_from_stl(X_ref,X_stl);++ Interface::matrix_from_stl(A,A_stl);+ Interface::matrix_from_stl(B,B_stl);+ Interface::matrix_from_stl(X,X_stl);++ _cost = 0;+ for (int j=0; j<_size; ++j)+ {+ _cost += 2*j + 1;+ }+ _cost *= _size;+ }++ // invalidate copy ctor++ Action_trisolve_matrix( const Action_trisolve_matrix & )+ {+ INFOS("illegal call to Action_trisolve_matrix Copy Ctor");+ exit(0);+ }++ // Dtor++ ~Action_trisolve_matrix( void ){++ MESSAGE("Action_trisolve_matrix Dtor");++ // deallocation++ Interface::free_matrix(A,_size);+ Interface::free_matrix(B,_size);+ Interface::free_matrix(X,_size);++ Interface::free_matrix(A_ref,_size);+ Interface::free_matrix(B_ref,_size);+ Interface::free_matrix(X_ref,_size);++ }++ // action name++ static inline std::string name( void )+ {+ return "trisolve_matrix_"+Interface::name();+ }++ double nb_op_base( void ){+ return _cost;+ }++ inline void initialize( void ){++ Interface::copy_matrix(A_ref,A,_size);+ Interface::copy_matrix(B_ref,B,_size);+ Interface::copy_matrix(X_ref,X,_size);++ }++ inline void calculate( void ) {+ Interface::trisolve_lower_matrix(A,B,X,_size);+ }++ void check_result( void ){++ // calculation check++// Interface::matrix_to_stl(X,resu_stl);+//+// STL_interface<typename Interface::real_type>::matrix_matrix_product(A_stl,B_stl,X_stl,_size);+//+// typename Interface::real_type error=+// STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);+//+// if (error>1.e-6){+// INFOS("WRONG CALCULATION...residual=" << error);+// // exit(1);+// }++ }++private :++ typename Interface::stl_matrix A_stl;+ typename Interface::stl_matrix B_stl;+ typename Interface::stl_matrix X_stl;+ typename Interface::stl_matrix resu_stl;++ typename Interface::gene_matrix A_ref;+ typename Interface::gene_matrix B_ref;+ typename Interface::gene_matrix X_ref;++ typename Interface::gene_matrix A;+ typename Interface::gene_matrix B;+ typename Interface::gene_matrix X;++ int _size;+ double _cost;++};+++#endif+++
+ eigen3/bench/btl/actions/action_trmm.hh view
@@ -0,0 +1,165 @@+//=====================================================+// File : action_matrix_matrix_product.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef ACTION_TRMM+#define ACTION_TRMM+#include "utilities.h"+#include "STL_interface.hh"+#include <string>+#include "init/init_function.hh"+#include "init/init_vector.hh"+#include "init/init_matrix.hh"++using namespace std;++template<class Interface>+class Action_trmm {++public :++ // Ctor++ Action_trmm( int size ):_size(size)+ {+ MESSAGE("Action_trmm Ctor");++ // STL matrix and vector initialization++ init_matrix<pseudo_random>(A_stl,_size);+ init_matrix<pseudo_random>(B_stl,_size);+ init_matrix<null_function>(X_stl,_size);+ init_matrix<null_function>(resu_stl,_size);++ for (int j=0; j<_size; ++j)+ {+ for (int i=0; i<j; ++i)+ A_stl[j][i] = 0;+ A_stl[j][j] += 3;+ }++ // generic matrix and vector initialization++ Interface::matrix_from_stl(A_ref,A_stl);+ Interface::matrix_from_stl(B_ref,B_stl);+ Interface::matrix_from_stl(X_ref,X_stl);++ Interface::matrix_from_stl(A,A_stl);+ Interface::matrix_from_stl(B,B_stl);+ Interface::matrix_from_stl(X,X_stl);++ _cost = 0;+ for (int j=0; j<_size; ++j)+ {+ _cost += 2*j + 1;+ }+ _cost *= _size;+ }++ // invalidate copy ctor++ Action_trmm( const Action_trmm & )+ {+ INFOS("illegal call to Action_trmm Copy Ctor");+ exit(0);+ }++ // Dtor++ ~Action_trmm( void ){++ MESSAGE("Action_trmm Dtor");++ // deallocation++ Interface::free_matrix(A,_size);+ Interface::free_matrix(B,_size);+ Interface::free_matrix(X,_size);++ Interface::free_matrix(A_ref,_size);+ Interface::free_matrix(B_ref,_size);+ Interface::free_matrix(X_ref,_size);++ }++ // action name++ static inline std::string name( void )+ {+ return "trmm_"+Interface::name();+ }++ double nb_op_base( void ){+ return _cost;+ }++ inline void initialize( void ){++ Interface::copy_matrix(A_ref,A,_size);+ Interface::copy_matrix(B_ref,B,_size);+ Interface::copy_matrix(X_ref,X,_size);++ }++ inline void calculate( void ) {+ Interface::trmm(A,B,X,_size);+ }++ void check_result( void ){++ // calculation check++// Interface::matrix_to_stl(X,resu_stl);+//+// STL_interface<typename Interface::real_type>::matrix_matrix_product(A_stl,B_stl,X_stl,_size);+//+// typename Interface::real_type error=+// STL_interface<typename Interface::real_type>::norm_diff(X_stl,resu_stl);+//+// if (error>1.e-6){+// INFOS("WRONG CALCULATION...residual=" << error);+// // exit(1);+// }++ }++private :++ typename Interface::stl_matrix A_stl;+ typename Interface::stl_matrix B_stl;+ typename Interface::stl_matrix X_stl;+ typename Interface::stl_matrix resu_stl;++ typename Interface::gene_matrix A_ref;+ typename Interface::gene_matrix B_ref;+ typename Interface::gene_matrix X_ref;++ typename Interface::gene_matrix A;+ typename Interface::gene_matrix B;+ typename Interface::gene_matrix X;++ int _size;+ double _cost;++};+++#endif+++
+ eigen3/bench/btl/actions/basic_actions.hh view
@@ -0,0 +1,21 @@++#include "action_axpy.hh"+#include "action_axpby.hh"++#include "action_matrix_vector_product.hh"+#include "action_atv_product.hh"++#include "action_matrix_matrix_product.hh"+// #include "action_ata_product.hh"+#include "action_aat_product.hh"++#include "action_trisolve.hh"+#include "action_trmm.hh"+#include "action_symv.hh"+// #include "action_symm.hh"+#include "action_syr2.hh"+#include "action_ger.hh"+#include "action_rot.hh"++// #include "action_lu_solve.hh"+
+ eigen3/bench/btl/cmake/FindACML.cmake view
@@ -0,0 +1,49 @@++if (ACML_LIBRARIES)+ set(ACML_FIND_QUIETLY TRUE)+endif (ACML_LIBRARIES)++find_library(ACML_LIBRARIES+ NAMES+ acml_mp acml_mv+ PATHS+ $ENV{ACMLDIR}/lib+ $ENV{ACML_DIR}/lib+ ${LIB_INSTALL_DIR}+)++find_file(ACML_LIBRARIES+ NAMES+ libacml_mp.so+ PATHS+ /usr/lib+ $ENV{ACMLDIR}/lib+ ${LIB_INSTALL_DIR}+)++if(NOT ACML_LIBRARIES)+ message(STATUS "Multi-threaded library not found, looking for single-threaded")+ find_library(ACML_LIBRARIES+ NAMES+ acml acml_mv+ PATHS+ $ENV{ACMLDIR}/lib+ $ENV{ACML_DIR}/lib+ ${LIB_INSTALL_DIR}+ )+ find_file(ACML_LIBRARIES+ libacml.so libacml_mv.so+ PATHS+ /usr/lib+ $ENV{ACMLDIR}/lib+ ${LIB_INSTALL_DIR}+ )+endif()+++++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(ACML DEFAULT_MSG ACML_LIBRARIES)++mark_as_advanced(ACML_LIBRARIES)
+ eigen3/bench/btl/cmake/FindATLAS.cmake view
@@ -0,0 +1,39 @@++if (ATLAS_LIBRARIES)+ set(ATLAS_FIND_QUIETLY TRUE)+endif (ATLAS_LIBRARIES)++find_file(ATLAS_LIB libatlas.so.3 PATHS /usr/lib $ENV{ATLASDIR} ${LIB_INSTALL_DIR})+find_library(ATLAS_LIB atlas PATHS $ENV{ATLASDIR} ${LIB_INSTALL_DIR})++find_file(ATLAS_CBLAS libcblas.so.3 PATHS /usr/lib $ENV{ATLASDIR} ${LIB_INSTALL_DIR})+find_library(ATLAS_CBLAS cblas PATHS $ENV{ATLASDIR} ${LIB_INSTALL_DIR})++find_file(ATLAS_LAPACK liblapack_atlas.so.3 PATHS /usr/lib $ENV{ATLASDIR} ${LIB_INSTALL_DIR})+find_library(ATLAS_LAPACK lapack_atlas PATHS $ENV{ATLASDIR} ${LIB_INSTALL_DIR})++if(NOT ATLAS_LAPACK)+ find_file(ATLAS_LAPACK liblapack.so.3 PATHS /usr/lib/atlas $ENV{ATLASDIR} ${LIB_INSTALL_DIR})+ find_library(ATLAS_LAPACK lapack PATHS $ENV{ATLASDIR} ${LIB_INSTALL_DIR})+endif(NOT ATLAS_LAPACK)++find_file(ATLAS_F77BLAS libf77blas.so.3 PATHS /usr/lib $ENV{ATLASDIR} ${LIB_INSTALL_DIR})+find_library(ATLAS_F77BLAS f77blas PATHS $ENV{ATLASDIR} ${LIB_INSTALL_DIR})++if(ATLAS_LIB AND ATLAS_CBLAS AND ATLAS_LAPACK AND ATLAS_F77BLAS)++ set(ATLAS_LIBRARIES ${ATLAS_LAPACK} ${ATLAS_CBLAS} ${ATLAS_F77BLAS} ${ATLAS_LIB})+ + # search the default lapack lib link to it+ find_file(ATLAS_REFERENCE_LAPACK liblapack.so.3 PATHS /usr/lib /usr/lib64)+ find_library(ATLAS_REFERENCE_LAPACK NAMES lapack)+ if(ATLAS_REFERENCE_LAPACK)+ set(ATLAS_LIBRARIES ${ATLAS_LIBRARIES} ${ATLAS_REFERENCE_LAPACK})+ endif()+ +endif(ATLAS_LIB AND ATLAS_CBLAS AND ATLAS_LAPACK AND ATLAS_F77BLAS)++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(ATLAS DEFAULT_MSG ATLAS_LIBRARIES)++mark_as_advanced(ATLAS_LIBRARIES)
+ eigen3/bench/btl/cmake/FindBlitz.cmake view
@@ -0,0 +1,40 @@+# - Try to find blitz lib+# Once done this will define+#+# BLITZ_FOUND - system has blitz lib+# BLITZ_INCLUDES - the blitz include directory+# BLITZ_LIBRARIES - The libraries needed to use blitz++# Copyright (c) 2006, Montel Laurent, <montel@kde.org>+# Copyright (c) 2007, Allen Winter, <winter@kde.org>+# Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+# Redistribution and use is allowed according to the terms of the BSD license.+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.++# include(FindLibraryWithDebug)++if (BLITZ_INCLUDES AND BLITZ_LIBRARIES)+ set(Blitz_FIND_QUIETLY TRUE)+endif (BLITZ_INCLUDES AND BLITZ_LIBRARIES)++find_path(BLITZ_INCLUDES+ NAMES+ blitz/array.h+ PATH_SUFFIXES blitz*+ PATHS+ $ENV{BLITZDIR}/include+ ${INCLUDE_INSTALL_DIR}+)++find_library(BLITZ_LIBRARIES+ blitz+ PATHS+ $ENV{BLITZDIR}/lib+ ${LIB_INSTALL_DIR}+)++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(Blitz DEFAULT_MSG+ BLITZ_INCLUDES BLITZ_LIBRARIES)++mark_as_advanced(BLITZ_INCLUDES BLITZ_LIBRARIES)
+ eigen3/bench/btl/cmake/FindCBLAS.cmake view
@@ -0,0 +1,34 @@+# include(FindLibraryWithDebug)++if (CBLAS_INCLUDES AND CBLAS_LIBRARIES)+ set(CBLAS_FIND_QUIETLY TRUE)+endif (CBLAS_INCLUDES AND CBLAS_LIBRARIES)++find_path(CBLAS_INCLUDES+ NAMES+ cblas.h+ PATHS+ $ENV{CBLASDIR}/include+ ${INCLUDE_INSTALL_DIR}+)++find_library(CBLAS_LIBRARIES+ cblas+ PATHS+ $ENV{CBLASDIR}/lib+ ${LIB_INSTALL_DIR}+)++find_file(CBLAS_LIBRARIES+ libcblas.so.3+ PATHS+ /usr/lib+ $ENV{CBLASDIR}/lib+ ${LIB_INSTALL_DIR}+)++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(CBLAS DEFAULT_MSG+ CBLAS_INCLUDES CBLAS_LIBRARIES)++mark_as_advanced(CBLAS_INCLUDES CBLAS_LIBRARIES)
+ eigen3/bench/btl/cmake/FindGMM.cmake view
@@ -0,0 +1,17 @@+if (GMM_INCLUDE_DIR)+ # in cache already+ set(GMM_FOUND TRUE)+else (GMM_INCLUDE_DIR)++find_path(GMM_INCLUDE_DIR NAMES gmm/gmm.h+ PATHS+ ${INCLUDE_INSTALL_DIR}+ ${GMM_INCLUDE_PATH}+ )++include(FindPackageHandleStandardArgs)+FIND_PACKAGE_HANDLE_STANDARD_ARGS(GMM DEFAULT_MSG GMM_INCLUDE_DIR )++mark_as_advanced(GMM_INCLUDE_DIR)++endif(GMM_INCLUDE_DIR)
+ eigen3/bench/btl/cmake/FindGOTO.cmake view
@@ -0,0 +1,15 @@++if (GOTO_LIBRARIES)+ set(GOTO_FIND_QUIETLY TRUE)+endif (GOTO_LIBRARIES)++find_library(GOTO_LIBRARIES goto PATHS $ENV{GOTODIR} ${LIB_INSTALL_DIR})++if(GOTO_LIBRARIES AND CMAKE_COMPILER_IS_GNUCXX)+ set(GOTO_LIBRARIES ${GOTO_LIBRARIES} "-lpthread -lgfortran")+endif()++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(GOTO DEFAULT_MSG GOTO_LIBRARIES)++mark_as_advanced(GOTO_LIBRARIES)
+ eigen3/bench/btl/cmake/FindGOTO2.cmake view
@@ -0,0 +1,25 @@++if (GOTO2_LIBRARIES)+ set(GOTO2_FIND_QUIETLY TRUE)+endif (GOTO2_LIBRARIES)+# +# find_path(GOTO_INCLUDES+# NAMES+# cblas.h+# PATHS+# $ENV{GOTODIR}/include+# ${INCLUDE_INSTALL_DIR}+# )++find_file(GOTO2_LIBRARIES libgoto2.so PATHS /usr/lib $ENV{GOTO2DIR} ${LIB_INSTALL_DIR})+find_library(GOTO2_LIBRARIES goto2 PATHS $ENV{GOTO2DIR} ${LIB_INSTALL_DIR})++if(GOTO2_LIBRARIES AND CMAKE_COMPILER_IS_GNUCXX)+ set(GOTO2_LIBRARIES ${GOTO2_LIBRARIES} "-lpthread -lgfortran")+endif()++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(GOTO2 DEFAULT_MSG+ GOTO2_LIBRARIES)++mark_as_advanced(GOTO2_LIBRARIES)
+ eigen3/bench/btl/cmake/FindMKL.cmake view
@@ -0,0 +1,65 @@++if (MKL_LIBRARIES)+ set(MKL_FIND_QUIETLY TRUE)+endif (MKL_LIBRARIES)++if(CMAKE_MINOR_VERSION GREATER 4)++if(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")++find_library(MKL_LIBRARIES+ mkl_core+ PATHS+ $ENV{MKLLIB}+ /opt/intel/mkl/*/lib/em64t+ /opt/intel/Compiler/*/*/mkl/lib/em64t+ ${LIB_INSTALL_DIR}+)++find_library(MKL_GUIDE+ guide+ PATHS+ $ENV{MKLLIB}+ /opt/intel/mkl/*/lib/em64t+ /opt/intel/Compiler/*/*/mkl/lib/em64t+ /opt/intel/Compiler/*/*/lib/intel64+ ${LIB_INSTALL_DIR}+)++if(MKL_LIBRARIES AND MKL_GUIDE)+ set(MKL_LIBRARIES ${MKL_LIBRARIES} mkl_intel_lp64 mkl_sequential ${MKL_GUIDE} pthread)+endif()++else(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")++find_library(MKL_LIBRARIES+ mkl_core+ PATHS+ $ENV{MKLLIB}+ /opt/intel/mkl/*/lib/32+ /opt/intel/Compiler/*/*/mkl/lib/32+ ${LIB_INSTALL_DIR}+)++find_library(MKL_GUIDE+ guide+ PATHS+ $ENV{MKLLIB}+ /opt/intel/mkl/*/lib/32+ /opt/intel/Compiler/*/*/mkl/lib/32+ /opt/intel/Compiler/*/*/lib/intel32+ ${LIB_INSTALL_DIR}+)++if(MKL_LIBRARIES AND MKL_GUIDE)+ set(MKL_LIBRARIES ${MKL_LIBRARIES} mkl_intel mkl_sequential ${MKL_GUIDE} pthread)+endif()++endif(${CMAKE_HOST_SYSTEM_PROCESSOR} STREQUAL "x86_64")++endif(CMAKE_MINOR_VERSION GREATER 4)++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(MKL DEFAULT_MSG MKL_LIBRARIES)++mark_as_advanced(MKL_LIBRARIES)
+ eigen3/bench/btl/cmake/FindMTL4.cmake view
@@ -0,0 +1,31 @@+# - Try to find eigen2 headers+# Once done this will define+#+# MTL4_FOUND - system has eigen2 lib+# MTL4_INCLUDE_DIR - the eigen2 include directory+#+# Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+# Adapted from FindEigen.cmake:+# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org>+# Redistribution and use is allowed according to the terms of the BSD license.+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.++if (MTL4_INCLUDE_DIR)++ # in cache already+ set(MTL4_FOUND TRUE)++else (MTL4_INCLUDE_DIR)++find_path(MTL4_INCLUDE_DIR NAMES boost/numeric/mtl/mtl.hpp+ PATHS+ ${INCLUDE_INSTALL_DIR}+ )++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(MTL4 DEFAULT_MSG MTL4_INCLUDE_DIR)++mark_as_advanced(MTL4_INCLUDE_DIR)++endif(MTL4_INCLUDE_DIR)+
+ eigen3/bench/btl/cmake/FindPackageHandleStandardArgs.cmake view
@@ -0,0 +1,60 @@+# FIND_PACKAGE_HANDLE_STANDARD_ARGS(NAME (DEFAULT_MSG|"Custom failure message") VAR1 ... )+#+# This macro is intended to be used in FindXXX.cmake modules files.+# It handles the REQUIRED and QUIET argument to FIND_PACKAGE() and+# it also sets the <UPPERCASED_NAME>_FOUND variable.+# The package is found if all variables listed are TRUE.+# Example:+#+# FIND_PACKAGE_HANDLE_STANDARD_ARGS(LibXml2 DEFAULT_MSG LIBXML2_LIBRARIES LIBXML2_INCLUDE_DIR)+#+# LibXml2 is considered to be found, if both LIBXML2_LIBRARIES and +# LIBXML2_INCLUDE_DIR are valid. Then also LIBXML2_FOUND is set to TRUE.+# If it is not found and REQUIRED was used, it fails with FATAL_ERROR, +# independent whether QUIET was used or not.+#+# If it is found, the location is reported using the VAR1 argument, so +# here a message "Found LibXml2: /usr/lib/libxml2.so" will be printed out.+# If the second argument is DEFAULT_MSG, the message in the failure case will +# be "Could NOT find LibXml2", if you don't like this message you can specify+# your own custom failure message there.++MACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS _NAME _FAIL_MSG _VAR1 )++ IF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG")+ IF (${_NAME}_FIND_REQUIRED)+ SET(_FAIL_MESSAGE "Could not find REQUIRED package ${_NAME}")+ ELSE (${_NAME}_FIND_REQUIRED)+ SET(_FAIL_MESSAGE "Could not find OPTIONAL package ${_NAME}")+ ENDIF (${_NAME}_FIND_REQUIRED)+ ELSE("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG")+ SET(_FAIL_MESSAGE "${_FAIL_MSG}")+ ENDIF("${_FAIL_MSG}" STREQUAL "DEFAULT_MSG")++ STRING(TOUPPER ${_NAME} _NAME_UPPER)++ SET(${_NAME_UPPER}_FOUND TRUE)+ IF(NOT ${_VAR1})+ SET(${_NAME_UPPER}_FOUND FALSE)+ ENDIF(NOT ${_VAR1})++ FOREACH(_CURRENT_VAR ${ARGN})+ IF(NOT ${_CURRENT_VAR})+ SET(${_NAME_UPPER}_FOUND FALSE)+ ENDIF(NOT ${_CURRENT_VAR})+ ENDFOREACH(_CURRENT_VAR)++ IF (${_NAME_UPPER}_FOUND)+ IF (NOT ${_NAME}_FIND_QUIETLY)+ MESSAGE(STATUS "Found ${_NAME}: ${${_VAR1}}")+ ENDIF (NOT ${_NAME}_FIND_QUIETLY)+ ELSE (${_NAME_UPPER}_FOUND)+ IF (${_NAME}_FIND_REQUIRED)+ MESSAGE(FATAL_ERROR "${_FAIL_MESSAGE}")+ ELSE (${_NAME}_FIND_REQUIRED)+ IF (NOT ${_NAME}_FIND_QUIETLY)+ MESSAGE(STATUS "${_FAIL_MESSAGE}")+ ENDIF (NOT ${_NAME}_FIND_QUIETLY)+ ENDIF (${_NAME}_FIND_REQUIRED)+ ENDIF (${_NAME_UPPER}_FOUND)+ENDMACRO(FIND_PACKAGE_HANDLE_STANDARD_ARGS)
+ eigen3/bench/btl/cmake/FindTvmet.cmake view
@@ -0,0 +1,32 @@+# - Try to find tvmet headers+# Once done this will define+#+# TVMET_FOUND - system has tvmet lib+# TVMET_INCLUDE_DIR - the tvmet include directory+#+# Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+# Adapted from FindEigen.cmake:+# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org>+# Redistribution and use is allowed according to the terms of the BSD license.+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.++if (TVMET_INCLUDE_DIR)++ # in cache already+ set(TVMET_FOUND TRUE)++else (TVMET_INCLUDE_DIR)++find_path(TVMET_INCLUDE_DIR NAMES tvmet/tvmet.h+ PATHS+ ${TVMETDIR}/+ ${INCLUDE_INSTALL_DIR}+ )++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(Tvmet DEFAULT_MSG TVMET_INCLUDE_DIR)++mark_as_advanced(TVMET_INCLUDE_DIR)++endif(TVMET_INCLUDE_DIR)+
+ eigen3/bench/btl/cmake/MacroOptionalAddSubdirectory.cmake view
@@ -0,0 +1,31 @@+# - MACRO_OPTIONAL_ADD_SUBDIRECTORY() combines ADD_SUBDIRECTORY() with an OPTION()+# MACRO_OPTIONAL_ADD_SUBDIRECTORY( <dir> )+# If you use MACRO_OPTIONAL_ADD_SUBDIRECTORY() instead of ADD_SUBDIRECTORY(),+# this will have two effects+# 1 - CMake will not complain if the directory doesn't exist+# This makes sense if you want to distribute just one of the subdirs+# in a source package, e.g. just one of the subdirs in kdeextragear.+# 2 - If the directory exists, it will offer an option to skip the +# subdirectory.+# This is useful if you want to compile only a subset of all+# directories.++# Copyright (c) 2007, Alexander Neundorf, <neundorf@kde.org>+#+# Redistribution and use is allowed according to the terms of the BSD license.+# For details see the accompanying COPYING-CMAKE-SCRIPTS file.+++MACRO (MACRO_OPTIONAL_ADD_SUBDIRECTORY _dir )+ GET_FILENAME_COMPONENT(_fullPath ${_dir} ABSOLUTE)+ IF(EXISTS ${_fullPath})+ IF(${ARGC} EQUAL 2)+ OPTION(BUILD_${_dir} "Build directory ${_dir}" ${ARGV1})+ ELSE(${ARGC} EQUAL 2)+ OPTION(BUILD_${_dir} "Build directory ${_dir}" TRUE)+ ENDIF(${ARGC} EQUAL 2)+ IF(BUILD_${_dir})+ ADD_SUBDIRECTORY(${_dir})+ ENDIF(BUILD_${_dir})+ ENDIF(EXISTS ${_fullPath})+ENDMACRO (MACRO_OPTIONAL_ADD_SUBDIRECTORY)
+ eigen3/bench/btl/data/CMakeLists.txt view
@@ -0,0 +1,32 @@++ADD_CUSTOM_TARGET(copy_scripts)++SET(script_files go_mean mk_mean_script.sh mk_new_gnuplot.sh+ perlib_plot_settings.txt action_settings.txt gnuplot_common_settings.hh )++FOREACH(script_file ${script_files})+ADD_CUSTOM_COMMAND(+ TARGET copy_scripts+ POST_BUILD+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${script_file} ${CMAKE_CURRENT_BINARY_DIR}/+ ARGS+)+ENDFOREACH(script_file)++ADD_CUSTOM_COMMAND(+ TARGET copy_scripts+ POST_BUILD+ COMMAND ${CMAKE_CXX_COMPILER} --version | head -n 1 > ${CMAKE_CURRENT_BINARY_DIR}/compiler_version.txt+ ARGS+)+ADD_CUSTOM_COMMAND(+ TARGET copy_scripts+ POST_BUILD+ COMMAND echo "${Eigen_SOURCE_DIR}" > ${CMAKE_CURRENT_BINARY_DIR}/eigen_root_dir.txt+ ARGS+)++add_executable(smooth smooth.cxx)+add_executable(regularize regularize.cxx)+add_executable(main mean.cxx)+add_dependencies(main copy_scripts)
+ eigen3/bench/btl/data/action_settings.txt view
@@ -0,0 +1,19 @@+aat ; "{/*1.5 A x A^T}" ; "matrix size" ; 4:3000+ata ; "{/*1.5 A^T x A}" ; "matrix size" ; 4:3000+atv ; "{/*1.5 matrix^T x vector}" ; "matrix size" ; 4:3000+axpby ; "{/*1.5 Y = alpha X + beta Y}" ; "vector size" ; 5:1000000+axpy ; "{/*1.5 Y += alpha X}" ; "vector size" ; 5:1000000+matrix_matrix ; "{/*1.5 matrix matrix product}" ; "matrix size" ; 4:3000+matrix_vector ; "{/*1.5 matrix vector product}" ; "matrix size" ; 4:3000+trmm ; "{/*1.5 triangular matrix matrix product}" ; "matrix size" ; 4:3000+trisolve_vector ; "{/*1.5 triangular solver - vector (X = inv(L) X)}" ; "size" ; 4:3000+trisolve_matrix ; "{/*1.5 triangular solver - matrix (M = inv(L) M)}" ; "size" ; 4:3000+cholesky ; "{/*1.5 Cholesky decomposition}" ; "matrix size" ; 4:3000+complete_lu_decomp ; "{/*1.5 Complete LU decomposition}" ; "matrix size" ; 4:3000+partial_lu_decomp ; "{/*1.5 Partial LU decomposition}" ; "matrix size" ; 4:3000+tridiagonalization ; "{/*1.5 Tridiagonalization}" ; "matrix size" ; 4:3000+hessenberg ; "{/*1.5 Hessenberg decomposition}" ; "matrix size" ; 4:3000+symv ; "{/*1.5 symmetric matrix vector product}" ; "matrix size" ; 4:3000+syr2 ; "{/*1.5 symmretric rank-2 update (A += u^T v + u v^T)}" ; "matrix size" ; 4:3000+ger ; "{/*1.5 general rank-1 update (A += u v^T)}" ; "matrix size" ; 4:3000+rot ; "{/*1.5 apply rotation in the plane}" ; "vector size" ; 4:1000000
+ eigen3/bench/btl/data/gnuplot_common_settings.hh view
@@ -0,0 +1,87 @@+set noclip points+set clip one+set noclip two+set bar 1.000000+set border 31 lt -1 lw 1.000+set xdata+set ydata+set zdata+set x2data+set y2data+set boxwidth+set dummy x,y+set format x "%g"+set format y "%g"+set format x2 "%g"+set format y2 "%g"+set format z "%g"+set angles radians+set nogrid+set key title ""+set key left top Right noreverse box linetype -2 linewidth 1.000 samplen 4 spacing 1 width 0+set nolabel+set noarrow+# set nolinestyle # deprecated+set nologscale+set logscale x 10+set offsets 0, 0, 0, 0+set pointsize 1+set encoding default+set nopolar+set noparametric+set view 60, 30, 1, 1+set samples 100, 100+set isosamples 10, 10+set surface+set nocontour+set clabel '%8.3g'+set mapping cartesian+set nohidden3d+set cntrparam order 4+set cntrparam linear+set cntrparam levels auto 5+set cntrparam points 5+set size ratio 0 1,1+set origin 0,0+# set data style lines+# set function style lines+set xzeroaxis lt -2 lw 1.000+set x2zeroaxis lt -2 lw 1.000+set yzeroaxis lt -2 lw 1.000+set y2zeroaxis lt -2 lw 1.000+set tics in+set ticslevel 0.5+set tics scale 1, 0.5+set mxtics default+set mytics default+set mx2tics default+set my2tics default+set xtics border mirror norotate autofreq+set ytics border mirror norotate autofreq+set ztics border nomirror norotate autofreq+set nox2tics+set noy2tics+set timestamp "" bottom norotate offset 0,0+set rrange [ * : * ] noreverse nowriteback # (currently [-0:10] )+set trange [ * : * ] noreverse nowriteback # (currently [-5:5] )+set urange [ * : * ] noreverse nowriteback # (currently [-5:5] )+set vrange [ * : * ] noreverse nowriteback # (currently [-5:5] )+set xlabel "matrix size" offset 0,0+set x2label "" offset 0,0+set timefmt "%d/%m/%y\n%H:%M"+set xrange [ 10 : 1000 ] noreverse nowriteback+set x2range [ * : * ] noreverse nowriteback # (currently [-10:10] )+set ylabel "MFLOPS" offset 0,0+set y2label "" offset 0,0+set yrange [ * : * ] noreverse nowriteback # (currently [-10:10] )+set y2range [ * : * ] noreverse nowriteback # (currently [-10:10] )+set zlabel "" offset 0,0+set zrange [ * : * ] noreverse nowriteback # (currently [-10:10] )+set zero 1e-08+set lmargin -1+set bmargin -1+set rmargin -1+set tmargin -1+set locale "C"+set xrange [4:1024]+
+ eigen3/bench/btl/data/go_mean view
@@ -0,0 +1,58 @@+#!/bin/bash++if [ $# < 1 ]; then+ echo "Usage: $0 working_directory [tiny|large [prefix]]"+else++mkdir -p $1+##cp ../libs/*/*.dat $1++mode=large+if [ $# > 2 ]; then+ mode=$2+fi+if [ $# > 3 ]; then+ prefix=$3+fi++EIGENDIR=`cat eigen_root_dir.txt`++webpagefilename=$1/index.html+meanstatsfilename=$1/mean.html++echo '' > $meanstatsfilename+echo '' > $webpagefilename+echo '<p><strong>Configuration</strong>' >> $webpagefilename+echo '<ul>'\+ '<li>' `cat /proc/cpuinfo | grep "model name" | head -n 1`\+ ' (' `uname -m` ')</li>'\+ '<li> compiler: ' `cat compiler_version.txt` '</li>'\+ '<li> eigen3: ' `hg identify -i $EIGENDIR` '</li>'\+ '</ul>' \+ '</p>' >> $webpagefilename++source mk_mean_script.sh axpy $1 11 2500 100000 250000 $mode $prefix+source mk_mean_script.sh axpby $1 11 2500 100000 250000 $mode $prefix+source mk_mean_script.sh matrix_vector $1 11 50 300 1000 $mode $prefix+source mk_mean_script.sh atv $1 11 50 300 1000 $mode $prefix+source mk_mean_script.sh matrix_matrix $1 11 100 300 1000 $mode $prefix+source mk_mean_script.sh aat $1 11 100 300 1000 $mode $prefix+# source mk_mean_script.sh ata $1 11 100 300 1000 $mode $prefix+source mk_mean_script.sh trmm $1 11 100 300 1000 $mode $prefix+source mk_mean_script.sh trisolve_vector $1 11 100 300 1000 $mode $prefix+source mk_mean_script.sh trisolve_matrix $1 11 100 300 1000 $mode $prefix+source mk_mean_script.sh cholesky $1 11 100 300 1000 $mode $prefix+source mk_mean_script.sh partial_lu_decomp $1 11 100 300 1000 $mode $prefix+source mk_mean_script.sh tridiagonalization $1 11 100 300 1000 $mode $prefix+source mk_mean_script.sh hessenberg $1 11 100 300 1000 $mode $prefix+source mk_mean_script.sh symv $1 11 50 300 1000 $mode $prefix+source mk_mean_script.sh syr2 $1 11 50 300 1000 $mode $prefix+source mk_mean_script.sh ger $1 11 50 300 1000 $mode $prefix+source mk_mean_script.sh rot $1 11 2500 100000 250000 $mode $prefix+source mk_mean_script.sh complete_lu_decomp $1 11 100 300 1000 $mode $prefix++fi++## compile the web page ##++#echo `cat footer.html` >> $webpagefilename
+ eigen3/bench/btl/data/mean.cxx view
@@ -0,0 +1,182 @@+//=====================================================+// File : mean.cxx+// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:15 CEST 2002+//=====================================================+// +// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+// +// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+// +#include "utilities.h"+#include <vector>+#include <string>+#include <iostream>+#include <fstream>+#include "bench_parameter.hh"+#include "utils/xy_file.hh"+#include <set>++using namespace std;++double mean_calc(const vector<int> & tab_sizes, const vector<double> & tab_mflops, const int size_min, const int size_max);++class Lib_Mean{++public:+ Lib_Mean( void ):_lib_name(),_mean_in_cache(),_mean_out_of_cache(){+ MESSAGE("Lib_mean Default Ctor");+ MESSAGE("!!! should not be used");+ exit(0);+ }+ Lib_Mean(const string & name, const double & mic, const double & moc):_lib_name(name),_mean_in_cache(mic),_mean_out_of_cache(moc){+ MESSAGE("Lib_mean Ctor");+ }+ Lib_Mean(const Lib_Mean & lm):_lib_name(lm._lib_name),_mean_in_cache(lm._mean_in_cache),_mean_out_of_cache(lm._mean_out_of_cache){+ MESSAGE("Lib_mean Copy Ctor");+ }+ ~Lib_Mean( void ){+ MESSAGE("Lib_mean Dtor");+ }+ + double _mean_in_cache;+ double _mean_out_of_cache;+ string _lib_name;++ bool operator < ( const Lib_Mean &right) const + {+ //return ( this->_mean_out_of_cache > right._mean_out_of_cache) ;+ return ( this->_mean_in_cache > right._mean_in_cache) ;+ }++}; +++int main( int argc , char *argv[] )+{++ if (argc<6){+ INFOS("!!! Error ... usage : main what mic Mic moc Moc filename1 finename2...");+ exit(0);+ }+ INFOS(argc);++ int min_in_cache=atoi(argv[2]);+ int max_in_cache=atoi(argv[3]);+ int min_out_of_cache=atoi(argv[4]);+ int max_out_of_cache=atoi(argv[5]);+++ multiset<Lib_Mean> s_lib_mean ;++ for (int i=6;i<argc;i++){+ + string filename=argv[i];+ + INFOS(filename);++ double mic=0;+ double moc=0;++ {+ + vector<int> tab_sizes;+ vector<double> tab_mflops;++ read_xy_file(filename,tab_sizes,tab_mflops);++ mic=mean_calc(tab_sizes,tab_mflops,min_in_cache,max_in_cache);+ moc=mean_calc(tab_sizes,tab_mflops,min_out_of_cache,max_out_of_cache);++ Lib_Mean cur_lib_mean(filename,mic,moc);+ + s_lib_mean.insert(cur_lib_mean); ++ } + + }+++ cout << "<TABLE BORDER CELLPADDING=2>" << endl ;+ cout << " <TR>" << endl ;+ cout << " <TH ALIGN=CENTER> " << argv[1] << " </TH>" << endl ;+ cout << " <TH ALIGN=CENTER> <a href=""#mean_marker""> in cache <BR> mean perf <BR> Mflops </a></TH>" << endl ;+ cout << " <TH ALIGN=CENTER> in cache <BR> % best </TH>" << endl ;+ cout << " <TH ALIGN=CENTER> <a href=""#mean_marker""> out of cache <BR> mean perf <BR> Mflops </a></TH>" << endl ;+ cout << " <TH ALIGN=CENTER> out of cache <BR> % best </TH>" << endl ;+ cout << " <TH ALIGN=CENTER> details </TH>" << endl ;+ cout << " <TH ALIGN=CENTER> comments </TH>" << endl ;+ cout << " </TR>" << endl ;++ multiset<Lib_Mean>::iterator is = s_lib_mean.begin();+ Lib_Mean best(*is); + ++ for (is=s_lib_mean.begin(); is!=s_lib_mean.end() ; is++){++ cout << " <TR>" << endl ;+ cout << " <TD> " << is->_lib_name << " </TD>" << endl ;+ cout << " <TD> " << is->_mean_in_cache << " </TD>" << endl ;+ cout << " <TD> " << 100*(is->_mean_in_cache/best._mean_in_cache) << " </TD>" << endl ;+ cout << " <TD> " << is->_mean_out_of_cache << " </TD>" << endl ;+ cout << " <TD> " << 100*(is->_mean_out_of_cache/best._mean_out_of_cache) << " </TD>" << endl ;+ cout << " <TD> " << + "<a href=\"#"<<is->_lib_name<<"_"<<argv[1]<<"\">snippet</a>/" + "<a href=\"#"<<is->_lib_name<<"_flags\">flags</a> </TD>" << endl ;+ cout << " <TD> " << + "<a href=\"#"<<is->_lib_name<<"_comments\">click here</a> </TD>" << endl ;+ cout << " </TR>" << endl ;+ + }++ cout << "</TABLE>" << endl ;++ ofstream output_file ("../order_lib",ios::out) ;+ + for (is=s_lib_mean.begin(); is!=s_lib_mean.end() ; is++){+ output_file << is->_lib_name << endl ;+ }++ output_file.close();++}++double mean_calc(const vector<int> & tab_sizes, const vector<double> & tab_mflops, const int size_min, const int size_max){+ + int size=tab_sizes.size();+ int nb_sample=0;+ double mean=0.0;++ for (int i=0;i<size;i++){+ + + if ((tab_sizes[i]>=size_min)&&(tab_sizes[i]<=size_max)){+ + nb_sample++;+ mean+=tab_mflops[i];++ }++ + }++ if (nb_sample==0){+ INFOS("no data for mean calculation");+ return 0.0;+ }++ return mean/nb_sample;+}++ ++
+ eigen3/bench/btl/data/mk_gnuplot_script.sh view
@@ -0,0 +1,68 @@+#! /bin/bash+WHAT=$1+DIR=$2+echo $WHAT script generation+cat $WHAT.hh > $WHAT.gnuplot++DATA_FILE=`find $DIR -name "*.dat" | grep $WHAT`++echo plot \\ >> $WHAT.gnuplot++for FILE in $DATA_FILE+do+ LAST=$FILE+done++echo LAST=$LAST++for FILE in $DATA_FILE+do+ if [ $FILE != $LAST ]+ then+ BASE=${FILE##*/} ; BASE=${FILE##*/} ; AVANT=bench_${WHAT}_ ; REDUC=${BASE##*$AVANT} ; TITLE=${REDUC%.dat}+ echo "'"$FILE"'" title "'"$TITLE"'" ",\\" >> $WHAT.gnuplot+ fi+done+BASE=${LAST##*/} ; BASE=${FILE##*/} ; AVANT=bench_${WHAT}_ ; REDUC=${BASE##*$AVANT} ; TITLE=${REDUC%.dat}+echo "'"$LAST"'" title "'"$TITLE"'" >> $WHAT.gnuplot++#echo set term postscript color >> $WHAT.gnuplot+#echo set output "'"$WHAT.ps"'" >> $WHAT.gnuplot+echo set term pbm small color >> $WHAT.gnuplot+echo set output "'"$WHAT.ppm"'" >> $WHAT.gnuplot+echo plot \\ >> $WHAT.gnuplot++for FILE in $DATA_FILE+do+ if [ $FILE != $LAST ]+ then+ BASE=${FILE##*/} ; BASE=${FILE##*/} ; AVANT=bench_${WHAT}_ ; REDUC=${BASE##*$AVANT} ; TITLE=${REDUC%.dat}+ echo "'"$FILE"'" title "'"$TITLE"'" ",\\" >> $WHAT.gnuplot+ fi+done+BASE=${LAST##*/} ; BASE=${FILE##*/} ; AVANT=bench_${WHAT}_ ; REDUC=${BASE##*$AVANT} ; TITLE=${REDUC%.dat}+echo "'"$LAST"'" title "'"$TITLE"'" >> $WHAT.gnuplot++echo set term jpeg large >> $WHAT.gnuplot+echo set output "'"$WHAT.jpg"'" >> $WHAT.gnuplot+echo plot \\ >> $WHAT.gnuplot++for FILE in $DATA_FILE+do+ if [ $FILE != $LAST ]+ then+ BASE=${FILE##*/} ; BASE=${FILE##*/} ; AVANT=bench_${WHAT}_ ; REDUC=${BASE##*$AVANT} ; TITLE=${REDUC%.dat}+ echo "'"$FILE"'" title "'"$TITLE"'" ",\\" >> $WHAT.gnuplot+ fi+done+BASE=${LAST##*/} ; BASE=${FILE##*/} ; AVANT=bench_${WHAT}_ ; REDUC=${BASE##*$AVANT} ; TITLE=${REDUC%.dat}+echo "'"$LAST"'" title "'"$TITLE"'" >> $WHAT.gnuplot+++gnuplot -persist < $WHAT.gnuplot++rm $WHAT.gnuplot++++
+ eigen3/bench/btl/data/mk_mean_script.sh view
@@ -0,0 +1,52 @@+#! /bin/bash+WHAT=$1+DIR=$2+MINIC=$3+MAXIC=$4+MINOC=$5+MAXOC=$6+prefix=$8++meanstatsfilename=$2/mean.html++WORK_DIR=tmp+mkdir $WORK_DIR++DATA_FILE=`find $DIR -name "*.dat" | grep _${WHAT}`++if [ -n "$DATA_FILE" ]; then++ echo ""+ echo "$1..."+ for FILE in $DATA_FILE+ do+ ##echo hello world+ ##echo "mk_mean_script1" ${FILE}+ BASE=${FILE##*/} ; BASE=${FILE##*/} ; AVANT=bench_${WHAT}_ ; REDUC=${BASE##*$AVANT} ; TITLE=${REDUC%.dat}++ ##echo "mk_mean_script1" ${TITLE}+ cp $FILE ${WORK_DIR}/${TITLE}++ done++ cd $WORK_DIR+ ../main $1 $3 $4 $5 $6 * >> ../$meanstatsfilename+ ../mk_new_gnuplot.sh $1 $2 $7+ rm -f *.gnuplot+ cd ..++ echo '<br/>' >> $meanstatsfilename++ webpagefilename=$2/index.html+ # echo '<h3>'${WHAT}'</h3>' >> $webpagefilename+ echo '<hr/><a href="'$prefix$1'.pdf"><img src="'$prefix$1'.png" alt="'${WHAT}'" /></a><br/>' >> $webpagefilename++fi++rm -R $WORK_DIR++++++
+ eigen3/bench/btl/data/mk_new_gnuplot.sh view
@@ -0,0 +1,54 @@+#!/bin/bash+WHAT=$1+DIR=$2++cat ../gnuplot_common_settings.hh > ${WHAT}.gnuplot++echo "set title " `grep ${WHAT} ../action_settings.txt | head -n 1 | cut -d ";" -f 2` >> $WHAT.gnuplot+echo "set xlabel " `grep ${WHAT} ../action_settings.txt | head -n 1 | cut -d ";" -f 3` " offset 0,0" >> $WHAT.gnuplot+echo "set xrange [" `grep ${WHAT} ../action_settings.txt | head -n 1 | cut -d ";" -f 4` "]" >> $WHAT.gnuplot++if [ $# > 3 ]; then+ if [ "$3" == "tiny" ]; then+ echo "set xrange [2:16]" >> $WHAT.gnuplot+ echo "set nologscale" >> $WHAT.gnuplot+ fi+fi++++DATA_FILE=`cat ../order_lib`+echo set term postscript color rounded enhanced >> $WHAT.gnuplot+echo set output "'"../${DIR}/$WHAT.ps"'" >> $WHAT.gnuplot++# echo set term svg color rounded enhanced >> $WHAT.gnuplot+# echo "set terminal svg enhanced size 1000 1000 fname \"Times\" fsize 36" >> $WHAT.gnuplot+# echo set output "'"../${DIR}/$WHAT.svg"'" >> $WHAT.gnuplot++echo plot \\ >> $WHAT.gnuplot++for FILE in $DATA_FILE+do+ LAST=$FILE+done++for FILE in $DATA_FILE+do+ BASE=${FILE##*/} ; BASE=${FILE##*/} ; AVANT=bench_${WHAT}_ ; REDUC=${BASE##*$AVANT} ; TITLE=${REDUC%.dat}++ echo "'"$FILE"'" `grep $TITLE ../perlib_plot_settings.txt | head -n 1 | cut -d ";" -f 2` "\\" >> $WHAT.gnuplot+ if [ $FILE != $LAST ]+ then+ echo ", \\" >> $WHAT.gnuplot+ fi+done+echo " " >> $WHAT.gnuplot++gnuplot -persist < $WHAT.gnuplot++rm $WHAT.gnuplot++ps2pdf ../${DIR}/$WHAT.ps ../${DIR}/$WHAT.pdf+convert -background white -density 120 -rotate 90 -resize 800 +dither -colors 256 -quality 0 ../${DIR}/$WHAT.ps -background white -flatten ../${DIR}/$WHAT.png++# pstoedit -rotate -90 -xscale 0.8 -yscale 0.8 -centered -yshift -50 -xshift -100 -f plot-svg aat.ps aat2.svg
+ eigen3/bench/btl/data/perlib_plot_settings.txt view
@@ -0,0 +1,16 @@+eigen3 ; with lines lw 4 lt 1 lc rgbcolor "black"+eigen2 ; with lines lw 3 lt 1 lc rgbcolor "#999999"+EigenBLAS ; with lines lw 3 lt 3 lc rgbcolor "#999999"+eigen3_novec ; with lines lw 2 lt 1 lc rgbcolor "#999999"+eigen3_nogccvec ; with lines lw 2 lt 2 lc rgbcolor "#991010"+INTEL_MKL ; with lines lw 3 lt 1 lc rgbcolor "#ff0000"+ATLAS ; with lines lw 3 lt 1 lc rgbcolor "#008000"+gmm ; with lines lw 3 lt 1 lc rgbcolor "#0000ff"+ublas ; with lines lw 3 lt 1 lc rgbcolor "#00b7ff"+mtl4 ; with lines lw 3 lt 1 lc rgbcolor "#d18847"+blitz ; with lines lw 3 lt 1 lc rgbcolor "#ff00ff"+F77 ; with lines lw 3 lt 3 lc rgbcolor "#e6e64c"+GOTO ; with lines lw 3 lt 3 lc rgbcolor "#C05600"+GOTO2 ; with lines lw 3 lt 1 lc rgbcolor "#C05600"+C ; with lines lw 3 lt 3 lc rgbcolor "#e6bd96"+ACML ; with lines lw 2 lt 3 lc rgbcolor "#e6e64c"
+ eigen3/bench/btl/data/regularize.cxx view
@@ -0,0 +1,131 @@+//=====================================================+// File : regularize.cxx+// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:15 CEST 2002+//=====================================================+// +// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+// +// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+// +#include "utilities.h"+#include <vector>+#include <string>+#include <iostream>+#include <fstream>+#include "bench_parameter.hh"+#include <set>++using namespace std;++void read_xy_file(const string & filename, vector<int> & tab_sizes, vector<double> & tab_mflops);+void regularize_curve(const string & filename,+ const vector<double> & tab_mflops, + const vector<int> & tab_sizes, + int start_cut_size, int stop_cut_size);+/////////////////////////////////////////////////////////////////////////////////////////////////++int main( int argc , char *argv[] )+{++ // input data++ if (argc<4){+ INFOS("!!! Error ... usage : main filename start_cut_size stop_cut_size regularize_filename");+ exit(0);+ }+ INFOS(argc);++ int start_cut_size=atoi(argv[2]);+ int stop_cut_size=atoi(argv[3]);++ string filename=argv[1];+ string regularize_filename=argv[4];+ + INFOS(filename);+ INFOS("start_cut_size="<<start_cut_size);++ vector<int> tab_sizes;+ vector<double> tab_mflops;++ read_xy_file(filename,tab_sizes,tab_mflops);++ // regularizeing++ regularize_curve(regularize_filename,tab_mflops,tab_sizes,start_cut_size,stop_cut_size);+ ++}++//////////////////////////////////////////////////////////////////////////////////////++void regularize_curve(const string & filename,+ const vector<double> & tab_mflops, + const vector<int> & tab_sizes, + int start_cut_size, int stop_cut_size)+{+ int size=tab_mflops.size();+ ofstream output_file (filename.c_str(),ios::out) ;++ int i=0;++ while(tab_sizes[i]<start_cut_size){+ + output_file << tab_sizes[i] << " " << tab_mflops[i] << endl ;+ i++;++ }+ + output_file << endl ;++ while(tab_sizes[i]<stop_cut_size){+ + i++;++ }++ while(i<size){+ + output_file << tab_sizes[i] << " " << tab_mflops[i] << endl ;+ i++;++ }++ output_file.close();++}++///////////////////////////////////////////////////////////////////////////////////////////////////////////////////++void read_xy_file(const string & filename, vector<int> & tab_sizes, vector<double> & tab_mflops){++ ifstream input_file (filename.c_str(),ios::in) ;++ if (!input_file){+ INFOS("!!! Error opening "<<filename);+ exit(0);+ }+ + int nb_point=0;+ int size=0;+ double mflops=0;++ while (input_file >> size >> mflops ){+ nb_point++;+ tab_sizes.push_back(size);+ tab_mflops.push_back(mflops);+ }+ SCRUTE(nb_point);++ input_file.close();+}+
+ eigen3/bench/btl/data/smooth.cxx view
@@ -0,0 +1,198 @@+//=====================================================+// File : smooth.cxx+// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:15 CEST 2002+//=====================================================+// +// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+// +// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+// +#include "utilities.h"+#include <vector>+#include <deque>+#include <string>+#include <iostream>+#include <fstream>+#include "bench_parameter.hh"+#include <set>++using namespace std;++void read_xy_file(const string & filename, vector<int> & tab_sizes, vector<double> & tab_mflops);+void write_xy_file(const string & filename, vector<int> & tab_sizes, vector<double> & tab_mflops);+void smooth_curve(const vector<double> & tab_mflops, vector<double> & smooth_tab_mflops,int window_half_width);+void centered_smooth_curve(const vector<double> & tab_mflops, vector<double> & smooth_tab_mflops,int window_half_width);++/////////////////////////////////////////////////////////////////////////////////////////////////++int main( int argc , char *argv[] )+{++ // input data++ if (argc<3){+ INFOS("!!! Error ... usage : main filename window_half_width smooth_filename");+ exit(0);+ }+ INFOS(argc);++ int window_half_width=atoi(argv[2]);++ string filename=argv[1];+ string smooth_filename=argv[3];+ + INFOS(filename);+ INFOS("window_half_width="<<window_half_width);++ vector<int> tab_sizes;+ vector<double> tab_mflops;++ read_xy_file(filename,tab_sizes,tab_mflops);++ // smoothing++ vector<double> smooth_tab_mflops;++ //smooth_curve(tab_mflops,smooth_tab_mflops,window_half_width);+ centered_smooth_curve(tab_mflops,smooth_tab_mflops,window_half_width);++ // output result++ write_xy_file(smooth_filename,tab_sizes,smooth_tab_mflops);+ ++}++///////////////////////////////////////////////////////////////////////////////////////////////////////////////////++template<class VECTOR>+double weighted_mean(const VECTOR & data)+{++ double mean=0.0;+ + for (int i=0 ; i<data.size() ; i++){++ mean+=data[i];++ }++ return mean/double(data.size()) ;++} +++++///////////////////////////////////////////////////////////////////////////////////////////////////////////////////+++void smooth_curve(const vector<double> & tab_mflops, vector<double> & smooth_tab_mflops,int window_half_width){+ + int window_width=2*window_half_width+1;++ int size=tab_mflops.size();++ vector<double> sample(window_width);+ + for (int i=0 ; i < size ; i++){+ + for ( int j=0 ; j < window_width ; j++ ){+ + int shifted_index=i+j-window_half_width;+ if (shifted_index<0) shifted_index=0;+ if (shifted_index>size-1) shifted_index=size-1;+ sample[j]=tab_mflops[shifted_index];+ + }++ smooth_tab_mflops.push_back(weighted_mean(sample));++ }++}++void centered_smooth_curve(const vector<double> & tab_mflops, vector<double> & smooth_tab_mflops,int window_half_width){+ + int max_window_width=2*window_half_width+1;++ int size=tab_mflops.size();++ + for (int i=0 ; i < size ; i++){++ deque<double> sample;++ + sample.push_back(tab_mflops[i]);++ for ( int j=1 ; j <= window_half_width ; j++ ){+ + int before=i-j;+ int after=i+j;+ + if ((before>=0)&&(after<size)) // inside of the vector+ { + sample.push_front(tab_mflops[before]);+ sample.push_back(tab_mflops[after]);+ }+ }+ + smooth_tab_mflops.push_back(weighted_mean(sample));+ + }++}+++///////////////////////////////////////////////////////////////////////////////////////////////////////////////////++void write_xy_file(const string & filename, vector<int> & tab_sizes, vector<double> & tab_mflops){++ ofstream output_file (filename.c_str(),ios::out) ;+ + for (int i=0 ; i < tab_sizes.size() ; i++)+ {+ output_file << tab_sizes[i] << " " << tab_mflops[i] << endl ;+ }+ + output_file.close();++}+++///////////////////////////////////////////////////////////////////////////////////////////////////////////////////++void read_xy_file(const string & filename, vector<int> & tab_sizes, vector<double> & tab_mflops){++ ifstream input_file (filename.c_str(),ios::in) ;++ if (!input_file){+ INFOS("!!! Error opening "<<filename);+ exit(0);+ }+ + int nb_point=0;+ int size=0;+ double mflops=0;++ while (input_file >> size >> mflops ){+ nb_point++;+ tab_sizes.push_back(size);+ tab_mflops.push_back(mflops);+ }+ SCRUTE(nb_point);++ input_file.close();+}+
+ eigen3/bench/btl/data/smooth_all.sh view
@@ -0,0 +1,68 @@+#! /bin/bash+ORIG_DIR=$1+SMOOTH_DIR=${ORIG_DIR}_smooth+mkdir ${SMOOTH_DIR}++AXPY_FILE=`find ${ORIG_DIR} -name "*.dat" | grep axpy`+for FILE in ${AXPY_FILE}+do+ echo $FILE+ BASE=${FILE##*/}+ ./smooth ${ORIG_DIR}/${BASE} 4 ${SMOOTH_DIR}/${BASE}_tmp+ ./regularize ${SMOOTH_DIR}/${BASE}_tmp 2500 15000 ${SMOOTH_DIR}/${BASE}+ rm -f ${SMOOTH_DIR}/${BASE}_tmp+done+++MATRIX_VECTOR_FILE=`find ${ORIG_DIR} -name "*.dat" | grep matrix_vector`+for FILE in ${MATRIX_VECTOR_FILE}+do+ echo $FILE+ BASE=${FILE##*/}+ ./smooth ${ORIG_DIR}/${BASE} 4 ${SMOOTH_DIR}/${BASE}_tmp+ ./regularize ${SMOOTH_DIR}/${BASE}_tmp 50 180 ${SMOOTH_DIR}/${BASE}+ rm -f ${SMOOTH_DIR}/${BASE}_tmp+done++MATRIX_MATRIX_FILE=`find ${ORIG_DIR} -name "*.dat" | grep matrix_matrix`+for FILE in ${MATRIX_MATRIX_FILE}+do+ echo $FILE+ BASE=${FILE##*/}+ ./smooth ${ORIG_DIR}/${BASE} 4 ${SMOOTH_DIR}/${BASE}+done++AAT_FILE=`find ${ORIG_DIR} -name "*.dat" | grep _aat`+for FILE in ${AAT_FILE}+do+ echo $FILE+ BASE=${FILE##*/}+ ./smooth ${ORIG_DIR}/${BASE} 4 ${SMOOTH_DIR}/${BASE}+done+++ATA_FILE=`find ${ORIG_DIR} -name "*.dat" | grep _ata`+for FILE in ${ATA_FILE}+do+ echo $FILE+ BASE=${FILE##*/}+ ./smooth ${ORIG_DIR}/${BASE} 4 ${SMOOTH_DIR}/${BASE}+done++### no smoothing for tinyvector and matrices libs++TINY_BLITZ_FILE=`find ${ORIG_DIR} -name "*.dat" | grep tiny_blitz`+for FILE in ${TINY_BLITZ_FILE}+do+ echo $FILE+ BASE=${FILE##*/}+ cp ${ORIG_DIR}/${BASE} ${SMOOTH_DIR}/${BASE}+done++TVMET_FILE=`find ${ORIG_DIR} -name "*.dat" | grep tvmet`+for FILE in ${TVMET_FILE}+do+ echo $FILE+ BASE=${FILE##*/}+ cp ${ORIG_DIR}/${BASE} ${SMOOTH_DIR}/${BASE}+done
+ eigen3/bench/btl/generic_bench/bench.hh view
@@ -0,0 +1,168 @@+//=====================================================+// File : bench.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:16 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef BENCH_HH+#define BENCH_HH++#include "btl.hh"+#include "bench_parameter.hh"+#include <iostream>+#include "utilities.h"+#include "size_lin_log.hh"+#include "xy_file.hh"+#include <vector>+#include <string>+#include "timers/portable_perf_analyzer.hh"+// #include "timers/mixed_perf_analyzer.hh"+// #include "timers/x86_perf_analyzer.hh"+// #include "timers/STL_perf_analyzer.hh"+#ifdef HAVE_MKL+extern "C" void cblas_saxpy(const int, const float, const float*, const int, float *, const int);+#endif+using namespace std;++template <template<class> class Perf_Analyzer, class Action>+BTL_DONT_INLINE void bench( int size_min, int size_max, int nb_point )+{+ if (BtlConfig::skipAction(Action::name()))+ return;++ string filename="bench_"+Action::name()+".dat";++ INFOS("starting " <<filename);++ // utilities++ std::vector<double> tab_mflops(nb_point);+ std::vector<int> tab_sizes(nb_point);++ // matrices and vector size calculations+ size_lin_log(nb_point,size_min,size_max,tab_sizes);++ std::vector<int> oldSizes;+ std::vector<double> oldFlops;+ bool hasOldResults = read_xy_file(filename, oldSizes, oldFlops, true);+ int oldi = oldSizes.size() - 1;++ // loop on matrix size+ Perf_Analyzer<Action> perf_action;+ for (int i=nb_point-1;i>=0;i--)+ {+ //INFOS("size=" <<tab_sizes[i]<<" ("<<nb_point-i<<"/"<<nb_point<<")");+ std::cout << " " << "size = " << tab_sizes[i] << " " << std::flush;++ BTL_DISABLE_SSE_EXCEPTIONS();+ #ifdef HAVE_MKL+ {+ float dummy;+ cblas_saxpy(1,0,&dummy,1,&dummy,1);+ }+ #endif++ tab_mflops[i] = perf_action.eval_mflops(tab_sizes[i]);+ std::cout << tab_mflops[i];+ + if (hasOldResults)+ {+ while (oldi>=0 && oldSizes[oldi]>tab_sizes[i])+ --oldi;+ if (oldi>=0 && oldSizes[oldi]==tab_sizes[i])+ {+ if (oldFlops[oldi]<tab_mflops[i])+ std::cout << "\t > ";+ else+ std::cout << "\t < ";+ std::cout << oldFlops[oldi];+ }+ --oldi;+ }+ std::cout << " MFlops (" << nb_point-i << "/" << nb_point << ")" << std::endl;+ }++ if (!BtlConfig::Instance.overwriteResults)+ {+ if (hasOldResults)+ {+ // merge the two data+ std::vector<int> newSizes;+ std::vector<double> newFlops;+ int i=0;+ int j=0;+ while (i<tab_sizes.size() && j<oldSizes.size())+ {+ if (tab_sizes[i] == oldSizes[j])+ {+ newSizes.push_back(tab_sizes[i]);+ newFlops.push_back(std::max(tab_mflops[i], oldFlops[j]));+ ++i;+ ++j;+ }+ else if (tab_sizes[i] < oldSizes[j])+ {+ newSizes.push_back(tab_sizes[i]);+ newFlops.push_back(tab_mflops[i]);+ ++i;+ }+ else+ {+ newSizes.push_back(oldSizes[j]);+ newFlops.push_back(oldFlops[j]);+ ++j;+ }+ }+ while (i<tab_sizes.size())+ {+ newSizes.push_back(tab_sizes[i]);+ newFlops.push_back(tab_mflops[i]);+ ++i;+ }+ while (j<oldSizes.size())+ {+ newSizes.push_back(oldSizes[j]);+ newFlops.push_back(oldFlops[j]);+ ++j;+ }+ tab_mflops = newFlops;+ tab_sizes = newSizes;+ }+ }++ // dump the result in a file :+ dump_xy_file(tab_sizes,tab_mflops,filename);++}++// default Perf Analyzer++template <class Action>+BTL_DONT_INLINE void bench( int size_min, int size_max, int nb_point ){++ // if the rdtsc is not available :+ bench<Portable_Perf_Analyzer,Action>(size_min,size_max,nb_point);+ // if the rdtsc is available :+// bench<Mixed_Perf_Analyzer,Action>(size_min,size_max,nb_point);+++ // Only for small problem size. Otherwize it will be too long+// bench<X86_Perf_Analyzer,Action>(size_min,size_max,nb_point);+// bench<STL_Perf_Analyzer,Action>(size_min,size_max,nb_point);++}++#endif
+ eigen3/bench/btl/generic_bench/bench_parameter.hh view
@@ -0,0 +1,53 @@+//=====================================================+// File : bench_parameter.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:16 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef BENCH_PARAMETER_HH+#define BENCH_PARAMETER_HH++// minimal time for each measurement+#define REAL_TYPE float+// minimal time for each measurement+#define MIN_TIME 0.2+// nb of point on bench curves+#define NB_POINT 100+// min vector size for axpy bench+#define MIN_AXPY 5+// max vector size for axpy bench+#define MAX_AXPY 1000000+// min matrix size for matrix vector product bench+#define MIN_MV 5+// max matrix size for matrix vector product bench+#define MAX_MV 3000+// min matrix size for matrix matrix product bench+#define MIN_MM 5+// max matrix size for matrix matrix product bench+#define MAX_MM MAX_MV+// min matrix size for LU bench+#define MIN_LU 5+// max matrix size for LU bench+#define MAX_LU 3000+// max size for tiny vector and matrix+#define TINY_MV_MAX_SIZE 16+// default nb_sample for x86 timer+#define DEFAULT_NB_SAMPLE 1000++// how many times we run a single bench (keep the best perf)+#define DEFAULT_NB_TRIES 3++#endif
+ eigen3/bench/btl/generic_bench/btl.hh view
@@ -0,0 +1,247 @@+//=====================================================+// File : btl.hh+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef BTL_HH+#define BTL_HH++#include "bench_parameter.hh"+#include <iostream>+#include <algorithm>+#include <vector>+#include <string>+#include "utilities.h"++#if (defined __GNUC__)+#define BTL_ALWAYS_INLINE __attribute__((always_inline)) inline+#else+#define BTL_ALWAYS_INLINE inline+#endif++#if (defined __GNUC__)+#define BTL_DONT_INLINE __attribute__((noinline))+#else+#define BTL_DONT_INLINE+#endif++#if (defined __GNUC__)+#define BTL_ASM_COMMENT(X) asm("#" X)+#else+#define BTL_ASM_COMMENT(X)+#endif++#if (defined __GNUC__) && (!defined __INTEL_COMPILER) && !defined(__arm__) && !defined(__powerpc__)+#define BTL_DISABLE_SSE_EXCEPTIONS() { \+ int aux; \+ asm( \+ "stmxcsr %[aux] \n\t" \+ "orl $32832, %[aux] \n\t" \+ "ldmxcsr %[aux] \n\t" \+ : : [aux] "m" (aux)); \+}+#else+#define BTL_DISABLE_SSE_EXCEPTIONS()+#endif++/** Enhanced std::string+*/+class BtlString : public std::string+{+public:+ BtlString() : std::string() {}+ BtlString(const BtlString& str) : std::string(static_cast<const std::string&>(str)) {}+ BtlString(const std::string& str) : std::string(str) {}+ BtlString(const char* str) : std::string(str) {}++ operator const char* () const { return c_str(); }++ void trim( bool left = true, bool right = true )+ {+ int lspaces, rspaces, len = length(), i;+ lspaces = rspaces = 0;++ if ( left )+ for (i=0; i<len && (at(i)==' '||at(i)=='\t'||at(i)=='\r'||at(i)=='\n'); ++lspaces,++i);++ if ( right && lspaces < len )+ for(i=len-1; i>=0 && (at(i)==' '||at(i)=='\t'||at(i)=='\r'||at(i)=='\n'); rspaces++,i--);++ *this = substr(lspaces, len-lspaces-rspaces);+ }++ std::vector<BtlString> split( const BtlString& delims = "\t\n ") const+ {+ std::vector<BtlString> ret;+ unsigned int numSplits = 0;+ size_t start, pos;+ start = 0;+ do+ {+ pos = find_first_of(delims, start);+ if (pos == start)+ {+ ret.push_back("");+ start = pos + 1;+ }+ else if (pos == npos)+ ret.push_back( substr(start) );+ else+ {+ ret.push_back( substr(start, pos - start) );+ start = pos + 1;+ }+ //start = find_first_not_of(delims, start);+ ++numSplits;+ } while (pos != npos);+ return ret;+ }++ bool endsWith(const BtlString& str) const+ {+ if(str.size()>this->size())+ return false;+ return this->substr(this->size()-str.size(),str.size()) == str;+ }+ bool contains(const BtlString& str) const+ {+ return this->find(str)<this->size();+ }+ bool beginsWith(const BtlString& str) const+ {+ if(str.size()>this->size())+ return false;+ return this->substr(0,str.size()) == str;+ }++ BtlString toLowerCase( void )+ {+ std::transform(begin(), end(), begin(), static_cast<int(*)(int)>(::tolower) );+ return *this;+ }+ BtlString toUpperCase( void )+ {+ std::transform(begin(), end(), begin(), static_cast<int(*)(int)>(::toupper) );+ return *this;+ }++ /** Case insensitive comparison.+ */+ bool isEquiv(const BtlString& str) const+ {+ BtlString str0 = *this;+ str0.toLowerCase();+ BtlString str1 = str;+ str1.toLowerCase();+ return str0 == str1;+ }++ /** Decompose the current string as a path and a file.+ For instance: "dir1/dir2/file.ext" leads to path="dir1/dir2/" and filename="file.ext"+ */+ void decomposePathAndFile(BtlString& path, BtlString& filename) const+ {+ std::vector<BtlString> elements = this->split("/\\");+ path = "";+ filename = elements.back();+ elements.pop_back();+ if (this->at(0)=='/')+ path = "/";+ for (unsigned int i=0 ; i<elements.size() ; ++i)+ path += elements[i] + "/";+ }+};++class BtlConfig+{+public:+ BtlConfig()+ : overwriteResults(false), checkResults(true), realclock(false), tries(DEFAULT_NB_TRIES)+ {+ char * _config;+ _config = getenv ("BTL_CONFIG");+ if (_config!=NULL)+ {+ std::vector<BtlString> config = BtlString(_config).split(" \t\n");+ for (int i = 0; i<config.size(); i++)+ {+ if (config[i].beginsWith("-a"))+ {+ if (i+1==config.size())+ {+ std::cerr << "error processing option: " << config[i] << "\n";+ exit(2);+ }+ Instance.m_selectedActionNames = config[i+1].split(":");++ i += 1;+ }+ else if (config[i].beginsWith("-t"))+ {+ if (i+1==config.size())+ {+ std::cerr << "error processing option: " << config[i] << "\n";+ exit(2);+ }+ Instance.tries = atoi(config[i+1].c_str());++ i += 1;+ }+ else if (config[i].beginsWith("--overwrite"))+ {+ Instance.overwriteResults = true;+ }+ else if (config[i].beginsWith("--nocheck"))+ {+ Instance.checkResults = false;+ }+ else if (config[i].beginsWith("--real"))+ {+ Instance.realclock = true;+ }+ }+ }++ BTL_DISABLE_SSE_EXCEPTIONS();+ }++ BTL_DONT_INLINE static bool skipAction(const std::string& _name)+ {+ if (Instance.m_selectedActionNames.empty())+ return false;++ BtlString name(_name);+ for (int i=0; i<Instance.m_selectedActionNames.size(); ++i)+ if (name.contains(Instance.m_selectedActionNames[i]))+ return false;++ return true;+ }++ static BtlConfig Instance;+ bool overwriteResults;+ bool checkResults;+ bool realclock;+ int tries;++protected:+ std::vector<BtlString> m_selectedActionNames;+};++#define BTL_MAIN \+ BtlConfig BtlConfig::Instance++#endif // BTL_HH
+ eigen3/bench/btl/generic_bench/init/init_function.hh view
@@ -0,0 +1,54 @@+//=====================================================+// File : init_function.hh+// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:18 CEST 2002+//=====================================================+// +// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+// +// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+// +#ifndef INIT_FUNCTION_HH+#define INIT_FUNCTION_HH++double simple_function(int index)+{+ return index;+}++double simple_function(int index_i, int index_j)+{+ return index_i+index_j;+}++double pseudo_random(int index)+{+ return std::rand()/double(RAND_MAX);+}++double pseudo_random(int index_i, int index_j)+{+ return std::rand()/double(RAND_MAX);+}+++double null_function(int index)+{+ return 0.0;+}++double null_function(int index_i, int index_j)+{+ return 0.0;+}++#endif
+ eigen3/bench/btl/generic_bench/init/init_matrix.hh view
@@ -0,0 +1,64 @@+//=====================================================+// File : init_matrix.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:19 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef INIT_MATRIX_HH+#define INIT_MATRIX_HH++// The Vector class must satisfy the following part of STL vector concept :+// resize() method+// [] operator for setting element+// value_type defined+template<double init_function(int,int), class Vector>+BTL_DONT_INLINE void init_row(Vector & X, int size, int row){++ X.resize(size);++ for (int j=0;j<X.size();j++){+ X[j]=typename Vector::value_type(init_function(row,j));+ }+}+++// Matrix is a Vector of Vector+// The Matrix class must satisfy the following part of STL vector concept :+// resize() method+// [] operator for setting rows+template<double init_function(int,int),class Vector>+BTL_DONT_INLINE void init_matrix(Vector & A, int size){+ A.resize(size);+ for (int row=0; row<A.size() ; row++){+ init_row<init_function>(A[row],size,row);+ }+}++template<double init_function(int,int),class Matrix>+BTL_DONT_INLINE void init_matrix_symm(Matrix& A, int size){+ A.resize(size);+ for (int row=0; row<A.size() ; row++)+ A[row].resize(size);+ for (int row=0; row<A.size() ; row++){+ A[row][row] = init_function(row,row);+ for (int col=0; col<row ; col++){+ double x = init_function(row,col);+ A[row][col] = A[col][row] = x;+ }+ }+}++#endif
+ eigen3/bench/btl/generic_bench/init/init_vector.hh view
@@ -0,0 +1,37 @@+//=====================================================+// File : init_vector.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:18 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef INIT_VECTOR_HH+#define INIT_VECTOR_HH++// The Vector class must satisfy the following part of STL vector concept :+// resize() method+// [] operator for setting element+// value_type defined+template<double init_function(int), class Vector>+void init_vector(Vector & X, int size){++ X.resize(size);++ for (int i=0;i<X.size();i++){+ X[i]=typename Vector::value_type(init_function(i));+ }+}++#endif
+ eigen3/bench/btl/generic_bench/static/bench_static.hh view
@@ -0,0 +1,80 @@+//=====================================================+// File : bench_static.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:16 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef BENCH_STATIC_HH+#define BENCH_STATIC_HH++#include "btl.hh"+#include "bench_parameter.hh"+#include <iostream>+#include "utilities.h"+#include "xy_file.hh"+#include "static/static_size_generator.hh"+#include "timers/portable_perf_analyzer.hh"+// #include "timers/mixed_perf_analyzer.hh"+// #include "timers/x86_perf_analyzer.hh"++using namespace std;+++template <template<class> class Perf_Analyzer, template<class> class Action, template<class,int> class Interface>+BTL_DONT_INLINE void bench_static(void)+{+ if (BtlConfig::skipAction(Action<Interface<REAL_TYPE,10> >::name()))+ return;++ string filename = "bench_" + Action<Interface<REAL_TYPE,10> >::name() + ".dat";++ INFOS("starting " << filename);++ const int max_size = TINY_MV_MAX_SIZE;++ std::vector<double> tab_mflops;+ std::vector<double> tab_sizes;++ static_size_generator<max_size,Perf_Analyzer,Action,Interface>::go(tab_sizes,tab_mflops);++ dump_xy_file(tab_sizes,tab_mflops,filename);+}++// default Perf Analyzer+template <template<class> class Action, template<class,int> class Interface>+BTL_DONT_INLINE void bench_static(void)+{+ bench_static<Portable_Perf_Analyzer,Action,Interface>();+ //bench_static<Mixed_Perf_Analyzer,Action,Interface>();+ //bench_static<X86_Perf_Analyzer,Action,Interface>();+}++#endif+++++++++++++++
+ eigen3/bench/btl/generic_bench/static/intel_bench_fixed_size.hh view
@@ -0,0 +1,66 @@+//=====================================================+// File : intel_bench_fixed_size.hh+// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, mar déc 3 18:59:37 CET 2002+//=====================================================+// +// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+// +// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+// +#ifndef _BENCH_FIXED_SIZE_HH_+#define _BENCH_FIXED_SIZE_HH_++#include "utilities.h"+#include "function_time.hh"++template <class Action>+double bench_fixed_size(int size, unsigned long long & nb_calc,unsigned long long & nb_init)+{+ + Action action(size);+ + double time_baseline=time_init(nb_init,action);++ while (time_baseline < MIN_TIME) {++ //INFOS("nb_init="<<nb_init);+ //INFOS("time_baseline="<<time_baseline);+ nb_init*=2;+ time_baseline=time_init(nb_init,action);+ }+ + time_baseline=time_baseline/(double(nb_init));+ + double time_action=time_calculate(nb_calc,action);+ + while (time_action < MIN_TIME) {+ + nb_calc*=2;+ time_action=time_calculate(nb_calc,action);+ }++ INFOS("nb_init="<<nb_init);+ INFOS("nb_calc="<<nb_calc);+ + + time_action=time_action/(double(nb_calc));+ + action.check_result();+ + time_action=time_action-time_baseline;++ return action.nb_op_base()/(time_action*1000000.0);++}++#endif
+ eigen3/bench/btl/generic_bench/static/static_size_generator.hh view
@@ -0,0 +1,57 @@+//=====================================================+// File : static_size_generator.hh+// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, mar déc 3 18:59:36 CET 2002+//=====================================================+// +// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+// +// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+// +#ifndef _STATIC_SIZE_GENERATOR_HH+#define _STATIC_SIZE_GENERATOR_HH+#include <vector>++using namespace std;++//recursive generation of statically defined matrix and vector sizes++template <int SIZE,template<class> class Perf_Analyzer, template<class> class Action, template<class,int> class Interface> +struct static_size_generator{+ static void go(vector<double> & tab_sizes, vector<double> & tab_mflops)+ {+ tab_sizes.push_back(SIZE);+ std::cout << tab_sizes.back() << " \t" << std::flush;+ Perf_Analyzer<Action<Interface<REAL_TYPE,SIZE> > > perf_action;+ tab_mflops.push_back(perf_action.eval_mflops(SIZE));+ std::cout << tab_mflops.back() << " MFlops" << std::endl;+ static_size_generator<SIZE-1,Perf_Analyzer,Action,Interface>::go(tab_sizes,tab_mflops);+ };+};++//recursion end++template <template<class> class Perf_Analyzer, template<class> class Action, template<class,int> class Interface> +struct static_size_generator<1,Perf_Analyzer,Action,Interface>{ + static void go(vector<double> & tab_sizes, vector<double> & tab_mflops)+ {+ tab_sizes.push_back(1);+ Perf_Analyzer<Action<Interface<REAL_TYPE,1> > > perf_action;+ tab_mflops.push_back(perf_action.eval_mflops(1));+ };+};++#endif+ + + +
+ eigen3/bench/btl/generic_bench/timers/STL_perf_analyzer.hh view
@@ -0,0 +1,82 @@+//=====================================================+// File : STL_perf_analyzer.hh+// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, mar déc 3 18:59:35 CET 2002+//=====================================================+// +// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+// +// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+// +#ifndef _STL_PERF_ANALYSER_HH+#define _STL_PERF_ANALYSER_HH++#include "STL_timer.hh"+#include "bench_parameter.hh"++template<class ACTION>+class STL_Perf_Analyzer{+public: + STL_Perf_Analyzer(unsigned long long nb_sample=DEFAULT_NB_SAMPLE):_nb_sample(nb_sample),_chronos()+ {+ MESSAGE("STL_Perf_Analyzer Ctor");+ }; + STL_Perf_Analyzer( const STL_Perf_Analyzer & ){+ INFOS("Copy Ctor not implemented");+ exit(0);+ };+ ~STL_Perf_Analyzer( void ){+ MESSAGE("STL_Perf_Analyzer Dtor");+ };+ + + inline double eval_mflops(int size)+ {++ ACTION action(size);++ _chronos.start_baseline(_nb_sample);+ + do {++ action.initialize();+ } while (_chronos.check());++ double baseline_time=_chronos.get_time();++ _chronos.start(_nb_sample);+ do {+ action.initialize();+ action.calculate();+ } while (_chronos.check());++ double calculate_time=_chronos.get_time();++ double corrected_time=calculate_time-baseline_time;+ + // cout << size <<" "<<baseline_time<<" "<<calculate_time<<" "<<corrected_time<<" "<<action.nb_op_base() << endl; + + return action.nb_op_base()/(corrected_time*1000000.0);+ //return action.nb_op_base()/(calculate_time*1000000.0);+ + }+private:++ STL_Timer _chronos;+ unsigned long long _nb_sample;++ +};++ + +#endif
+ eigen3/bench/btl/generic_bench/timers/STL_timer.hh view
@@ -0,0 +1,78 @@+//=====================================================+// File : STL_Timer.hh+// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, mar déc 3 18:59:35 CET 2002+//=====================================================+// +// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+// +// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+// +// STL Timer Class. Adapted (L.P.) from the timer class by Musser et Al+// described int the Book : STL Tutorial and reference guide.+// Define a timer class for analyzing algorithm performance.+#include <iostream>+#include <iomanip>+#include <vector>+#include <map>+#include <algorithm>+using namespace std;++class STL_Timer {+public:+ STL_Timer(){ baseline = false; }; // Default constructor+ // Start a series of r trials:+ void start(unsigned int r){+ reps = r;+ count = 0;+ iterations.clear();+ iterations.reserve(reps);+ initial = time(0);+ };+ // Start a series of r trials to determine baseline time:+ void start_baseline(unsigned int r)+ {+ baseline = true;+ start(r);+ }+ // Returns true if the trials have been completed, else false+ bool check()+ {+ ++count;+ final = time(0);+ if (initial < final) {+ iterations.push_back(count); + initial = final;+ count = 0;+ }+ return (iterations.size() < reps);+ };+ // Returns the results for external use+ double get_time( void )+ {+ sort(iterations.begin(), iterations.end());+ return 1.0/iterations[reps/2];+ };+private:+ unsigned int reps; // Number of trials+ // For storing loop iterations of a trial+ vector<long> iterations;+ // For saving initial and final times of a trial+ time_t initial, final;+ // For counting loop iterations of a trial+ unsigned long count;+ // true if this is a baseline computation, false otherwise+ bool baseline;+ // For recording the baseline time + double baseline_time;+};+
+ eigen3/bench/btl/generic_bench/timers/mixed_perf_analyzer.hh view
@@ -0,0 +1,73 @@+//=====================================================+// File : mixed_perf_analyzer.hh+// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, mar déc 3 18:59:36 CET 2002+//=====================================================+// +// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+// +// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+// +#ifndef _MIXED_PERF_ANALYSER_HH+#define _MIXED_PERF_ANALYSER_HH++#include "x86_perf_analyzer.hh"+#include "portable_perf_analyzer.hh"++// choose portable perf analyzer for long calculations and x86 analyser for short ones+++template<class Action>+class Mixed_Perf_Analyzer{+ +public: + Mixed_Perf_Analyzer( void ):_x86pa(),_ppa(),_use_ppa(true)+ {+ MESSAGE("Mixed_Perf_Analyzer Ctor");+ }; + Mixed_Perf_Analyzer( const Mixed_Perf_Analyzer & ){+ INFOS("Copy Ctor not implemented");+ exit(0);+ };+ ~Mixed_Perf_Analyzer( void ){+ MESSAGE("Mixed_Perf_Analyzer Dtor");+ };+ + + inline double eval_mflops(int size)+ {++ double result=0.0;+ if (_use_ppa){ + result=_ppa.eval_mflops(size);+ if (_ppa.get_nb_calc()>DEFAULT_NB_SAMPLE){_use_ppa=false;} + }+ else{ + result=_x86pa.eval_mflops(size);+ }++ return result;+ }++private:++ Portable_Perf_Analyzer<Action> _ppa;+ X86_Perf_Analyzer<Action> _x86pa;+ bool _use_ppa;++};++#endif++ + +
+ eigen3/bench/btl/generic_bench/timers/portable_perf_analyzer.hh view
@@ -0,0 +1,103 @@+//=====================================================+// File : portable_perf_analyzer.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, mar d�c 3 18:59:35 CET 2002+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef _PORTABLE_PERF_ANALYZER_HH+#define _PORTABLE_PERF_ANALYZER_HH++#include "utilities.h"+#include "timers/portable_timer.hh"++template <class Action>+class Portable_Perf_Analyzer{+public:+ Portable_Perf_Analyzer( ):_nb_calc(0), m_time_action(0), _chronos(){+ MESSAGE("Portable_Perf_Analyzer Ctor");+ };+ Portable_Perf_Analyzer( const Portable_Perf_Analyzer & ){+ INFOS("Copy Ctor not implemented");+ exit(0);+ };+ ~Portable_Perf_Analyzer(){+ MESSAGE("Portable_Perf_Analyzer Dtor");+ };++ BTL_DONT_INLINE double eval_mflops(int size)+ {+ Action action(size);++// action.initialize();+// time_action = time_calculate(action);+ while (m_time_action < MIN_TIME)+ {+ if(_nb_calc==0) _nb_calc = 1;+ else _nb_calc *= 2;+ action.initialize();+ m_time_action = time_calculate(action);+ }++ // optimize+ for (int i=1; i<BtlConfig::Instance.tries; ++i)+ {+ Action _action(size);+ std::cout << " " << _action.nb_op_base()*_nb_calc/(m_time_action*1e6) << " ";+ _action.initialize();+ m_time_action = std::min(m_time_action, time_calculate(_action));+ }++ double time_action = m_time_action / (double(_nb_calc));++ // check+ if (BtlConfig::Instance.checkResults && size<128)+ {+ action.initialize();+ action.calculate();+ action.check_result();+ }+ return action.nb_op_base()/(time_action*1e6);+ }++ BTL_DONT_INLINE double time_calculate(Action & action)+ {+ // time measurement+ action.calculate();+ _chronos.start();+ for (int ii=0;ii<_nb_calc;ii++)+ {+ action.calculate();+ }+ _chronos.stop();+ return _chronos.user_time();+ }++ unsigned long long get_nb_calc()+ {+ return _nb_calc;+ }+++private:+ unsigned long long _nb_calc;+ double m_time_action;+ Portable_Timer _chronos;++};++#endif //_PORTABLE_PERF_ANALYZER_HH+
+ eigen3/bench/btl/generic_bench/timers/portable_perf_analyzer_old.hh view
@@ -0,0 +1,134 @@+//=====================================================+// File : portable_perf_analyzer.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, mar d�c 3 18:59:35 CET 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef _PORTABLE_PERF_ANALYZER_HH+#define _PORTABLE_PERF_ANALYZER_HH++#include "utilities.h"+#include "timers/portable_timer.hh"++template <class Action>+class Portable_Perf_Analyzer{+public:+ Portable_Perf_Analyzer( void ):_nb_calc(1),_nb_init(1),_chronos(){+ MESSAGE("Portable_Perf_Analyzer Ctor");+ };+ Portable_Perf_Analyzer( const Portable_Perf_Analyzer & ){+ INFOS("Copy Ctor not implemented");+ exit(0);+ };+ ~Portable_Perf_Analyzer( void ){+ MESSAGE("Portable_Perf_Analyzer Dtor");+ };++++ inline double eval_mflops(int size)+ {++ Action action(size);++// double time_baseline = time_init(action);+// while (time_baseline < MIN_TIME_INIT)+// {+// _nb_init *= 2;+// time_baseline = time_init(action);+// }+//+// // optimize+// for (int i=1; i<NB_TRIES; ++i)+// time_baseline = std::min(time_baseline, time_init(action));+//+// time_baseline = time_baseline/(double(_nb_init));++ double time_action = time_calculate(action);+ while (time_action < MIN_TIME)+ {+ _nb_calc *= 2;+ time_action = time_calculate(action);+ }++ // optimize+ for (int i=1; i<NB_TRIES; ++i)+ time_action = std::min(time_action, time_calculate(action));++// INFOS("size="<<size);+// INFOS("_nb_init="<<_nb_init);+// INFOS("_nb_calc="<<_nb_calc);++ time_action = time_action / (double(_nb_calc));++ action.check_result();+++ double time_baseline = time_init(action);+ for (int i=1; i<NB_TRIES; ++i)+ time_baseline = std::min(time_baseline, time_init(action));+ time_baseline = time_baseline/(double(_nb_init));++++// INFOS("time_baseline="<<time_baseline);+// INFOS("time_action="<<time_action);++ time_action = time_action - time_baseline;++// INFOS("time_corrected="<<time_action);++ return action.nb_op_base()/(time_action*1000000.0);+ }++ inline double time_init(Action & action)+ {+ // time measurement+ _chronos.start();+ for (int ii=0; ii<_nb_init; ii++)+ action.initialize();+ _chronos.stop();+ return _chronos.user_time();+ }+++ inline double time_calculate(Action & action)+ {+ // time measurement+ _chronos.start();+ for (int ii=0;ii<_nb_calc;ii++)+ {+ action.initialize();+ action.calculate();+ }+ _chronos.stop();+ return _chronos.user_time();+ }++ unsigned long long get_nb_calc( void )+ {+ return _nb_calc;+ }+++private:+ unsigned long long _nb_calc;+ unsigned long long _nb_init;+ Portable_Timer _chronos;++};++#endif //_PORTABLE_PERF_ANALYZER_HH
+ eigen3/bench/btl/generic_bench/timers/portable_timer.hh view
@@ -0,0 +1,145 @@+//=====================================================+// File : portable_timer.hh+// Author : L. Plagne <laurent.plagne@edf.fr)> from boost lib+// Copyright (C) EDF R&D, lun sep 30 14:23:17 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+// simple_time extracted from the boost library+//+#ifndef _PORTABLE_TIMER_HH+#define _PORTABLE_TIMER_HH++#include <ctime>+#include <cstdlib>++#include <time.h>+++#define USEC_IN_SEC 1000000+++// timer -------------------------------------------------------------------//++// A timer object measures CPU time.+#ifdef _MSC_VER++#define NOMINMAX+#include <windows.h>++/*#ifndef hr_timer+#include "hr_time.h"+#define hr_timer+#endif*/++ class Portable_Timer+ {+ public:++ typedef struct {+ LARGE_INTEGER start;+ LARGE_INTEGER stop;+ } stopWatch;+++ Portable_Timer()+ {+ startVal.QuadPart = 0;+ stopVal.QuadPart = 0;+ QueryPerformanceFrequency(&frequency);+ }++ void start() { QueryPerformanceCounter(&startVal); }++ void stop() { QueryPerformanceCounter(&stopVal); }++ double elapsed() {+ LARGE_INTEGER time;+ time.QuadPart = stopVal.QuadPart - startVal.QuadPart;+ return LIToSecs(time);+ }++ double user_time() { return elapsed(); }+++ private:++ double LIToSecs(LARGE_INTEGER& L) {+ return ((double)L.QuadPart /(double)frequency.QuadPart) ;+ }++ LARGE_INTEGER startVal;+ LARGE_INTEGER stopVal;+ LARGE_INTEGER frequency;+++ }; // Portable_Timer++#else++#include <sys/time.h>+#include <sys/resource.h>+#include <unistd.h>+#include <sys/times.h>++class Portable_Timer+{+ public:++ Portable_Timer()+ {+ m_clkid = BtlConfig::Instance.realclock ? CLOCK_REALTIME : CLOCK_PROCESS_CPUTIME_ID;+ }++ Portable_Timer(int clkid) : m_clkid(clkid)+ {}++ void start()+ {+ timespec ts;+ clock_gettime(m_clkid, &ts);+ m_start_time = double(ts.tv_sec) + 1e-9 * double(ts.tv_nsec);++ }++ void stop()+ {+ timespec ts;+ clock_gettime(m_clkid, &ts);+ m_stop_time = double(ts.tv_sec) + 1e-9 * double(ts.tv_nsec);++ }++ double elapsed()+ {+ return user_time();+ }++ double user_time()+ {+ return m_stop_time - m_start_time;+ }+++private:++ int m_clkid;+ double m_stop_time, m_start_time;++}; // Portable_Timer++#endif++#endif // PORTABLE_TIMER_HPP
+ eigen3/bench/btl/generic_bench/timers/x86_perf_analyzer.hh view
@@ -0,0 +1,108 @@+//=====================================================+// File : x86_perf_analyzer.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, mar d�c 3 18:59:35 CET 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef _X86_PERF_ANALYSER_HH+#define _X86_PERF_ANALYSER_HH++#include "x86_timer.hh"+#include "bench_parameter.hh"++template<class ACTION>+class X86_Perf_Analyzer{+public:+ X86_Perf_Analyzer( unsigned long long nb_sample=DEFAULT_NB_SAMPLE):_nb_sample(nb_sample),_chronos()+ {+ MESSAGE("X86_Perf_Analyzer Ctor");+ _chronos.find_frequency();+ };+ X86_Perf_Analyzer( const X86_Perf_Analyzer & ){+ INFOS("Copy Ctor not implemented");+ exit(0);+ };+ ~X86_Perf_Analyzer( void ){+ MESSAGE("X86_Perf_Analyzer Dtor");+ };+++ inline double eval_mflops(int size)+ {++ ACTION action(size);++ int nb_loop=5;+ double calculate_time=0.0;+ double baseline_time=0.0;++ for (int j=0 ; j < nb_loop ; j++){++ _chronos.clear();++ for(int i=0 ; i < _nb_sample ; i++)+ {+ _chronos.start();+ action.initialize();+ action.calculate();+ _chronos.stop();+ _chronos.add_get_click();+ }++ calculate_time += double(_chronos.get_shortest_clicks())/_chronos.frequency();++ if (j==0) action.check_result();++ _chronos.clear();++ for(int i=0 ; i < _nb_sample ; i++)+ {+ _chronos.start();+ action.initialize();+ _chronos.stop();+ _chronos.add_get_click();++ }++ baseline_time+=double(_chronos.get_shortest_clicks())/_chronos.frequency();++ }++ double corrected_time = (calculate_time-baseline_time)/double(nb_loop);+++// INFOS("_nb_sample="<<_nb_sample);+// INFOS("baseline_time="<<baseline_time);+// INFOS("calculate_time="<<calculate_time);+// INFOS("corrected_time="<<corrected_time);++// cout << size <<" "<<baseline_time<<" "<<calculate_time<<" "<<corrected_time<<" "<<action.nb_op_base() << endl;++ return action.nb_op_base()/(corrected_time*1000000.0);+ //return action.nb_op_base()/(calculate_time*1000000.0);+ }++private:++ X86_Timer _chronos;+ unsigned long long _nb_sample;+++};++++#endif
+ eigen3/bench/btl/generic_bench/timers/x86_timer.hh view
@@ -0,0 +1,246 @@+//=====================================================+// File : x86_timer.hh+// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, mar d�c 3 18:59:35 CET 2002+//=====================================================+// +// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+// +// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+// +#ifndef _X86_TIMER_HH+#define _X86_TIMER_HH++#include <sys/time.h>+#include <sys/resource.h>+#include <unistd.h>+#include <sys/times.h>+//#include "system_time.h"+#define u32 unsigned int+#include <asm/msr.h>+#include "utilities.h"+#include <map>+#include <fstream>+#include <string>+#include <iostream>++// frequence de la becanne en Hz+//#define FREQUENCY 648000000+//#define FREQUENCY 1400000000+#define FREQUENCY 1695000000++using namespace std;+++class X86_Timer {++public :++ X86_Timer( void ):_frequency(FREQUENCY),_nb_sample(0)+ {+ MESSAGE("X86_Timer Default Ctor"); + }++ inline void start( void ){++ rdtsc(_click_start.n32[0],_click_start.n32[1]);++ }+++ inline void stop( void ){++ rdtsc(_click_stop.n32[0],_click_stop.n32[1]);++ }+ ++ inline double frequency( void ){+ return _frequency;+ }++ double get_elapsed_time_in_second( void ){++ return (_click_stop.n64-_click_start.n64)/double(FREQUENCY);+++ } ++ unsigned long long get_click( void ){+ + return (_click_stop.n64-_click_start.n64);++ } ++ inline void find_frequency( void ){++ time_t initial, final;+ int dummy=2;++ initial = time(0);+ start();+ do {+ dummy+=2;+ }+ while(time(0)==initial);+ // On est au debut d'un cycle d'une seconde !!!+ initial = time(0);+ start();+ do {+ dummy+=2;+ }+ while(time(0)==initial);+ final=time(0);+ stop();+ // INFOS("fine grained time : "<< get_elapsed_time_in_second());+ // INFOS("coarse grained time : "<< final-initial);+ _frequency=_frequency*get_elapsed_time_in_second()/double(final-initial);+ /// INFOS("CPU frequency : "<< _frequency); ++ }++ void add_get_click( void ){+ + _nb_sample++;+ _counted_clicks[get_click()]++;+ fill_history_clicks();++ } ++ void dump_statistics(string filemane){+ + ofstream outfile (filemane.c_str(),ios::out) ;++ std::map<unsigned long long , unsigned long long>::iterator itr;+ for(itr=_counted_clicks.begin() ; itr!=_counted_clicks.end() ; itr++)+ { + outfile << (*itr).first << " " << (*itr).second << endl ; + } + + outfile.close();++ }++ void dump_history(string filemane){+ + ofstream outfile (filemane.c_str(),ios::out) ;++++ for(int i=0 ; i<_history_mean_clicks.size() ; i++)+ { + outfile << i << " " + << _history_mean_clicks[i] << " " + << _history_shortest_clicks[i] << " " + << _history_most_occured_clicks[i] << endl ;+ } + + outfile.close();++ }+ +++ double get_mean_clicks( void ){+ + std::map<unsigned long long,unsigned long long>::iterator itr;+ + unsigned long long mean_clicks=0;++ for(itr=_counted_clicks.begin() ; itr!=_counted_clicks.end() ; itr++)+ { + + mean_clicks+=(*itr).second*(*itr).first;+ } ++ return mean_clicks/double(_nb_sample);++ }++ double get_shortest_clicks( void ){+ + return double((*_counted_clicks.begin()).first);++ }++ void fill_history_clicks( void ){++ _history_mean_clicks.push_back(get_mean_clicks());+ _history_shortest_clicks.push_back(get_shortest_clicks());+ _history_most_occured_clicks.push_back(get_most_occured_clicks());++ }+++ double get_most_occured_clicks( void ){++ unsigned long long moc=0;+ unsigned long long max_occurence=0;++ std::map<unsigned long long,unsigned long long>::iterator itr;++ for(itr=_counted_clicks.begin() ; itr!=_counted_clicks.end() ; itr++)+ { + + if (max_occurence<=(*itr).second){+ max_occurence=(*itr).second;+ moc=(*itr).first;+ }+ } + + return double(moc); ++ }+ + void clear( void )+ {+ _counted_clicks.clear();++ _history_mean_clicks.clear();+ _history_shortest_clicks.clear();+ _history_most_occured_clicks.clear();++ _nb_sample=0;+ }+++ +private :+ + union+ {+ unsigned long int n32[2] ;+ unsigned long long n64 ;+ } _click_start;++ union+ {+ unsigned long int n32[2] ;+ unsigned long long n64 ;+ } _click_stop;++ double _frequency ;++ map<unsigned long long,unsigned long long> _counted_clicks;++ vector<double> _history_mean_clicks;+ vector<double> _history_shortest_clicks;+ vector<double> _history_most_occured_clicks;++ unsigned long long _nb_sample;++ ++};+++#endif
+ eigen3/bench/btl/generic_bench/utils/size_lin_log.hh view
@@ -0,0 +1,70 @@+//=====================================================+// File : size_lin_log.hh+// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, mar déc 3 18:59:37 CET 2002+//=====================================================+// +// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+// +// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+// +#ifndef SIZE_LIN_LOG+#define SIZE_LIN_LOG++#include "size_log.hh"++template<class Vector>+void size_lin_log(const int nb_point, const int size_min, const int size_max, Vector & X)+{+ int ten=10;+ int nine=9;++ X.resize(nb_point);++ if (nb_point>ten){++ for (int i=0;i<nine;i++){+ + X[i]=i+1;++ }++ Vector log_size;+ size_log(nb_point-nine,ten,size_max,log_size);++ for (int i=0;i<nb_point-nine;i++){+ + X[i+nine]=log_size[i];++ }+ }+ else{++ for (int i=0;i<nb_point;i++){+ + X[i]=i+1;++ }+ }++ // for (int i=0;i<nb_point;i++){+ +// INFOS("computed sizes : X["<<i<<"]="<<X[i]);+ +// }++}+ +#endif+ ++
+ eigen3/bench/btl/generic_bench/utils/size_log.hh view
@@ -0,0 +1,54 @@+//=====================================================+// File : size_log.hh+// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:17 CEST 2002+//=====================================================+// +// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+// +// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+// +#ifndef SIZE_LOG+#define SIZE_LOG++#include "math.h"+// The Vector class must satisfy the following part of STL vector concept :+// resize() method+// [] operator for seting element+// the vector element are int compatible.+template<class Vector>+void size_log(const int nb_point, const int size_min, const int size_max, Vector & X)+{+ X.resize(nb_point);++ float ls_min=log(float(size_min));+ float ls_max=log(float(size_max));++ float ls=0.0;++ float delta_ls=(ls_max-ls_min)/(float(nb_point-1));++ int size=0;++ for (int i=0;i<nb_point;i++){++ ls = ls_min + float(i)*delta_ls ;+ + size=int(exp(ls)); ++ X[i]=size;+ }++}+++#endif
+ eigen3/bench/btl/generic_bench/utils/utilities.h view
@@ -0,0 +1,90 @@+//=============================================================================+// File : utilities.h+// Created : mar jun 19 13:18:14 CEST 2001+// Author : Antoine YESSAYAN, Paul RASCLE, EDF+// Project : SALOME+// Copyright : EDF 2001+// $Header$+//=============================================================================++/* --- Definition macros file to print information if _DEBUG_ is defined --- */++# ifndef UTILITIES_H+# define UTILITIES_H++# include <stdlib.h>+//# include <iostream> ok for gcc3.01+# include <iostream>++/* --- INFOS is always defined (without _DEBUG_): to be used for warnings, with release version --- */++# define HEREWEARE cout<<flush ; cerr << __FILE__ << " [" << __LINE__ << "] : " << flush ;+# define INFOS(chain) {HEREWEARE ; cerr << chain << endl ;}+# define PYSCRIPT(chain) {cout<<flush ; cerr << "---PYSCRIPT--- " << chain << endl ;}++/* --- To print date and time of compilation of current source on stdout --- */++# if defined ( __GNUC__ )+# define COMPILER "g++" ;+# elif defined ( __sun )+# define COMPILER "CC" ;+# elif defined ( __KCC )+# define COMPILER "KCC" ;+# elif defined ( __PGI )+# define COMPILER "pgCC" ;+# else+# define COMPILER "undefined" ;+# endif++# ifdef INFOS_COMPILATION+# error INFOS_COMPILATION already defined+# endif+# define INFOS_COMPILATION {\+ cerr << flush;\+ cout << __FILE__ ;\+ cout << " [" << __LINE__ << "] : " ;\+ cout << "COMPILED with " << COMPILER ;\+ cout << ", " << __DATE__ ; \+ cout << " at " << __TIME__ << endl ;\+ cout << "\n\n" ;\+ cout << flush ;\+ }++# ifdef _DEBUG_++/* --- the following MACROS are useful at debug time --- */++# define HERE cout<<flush ; cerr << "- Trace " << __FILE__ << " [" << __LINE__ << "] : " << flush ;+# define SCRUTE(var) HERE ; cerr << #var << "=" << var << endl ;+# define MESSAGE(chain) {HERE ; cerr << chain << endl ;}+# define INTERRUPTION(code) HERE ; cerr << "INTERRUPTION return code= " << code << endl ; exit(code) ;++# ifndef ASSERT+# define ASSERT(condition) if (!(condition)){ HERE ; cerr << "CONDITION " << #condition << " NOT VERIFIED"<< endl ; INTERRUPTION(1) ;}+# endif /* ASSERT */++#define REPERE cout<<flush ; cerr << " --------------" << endl << flush ;+#define BEGIN_OF(chain) {REPERE ; HERE ; cerr << "Begin of: " << chain << endl ; REPERE ; }+#define END_OF(chain) {REPERE ; HERE ; cerr << "Normal end of: " << chain << endl ; REPERE ; }++++# else /* ifdef _DEBUG_*/++# define HERE+# define SCRUTE(var)+# define MESSAGE(chain)+# define INTERRUPTION(code)++# ifndef ASSERT+# define ASSERT(condition)+# endif /* ASSERT */++#define REPERE+#define BEGIN_OF(chain)+#define END_OF(chain)+++# endif /* ifdef _DEBUG_*/++# endif /* ifndef UTILITIES_H */
+ eigen3/bench/btl/generic_bench/utils/xy_file.hh view
@@ -0,0 +1,75 @@+//=====================================================+// File : dump_file_x_y.hh+// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:20 CEST 2002+//=====================================================+// +// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+// +// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+// +#ifndef XY_FILE_HH+#define XY_FILE_HH+#include <fstream>+#include <iostream>+#include <string>+#include <vector>+using namespace std;++bool read_xy_file(const std::string & filename, std::vector<int> & tab_sizes,+ std::vector<double> & tab_mflops, bool quiet = false)+{++ std::ifstream input_file (filename.c_str(),std::ios::in);++ if (!input_file){+ if (!quiet) {+ INFOS("!!! Error opening "<<filename);+ }+ return false;+ }++ int nb_point=0;+ int size=0;+ double mflops=0;++ while (input_file >> size >> mflops ){+ nb_point++;+ tab_sizes.push_back(size);+ tab_mflops.push_back(mflops);+ }+ SCRUTE(nb_point);++ input_file.close();+ return true;+}++// The Vector class must satisfy the following part of STL vector concept :+// resize() method+// [] operator for seting element+// the vector element must have the << operator define++using namespace std;++template<class Vector_A, class Vector_B>+void dump_xy_file(const Vector_A & X, const Vector_B & Y, const std::string & filename){+ + ofstream outfile (filename.c_str(),ios::out) ;+ int size=X.size();+ + for (int i=0;i<size;i++)+ outfile << X[i] << " " << Y[i] << endl;++ outfile.close();+} ++#endif
+ eigen3/bench/btl/libs/BLAS/CMakeLists.txt view
@@ -0,0 +1,60 @@++find_package(ATLAS)+if (ATLAS_FOUND)+ btl_add_bench(btl_atlas main.cpp)+ if(BUILD_btl_atlas)+ target_link_libraries(btl_atlas ${ATLAS_LIBRARIES})+ set_target_properties(btl_atlas PROPERTIES COMPILE_FLAGS "-DCBLASNAME=ATLAS -DHAS_LAPACK=1")+ endif(BUILD_btl_atlas)+endif (ATLAS_FOUND)++find_package(MKL)+if (MKL_FOUND)+ btl_add_bench(btl_mkl main.cpp)+ if(BUILD_btl_mkl)+ target_link_libraries(btl_mkl ${MKL_LIBRARIES})+ set_target_properties(btl_mkl PROPERTIES COMPILE_FLAGS "-DCBLASNAME=INTEL_MKL -DHAS_LAPACK=1")+ endif(BUILD_btl_mkl)+endif (MKL_FOUND)+++find_package(GOTO2)+if (GOTO2_FOUND)+ btl_add_bench(btl_goto2 main.cpp)+ if(BUILD_btl_goto2)+ target_link_libraries(btl_goto2 ${GOTO_LIBRARIES} )+ set_target_properties(btl_goto2 PROPERTIES COMPILE_FLAGS "-DCBLASNAME=GOTO2")+ endif(BUILD_btl_goto2)+endif (GOTO2_FOUND)++find_package(GOTO)+if (GOTO_FOUND)+ if(GOTO2_FOUND)+ btl_add_bench(btl_goto main.cpp OFF)+ else()+ btl_add_bench(btl_goto main.cpp)+ endif()+ if(BUILD_btl_goto)+ target_link_libraries(btl_goto ${GOTO_LIBRARIES} )+ set_target_properties(btl_goto PROPERTIES COMPILE_FLAGS "-DCBLASNAME=GOTO")+ endif(BUILD_btl_goto)+endif (GOTO_FOUND)++find_package(ACML)+if (ACML_FOUND)+ btl_add_bench(btl_acml main.cpp)+ if(BUILD_btl_acml)+ target_link_libraries(btl_acml ${ACML_LIBRARIES} )+ set_target_properties(btl_acml PROPERTIES COMPILE_FLAGS "-DCBLASNAME=ACML -DHAS_LAPACK=1")+ endif(BUILD_btl_acml)+endif (ACML_FOUND)++if(Eigen_SOURCE_DIR AND CMAKE_Fortran_COMPILER_WORKS)+ # we are inside Eigen and blas/lapack interface is compilable+ include_directories(${Eigen_SOURCE_DIR})+ btl_add_bench(btl_eigenblas main.cpp)+ if(BUILD_btl_eigenblas)+ target_link_libraries(btl_eigenblas eigen_blas eigen_lapack )+ set_target_properties(btl_eigenblas PROPERTIES COMPILE_FLAGS "-DCBLASNAME=EigenBLAS")+ endif()+endif()
+ eigen3/bench/btl/libs/BLAS/blas.h view
@@ -0,0 +1,675 @@+#ifndef BLAS_H+#define BLAS_H++#define BLASFUNC(FUNC) FUNC##_++#ifdef __WIN64__+typedef long long BLASLONG;+typedef unsigned long long BLASULONG;+#else+typedef long BLASLONG;+typedef unsigned long BLASULONG;+#endif++int BLASFUNC(xerbla)(const char *, int *info, int);++float BLASFUNC(sdot) (int *, float *, int *, float *, int *);+float BLASFUNC(sdsdot)(int *, float *, float *, int *, float *, int *);++double BLASFUNC(dsdot) (int *, float *, int *, float *, int *);+double BLASFUNC(ddot) (int *, double *, int *, double *, int *);+double BLASFUNC(qdot) (int *, double *, int *, double *, int *);++#if defined(F_INTERFACE_GFORT) && !defined(__64BIT__)+int BLASFUNC(cdotu) (int *, float * , int *, float *, int *);+int BLASFUNC(cdotc) (int *, float *, int *, float *, int *);+void BLASFUNC(zdotu) (double *, int *, double *, int *, double *, int *);+void BLASFUNC(zdotc) (double *, int *, double *, int *, double *, int *);+void BLASFUNC(xdotu) (double *, int *, double *, int *, double *, int *);+void BLASFUNC(xdotc) (double *, int *, double *, int *, double *, int *);+#elif defined(F_INTERFACE_F2C) || \+ defined(F_INTERFACE_PGI) || \+ defined(F_INTERFACE_GFORT) || \+ (defined(F_INTERFACE_PATHSCALE) && defined(__64BIT__))+void BLASFUNC(cdotu) (float *, int *, float * , int *, float *, int *);+void BLASFUNC(cdotc) (float *, int *, float *, int *, float *, int *);+void BLASFUNC(zdotu) (double *, int *, double *, int *, double *, int *);+void BLASFUNC(zdotc) (double *, int *, double *, int *, double *, int *);+void BLASFUNC(xdotu) (double *, int *, double *, int *, double *, int *);+void BLASFUNC(xdotc) (double *, int *, double *, int *, double *, int *);+#else+std::complex<float> BLASFUNC(cdotu) (int *, float *, int *, float *, int *);+std::complex<float> BLASFUNC(cdotc) (int *, float *, int *, float *, int *);+std::complex<double> BLASFUNC(zdotu) (int *, double *, int *, double *, int *);+std::complex<double> BLASFUNC(zdotc) (int *, double *, int *, double *, int *);+double BLASFUNC(xdotu) (int *, double *, int *, double *, int *);+double BLASFUNC(xdotc) (int *, double *, int *, double *, int *);+#endif++int BLASFUNC(cdotuw) (int *, float *, int *, float *, int *, float*);+int BLASFUNC(cdotcw) (int *, float *, int *, float *, int *, float*);+int BLASFUNC(zdotuw) (int *, double *, int *, double *, int *, double*);+int BLASFUNC(zdotcw) (int *, double *, int *, double *, int *, double*);++int BLASFUNC(saxpy) (int *, float *, float *, int *, float *, int *);+int BLASFUNC(daxpy) (int *, double *, double *, int *, double *, int *);+int BLASFUNC(qaxpy) (int *, double *, double *, int *, double *, int *);+int BLASFUNC(caxpy) (int *, float *, float *, int *, float *, int *);+int BLASFUNC(zaxpy) (int *, double *, double *, int *, double *, int *);+int BLASFUNC(xaxpy) (int *, double *, double *, int *, double *, int *);+int BLASFUNC(caxpyc)(int *, float *, float *, int *, float *, int *);+int BLASFUNC(zaxpyc)(int *, double *, double *, int *, double *, int *);+int BLASFUNC(xaxpyc)(int *, double *, double *, int *, double *, int *);++int BLASFUNC(scopy) (int *, float *, int *, float *, int *);+int BLASFUNC(dcopy) (int *, double *, int *, double *, int *);+int BLASFUNC(qcopy) (int *, double *, int *, double *, int *);+int BLASFUNC(ccopy) (int *, float *, int *, float *, int *);+int BLASFUNC(zcopy) (int *, double *, int *, double *, int *);+int BLASFUNC(xcopy) (int *, double *, int *, double *, int *);++int BLASFUNC(sswap) (int *, float *, int *, float *, int *);+int BLASFUNC(dswap) (int *, double *, int *, double *, int *);+int BLASFUNC(qswap) (int *, double *, int *, double *, int *);+int BLASFUNC(cswap) (int *, float *, int *, float *, int *);+int BLASFUNC(zswap) (int *, double *, int *, double *, int *);+int BLASFUNC(xswap) (int *, double *, int *, double *, int *);++float BLASFUNC(sasum) (int *, float *, int *);+float BLASFUNC(scasum)(int *, float *, int *);+double BLASFUNC(dasum) (int *, double *, int *);+double BLASFUNC(qasum) (int *, double *, int *);+double BLASFUNC(dzasum)(int *, double *, int *);+double BLASFUNC(qxasum)(int *, double *, int *);++int BLASFUNC(isamax)(int *, float *, int *);+int BLASFUNC(idamax)(int *, double *, int *);+int BLASFUNC(iqamax)(int *, double *, int *);+int BLASFUNC(icamax)(int *, float *, int *);+int BLASFUNC(izamax)(int *, double *, int *);+int BLASFUNC(ixamax)(int *, double *, int *);++int BLASFUNC(ismax) (int *, float *, int *);+int BLASFUNC(idmax) (int *, double *, int *);+int BLASFUNC(iqmax) (int *, double *, int *);+int BLASFUNC(icmax) (int *, float *, int *);+int BLASFUNC(izmax) (int *, double *, int *);+int BLASFUNC(ixmax) (int *, double *, int *);++int BLASFUNC(isamin)(int *, float *, int *);+int BLASFUNC(idamin)(int *, double *, int *);+int BLASFUNC(iqamin)(int *, double *, int *);+int BLASFUNC(icamin)(int *, float *, int *);+int BLASFUNC(izamin)(int *, double *, int *);+int BLASFUNC(ixamin)(int *, double *, int *);++int BLASFUNC(ismin)(int *, float *, int *);+int BLASFUNC(idmin)(int *, double *, int *);+int BLASFUNC(iqmin)(int *, double *, int *);+int BLASFUNC(icmin)(int *, float *, int *);+int BLASFUNC(izmin)(int *, double *, int *);+int BLASFUNC(ixmin)(int *, double *, int *);++float BLASFUNC(samax) (int *, float *, int *);+double BLASFUNC(damax) (int *, double *, int *);+double BLASFUNC(qamax) (int *, double *, int *);+float BLASFUNC(scamax)(int *, float *, int *);+double BLASFUNC(dzamax)(int *, double *, int *);+double BLASFUNC(qxamax)(int *, double *, int *);++float BLASFUNC(samin) (int *, float *, int *);+double BLASFUNC(damin) (int *, double *, int *);+double BLASFUNC(qamin) (int *, double *, int *);+float BLASFUNC(scamin)(int *, float *, int *);+double BLASFUNC(dzamin)(int *, double *, int *);+double BLASFUNC(qxamin)(int *, double *, int *);++float BLASFUNC(smax) (int *, float *, int *);+double BLASFUNC(dmax) (int *, double *, int *);+double BLASFUNC(qmax) (int *, double *, int *);+float BLASFUNC(scmax) (int *, float *, int *);+double BLASFUNC(dzmax) (int *, double *, int *);+double BLASFUNC(qxmax) (int *, double *, int *);++float BLASFUNC(smin) (int *, float *, int *);+double BLASFUNC(dmin) (int *, double *, int *);+double BLASFUNC(qmin) (int *, double *, int *);+float BLASFUNC(scmin) (int *, float *, int *);+double BLASFUNC(dzmin) (int *, double *, int *);+double BLASFUNC(qxmin) (int *, double *, int *);++int BLASFUNC(sscal) (int *, float *, float *, int *);+int BLASFUNC(dscal) (int *, double *, double *, int *);+int BLASFUNC(qscal) (int *, double *, double *, int *);+int BLASFUNC(cscal) (int *, float *, float *, int *);+int BLASFUNC(zscal) (int *, double *, double *, int *);+int BLASFUNC(xscal) (int *, double *, double *, int *);+int BLASFUNC(csscal)(int *, float *, float *, int *);+int BLASFUNC(zdscal)(int *, double *, double *, int *);+int BLASFUNC(xqscal)(int *, double *, double *, int *);++float BLASFUNC(snrm2) (int *, float *, int *);+float BLASFUNC(scnrm2)(int *, float *, int *);++double BLASFUNC(dnrm2) (int *, double *, int *);+double BLASFUNC(qnrm2) (int *, double *, int *);+double BLASFUNC(dznrm2)(int *, double *, int *);+double BLASFUNC(qxnrm2)(int *, double *, int *);++int BLASFUNC(srot) (int *, float *, int *, float *, int *, float *, float *);+int BLASFUNC(drot) (int *, double *, int *, double *, int *, double *, double *);+int BLASFUNC(qrot) (int *, double *, int *, double *, int *, double *, double *);+int BLASFUNC(csrot) (int *, float *, int *, float *, int *, float *, float *);+int BLASFUNC(zdrot) (int *, double *, int *, double *, int *, double *, double *);+int BLASFUNC(xqrot) (int *, double *, int *, double *, int *, double *, double *);++int BLASFUNC(srotg) (float *, float *, float *, float *);+int BLASFUNC(drotg) (double *, double *, double *, double *);+int BLASFUNC(qrotg) (double *, double *, double *, double *);+int BLASFUNC(crotg) (float *, float *, float *, float *);+int BLASFUNC(zrotg) (double *, double *, double *, double *);+int BLASFUNC(xrotg) (double *, double *, double *, double *);++int BLASFUNC(srotmg)(float *, float *, float *, float *, float *);+int BLASFUNC(drotmg)(double *, double *, double *, double *, double *);++int BLASFUNC(srotm) (int *, float *, int *, float *, int *, float *);+int BLASFUNC(drotm) (int *, double *, int *, double *, int *, double *);+int BLASFUNC(qrotm) (int *, double *, int *, double *, int *, double *);++/* Level 2 routines */++int BLASFUNC(sger)(int *, int *, float *, float *, int *,+ float *, int *, float *, int *);+int BLASFUNC(dger)(int *, int *, double *, double *, int *,+ double *, int *, double *, int *);+int BLASFUNC(qger)(int *, int *, double *, double *, int *,+ double *, int *, double *, int *);+int BLASFUNC(cgeru)(int *, int *, float *, float *, int *,+ float *, int *, float *, int *);+int BLASFUNC(cgerc)(int *, int *, float *, float *, int *,+ float *, int *, float *, int *);+int BLASFUNC(zgeru)(int *, int *, double *, double *, int *,+ double *, int *, double *, int *);+int BLASFUNC(zgerc)(int *, int *, double *, double *, int *,+ double *, int *, double *, int *);+int BLASFUNC(xgeru)(int *, int *, double *, double *, int *,+ double *, int *, double *, int *);+int BLASFUNC(xgerc)(int *, int *, double *, double *, int *,+ double *, int *, double *, int *);++int BLASFUNC(sgemv)(char *, int *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(dgemv)(char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(qgemv)(char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(cgemv)(char *, int *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(zgemv)(char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(xgemv)(char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);++int BLASFUNC(strsv) (char *, char *, char *, int *, float *, int *,+ float *, int *);+int BLASFUNC(dtrsv) (char *, char *, char *, int *, double *, int *,+ double *, int *);+int BLASFUNC(qtrsv) (char *, char *, char *, int *, double *, int *,+ double *, int *);+int BLASFUNC(ctrsv) (char *, char *, char *, int *, float *, int *,+ float *, int *);+int BLASFUNC(ztrsv) (char *, char *, char *, int *, double *, int *,+ double *, int *);+int BLASFUNC(xtrsv) (char *, char *, char *, int *, double *, int *,+ double *, int *);++int BLASFUNC(stpsv) (char *, char *, char *, int *, float *, float *, int *);+int BLASFUNC(dtpsv) (char *, char *, char *, int *, double *, double *, int *);+int BLASFUNC(qtpsv) (char *, char *, char *, int *, double *, double *, int *);+int BLASFUNC(ctpsv) (char *, char *, char *, int *, float *, float *, int *);+int BLASFUNC(ztpsv) (char *, char *, char *, int *, double *, double *, int *);+int BLASFUNC(xtpsv) (char *, char *, char *, int *, double *, double *, int *);++int BLASFUNC(strmv) (char *, char *, char *, int *, float *, int *,+ float *, int *);+int BLASFUNC(dtrmv) (char *, char *, char *, int *, double *, int *,+ double *, int *);+int BLASFUNC(qtrmv) (char *, char *, char *, int *, double *, int *,+ double *, int *);+int BLASFUNC(ctrmv) (char *, char *, char *, int *, float *, int *,+ float *, int *);+int BLASFUNC(ztrmv) (char *, char *, char *, int *, double *, int *,+ double *, int *);+int BLASFUNC(xtrmv) (char *, char *, char *, int *, double *, int *,+ double *, int *);++int BLASFUNC(stpmv) (char *, char *, char *, int *, float *, float *, int *);+int BLASFUNC(dtpmv) (char *, char *, char *, int *, double *, double *, int *);+int BLASFUNC(qtpmv) (char *, char *, char *, int *, double *, double *, int *);+int BLASFUNC(ctpmv) (char *, char *, char *, int *, float *, float *, int *);+int BLASFUNC(ztpmv) (char *, char *, char *, int *, double *, double *, int *);+int BLASFUNC(xtpmv) (char *, char *, char *, int *, double *, double *, int *);++int BLASFUNC(stbmv) (char *, char *, char *, int *, int *, float *, int *, float *, int *);+int BLASFUNC(dtbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *);+int BLASFUNC(qtbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *);+int BLASFUNC(ctbmv) (char *, char *, char *, int *, int *, float *, int *, float *, int *);+int BLASFUNC(ztbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *);+int BLASFUNC(xtbmv) (char *, char *, char *, int *, int *, double *, int *, double *, int *);++int BLASFUNC(stbsv) (char *, char *, char *, int *, int *, float *, int *, float *, int *);+int BLASFUNC(dtbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *);+int BLASFUNC(qtbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *);+int BLASFUNC(ctbsv) (char *, char *, char *, int *, int *, float *, int *, float *, int *);+int BLASFUNC(ztbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *);+int BLASFUNC(xtbsv) (char *, char *, char *, int *, int *, double *, int *, double *, int *);++int BLASFUNC(ssymv) (char *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(dsymv) (char *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(qsymv) (char *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(csymv) (char *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(zsymv) (char *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(xsymv) (char *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);++int BLASFUNC(sspmv) (char *, int *, float *, float *,+ float *, int *, float *, float *, int *);+int BLASFUNC(dspmv) (char *, int *, double *, double *,+ double *, int *, double *, double *, int *);+int BLASFUNC(qspmv) (char *, int *, double *, double *,+ double *, int *, double *, double *, int *);+int BLASFUNC(cspmv) (char *, int *, float *, float *,+ float *, int *, float *, float *, int *);+int BLASFUNC(zspmv) (char *, int *, double *, double *,+ double *, int *, double *, double *, int *);+int BLASFUNC(xspmv) (char *, int *, double *, double *,+ double *, int *, double *, double *, int *);++int BLASFUNC(ssyr) (char *, int *, float *, float *, int *,+ float *, int *);+int BLASFUNC(dsyr) (char *, int *, double *, double *, int *,+ double *, int *);+int BLASFUNC(qsyr) (char *, int *, double *, double *, int *,+ double *, int *);+int BLASFUNC(csyr) (char *, int *, float *, float *, int *,+ float *, int *);+int BLASFUNC(zsyr) (char *, int *, double *, double *, int *,+ double *, int *);+int BLASFUNC(xsyr) (char *, int *, double *, double *, int *,+ double *, int *);++int BLASFUNC(ssyr2) (char *, int *, float *,+ float *, int *, float *, int *, float *, int *);+int BLASFUNC(dsyr2) (char *, int *, double *,+ double *, int *, double *, int *, double *, int *);+int BLASFUNC(qsyr2) (char *, int *, double *,+ double *, int *, double *, int *, double *, int *);+int BLASFUNC(csyr2) (char *, int *, float *,+ float *, int *, float *, int *, float *, int *);+int BLASFUNC(zsyr2) (char *, int *, double *,+ double *, int *, double *, int *, double *, int *);+int BLASFUNC(xsyr2) (char *, int *, double *,+ double *, int *, double *, int *, double *, int *);++int BLASFUNC(sspr) (char *, int *, float *, float *, int *,+ float *);+int BLASFUNC(dspr) (char *, int *, double *, double *, int *,+ double *);+int BLASFUNC(qspr) (char *, int *, double *, double *, int *,+ double *);+int BLASFUNC(cspr) (char *, int *, float *, float *, int *,+ float *);+int BLASFUNC(zspr) (char *, int *, double *, double *, int *,+ double *);+int BLASFUNC(xspr) (char *, int *, double *, double *, int *,+ double *);++int BLASFUNC(sspr2) (char *, int *, float *,+ float *, int *, float *, int *, float *);+int BLASFUNC(dspr2) (char *, int *, double *,+ double *, int *, double *, int *, double *);+int BLASFUNC(qspr2) (char *, int *, double *,+ double *, int *, double *, int *, double *);+int BLASFUNC(cspr2) (char *, int *, float *,+ float *, int *, float *, int *, float *);+int BLASFUNC(zspr2) (char *, int *, double *,+ double *, int *, double *, int *, double *);+int BLASFUNC(xspr2) (char *, int *, double *,+ double *, int *, double *, int *, double *);++int BLASFUNC(cher) (char *, int *, float *, float *, int *,+ float *, int *);+int BLASFUNC(zher) (char *, int *, double *, double *, int *,+ double *, int *);+int BLASFUNC(xher) (char *, int *, double *, double *, int *,+ double *, int *);++int BLASFUNC(chpr) (char *, int *, float *, float *, int *, float *);+int BLASFUNC(zhpr) (char *, int *, double *, double *, int *, double *);+int BLASFUNC(xhpr) (char *, int *, double *, double *, int *, double *);++int BLASFUNC(cher2) (char *, int *, float *,+ float *, int *, float *, int *, float *, int *);+int BLASFUNC(zher2) (char *, int *, double *,+ double *, int *, double *, int *, double *, int *);+int BLASFUNC(xher2) (char *, int *, double *,+ double *, int *, double *, int *, double *, int *);++int BLASFUNC(chpr2) (char *, int *, float *,+ float *, int *, float *, int *, float *);+int BLASFUNC(zhpr2) (char *, int *, double *,+ double *, int *, double *, int *, double *);+int BLASFUNC(xhpr2) (char *, int *, double *,+ double *, int *, double *, int *, double *);++int BLASFUNC(chemv) (char *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(zhemv) (char *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(xhemv) (char *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);++int BLASFUNC(chpmv) (char *, int *, float *, float *,+ float *, int *, float *, float *, int *);+int BLASFUNC(zhpmv) (char *, int *, double *, double *,+ double *, int *, double *, double *, int *);+int BLASFUNC(xhpmv) (char *, int *, double *, double *,+ double *, int *, double *, double *, int *);++int BLASFUNC(snorm)(char *, int *, int *, float *, int *);+int BLASFUNC(dnorm)(char *, int *, int *, double *, int *);+int BLASFUNC(cnorm)(char *, int *, int *, float *, int *);+int BLASFUNC(znorm)(char *, int *, int *, double *, int *);++int BLASFUNC(sgbmv)(char *, int *, int *, int *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(dgbmv)(char *, int *, int *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(qgbmv)(char *, int *, int *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(cgbmv)(char *, int *, int *, int *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(zgbmv)(char *, int *, int *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(xgbmv)(char *, int *, int *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);++int BLASFUNC(ssbmv)(char *, int *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(dsbmv)(char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(qsbmv)(char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(csbmv)(char *, int *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(zsbmv)(char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(xsbmv)(char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);++int BLASFUNC(chbmv)(char *, int *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(zhbmv)(char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(xhbmv)(char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);++/* Level 3 routines */++int BLASFUNC(sgemm)(char *, char *, int *, int *, int *, float *,+ float *, int *, float *, int *, float *, float *, int *);+int BLASFUNC(dgemm)(char *, char *, int *, int *, int *, double *,+ double *, int *, double *, int *, double *, double *, int *);+int BLASFUNC(qgemm)(char *, char *, int *, int *, int *, double *,+ double *, int *, double *, int *, double *, double *, int *);+int BLASFUNC(cgemm)(char *, char *, int *, int *, int *, float *,+ float *, int *, float *, int *, float *, float *, int *);+int BLASFUNC(zgemm)(char *, char *, int *, int *, int *, double *,+ double *, int *, double *, int *, double *, double *, int *);+int BLASFUNC(xgemm)(char *, char *, int *, int *, int *, double *,+ double *, int *, double *, int *, double *, double *, int *);++int BLASFUNC(cgemm3m)(char *, char *, int *, int *, int *, float *,+ float *, int *, float *, int *, float *, float *, int *);+int BLASFUNC(zgemm3m)(char *, char *, int *, int *, int *, double *,+ double *, int *, double *, int *, double *, double *, int *);+int BLASFUNC(xgemm3m)(char *, char *, int *, int *, int *, double *,+ double *, int *, double *, int *, double *, double *, int *);++int BLASFUNC(sge2mm)(char *, char *, char *, int *, int *,+ float *, float *, int *, float *, int *,+ float *, float *, int *);+int BLASFUNC(dge2mm)(char *, char *, char *, int *, int *,+ double *, double *, int *, double *, int *,+ double *, double *, int *);+int BLASFUNC(cge2mm)(char *, char *, char *, int *, int *,+ float *, float *, int *, float *, int *,+ float *, float *, int *);+int BLASFUNC(zge2mm)(char *, char *, char *, int *, int *,+ double *, double *, int *, double *, int *,+ double *, double *, int *);++int BLASFUNC(strsm)(char *, char *, char *, char *, int *, int *,+ float *, float *, int *, float *, int *);+int BLASFUNC(dtrsm)(char *, char *, char *, char *, int *, int *,+ double *, double *, int *, double *, int *);+int BLASFUNC(qtrsm)(char *, char *, char *, char *, int *, int *,+ double *, double *, int *, double *, int *);+int BLASFUNC(ctrsm)(char *, char *, char *, char *, int *, int *,+ float *, float *, int *, float *, int *);+int BLASFUNC(ztrsm)(char *, char *, char *, char *, int *, int *,+ double *, double *, int *, double *, int *);+int BLASFUNC(xtrsm)(char *, char *, char *, char *, int *, int *,+ double *, double *, int *, double *, int *);++int BLASFUNC(strmm)(char *, char *, char *, char *, int *, int *,+ float *, float *, int *, float *, int *);+int BLASFUNC(dtrmm)(char *, char *, char *, char *, int *, int *,+ double *, double *, int *, double *, int *);+int BLASFUNC(qtrmm)(char *, char *, char *, char *, int *, int *,+ double *, double *, int *, double *, int *);+int BLASFUNC(ctrmm)(char *, char *, char *, char *, int *, int *,+ float *, float *, int *, float *, int *);+int BLASFUNC(ztrmm)(char *, char *, char *, char *, int *, int *,+ double *, double *, int *, double *, int *);+int BLASFUNC(xtrmm)(char *, char *, char *, char *, int *, int *,+ double *, double *, int *, double *, int *);++int BLASFUNC(ssymm)(char *, char *, int *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(dsymm)(char *, char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(qsymm)(char *, char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(csymm)(char *, char *, int *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(zsymm)(char *, char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(xsymm)(char *, char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);++int BLASFUNC(csymm3m)(char *, char *, int *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(zsymm3m)(char *, char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(xsymm3m)(char *, char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);++int BLASFUNC(ssyrk)(char *, char *, int *, int *, float *, float *, int *,+ float *, float *, int *);+int BLASFUNC(dsyrk)(char *, char *, int *, int *, double *, double *, int *,+ double *, double *, int *);+int BLASFUNC(qsyrk)(char *, char *, int *, int *, double *, double *, int *,+ double *, double *, int *);+int BLASFUNC(csyrk)(char *, char *, int *, int *, float *, float *, int *,+ float *, float *, int *);+int BLASFUNC(zsyrk)(char *, char *, int *, int *, double *, double *, int *,+ double *, double *, int *);+int BLASFUNC(xsyrk)(char *, char *, int *, int *, double *, double *, int *,+ double *, double *, int *);++int BLASFUNC(ssyr2k)(char *, char *, int *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(dsyr2k)(char *, char *, int *, int *, double *, double *, int *,+ double*, int *, double *, double *, int *);+int BLASFUNC(qsyr2k)(char *, char *, int *, int *, double *, double *, int *,+ double*, int *, double *, double *, int *);+int BLASFUNC(csyr2k)(char *, char *, int *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(zsyr2k)(char *, char *, int *, int *, double *, double *, int *,+ double*, int *, double *, double *, int *);+int BLASFUNC(xsyr2k)(char *, char *, int *, int *, double *, double *, int *,+ double*, int *, double *, double *, int *);++int BLASFUNC(chemm)(char *, char *, int *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(zhemm)(char *, char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(xhemm)(char *, char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);++int BLASFUNC(chemm3m)(char *, char *, int *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(zhemm3m)(char *, char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);+int BLASFUNC(xhemm3m)(char *, char *, int *, int *, double *, double *, int *,+ double *, int *, double *, double *, int *);++int BLASFUNC(cherk)(char *, char *, int *, int *, float *, float *, int *,+ float *, float *, int *);+int BLASFUNC(zherk)(char *, char *, int *, int *, double *, double *, int *,+ double *, double *, int *);+int BLASFUNC(xherk)(char *, char *, int *, int *, double *, double *, int *,+ double *, double *, int *);++int BLASFUNC(cher2k)(char *, char *, int *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(zher2k)(char *, char *, int *, int *, double *, double *, int *,+ double*, int *, double *, double *, int *);+int BLASFUNC(xher2k)(char *, char *, int *, int *, double *, double *, int *,+ double*, int *, double *, double *, int *);+int BLASFUNC(cher2m)(char *, char *, char *, int *, int *, float *, float *, int *,+ float *, int *, float *, float *, int *);+int BLASFUNC(zher2m)(char *, char *, char *, int *, int *, double *, double *, int *,+ double*, int *, double *, double *, int *);+int BLASFUNC(xher2m)(char *, char *, char *, int *, int *, double *, double *, int *,+ double*, int *, double *, double *, int *);++int BLASFUNC(sgemt)(char *, int *, int *, float *, float *, int *,+ float *, int *);+int BLASFUNC(dgemt)(char *, int *, int *, double *, double *, int *,+ double *, int *);+int BLASFUNC(cgemt)(char *, int *, int *, float *, float *, int *,+ float *, int *);+int BLASFUNC(zgemt)(char *, int *, int *, double *, double *, int *,+ double *, int *);++int BLASFUNC(sgema)(char *, char *, int *, int *, float *,+ float *, int *, float *, float *, int *, float *, int *);+int BLASFUNC(dgema)(char *, char *, int *, int *, double *,+ double *, int *, double*, double *, int *, double*, int *);+int BLASFUNC(cgema)(char *, char *, int *, int *, float *,+ float *, int *, float *, float *, int *, float *, int *);+int BLASFUNC(zgema)(char *, char *, int *, int *, double *,+ double *, int *, double*, double *, int *, double*, int *);++int BLASFUNC(sgems)(char *, char *, int *, int *, float *,+ float *, int *, float *, float *, int *, float *, int *);+int BLASFUNC(dgems)(char *, char *, int *, int *, double *,+ double *, int *, double*, double *, int *, double*, int *);+int BLASFUNC(cgems)(char *, char *, int *, int *, float *,+ float *, int *, float *, float *, int *, float *, int *);+int BLASFUNC(zgems)(char *, char *, int *, int *, double *,+ double *, int *, double*, double *, int *, double*, int *);++int BLASFUNC(sgetf2)(int *, int *, float *, int *, int *, int *);+int BLASFUNC(dgetf2)(int *, int *, double *, int *, int *, int *);+int BLASFUNC(qgetf2)(int *, int *, double *, int *, int *, int *);+int BLASFUNC(cgetf2)(int *, int *, float *, int *, int *, int *);+int BLASFUNC(zgetf2)(int *, int *, double *, int *, int *, int *);+int BLASFUNC(xgetf2)(int *, int *, double *, int *, int *, int *);++int BLASFUNC(sgetrf)(int *, int *, float *, int *, int *, int *);+int BLASFUNC(dgetrf)(int *, int *, double *, int *, int *, int *);+int BLASFUNC(qgetrf)(int *, int *, double *, int *, int *, int *);+int BLASFUNC(cgetrf)(int *, int *, float *, int *, int *, int *);+int BLASFUNC(zgetrf)(int *, int *, double *, int *, int *, int *);+int BLASFUNC(xgetrf)(int *, int *, double *, int *, int *, int *);++int BLASFUNC(slaswp)(int *, float *, int *, int *, int *, int *, int *);+int BLASFUNC(dlaswp)(int *, double *, int *, int *, int *, int *, int *);+int BLASFUNC(qlaswp)(int *, double *, int *, int *, int *, int *, int *);+int BLASFUNC(claswp)(int *, float *, int *, int *, int *, int *, int *);+int BLASFUNC(zlaswp)(int *, double *, int *, int *, int *, int *, int *);+int BLASFUNC(xlaswp)(int *, double *, int *, int *, int *, int *, int *);++int BLASFUNC(sgetrs)(char *, int *, int *, float *, int *, int *, float *, int *, int *);+int BLASFUNC(dgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *);+int BLASFUNC(qgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *);+int BLASFUNC(cgetrs)(char *, int *, int *, float *, int *, int *, float *, int *, int *);+int BLASFUNC(zgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *);+int BLASFUNC(xgetrs)(char *, int *, int *, double *, int *, int *, double *, int *, int *);++int BLASFUNC(sgesv)(int *, int *, float *, int *, int *, float *, int *, int *);+int BLASFUNC(dgesv)(int *, int *, double *, int *, int *, double*, int *, int *);+int BLASFUNC(qgesv)(int *, int *, double *, int *, int *, double*, int *, int *);+int BLASFUNC(cgesv)(int *, int *, float *, int *, int *, float *, int *, int *);+int BLASFUNC(zgesv)(int *, int *, double *, int *, int *, double*, int *, int *);+int BLASFUNC(xgesv)(int *, int *, double *, int *, int *, double*, int *, int *);++int BLASFUNC(spotf2)(char *, int *, float *, int *, int *);+int BLASFUNC(dpotf2)(char *, int *, double *, int *, int *);+int BLASFUNC(qpotf2)(char *, int *, double *, int *, int *);+int BLASFUNC(cpotf2)(char *, int *, float *, int *, int *);+int BLASFUNC(zpotf2)(char *, int *, double *, int *, int *);+int BLASFUNC(xpotf2)(char *, int *, double *, int *, int *);++int BLASFUNC(spotrf)(char *, int *, float *, int *, int *);+int BLASFUNC(dpotrf)(char *, int *, double *, int *, int *);+int BLASFUNC(qpotrf)(char *, int *, double *, int *, int *);+int BLASFUNC(cpotrf)(char *, int *, float *, int *, int *);+int BLASFUNC(zpotrf)(char *, int *, double *, int *, int *);+int BLASFUNC(xpotrf)(char *, int *, double *, int *, int *);++int BLASFUNC(slauu2)(char *, int *, float *, int *, int *);+int BLASFUNC(dlauu2)(char *, int *, double *, int *, int *);+int BLASFUNC(qlauu2)(char *, int *, double *, int *, int *);+int BLASFUNC(clauu2)(char *, int *, float *, int *, int *);+int BLASFUNC(zlauu2)(char *, int *, double *, int *, int *);+int BLASFUNC(xlauu2)(char *, int *, double *, int *, int *);++int BLASFUNC(slauum)(char *, int *, float *, int *, int *);+int BLASFUNC(dlauum)(char *, int *, double *, int *, int *);+int BLASFUNC(qlauum)(char *, int *, double *, int *, int *);+int BLASFUNC(clauum)(char *, int *, float *, int *, int *);+int BLASFUNC(zlauum)(char *, int *, double *, int *, int *);+int BLASFUNC(xlauum)(char *, int *, double *, int *, int *);++int BLASFUNC(strti2)(char *, char *, int *, float *, int *, int *);+int BLASFUNC(dtrti2)(char *, char *, int *, double *, int *, int *);+int BLASFUNC(qtrti2)(char *, char *, int *, double *, int *, int *);+int BLASFUNC(ctrti2)(char *, char *, int *, float *, int *, int *);+int BLASFUNC(ztrti2)(char *, char *, int *, double *, int *, int *);+int BLASFUNC(xtrti2)(char *, char *, int *, double *, int *, int *);++int BLASFUNC(strtri)(char *, char *, int *, float *, int *, int *);+int BLASFUNC(dtrtri)(char *, char *, int *, double *, int *, int *);+int BLASFUNC(qtrtri)(char *, char *, int *, double *, int *, int *);+int BLASFUNC(ctrtri)(char *, char *, int *, float *, int *, int *);+int BLASFUNC(ztrtri)(char *, char *, int *, double *, int *, int *);+int BLASFUNC(xtrtri)(char *, char *, int *, double *, int *, int *);++int BLASFUNC(spotri)(char *, int *, float *, int *, int *);+int BLASFUNC(dpotri)(char *, int *, double *, int *, int *);+int BLASFUNC(qpotri)(char *, int *, double *, int *, int *);+int BLASFUNC(cpotri)(char *, int *, float *, int *, int *);+int BLASFUNC(zpotri)(char *, int *, double *, int *, int *);+int BLASFUNC(xpotri)(char *, int *, double *, int *, int *);++#endif
+ eigen3/bench/btl/libs/BLAS/blas_interface.hh view
@@ -0,0 +1,83 @@+//=====================================================+// File : blas_interface.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:28 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef blas_PRODUIT_MATRICE_VECTEUR_HH+#define blas_PRODUIT_MATRICE_VECTEUR_HH++#include <c_interface_base.h>+#include <complex>+extern "C"+{+#include "blas.h"++ // Cholesky Factorization+// void spotrf_(const char* uplo, const int* n, float *a, const int* ld, int* info);+// void dpotrf_(const char* uplo, const int* n, double *a, const int* ld, int* info);+ void ssytrd_(char *uplo, const int *n, float *a, const int *lda, float *d, float *e, float *tau, float *work, int *lwork, int *info );+ void dsytrd_(char *uplo, const int *n, double *a, const int *lda, double *d, double *e, double *tau, double *work, int *lwork, int *info );+ void sgehrd_( const int *n, int *ilo, int *ihi, float *a, const int *lda, float *tau, float *work, int *lwork, int *info );+ void dgehrd_( const int *n, int *ilo, int *ihi, double *a, const int *lda, double *tau, double *work, int *lwork, int *info );++ // LU row pivoting+// void dgetrf_( int *m, int *n, double *a, int *lda, int *ipiv, int *info );+// void sgetrf_(const int* m, const int* n, float *a, const int* ld, int* ipivot, int* info);+ // LU full pivoting+ void sgetc2_(const int* n, float *a, const int *lda, int *ipiv, int *jpiv, int*info );+ void dgetc2_(const int* n, double *a, const int *lda, int *ipiv, int *jpiv, int*info );+#ifdef HAS_LAPACK+#endif+}++#define MAKE_STRING2(S) #S+#define MAKE_STRING(S) MAKE_STRING2(S)++#define CAT2(A,B) A##B+#define CAT(A,B) CAT2(A,B)+++template<class real> class blas_interface;+++static char notrans = 'N';+static char trans = 'T';+static char nonunit = 'N';+static char lower = 'L';+static char right = 'R';+static char left = 'L';+static int intone = 1;++++#define SCALAR float+#define SCALAR_PREFIX s+#include "blas_interface_impl.hh"+#undef SCALAR+#undef SCALAR_PREFIX+++#define SCALAR double+#define SCALAR_PREFIX d+#include "blas_interface_impl.hh"+#undef SCALAR+#undef SCALAR_PREFIX++#endif+++
+ eigen3/bench/btl/libs/BLAS/blas_interface_impl.hh view
@@ -0,0 +1,151 @@++#define BLAS_FUNC(NAME) CAT(CAT(SCALAR_PREFIX,NAME),_)++template<> class blas_interface<SCALAR> : public c_interface_base<SCALAR>+{++public :+ + static SCALAR fone;+ static SCALAR fzero;++ static inline std::string name()+ {+ return MAKE_STRING(CBLASNAME);+ }++ static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){+ BLAS_FUNC(gemv)(¬rans,&N,&N,&fone,A,&N,B,&intone,&fzero,X,&intone);+ }++ static inline void symv(gene_matrix & A, gene_vector & B, gene_vector & X, int N){+ BLAS_FUNC(symv)(&lower, &N,&fone,A,&N,B,&intone,&fzero,X,&intone);+ }++ static inline void syr2(gene_matrix & A, gene_vector & B, gene_vector & X, int N){+ BLAS_FUNC(syr2)(&lower,&N,&fone,B,&intone,X,&intone,A,&N);+ }++ static inline void ger(gene_matrix & A, gene_vector & X, gene_vector & Y, int N){+ BLAS_FUNC(ger)(&N,&N,&fone,X,&intone,Y,&intone,A,&N);+ }++ static inline void rot(gene_vector & A, gene_vector & B, SCALAR c, SCALAR s, int N){+ BLAS_FUNC(rot)(&N,A,&intone,B,&intone,&c,&s);+ }++ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){+ BLAS_FUNC(gemv)(&trans,&N,&N,&fone,A,&N,B,&intone,&fzero,X,&intone);+ }++ static inline void matrix_matrix_product(gene_matrix & A, gene_matrix & B, gene_matrix & X, int N){+ BLAS_FUNC(gemm)(¬rans,¬rans,&N,&N,&N,&fone,A,&N,B,&N,&fzero,X,&N);+ }++ static inline void transposed_matrix_matrix_product(gene_matrix & A, gene_matrix & B, gene_matrix & X, int N){+ BLAS_FUNC(gemm)(¬rans,¬rans,&N,&N,&N,&fone,A,&N,B,&N,&fzero,X,&N);+ }++// static inline void ata_product(gene_matrix & A, gene_matrix & X, int N){+// ssyrk_(&lower,&trans,&N,&N,&fone,A,&N,&fzero,X,&N);+// }++ static inline void aat_product(gene_matrix & A, gene_matrix & X, int N){+ BLAS_FUNC(syrk)(&lower,¬rans,&N,&N,&fone,A,&N,&fzero,X,&N);+ }++ static inline void axpy(SCALAR coef, const gene_vector & X, gene_vector & Y, int N){+ BLAS_FUNC(axpy)(&N,&coef,X,&intone,Y,&intone);+ }++ static inline void axpby(SCALAR a, const gene_vector & X, SCALAR b, gene_vector & Y, int N){+ BLAS_FUNC(scal)(&N,&b,Y,&intone);+ BLAS_FUNC(axpy)(&N,&a,X,&intone,Y,&intone);+ }++ static inline void cholesky(const gene_matrix & X, gene_matrix & C, int N){+ int N2 = N*N;+ BLAS_FUNC(copy)(&N2, X, &intone, C, &intone);+ char uplo = 'L';+ int info = 0;+ BLAS_FUNC(potrf)(&uplo, &N, C, &N, &info);+ if(info!=0) std::cerr << "potrf_ error " << info << "\n";+ }++ static inline void partial_lu_decomp(const gene_matrix & X, gene_matrix & C, int N){+ int N2 = N*N;+ BLAS_FUNC(copy)(&N2, X, &intone, C, &intone);+ char uplo = 'L';+ int info = 0;+ int * ipiv = (int*)alloca(sizeof(int)*N);+ BLAS_FUNC(getrf)(&N, &N, C, &N, ipiv, &info);+ if(info!=0) std::cerr << "getrf_ error " << info << "\n";+ }+ + static inline void trisolve_lower(const gene_matrix & L, const gene_vector& B, gene_vector & X, int N){+ BLAS_FUNC(copy)(&N, B, &intone, X, &intone);+ BLAS_FUNC(trsv)(&lower, ¬rans, &nonunit, &N, L, &N, X, &intone);+ }++ static inline void trisolve_lower_matrix(const gene_matrix & L, const gene_matrix& B, gene_matrix & X, int N){+ BLAS_FUNC(copy)(&N, B, &intone, X, &intone);+ BLAS_FUNC(trsm)(&right, &lower, ¬rans, &nonunit, &N, &N, &fone, L, &N, X, &N);+ }++ static inline void trmm(gene_matrix & A, gene_matrix & B, gene_matrix & X, int N){+ BLAS_FUNC(trmm)(&left, &lower, ¬rans,&nonunit, &N,&N,&fone,A,&N,B,&N);+ }++ #ifdef HAS_LAPACK++ static inline void lu_decomp(const gene_matrix & X, gene_matrix & C, int N){+ int N2 = N*N;+ BLAS_FUNC(copy)(&N2, X, &intone, C, &intone);+ char uplo = 'L';+ int info = 0;+ int * ipiv = (int*)alloca(sizeof(int)*N);+ int * jpiv = (int*)alloca(sizeof(int)*N);+ BLAS_FUNC(getc2)(&N, C, &N, ipiv, jpiv, &info);+ }++++ static inline void hessenberg(const gene_matrix & X, gene_matrix & C, int N){+ {+ int N2 = N*N;+ int inc = 1;+ BLAS_FUNC(copy)(&N2, X, &inc, C, &inc);+ }+ int info = 0;+ int ilo = 1;+ int ihi = N;+ int bsize = 64;+ int worksize = N*bsize;+ SCALAR* d = new SCALAR[N+worksize];+ BLAS_FUNC(gehrd)(&N, &ilo, &ihi, C, &N, d, d+N, &worksize, &info);+ delete[] d;+ }++ static inline void tridiagonalization(const gene_matrix & X, gene_matrix & C, int N){+ {+ int N2 = N*N;+ int inc = 1;+ BLAS_FUNC(copy)(&N2, X, &inc, C, &inc);+ }+ char uplo = 'U';+ int info = 0;+ int ilo = 1;+ int ihi = N;+ int bsize = 64;+ int worksize = N*bsize;+ SCALAR* d = new SCALAR[3*N+worksize];+ BLAS_FUNC(sytrd)(&uplo, &N, C, &N, d, d+N, d+2*N, d+3*N, &worksize, &info);+ delete[] d;+ }+ + #endif // HAS_LAPACK++};++SCALAR blas_interface<SCALAR>::fone = SCALAR(1);+SCALAR blas_interface<SCALAR>::fzero = SCALAR(0);
+ eigen3/bench/btl/libs/BLAS/c_interface_base.h view
@@ -0,0 +1,73 @@++#ifndef BTL_C_INTERFACE_BASE_H+#define BTL_C_INTERFACE_BASE_H++#include "utilities.h"+#include <vector>++template<class real> class c_interface_base+{++public:++ typedef real real_type;+ typedef std::vector<real> stl_vector;+ typedef std::vector<stl_vector > stl_matrix;++ typedef real* gene_matrix;+ typedef real* gene_vector;++ static void free_matrix(gene_matrix & A, int N){+ delete A;+ }++ static void free_vector(gene_vector & B){+ delete B;+ }++ static inline void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){+ int N = A_stl.size();+ A = new real[N*N];+ for (int j=0;j<N;j++)+ for (int i=0;i<N;i++)+ A[i+N*j] = A_stl[j][i];+ }++ static inline void vector_from_stl(gene_vector & B, stl_vector & B_stl){+ int N = B_stl.size();+ B = new real[N];+ for (int i=0;i<N;i++)+ B[i] = B_stl[i];+ }++ static inline void vector_to_stl(gene_vector & B, stl_vector & B_stl){+ int N = B_stl.size();+ for (int i=0;i<N;i++)+ B_stl[i] = B[i];+ }++ static inline void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){+ int N = A_stl.size();+ for (int j=0;j<N;j++){+ A_stl[j].resize(N);+ for (int i=0;i<N;i++)+ A_stl[j][i] = A[i+N*j];+ }+ }++ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){+ for (int i=0;i<N;i++)+ cible[i]=source[i];+ }++ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){+ for (int j=0;j<N;j++){+ for (int i=0;i<N;i++){+ cible[i+N*j] = source[i+N*j];+ }+ }+ }++};++#endif
+ eigen3/bench/btl/libs/BLAS/main.cpp view
@@ -0,0 +1,73 @@+//=====================================================+// File : main.cpp+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:28 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "blas_interface.hh"+#include "bench.hh"+#include "basic_actions.hh"++#include "action_cholesky.hh"+#include "action_lu_decomp.hh"+#include "action_partial_lu.hh"+#include "action_trisolve_matrix.hh"++#ifdef HAS_LAPACK+#include "action_hessenberg.hh"+#endif++BTL_MAIN;++int main()+{++ bench<Action_axpy<blas_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);+ bench<Action_axpby<blas_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);++ bench<Action_matrix_vector_product<blas_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_atv_product<blas_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_symv<blas_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_syr2<blas_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);++ bench<Action_ger<blas_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_rot<blas_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);++ bench<Action_matrix_matrix_product<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+// bench<Action_ata_product<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_aat_product<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ bench<Action_trisolve<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_trisolve_matrix<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ bench<Action_trmm<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ bench<Action_cholesky<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_partial_lu<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ #ifdef HAS_LAPACK+ bench<Action_lu_decomp<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_hessenberg<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_tridiagonalization<blas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ #endif++ //bench<Action_lu_solve<blas_LU_solve_interface<REAL_TYPE> > >(MIN_LU,MAX_LU,NB_POINT);++ return 0;+}++
+ eigen3/bench/btl/libs/STL/CMakeLists.txt view
@@ -0,0 +1,2 @@++btl_add_bench(btl_STL main.cpp OFF)
+ eigen3/bench/btl/libs/STL/STL_interface.hh view
@@ -0,0 +1,244 @@+//=====================================================+// File : STL_interface.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:24 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef STL_INTERFACE_HH+#define STL_INTERFACE_HH+#include <string>+#include <vector>+#include "utilities.h"++using namespace std;++template<class real>+class STL_interface{++public :++ typedef real real_type ;++ typedef std::vector<real> stl_vector;+ typedef std::vector<stl_vector > stl_matrix;++ typedef stl_matrix gene_matrix;++ typedef stl_vector gene_vector;++ static inline std::string name( void )+ {+ return "STL";+ }++ static void free_matrix(gene_matrix & A, int N){}++ static void free_vector(gene_vector & B){}++ static inline void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){+ A = A_stl;+ }++ static inline void vector_from_stl(gene_vector & B, stl_vector & B_stl){+ B = B_stl;+ }++ static inline void vector_to_stl(gene_vector & B, stl_vector & B_stl){+ B_stl = B ;+ }+++ static inline void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){+ A_stl = A ;+ }++ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){+ for (int i=0;i<N;i++){+ cible[i]=source[i];+ }+ }+++ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){+ for (int i=0;i<N;i++)+ for (int j=0;j<N;j++)+ cible[i][j]=source[i][j];+ }++// static inline void ata_product(const gene_matrix & A, gene_matrix & X, int N)+// {+// real somme;+// for (int j=0;j<N;j++){+// for (int i=0;i<N;i++){+// somme=0.0;+// for (int k=0;k<N;k++)+// somme += A[i][k]*A[j][k];+// X[j][i]=somme;+// }+// }+// }++ static inline void aat_product(const gene_matrix & A, gene_matrix & X, int N)+ {+ real somme;+ for (int j=0;j<N;j++){+ for (int i=0;i<N;i++){+ somme=0.0;+ if(i>=j)+ {+ for (int k=0;k<N;k++){+ somme+=A[k][i]*A[k][j];+ }+ X[j][i]=somme;+ }+ }+ }+ }+++ static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N)+ {+ real somme;+ for (int j=0;j<N;j++){+ for (int i=0;i<N;i++){+ somme=0.0;+ for (int k=0;k<N;k++)+ somme+=A[k][i]*B[j][k];+ X[j][i]=somme;+ }+ }+ }++ static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N)+ {+ real somme;+ for (int i=0;i<N;i++){+ somme=0.0;+ for (int j=0;j<N;j++)+ somme+=A[j][i]*B[j];+ X[i]=somme;+ }+ }++ static inline void symv(gene_matrix & A, gene_vector & B, gene_vector & X, int N)+ {+ for (int j=0; j<N; ++j)+ X[j] = 0;+ for (int j=0; j<N; ++j)+ {+ real t1 = B[j];+ real t2 = 0;+ X[j] += t1 * A[j][j];+ for (int i=j+1; i<N; ++i) {+ X[i] += t1 * A[j][i];+ t2 += A[j][i] * B[i];+ }+ X[j] += t2;+ }+ }+ + static inline void syr2(gene_matrix & A, gene_vector & B, gene_vector & X, int N)+ {+ for (int j=0; j<N; ++j)+ {+ for (int i=j; i<N; ++i)+ A[j][i] += B[i]*X[j] + B[j]*X[i];+ }+ }++ static inline void ger(gene_matrix & A, gene_vector & X, gene_vector & Y, int N)+ {+ for (int j=0; j<N; ++j)+ {+ for (int i=j; i<N; ++i)+ A[j][i] += X[i]*Y[j];+ }+ }++ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N)+ {+ real somme;+ for (int i=0;i<N;i++){+ somme = 0.0;+ for (int j=0;j<N;j++)+ somme += A[i][j]*B[j];+ X[i] = somme;+ }+ }++ static inline void axpy(real coef, const gene_vector & X, gene_vector & Y, int N){+ for (int i=0;i<N;i++)+ Y[i]+=coef*X[i];+ }++ static inline void axpby(real a, const gene_vector & X, real b, gene_vector & Y, int N){+ for (int i=0;i<N;i++)+ Y[i] = a*X[i] + b*Y[i];+ }++ static inline void trisolve_lower(const gene_matrix & L, const gene_vector & B, gene_vector & X, int N){+ copy_vector(B,X,N);+ for(int i=0; i<N; ++i)+ {+ X[i] /= L[i][i];+ real tmp = X[i];+ for (int j=i+1; j<N; ++j)+ X[j] -= tmp * L[i][j];+ }+ }++ static inline real norm_diff(const stl_vector & A, const stl_vector & B)+ {+ int N=A.size();+ real somme=0.0;+ real somme2=0.0;++ for (int i=0;i<N;i++){+ real diff=A[i]-B[i];+ somme+=diff*diff;+ somme2+=A[i]*A[i];+ }+ return somme/somme2;+ }++ static inline real norm_diff(const stl_matrix & A, const stl_matrix & B)+ {+ int N=A[0].size();+ real somme=0.0;+ real somme2=0.0;++ for (int i=0;i<N;i++){+ for (int j=0;j<N;j++){+ real diff=A[i][j] - B[i][j];+ somme += diff*diff;+ somme2 += A[i][j]*A[i][j];+ }+ }++ return somme/somme2;+ }++ static inline void display_vector(const stl_vector & A)+ {+ int N=A.size();+ for (int i=0;i<N;i++){+ INFOS("A["<<i<<"]="<<A[i]<<endl);+ }+ }++};++#endif
+ eigen3/bench/btl/libs/STL/main.cpp view
@@ -0,0 +1,42 @@+//=====================================================+// File : main.cpp+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:23 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "STL_interface.hh"+#include "bench.hh"+#include "basic_actions.hh"++BTL_MAIN;++int main()+{+ bench<Action_axpy<STL_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);+ bench<Action_axpby<STL_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);+ bench<Action_matrix_vector_product<STL_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_atv_product<STL_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_symv<STL_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_syr2<STL_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_matrix_matrix_product<STL_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_ata_product<STL_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_aat_product<STL_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ return 0;+}++
+ eigen3/bench/btl/libs/blitz/CMakeLists.txt view
@@ -0,0 +1,17 @@++find_package(Blitz)++if (BLITZ_FOUND)+ include_directories(${BLITZ_INCLUDES})++ btl_add_bench(btl_blitz btl_blitz.cpp)+ if (BUILD_btl_blitz)+ target_link_libraries(btl_blitz ${BLITZ_LIBRARIES})+ endif (BUILD_btl_blitz)++ btl_add_bench(btl_tiny_blitz btl_tiny_blitz.cpp OFF)+ if (BUILD_btl_tiny_blitz)+ target_link_libraries(btl_tiny_blitz ${BLITZ_LIBRARIES})+ endif (BUILD_btl_tiny_blitz)++endif (BLITZ_FOUND)
+ eigen3/bench/btl/libs/blitz/blitz_LU_solve_interface.hh view
@@ -0,0 +1,192 @@+//=====================================================+// File : blitz_LU_solve_interface.hh+// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:31 CEST 2002+//=====================================================+// +// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+// +// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+// +#ifndef BLITZ_LU_SOLVE_INTERFACE_HH+#define BLITZ_LU_SOLVE_INTERFACE_HH++#include "blitz/array.h"+#include <vector>++BZ_USING_NAMESPACE(blitz)++template<class real>+class blitz_LU_solve_interface : public blitz_interface<real>+{++public :++ typedef typename blitz_interface<real>::gene_matrix gene_matrix;+ typedef typename blitz_interface<real>::gene_vector gene_vector;++ typedef blitz::Array<int,1> Pivot_Vector;++ inline static void new_Pivot_Vector(Pivot_Vector & pivot,int N)+ {++ pivot.resize(N);++ }++ inline static void free_Pivot_Vector(Pivot_Vector & pivot)+ {+ + return;++ }+++ static inline real matrix_vector_product_sliced(const gene_matrix & A, gene_vector B, int row, int col_start, int col_end)+ {+ + real somme=0.;+ + for (int j=col_start ; j<col_end+1 ; j++){+ + somme+=A(row,j)*B(j);+ + }++ return somme;++ }+++++ static inline real matrix_matrix_product_sliced(gene_matrix & A, int row, int col_start, int col_end, gene_matrix & B, int row_shift, int col )+ {+ + real somme=0.;+ + for (int j=col_start ; j<col_end+1 ; j++){+ + somme+=A(row,j)*B(j+row_shift,col);+ + }++ return somme;++ }++ inline static void LU_factor(gene_matrix & LU, Pivot_Vector & pivot, int N)+ {++ ASSERT( LU.rows()==LU.cols() ) ;+ int index_max = 0 ;+ real big = 0. ;+ real theSum = 0. ;+ real dum = 0. ;+ // Get the implicit scaling information :+ gene_vector ImplicitScaling( N ) ;+ for( int i=0; i<N; i++ ) {+ big = 0. ;+ for( int j=0; j<N; j++ ) {+ if( abs( LU( i, j ) )>=big ) big = abs( LU( i, j ) ) ;+ }+ if( big==0. ) {+ INFOS( "blitz_LU_factor::Singular matrix" ) ;+ exit( 0 ) ;+ }+ ImplicitScaling( i ) = 1./big ;+ }+ // Loop over columns of Crout's method :+ for( int j=0; j<N; j++ ) {+ for( int i=0; i<j; i++ ) {+ theSum = LU( i, j ) ;+ theSum -= matrix_matrix_product_sliced(LU, i, 0, i-1, LU, 0, j) ;+ // theSum -= sum( LU( i, Range( fromStart, i-1 ) )*LU( Range( fromStart, i-1 ), j ) ) ;+ LU( i, j ) = theSum ;+ }+ + // Search for the largest pivot element :+ big = 0. ;+ for( int i=j; i<N; i++ ) {+ theSum = LU( i, j ) ;+ theSum -= matrix_matrix_product_sliced(LU, i, 0, j-1, LU, 0, j) ;+ // theSum -= sum( LU( i, Range( fromStart, j-1 ) )*LU( Range( fromStart, j-1 ), j ) ) ;+ LU( i, j ) = theSum ;+ if( (ImplicitScaling( i )*abs( theSum ))>=big ) {+ dum = ImplicitScaling( i )*abs( theSum ) ;+ big = dum ;+ index_max = i ;+ }+ }+ // Interchanging rows and the scale factor :+ if( j!=index_max ) {+ for( int k=0; k<N; k++ ) {+ dum = LU( index_max, k ) ;+ LU( index_max, k ) = LU( j, k ) ;+ LU( j, k ) = dum ;+ }+ ImplicitScaling( index_max ) = ImplicitScaling( j ) ;+ }+ pivot( j ) = index_max ;+ if ( LU( j, j )==0. ) LU( j, j ) = 1.e-20 ;+ // Divide by the pivot element :+ if( j<N ) {+ dum = 1./LU( j, j ) ;+ for( int i=j+1; i<N; i++ ) LU( i, j ) *= dum ;+ }+ }++ }++ inline static void LU_solve(const gene_matrix & LU, const Pivot_Vector pivot, gene_vector &B, gene_vector X, int N)+ {++ // Pour conserver le meme header, on travaille sur X, copie du second-membre B+ X = B.copy() ;+ ASSERT( LU.rows()==LU.cols() ) ;+ firstIndex indI ;+ // Forward substitution :+ int ii = 0 ;+ real theSum = 0. ;+ for( int i=0; i<N; i++ ) {+ int ip = pivot( i ) ;+ theSum = X( ip ) ;+ // theSum = B( ip ) ;+ X( ip ) = X( i ) ;+ // B( ip ) = B( i ) ;+ if( ii ) {+ theSum -= matrix_vector_product_sliced(LU, X, i, ii-1, i-1) ;+ // theSum -= sum( LU( i, Range( ii-1, i-1 ) )*X( Range( ii-1, i-1 ) ) ) ;+ // theSum -= sum( LU( i, Range( ii-1, i-1 ) )*B( Range( ii-1, i-1 ) ) ) ;+ } else if( theSum ) {+ ii = i+1 ;+ }+ X( i ) = theSum ;+ // B( i ) = theSum ;+ }+ // Backsubstitution :+ for( int i=N-1; i>=0; i-- ) {+ theSum = X( i ) ;+ // theSum = B( i ) ;+ theSum -= matrix_vector_product_sliced(LU, X, i, i+1, N) ;+ // theSum -= sum( LU( i, Range( i+1, toEnd ) )*X( Range( i+1, toEnd ) ) ) ;+ // theSum -= sum( LU( i, Range( i+1, toEnd ) )*B( Range( i+1, toEnd ) ) ) ;+ // Store a component of the solution vector :+ X( i ) = theSum/LU( i, i ) ;+ // B( i ) = theSum/LU( i, i ) ;+ }++ }++};++#endif
+ eigen3/bench/btl/libs/blitz/blitz_interface.hh view
@@ -0,0 +1,147 @@+//=====================================================+// File : blitz_interface.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:30 CEST 2002+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef BLITZ_INTERFACE_HH+#define BLITZ_INTERFACE_HH++#include <blitz/blitz.h>+#include <blitz/array.h>+#include <blitz/vector-et.h>+#include <blitz/vecwhere.h>+#include <blitz/matrix.h>+#include <vector>++BZ_USING_NAMESPACE(blitz)++template<class real>+class blitz_interface{++public :++ typedef real real_type ;++ typedef std::vector<real> stl_vector;+ typedef std::vector<stl_vector > stl_matrix;++ typedef blitz::Array<real, 2> gene_matrix;+ typedef blitz::Array<real, 1> gene_vector;+// typedef blitz::Matrix<real, blitz::ColumnMajor> gene_matrix;+// typedef blitz::Vector<real> gene_vector;++ static inline std::string name() { return "blitz"; }++ static void free_matrix(gene_matrix & A, int N){}++ static void free_vector(gene_vector & B){}++ static inline void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){+ A.resize(A_stl[0].size(),A_stl.size());+ for (int j=0; j<A_stl.size() ; j++){+ for (int i=0; i<A_stl[j].size() ; i++){+ A(i,j)=A_stl[j][i];+ }+ }+ }++ static inline void vector_from_stl(gene_vector & B, stl_vector & B_stl){+ B.resize(B_stl.size());+ for (int i=0; i<B_stl.size() ; i++){+ B(i)=B_stl[i];+ }+ }++ static inline void vector_to_stl(gene_vector & B, stl_vector & B_stl){+ for (int i=0; i<B_stl.size() ; i++){+ B_stl[i]=B(i);+ }+ }++ static inline void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){+ int N=A_stl.size();+ for (int j=0;j<N;j++){+ A_stl[j].resize(N);+ for (int i=0;i<N;i++)+ A_stl[j][i] = A(i,j);+ }+ }++ static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N)+ {+ firstIndex i;+ secondIndex j;+ thirdIndex k;+ X = sum(A(i,k) * B(k,j), k);+ }++ static inline void ata_product(const gene_matrix & A, gene_matrix & X, int N)+ {+ firstIndex i;+ secondIndex j;+ thirdIndex k;+ X = sum(A(k,i) * A(k,j), k);+ }++ static inline void aat_product(const gene_matrix & A, gene_matrix & X, int N)+ {+ firstIndex i;+ secondIndex j;+ thirdIndex k;+ X = sum(A(i,k) * A(j,k), k);+ }++ static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N)+ {+ firstIndex i;+ secondIndex j;+ X = sum(A(i,j)*B(j),j);+ }++ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N)+ {+ firstIndex i;+ secondIndex j;+ X = sum(A(j,i) * B(j),j);+ }++ static inline void axpy(const real coef, const gene_vector & X, gene_vector & Y, int N)+ {+ firstIndex i;+ Y = Y(i) + coef * X(i);+ //Y += coef * X;+ }++ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){+ cible = source;+ //cible.template operator=<gene_matrix>(source);+// for (int i=0;i<N;i++){+// for (int j=0;j<N;j++){+// cible(i,j)=source(i,j);+// }+// }+ }++ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){+ //cible.template operator=<gene_vector>(source);+ cible = source;+ }++};++#endif
+ eigen3/bench/btl/libs/blitz/btl_blitz.cpp view
@@ -0,0 +1,51 @@+//=====================================================+// File : main.cpp+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:30 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "blitz_interface.hh"+#include "blitz_LU_solve_interface.hh"+#include "bench.hh"+#include "action_matrix_vector_product.hh"+#include "action_matrix_matrix_product.hh"+#include "action_axpy.hh"+#include "action_lu_solve.hh"+#include "action_ata_product.hh"+#include "action_aat_product.hh"+#include "action_atv_product.hh"++BTL_MAIN;++int main()+{++ bench<Action_matrix_vector_product<blitz_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_atv_product<blitz_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);++ bench<Action_matrix_matrix_product<blitz_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_ata_product<blitz_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_aat_product<blitz_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ bench<Action_axpy<blitz_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);++ //bench<Action_lu_solve<blitz_LU_solve_interface<REAL_TYPE> > >(MIN_LU,MAX_LU,NB_POINT);++ return 0;+}++
+ eigen3/bench/btl/libs/blitz/btl_tiny_blitz.cpp view
@@ -0,0 +1,38 @@+//=====================================================+// File : main.cpp+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:30 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "tiny_blitz_interface.hh"+#include "static/bench_static.hh"+#include "action_matrix_vector_product.hh"+#include "action_matrix_matrix_product.hh"+#include "action_axpy.hh"++BTL_MAIN;++int main()+{+ bench_static<Action_axpy,tiny_blitz_interface>();+ bench_static<Action_matrix_matrix_product,tiny_blitz_interface>();+ bench_static<Action_matrix_vector_product,tiny_blitz_interface>();++ return 0;+}++
+ eigen3/bench/btl/libs/blitz/tiny_blitz_interface.hh view
@@ -0,0 +1,106 @@+//=====================================================+// File : tiny_blitz_interface.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:30 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef TINY_BLITZ_INTERFACE_HH+#define TINY_BLITZ_INTERFACE_HH++#include "blitz/array.h"+#include "blitz/tiny.h"+#include "blitz/tinymat.h"+#include "blitz/tinyvec.h"+#include <blitz/tinyvec-et.h>++#include <vector>++BZ_USING_NAMESPACE(blitz)++template<class real, int SIZE>+class tiny_blitz_interface+{++public :++ typedef real real_type ;++ typedef std::vector<real> stl_vector;+ typedef std::vector<stl_vector > stl_matrix;++ typedef TinyVector<real,SIZE> gene_vector;+ typedef TinyMatrix<real,SIZE,SIZE> gene_matrix;++ static inline std::string name() { return "tiny_blitz"; }++ static void free_matrix(gene_matrix & A, int N){}++ static void free_vector(gene_vector & B){}++ static inline void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){+ for (int j=0; j<A_stl.size() ; j++)+ for (int i=0; i<A_stl[j].size() ; i++)+ A(i,j)=A_stl[j][i];+ }++ static inline void vector_from_stl(gene_vector & B, stl_vector & B_stl){+ for (int i=0; i<B_stl.size() ; i++)+ B(i) = B_stl[i];+ }++ static inline void vector_to_stl(gene_vector & B, stl_vector & B_stl){+ for (int i=0; i<B_stl.size() ; i++)+ B_stl[i] = B(i);+ }++ static inline void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){+ int N = A_stl.size();+ for (int j=0;j<N;j++)+ {+ A_stl[j].resize(N);+ for (int i=0;i<N;i++)+ A_stl[j][i] = A(i,j);+ }+ }++ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){+ for (int j=0;j<N;j++)+ for (int i=0;i<N;i++)+ cible(i,j) = source(i,j);+ }++ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){+ for (int i=0;i<N;i++){+ cible(i) = source(i);+ }+ }++ static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){+ X = product(A,B);+ }++ static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){+ X = product(A,B);+ }++ static inline void axpy(const real coef, const gene_vector & X, gene_vector & Y, int N){+ Y += coef * X;+ }++};+++#endif
+ eigen3/bench/btl/libs/eigen2/CMakeLists.txt view
@@ -0,0 +1,19 @@++find_package(Eigen2)++if(EIGEN2_FOUND)++ include_directories(BEFORE ${EIGEN2_INCLUDE_DIR})+ btl_add_bench(btl_eigen2_linear main_linear.cpp)+ btl_add_bench(btl_eigen2_vecmat main_vecmat.cpp)+ btl_add_bench(btl_eigen2_matmat main_matmat.cpp)+ btl_add_bench(btl_eigen2_adv main_adv.cpp )++ btl_add_target_property(btl_eigen2_linear COMPILE_FLAGS "-fno-exceptions -DBTL_PREFIX=eigen2")+ btl_add_target_property(btl_eigen2_vecmat COMPILE_FLAGS "-fno-exceptions -DBTL_PREFIX=eigen2")+ btl_add_target_property(btl_eigen2_matmat COMPILE_FLAGS "-fno-exceptions -DBTL_PREFIX=eigen2")+ btl_add_target_property(btl_eigen2_adv COMPILE_FLAGS "-fno-exceptions -DBTL_PREFIX=eigen2")++ btl_add_bench(btl_tiny_eigen2 btl_tiny_eigen2.cpp OFF)++endif() # EIGEN2_FOUND
+ eigen3/bench/btl/libs/eigen2/btl_tiny_eigen2.cpp view
@@ -0,0 +1,46 @@+//=====================================================+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "eigen3_interface.hh"+#include "static/bench_static.hh"+#include "action_matrix_vector_product.hh"+#include "action_matrix_matrix_product.hh"+#include "action_axpy.hh"+#include "action_lu_solve.hh"+#include "action_ata_product.hh"+#include "action_aat_product.hh"+#include "action_atv_product.hh"+#include "action_cholesky.hh"+#include "action_trisolve.hh"++BTL_MAIN;++int main()+{++ bench_static<Action_axpy,eigen2_interface>();+ bench_static<Action_matrix_matrix_product,eigen2_interface>();+ bench_static<Action_matrix_vector_product,eigen2_interface>();+ bench_static<Action_atv_product,eigen2_interface>();+ bench_static<Action_cholesky,eigen2_interface>();+ bench_static<Action_trisolve,eigen2_interface>();++ return 0;+}++
+ eigen3/bench/btl/libs/eigen2/eigen2_interface.hh view
@@ -0,0 +1,168 @@+//=====================================================+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef EIGEN2_INTERFACE_HH+#define EIGEN2_INTERFACE_HH+// #include <cblas.h>+#include <Eigen/Core>+#include <Eigen/Cholesky>+#include <Eigen/LU>+#include <Eigen/QR>+#include <vector>+#include "btl.hh"++using namespace Eigen;++template<class real, int SIZE=Dynamic>+class eigen2_interface+{++public :++ enum {IsFixedSize = (SIZE!=Dynamic)};++ typedef real real_type;++ typedef std::vector<real> stl_vector;+ typedef std::vector<stl_vector> stl_matrix;++ typedef Eigen::Matrix<real,SIZE,SIZE> gene_matrix;+ typedef Eigen::Matrix<real,SIZE,1> gene_vector;++ static inline std::string name( void )+ {+ #if defined(EIGEN_VECTORIZE_SSE)+ if (SIZE==Dynamic) return "eigen2"; else return "tiny_eigen2";+ #elif defined(EIGEN_VECTORIZE_ALTIVEC)+ if (SIZE==Dynamic) return "eigen2"; else return "tiny_eigen2";+ #else+ if (SIZE==Dynamic) return "eigen2_novec"; else return "tiny_eigen2_novec";+ #endif+ }++ static void free_matrix(gene_matrix & A, int N) {}++ static void free_vector(gene_vector & B) {}++ static BTL_DONT_INLINE void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){+ A.resize(A_stl[0].size(), A_stl.size());++ for (int j=0; j<A_stl.size() ; j++){+ for (int i=0; i<A_stl[j].size() ; i++){+ A.coeffRef(i,j) = A_stl[j][i];+ }+ }+ }++ static BTL_DONT_INLINE void vector_from_stl(gene_vector & B, stl_vector & B_stl){+ B.resize(B_stl.size(),1);++ for (int i=0; i<B_stl.size() ; i++){+ B.coeffRef(i) = B_stl[i];+ }+ }++ static BTL_DONT_INLINE void vector_to_stl(gene_vector & B, stl_vector & B_stl){+ for (int i=0; i<B_stl.size() ; i++){+ B_stl[i] = B.coeff(i);+ }+ }++ static BTL_DONT_INLINE void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){+ int N=A_stl.size();++ for (int j=0;j<N;j++){+ A_stl[j].resize(N);+ for (int i=0;i<N;i++){+ A_stl[j][i] = A.coeff(i,j);+ }+ }+ }++ static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){+ X = (A*B).lazy();+ }++ static inline void transposed_matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){+ X = (A.transpose()*B.transpose()).lazy();+ }++ static inline void ata_product(const gene_matrix & A, gene_matrix & X, int N){+ X = (A.transpose()*A).lazy();+ }++ static inline void aat_product(const gene_matrix & A, gene_matrix & X, int N){+ X = (A*A.transpose()).lazy();+ }++ static inline void matrix_vector_product(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N){+ X = (A*B)/*.lazy()*/;+ }++ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){+ X = (A.transpose()*B)/*.lazy()*/;+ }++ static inline void axpy(real coef, const gene_vector & X, gene_vector & Y, int N){+ Y += coef * X;+ }++ static inline void axpby(real a, const gene_vector & X, real b, gene_vector & Y, int N){+ Y = a*X + b*Y;+ }++ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){+ cible = source;+ }++ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){+ cible = source;+ }++ static inline void trisolve_lower(const gene_matrix & L, const gene_vector& B, gene_vector& X, int N){+ X = L.template marked<LowerTriangular>().solveTriangular(B);+ }++ static inline void trisolve_lower_matrix(const gene_matrix & L, const gene_matrix& B, gene_matrix& X, int N){+ X = L.template marked<LowerTriangular>().solveTriangular(B);+ }++ static inline void cholesky(const gene_matrix & X, gene_matrix & C, int N){+ C = X.llt().matrixL();+// C = X;+// Cholesky<gene_matrix>::computeInPlace(C);+// Cholesky<gene_matrix>::computeInPlaceBlock(C);+ }++ static inline void lu_decomp(const gene_matrix & X, gene_matrix & C, int N){+ C = X.lu().matrixLU();+// C = X.inverse();+ }++ static inline void tridiagonalization(const gene_matrix & X, gene_matrix & C, int N){+ C = Tridiagonalization<gene_matrix>(X).packedMatrix();+ }++ static inline void hessenberg(const gene_matrix & X, gene_matrix & C, int N){+ C = HessenbergDecomposition<gene_matrix>(X).packedMatrix();+ }++++};++#endif
+ eigen3/bench/btl/libs/eigen2/main_adv.cpp view
@@ -0,0 +1,44 @@+//=====================================================+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "eigen2_interface.hh"+#include "bench.hh"+#include "action_trisolve.hh"+#include "action_trisolve_matrix.hh"+#include "action_cholesky.hh"+#include "action_hessenberg.hh"+#include "action_lu_decomp.hh"+// #include "action_partial_lu.hh"++BTL_MAIN;++int main()+{+ bench<Action_trisolve<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_trisolve_matrix<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_cholesky<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_lu_decomp<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+// bench<Action_partial_lu<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ bench<Action_hessenberg<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_tridiagonalization<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ return 0;+}++
+ eigen3/bench/btl/libs/eigen2/main_linear.cpp view
@@ -0,0 +1,34 @@+//=====================================================+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "eigen2_interface.hh"+#include "bench.hh"+#include "basic_actions.hh"++BTL_MAIN;++int main()+{++ bench<Action_axpy<eigen2_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);+ bench<Action_axpby<eigen2_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);+ + return 0;+}++
+ eigen3/bench/btl/libs/eigen2/main_matmat.cpp view
@@ -0,0 +1,35 @@+//=====================================================+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "eigen2_interface.hh"+#include "bench.hh"+#include "basic_actions.hh"++BTL_MAIN;++int main()+{+ bench<Action_matrix_matrix_product<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+// bench<Action_ata_product<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_aat_product<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+// bench<Action_trmm<eigen2_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ return 0;+}++
+ eigen3/bench/btl/libs/eigen2/main_vecmat.cpp view
@@ -0,0 +1,36 @@+//=====================================================+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "eigen2_interface.hh"+#include "bench.hh"+#include "basic_actions.hh"++BTL_MAIN;++int main()+{+ bench<Action_matrix_vector_product<eigen2_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_atv_product<eigen2_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+// bench<Action_symv<eigen2_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+// bench<Action_syr2<eigen2_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+// bench<Action_ger<eigen2_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);++ return 0;+}++
+ eigen3/bench/btl/libs/eigen3/CMakeLists.txt view
@@ -0,0 +1,65 @@+++if((NOT EIGEN3_INCLUDE_DIR) AND Eigen_SOURCE_DIR)+ # unless EIGEN3_INCLUDE_DIR is defined, let's use current Eigen version+ set(EIGEN3_INCLUDE_DIR ${Eigen_SOURCE_DIR})+ set(EIGEN3_FOUND TRUE)+else()+ find_package(Eigen3)+endif()++if (EIGEN3_FOUND)++ include_directories(${EIGEN3_INCLUDE_DIR})+ btl_add_bench(btl_eigen3_linear main_linear.cpp)+ btl_add_bench(btl_eigen3_vecmat main_vecmat.cpp)+ btl_add_bench(btl_eigen3_matmat main_matmat.cpp)+ btl_add_bench(btl_eigen3_adv main_adv.cpp )++ btl_add_target_property(btl_eigen3_linear COMPILE_FLAGS "-fno-exceptions -DBTL_PREFIX=eigen3")+ btl_add_target_property(btl_eigen3_vecmat COMPILE_FLAGS "-fno-exceptions -DBTL_PREFIX=eigen3")+ btl_add_target_property(btl_eigen3_matmat COMPILE_FLAGS "-fno-exceptions -DBTL_PREFIX=eigen3")+ btl_add_target_property(btl_eigen3_adv COMPILE_FLAGS "-fno-exceptions -DBTL_PREFIX=eigen3")++ option(BTL_BENCH_NOGCCVEC "also bench Eigen explicit vec without GCC's auto vec" OFF)+ if(CMAKE_COMPILER_IS_GNUCXX AND BTL_BENCH_NOGCCVEC)+ btl_add_bench(btl_eigen3_nogccvec_linear main_linear.cpp)+ btl_add_bench(btl_eigen3_nogccvec_vecmat main_vecmat.cpp)+ btl_add_bench(btl_eigen3_nogccvec_matmat main_matmat.cpp)+ btl_add_bench(btl_eigen3_nogccvec_adv main_adv.cpp )++ btl_add_target_property(btl_eigen3_nogccvec_linear COMPILE_FLAGS "-fno-exceptions -fno-tree-vectorize -DBTL_PREFIX=eigen3_nogccvec")+ btl_add_target_property(btl_eigen3_nogccvec_vecmat COMPILE_FLAGS "-fno-exceptions -fno-tree-vectorize -DBTL_PREFIX=eigen3_nogccvec")+ btl_add_target_property(btl_eigen3_nogccvec_matmat COMPILE_FLAGS "-fno-exceptions -fno-tree-vectorize -DBTL_PREFIX=eigen3_nogccvec")+ btl_add_target_property(btl_eigen3_nogccvec_adv COMPILE_FLAGS "-fno-exceptions -fno-tree-vectorize -DBTL_PREFIX=eigen3_nogccvec")+ endif()+++ if(NOT BTL_NOVEC)+ btl_add_bench(btl_eigen3_novec_linear main_linear.cpp OFF)+ btl_add_bench(btl_eigen3_novec_vecmat main_vecmat.cpp OFF)+ btl_add_bench(btl_eigen3_novec_matmat main_matmat.cpp OFF)+ btl_add_bench(btl_eigen3_novec_adv main_adv.cpp OFF)+ btl_add_target_property(btl_eigen3_novec_linear COMPILE_FLAGS "-fno-exceptions -DEIGEN_DONT_VECTORIZE -DBTL_PREFIX=eigen3_novec")+ btl_add_target_property(btl_eigen3_novec_vecmat COMPILE_FLAGS "-fno-exceptions -DEIGEN_DONT_VECTORIZE -DBTL_PREFIX=eigen3_novec")+ btl_add_target_property(btl_eigen3_novec_matmat COMPILE_FLAGS "-fno-exceptions -DEIGEN_DONT_VECTORIZE -DBTL_PREFIX=eigen3_novec")+ btl_add_target_property(btl_eigen3_novec_adv COMPILE_FLAGS "-fno-exceptions -DEIGEN_DONT_VECTORIZE -DBTL_PREFIX=eigen3_novec")++# if(BUILD_btl_eigen3_adv)+# target_link_libraries(btl_eigen3_adv ${MKL_LIBRARIES})+# endif(BUILD_btl_eigen3_adv)++ endif(NOT BTL_NOVEC)++ btl_add_bench(btl_tiny_eigen3 btl_tiny_eigen3.cpp OFF)++ if(NOT BTL_NOVEC)+ btl_add_bench(btl_tiny_eigen3_novec btl_tiny_eigen3.cpp OFF)+ btl_add_target_property(btl_tiny_eigen3_novec COMPILE_FLAGS "-DBTL_PREFIX=eigen3_tiny")++ if(BUILD_btl_tiny_eigen3_novec)+ btl_add_target_property(btl_tiny_eigen3_novec COMPILE_FLAGS "-DEIGEN_DONT_VECTORIZE -DBTL_PREFIX=eigen3_tiny_novec")+ endif(BUILD_btl_tiny_eigen3_novec)+ endif(NOT BTL_NOVEC)++endif (EIGEN3_FOUND)
+ eigen3/bench/btl/libs/eigen3/btl_tiny_eigen3.cpp view
@@ -0,0 +1,46 @@+//=====================================================+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "eigen3_interface.hh"+#include "static/bench_static.hh"+#include "action_matrix_vector_product.hh"+#include "action_matrix_matrix_product.hh"+#include "action_axpy.hh"+#include "action_lu_solve.hh"+#include "action_ata_product.hh"+#include "action_aat_product.hh"+#include "action_atv_product.hh"+#include "action_cholesky.hh"+#include "action_trisolve.hh"++BTL_MAIN;++int main()+{++ bench_static<Action_axpy,eigen2_interface>();+ bench_static<Action_matrix_matrix_product,eigen2_interface>();+ bench_static<Action_matrix_vector_product,eigen2_interface>();+ bench_static<Action_atv_product,eigen2_interface>();+ bench_static<Action_cholesky,eigen2_interface>();+ bench_static<Action_trisolve,eigen2_interface>();++ return 0;+}++
+ eigen3/bench/btl/libs/eigen3/eigen3_interface.hh view
@@ -0,0 +1,240 @@+//=====================================================+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef EIGEN3_INTERFACE_HH+#define EIGEN3_INTERFACE_HH++#include <Eigen/Eigen>+#include <vector>+#include "btl.hh"++using namespace Eigen;++template<class real, int SIZE=Dynamic>+class eigen3_interface+{++public :++ enum {IsFixedSize = (SIZE!=Dynamic)};++ typedef real real_type;++ typedef std::vector<real> stl_vector;+ typedef std::vector<stl_vector> stl_matrix;++ typedef Eigen::Matrix<real,SIZE,SIZE> gene_matrix;+ typedef Eigen::Matrix<real,SIZE,1> gene_vector;++ static inline std::string name( void )+ {+ return EIGEN_MAKESTRING(BTL_PREFIX);+ }++ static void free_matrix(gene_matrix & A, int N) {}++ static void free_vector(gene_vector & B) {}++ static BTL_DONT_INLINE void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){+ A.resize(A_stl[0].size(), A_stl.size());++ for (int j=0; j<A_stl.size() ; j++){+ for (int i=0; i<A_stl[j].size() ; i++){+ A.coeffRef(i,j) = A_stl[j][i];+ }+ }+ }++ static BTL_DONT_INLINE void vector_from_stl(gene_vector & B, stl_vector & B_stl){+ B.resize(B_stl.size(),1);++ for (int i=0; i<B_stl.size() ; i++){+ B.coeffRef(i) = B_stl[i];+ }+ }++ static BTL_DONT_INLINE void vector_to_stl(gene_vector & B, stl_vector & B_stl){+ for (int i=0; i<B_stl.size() ; i++){+ B_stl[i] = B.coeff(i);+ }+ }++ static BTL_DONT_INLINE void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){+ int N=A_stl.size();++ for (int j=0;j<N;j++){+ A_stl[j].resize(N);+ for (int i=0;i<N;i++){+ A_stl[j][i] = A.coeff(i,j);+ }+ }+ }++ static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){+ X.noalias() = A*B;+ }++ static inline void transposed_matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){+ X.noalias() = A.transpose()*B.transpose();+ }++// static inline void ata_product(const gene_matrix & A, gene_matrix & X, int N){+// X.noalias() = A.transpose()*A;+// }++ static inline void aat_product(const gene_matrix & A, gene_matrix & X, int N){+ X.template triangularView<Lower>().setZero();+ X.template selfadjointView<Lower>().rankUpdate(A);+ }++ static inline void matrix_vector_product(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N){+ X.noalias() = A*B;+ }++ static inline void symv(const gene_matrix & A, const gene_vector & B, gene_vector & X, int N){+ X.noalias() = (A.template selfadjointView<Lower>() * B);+// internal::product_selfadjoint_vector<real,0,LowerTriangularBit,false,false>(N,A.data(),N, B.data(), 1, X.data(), 1);+ }++ template<typename Dest, typename Src> static void triassign(Dest& dst, const Src& src)+ {+ typedef typename Dest::Scalar Scalar;+ typedef typename internal::packet_traits<Scalar>::type Packet;+ const int PacketSize = sizeof(Packet)/sizeof(Scalar);+ int size = dst.cols();+ for(int j=0; j<size; j+=1)+ {+// const int alignedEnd = alignedStart + ((innerSize-alignedStart) & ~packetAlignedMask);+ Scalar* A0 = dst.data() + j*dst.stride();+ int starti = j;+ int alignedEnd = starti;+ int alignedStart = (starti) + internal::first_aligned(&A0[starti], size-starti);+ alignedEnd = alignedStart + ((size-alignedStart)/(2*PacketSize))*(PacketSize*2);++ // do the non-vectorizable part of the assignment+ for (int index = starti; index<alignedStart ; ++index)+ {+ if(Dest::Flags&RowMajorBit)+ dst.copyCoeff(j, index, src);+ else+ dst.copyCoeff(index, j, src);+ }++ // do the vectorizable part of the assignment+ for (int index = alignedStart; index<alignedEnd; index+=PacketSize)+ {+ if(Dest::Flags&RowMajorBit)+ dst.template copyPacket<Src, Aligned, Unaligned>(j, index, src);+ else+ dst.template copyPacket<Src, Aligned, Unaligned>(index, j, src);+ }++ // do the non-vectorizable part of the assignment+ for (int index = alignedEnd; index<size; ++index)+ {+ if(Dest::Flags&RowMajorBit)+ dst.copyCoeff(j, index, src);+ else+ dst.copyCoeff(index, j, src);+ }+ //dst.col(j).tail(N-j) = src.col(j).tail(N-j);+ }+ }++ static EIGEN_DONT_INLINE void syr2(gene_matrix & A, gene_vector & X, gene_vector & Y, int N){+ // internal::product_selfadjoint_rank2_update<real,0,LowerTriangularBit>(N,A.data(),N, X.data(), 1, Y.data(), 1, -1);+ for(int j=0; j<N; ++j)+ A.col(j).tail(N-j) += X[j] * Y.tail(N-j) + Y[j] * X.tail(N-j);+ }++ static EIGEN_DONT_INLINE void ger(gene_matrix & A, gene_vector & X, gene_vector & Y, int N){+ for(int j=0; j<N; ++j)+ A.col(j) += X * Y[j];+ }++ static EIGEN_DONT_INLINE void rot(gene_vector & A, gene_vector & B, real c, real s, int N){+ internal::apply_rotation_in_the_plane(A, B, JacobiRotation<real>(c,s));+ }++ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){+ X.noalias() = (A.transpose()*B);+ }++ static inline void axpy(real coef, const gene_vector & X, gene_vector & Y, int N){+ Y += coef * X;+ }++ static inline void axpby(real a, const gene_vector & X, real b, gene_vector & Y, int N){+ Y = a*X + b*Y;+ }++ static EIGEN_DONT_INLINE void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){+ cible = source;+ }++ static EIGEN_DONT_INLINE void copy_vector(const gene_vector & source, gene_vector & cible, int N){+ cible = source;+ }++ static inline void trisolve_lower(const gene_matrix & L, const gene_vector& B, gene_vector& X, int N){+ X = L.template triangularView<Lower>().solve(B);+ }++ static inline void trisolve_lower_matrix(const gene_matrix & L, const gene_matrix& B, gene_matrix& X, int N){+ X = L.template triangularView<Upper>().solve(B);+ }++ static inline void trmm(const gene_matrix & L, const gene_matrix& B, gene_matrix& X, int N){+ X.noalias() = L.template triangularView<Lower>() * B;+ }++ static inline void cholesky(const gene_matrix & X, gene_matrix & C, int N){+ C = X;+ internal::llt_inplace<real,Lower>::blocked(C);+ //C = X.llt().matrixL();+// C = X;+// Cholesky<gene_matrix>::computeInPlace(C);+// Cholesky<gene_matrix>::computeInPlaceBlock(C);+ }++ static inline void lu_decomp(const gene_matrix & X, gene_matrix & C, int N){+ C = X.fullPivLu().matrixLU();+ }++ static inline void partial_lu_decomp(const gene_matrix & X, gene_matrix & C, int N){+ Matrix<DenseIndex,1,Dynamic> piv(N);+ DenseIndex nb;+ C = X;+ internal::partial_lu_inplace(C,piv,nb);+// C = X.partialPivLu().matrixLU();+ }++ static inline void tridiagonalization(const gene_matrix & X, gene_matrix & C, int N){+ typename Tridiagonalization<gene_matrix>::CoeffVectorType aux(N-1);+ C = X;+ internal::tridiagonalization_inplace(C, aux);+ }++ static inline void hessenberg(const gene_matrix & X, gene_matrix & C, int N){+ C = HessenbergDecomposition<gene_matrix>(X).packedMatrix();+ }++++};++#endif
+ eigen3/bench/btl/libs/eigen3/main_adv.cpp view
@@ -0,0 +1,44 @@+//=====================================================+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "eigen3_interface.hh"+#include "bench.hh"+#include "action_trisolve.hh"+#include "action_trisolve_matrix.hh"+#include "action_cholesky.hh"+#include "action_hessenberg.hh"+#include "action_lu_decomp.hh"+#include "action_partial_lu.hh"++BTL_MAIN;++int main()+{+ bench<Action_trisolve<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_trisolve_matrix<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_cholesky<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_lu_decomp<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_partial_lu<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ bench<Action_hessenberg<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_tridiagonalization<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ return 0;+}++
+ eigen3/bench/btl/libs/eigen3/main_linear.cpp view
@@ -0,0 +1,35 @@+//=====================================================+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "eigen3_interface.hh"+#include "bench.hh"+#include "basic_actions.hh"++BTL_MAIN;++int main()+{++ bench<Action_axpy<eigen3_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);+ bench<Action_axpby<eigen3_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);+ bench<Action_rot<eigen3_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);+ + return 0;+}++
+ eigen3/bench/btl/libs/eigen3/main_matmat.cpp view
@@ -0,0 +1,35 @@+//=====================================================+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "eigen3_interface.hh"+#include "bench.hh"+#include "basic_actions.hh"++BTL_MAIN;++int main()+{+ bench<Action_matrix_matrix_product<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+// bench<Action_ata_product<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_aat_product<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_trmm<eigen3_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ return 0;+}++
+ eigen3/bench/btl/libs/eigen3/main_vecmat.cpp view
@@ -0,0 +1,36 @@+//=====================================================+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "eigen3_interface.hh"+#include "bench.hh"+#include "basic_actions.hh"++BTL_MAIN;++int main()+{+ bench<Action_matrix_vector_product<eigen3_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_atv_product<eigen3_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_symv<eigen3_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_syr2<eigen3_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_ger<eigen3_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);++ return 0;+}++
+ eigen3/bench/btl/libs/gmm/CMakeLists.txt view
@@ -0,0 +1,6 @@++find_package(GMM)+if (GMM_FOUND)+ include_directories(${GMM_INCLUDES})+ btl_add_bench(btl_gmm main.cpp)+endif (GMM_FOUND)
+ eigen3/bench/btl/libs/gmm/gmm_LU_solve_interface.hh view
@@ -0,0 +1,192 @@+//=====================================================+// File : blitz_LU_solve_interface.hh+// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:31 CEST 2002+//=====================================================+// +// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+// +// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+// +#ifndef BLITZ_LU_SOLVE_INTERFACE_HH+#define BLITZ_LU_SOLVE_INTERFACE_HH++#include "blitz/array.h"+#include <vector>++BZ_USING_NAMESPACE(blitz)++template<class real>+class blitz_LU_solve_interface : public blitz_interface<real>+{++public :++ typedef typename blitz_interface<real>::gene_matrix gene_matrix;+ typedef typename blitz_interface<real>::gene_vector gene_vector;++ typedef blitz::Array<int,1> Pivot_Vector;++ inline static void new_Pivot_Vector(Pivot_Vector & pivot,int N)+ {++ pivot.resize(N);++ }++ inline static void free_Pivot_Vector(Pivot_Vector & pivot)+ {+ + return;++ }+++ static inline real matrix_vector_product_sliced(const gene_matrix & A, gene_vector B, int row, int col_start, int col_end)+ {+ + real somme=0.;+ + for (int j=col_start ; j<col_end+1 ; j++){+ + somme+=A(row,j)*B(j);+ + }++ return somme;++ }+++++ static inline real matrix_matrix_product_sliced(gene_matrix & A, int row, int col_start, int col_end, gene_matrix & B, int row_shift, int col )+ {+ + real somme=0.;+ + for (int j=col_start ; j<col_end+1 ; j++){+ + somme+=A(row,j)*B(j+row_shift,col);+ + }++ return somme;++ }++ inline static void LU_factor(gene_matrix & LU, Pivot_Vector & pivot, int N)+ {++ ASSERT( LU.rows()==LU.cols() ) ;+ int index_max = 0 ;+ real big = 0. ;+ real theSum = 0. ;+ real dum = 0. ;+ // Get the implicit scaling information :+ gene_vector ImplicitScaling( N ) ;+ for( int i=0; i<N; i++ ) {+ big = 0. ;+ for( int j=0; j<N; j++ ) {+ if( abs( LU( i, j ) )>=big ) big = abs( LU( i, j ) ) ;+ }+ if( big==0. ) {+ INFOS( "blitz_LU_factor::Singular matrix" ) ;+ exit( 0 ) ;+ }+ ImplicitScaling( i ) = 1./big ;+ }+ // Loop over columns of Crout's method :+ for( int j=0; j<N; j++ ) {+ for( int i=0; i<j; i++ ) {+ theSum = LU( i, j ) ;+ theSum -= matrix_matrix_product_sliced(LU, i, 0, i-1, LU, 0, j) ;+ // theSum -= sum( LU( i, Range( fromStart, i-1 ) )*LU( Range( fromStart, i-1 ), j ) ) ;+ LU( i, j ) = theSum ;+ }+ + // Search for the largest pivot element :+ big = 0. ;+ for( int i=j; i<N; i++ ) {+ theSum = LU( i, j ) ;+ theSum -= matrix_matrix_product_sliced(LU, i, 0, j-1, LU, 0, j) ;+ // theSum -= sum( LU( i, Range( fromStart, j-1 ) )*LU( Range( fromStart, j-1 ), j ) ) ;+ LU( i, j ) = theSum ;+ if( (ImplicitScaling( i )*abs( theSum ))>=big ) {+ dum = ImplicitScaling( i )*abs( theSum ) ;+ big = dum ;+ index_max = i ;+ }+ }+ // Interchanging rows and the scale factor :+ if( j!=index_max ) {+ for( int k=0; k<N; k++ ) {+ dum = LU( index_max, k ) ;+ LU( index_max, k ) = LU( j, k ) ;+ LU( j, k ) = dum ;+ }+ ImplicitScaling( index_max ) = ImplicitScaling( j ) ;+ }+ pivot( j ) = index_max ;+ if ( LU( j, j )==0. ) LU( j, j ) = 1.e-20 ;+ // Divide by the pivot element :+ if( j<N ) {+ dum = 1./LU( j, j ) ;+ for( int i=j+1; i<N; i++ ) LU( i, j ) *= dum ;+ }+ }++ }++ inline static void LU_solve(const gene_matrix & LU, const Pivot_Vector pivot, gene_vector &B, gene_vector X, int N)+ {++ // Pour conserver le meme header, on travaille sur X, copie du second-membre B+ X = B.copy() ;+ ASSERT( LU.rows()==LU.cols() ) ;+ firstIndex indI ;+ // Forward substitution :+ int ii = 0 ;+ real theSum = 0. ;+ for( int i=0; i<N; i++ ) {+ int ip = pivot( i ) ;+ theSum = X( ip ) ;+ // theSum = B( ip ) ;+ X( ip ) = X( i ) ;+ // B( ip ) = B( i ) ;+ if( ii ) {+ theSum -= matrix_vector_product_sliced(LU, X, i, ii-1, i-1) ;+ // theSum -= sum( LU( i, Range( ii-1, i-1 ) )*X( Range( ii-1, i-1 ) ) ) ;+ // theSum -= sum( LU( i, Range( ii-1, i-1 ) )*B( Range( ii-1, i-1 ) ) ) ;+ } else if( theSum ) {+ ii = i+1 ;+ }+ X( i ) = theSum ;+ // B( i ) = theSum ;+ }+ // Backsubstitution :+ for( int i=N-1; i>=0; i-- ) {+ theSum = X( i ) ;+ // theSum = B( i ) ;+ theSum -= matrix_vector_product_sliced(LU, X, i, i+1, N) ;+ // theSum -= sum( LU( i, Range( i+1, toEnd ) )*X( Range( i+1, toEnd ) ) ) ;+ // theSum -= sum( LU( i, Range( i+1, toEnd ) )*B( Range( i+1, toEnd ) ) ) ;+ // Store a component of the solution vector :+ X( i ) = theSum/LU( i, i ) ;+ // B( i ) = theSum/LU( i, i ) ;+ }++ }++};++#endif
+ eigen3/bench/btl/libs/gmm/gmm_interface.hh view
@@ -0,0 +1,144 @@+//=====================================================+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef GMM_INTERFACE_HH+#define GMM_INTERFACE_HH++#include <gmm/gmm.h>+#include <vector>++using namespace gmm;++template<class real>+class gmm_interface {++public :++ typedef real real_type ;++ typedef std::vector<real> stl_vector;+ typedef std::vector<stl_vector > stl_matrix;++ typedef gmm::dense_matrix<real> gene_matrix;+ typedef stl_vector gene_vector;++ static inline std::string name( void )+ {+ return "gmm";+ }++ static void free_matrix(gene_matrix & A, int N){+ return ;+ }++ static void free_vector(gene_vector & B){+ return ;+ }++ static inline void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){+ A.resize(A_stl[0].size(),A_stl.size());++ for (int j=0; j<A_stl.size() ; j++){+ for (int i=0; i<A_stl[j].size() ; i++){+ A(i,j) = A_stl[j][i];+ }+ }+ }++ static inline void vector_from_stl(gene_vector & B, stl_vector & B_stl){+ B = B_stl;+ }++ static inline void vector_to_stl(gene_vector & B, stl_vector & B_stl){+ B_stl = B;+ }++ static inline void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){+ int N=A_stl.size();++ for (int j=0;j<N;j++){+ A_stl[j].resize(N);+ for (int i=0;i<N;i++){+ A_stl[j][i] = A(i,j);+ }+ }+ }++ static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){+ gmm::mult(A,B, X);+ }++ static inline void transposed_matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){+ gmm::mult(gmm::transposed(A),gmm::transposed(B), X);+ }++ static inline void ata_product(const gene_matrix & A, gene_matrix & X, int N){+ gmm::mult(gmm::transposed(A),A, X);+ }++ static inline void aat_product(const gene_matrix & A, gene_matrix & X, int N){+ gmm::mult(A,gmm::transposed(A), X);+ }++ static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){+ gmm::mult(A,B,X);+ }++ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){+ gmm::mult(gmm::transposed(A),B,X);+ }++ static inline void axpy(const real coef, const gene_vector & X, gene_vector & Y, int N){+ gmm::add(gmm::scaled(X,coef), Y);+ }++ static inline void axpby(real a, const gene_vector & X, real b, gene_vector & Y, int N){+ gmm::add(gmm::scaled(X,a), gmm::scaled(Y,b), Y);+ }++ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){+ gmm::copy(source,cible);+ }++ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){+ gmm::copy(source,cible);+ }++ static inline void trisolve_lower(const gene_matrix & L, const gene_vector& B, gene_vector & X, int N){+ gmm::copy(B,X);+ gmm::lower_tri_solve(L, X, false);+ }++ static inline void partial_lu_decomp(const gene_matrix & X, gene_matrix & R, int N){+ gmm::copy(X,R);+ std::vector<int> ipvt(N);+ gmm::lu_factor(R, ipvt);+ }++ static inline void hessenberg(const gene_matrix & X, gene_matrix & R, int N){+ gmm::copy(X,R);+ gmm::Hessenberg_reduction(R,X,false);+ }++ static inline void tridiagonalization(const gene_matrix & X, gene_matrix & R, int N){+ gmm::copy(X,R);+ gmm::Householder_tridiagonalization(R,X,false);+ }++};++#endif
+ eigen3/bench/btl/libs/gmm/main.cpp view
@@ -0,0 +1,51 @@+//=====================================================+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "gmm_interface.hh"+#include "bench.hh"+#include "basic_actions.hh"+#include "action_hessenberg.hh"+#include "action_partial_lu.hh"++BTL_MAIN;++int main()+{++ bench<Action_axpy<gmm_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);+ bench<Action_axpby<gmm_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);++ bench<Action_matrix_vector_product<gmm_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_atv_product<gmm_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);++ bench<Action_matrix_matrix_product<gmm_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+// bench<Action_ata_product<gmm_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+// bench<Action_aat_product<gmm_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ bench<Action_trisolve<gmm_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ //bench<Action_lu_solve<blitz_LU_solve_interface<REAL_TYPE> > >(MIN_LU,MAX_LU,NB_POINT);++ bench<Action_partial_lu<gmm_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ + bench<Action_hessenberg<gmm_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+ bench<Action_tridiagonalization<gmm_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ return 0;+}++
+ eigen3/bench/btl/libs/mtl4/.kdbgrc.main view
@@ -0,0 +1,12 @@+[General]+DebuggerCmdStr=+DriverName=GDB+FileVersion=1+OptionsSelected=+ProgramArgs=+TTYLevel=7+WorkingDirectory=++[Memory]+ColumnWidths=80,0+NumExprs=0
+ eigen3/bench/btl/libs/mtl4/CMakeLists.txt view
@@ -0,0 +1,6 @@++find_package(MTL4)+if (MTL4_FOUND)+ include_directories(${MTL4_INCLUDE_DIR})+ btl_add_bench(btl_mtl4 main.cpp)+endif (MTL4_FOUND)
+ eigen3/bench/btl/libs/mtl4/main.cpp view
@@ -0,0 +1,46 @@+//=====================================================+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "mtl4_interface.hh"+#include "bench.hh"+#include "basic_actions.hh"+#include "action_cholesky.hh"+// #include "action_lu_decomp.hh"++BTL_MAIN;++int main()+{++ bench<Action_axpy<mtl4_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);+ bench<Action_axpby<mtl4_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);++ bench<Action_matrix_vector_product<mtl4_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_atv_product<mtl4_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_matrix_matrix_product<mtl4_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+// bench<Action_ata_product<mtl4_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+// bench<Action_aat_product<mtl4_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ bench<Action_trisolve<mtl4_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+// bench<Action_cholesky<mtl4_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+// bench<Action_lu_decomp<mtl4_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ return 0;+}++
+ eigen3/bench/btl/libs/mtl4/mtl4_LU_solve_interface.hh view
@@ -0,0 +1,192 @@+//=====================================================+// File : blitz_LU_solve_interface.hh+// Author : L. Plagne <laurent.plagne@edf.fr)> +// Copyright (C) EDF R&D, lun sep 30 14:23:31 CEST 2002+//=====================================================+// +// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+// +// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+// +#ifndef BLITZ_LU_SOLVE_INTERFACE_HH+#define BLITZ_LU_SOLVE_INTERFACE_HH++#include "blitz/array.h"+#include <vector>++BZ_USING_NAMESPACE(blitz)++template<class real>+class blitz_LU_solve_interface : public blitz_interface<real>+{++public :++ typedef typename blitz_interface<real>::gene_matrix gene_matrix;+ typedef typename blitz_interface<real>::gene_vector gene_vector;++ typedef blitz::Array<int,1> Pivot_Vector;++ inline static void new_Pivot_Vector(Pivot_Vector & pivot,int N)+ {++ pivot.resize(N);++ }++ inline static void free_Pivot_Vector(Pivot_Vector & pivot)+ {+ + return;++ }+++ static inline real matrix_vector_product_sliced(const gene_matrix & A, gene_vector B, int row, int col_start, int col_end)+ {+ + real somme=0.;+ + for (int j=col_start ; j<col_end+1 ; j++){+ + somme+=A(row,j)*B(j);+ + }++ return somme;++ }+++++ static inline real matrix_matrix_product_sliced(gene_matrix & A, int row, int col_start, int col_end, gene_matrix & B, int row_shift, int col )+ {+ + real somme=0.;+ + for (int j=col_start ; j<col_end+1 ; j++){+ + somme+=A(row,j)*B(j+row_shift,col);+ + }++ return somme;++ }++ inline static void LU_factor(gene_matrix & LU, Pivot_Vector & pivot, int N)+ {++ ASSERT( LU.rows()==LU.cols() ) ;+ int index_max = 0 ;+ real big = 0. ;+ real theSum = 0. ;+ real dum = 0. ;+ // Get the implicit scaling information :+ gene_vector ImplicitScaling( N ) ;+ for( int i=0; i<N; i++ ) {+ big = 0. ;+ for( int j=0; j<N; j++ ) {+ if( abs( LU( i, j ) )>=big ) big = abs( LU( i, j ) ) ;+ }+ if( big==0. ) {+ INFOS( "blitz_LU_factor::Singular matrix" ) ;+ exit( 0 ) ;+ }+ ImplicitScaling( i ) = 1./big ;+ }+ // Loop over columns of Crout's method :+ for( int j=0; j<N; j++ ) {+ for( int i=0; i<j; i++ ) {+ theSum = LU( i, j ) ;+ theSum -= matrix_matrix_product_sliced(LU, i, 0, i-1, LU, 0, j) ;+ // theSum -= sum( LU( i, Range( fromStart, i-1 ) )*LU( Range( fromStart, i-1 ), j ) ) ;+ LU( i, j ) = theSum ;+ }+ + // Search for the largest pivot element :+ big = 0. ;+ for( int i=j; i<N; i++ ) {+ theSum = LU( i, j ) ;+ theSum -= matrix_matrix_product_sliced(LU, i, 0, j-1, LU, 0, j) ;+ // theSum -= sum( LU( i, Range( fromStart, j-1 ) )*LU( Range( fromStart, j-1 ), j ) ) ;+ LU( i, j ) = theSum ;+ if( (ImplicitScaling( i )*abs( theSum ))>=big ) {+ dum = ImplicitScaling( i )*abs( theSum ) ;+ big = dum ;+ index_max = i ;+ }+ }+ // Interchanging rows and the scale factor :+ if( j!=index_max ) {+ for( int k=0; k<N; k++ ) {+ dum = LU( index_max, k ) ;+ LU( index_max, k ) = LU( j, k ) ;+ LU( j, k ) = dum ;+ }+ ImplicitScaling( index_max ) = ImplicitScaling( j ) ;+ }+ pivot( j ) = index_max ;+ if ( LU( j, j )==0. ) LU( j, j ) = 1.e-20 ;+ // Divide by the pivot element :+ if( j<N ) {+ dum = 1./LU( j, j ) ;+ for( int i=j+1; i<N; i++ ) LU( i, j ) *= dum ;+ }+ }++ }++ inline static void LU_solve(const gene_matrix & LU, const Pivot_Vector pivot, gene_vector &B, gene_vector X, int N)+ {++ // Pour conserver le meme header, on travaille sur X, copie du second-membre B+ X = B.copy() ;+ ASSERT( LU.rows()==LU.cols() ) ;+ firstIndex indI ;+ // Forward substitution :+ int ii = 0 ;+ real theSum = 0. ;+ for( int i=0; i<N; i++ ) {+ int ip = pivot( i ) ;+ theSum = X( ip ) ;+ // theSum = B( ip ) ;+ X( ip ) = X( i ) ;+ // B( ip ) = B( i ) ;+ if( ii ) {+ theSum -= matrix_vector_product_sliced(LU, X, i, ii-1, i-1) ;+ // theSum -= sum( LU( i, Range( ii-1, i-1 ) )*X( Range( ii-1, i-1 ) ) ) ;+ // theSum -= sum( LU( i, Range( ii-1, i-1 ) )*B( Range( ii-1, i-1 ) ) ) ;+ } else if( theSum ) {+ ii = i+1 ;+ }+ X( i ) = theSum ;+ // B( i ) = theSum ;+ }+ // Backsubstitution :+ for( int i=N-1; i>=0; i-- ) {+ theSum = X( i ) ;+ // theSum = B( i ) ;+ theSum -= matrix_vector_product_sliced(LU, X, i, i+1, N) ;+ // theSum -= sum( LU( i, Range( i+1, toEnd ) )*X( Range( i+1, toEnd ) ) ) ;+ // theSum -= sum( LU( i, Range( i+1, toEnd ) )*B( Range( i+1, toEnd ) ) ) ;+ // Store a component of the solution vector :+ X( i ) = theSum/LU( i, i ) ;+ // B( i ) = theSum/LU( i, i ) ;+ }++ }++};++#endif
+ eigen3/bench/btl/libs/mtl4/mtl4_interface.hh view
@@ -0,0 +1,144 @@+//=====================================================+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef MTL4_INTERFACE_HH+#define MTL4_INTERFACE_HH++#include <boost/numeric/mtl/mtl.hpp>+#include <boost/numeric/mtl/utility/range_generator.hpp>+// #include <boost/numeric/mtl/operation/cholesky.hpp>+#include <vector>++using namespace mtl;++template<class real>+class mtl4_interface {++public :++ typedef real real_type ;++ typedef std::vector<real> stl_vector;+ typedef std::vector<stl_vector > stl_matrix;++ typedef mtl::dense2D<real, mtl::matrix::parameters<mtl::tag::col_major> > gene_matrix;+ typedef mtl::dense_vector<real> gene_vector;++ static inline std::string name() { return "mtl4"; }++ static void free_matrix(gene_matrix & A, int N){+ return ;+ }++ static void free_vector(gene_vector & B){+ return ;+ }++ static inline void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){+ A.change_dim(A_stl[0].size(), A_stl.size());++ for (int j=0; j<A_stl.size() ; j++){+ for (int i=0; i<A_stl[j].size() ; i++){+ A(i,j) = A_stl[j][i];+ }+ }+ }++ static inline void vector_from_stl(gene_vector & B, stl_vector & B_stl){+ B.change_dim(B_stl.size());+ for (int i=0; i<B_stl.size() ; i++){+ B[i] = B_stl[i];+ }+ }++ static inline void vector_to_stl(gene_vector & B, stl_vector & B_stl){+ for (int i=0; i<B_stl.size() ; i++){+ B_stl[i] = B[i];+ }+ }++ static inline void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){+ int N=A_stl.size();+ for (int j=0;j<N;j++){+ A_stl[j].resize(N);+ for (int i=0;i<N;i++){+ A_stl[j][i] = A(i,j);+ }+ }+ }++ static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){+ X = (A*B);+// morton_dense<double, doppled_64_row_mask> C(N,N);+// C = B;+// X = (A*C);+ }++ static inline void transposed_matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){+ X = (trans(A)*trans(B));+ }++// static inline void ata_product(const gene_matrix & A, gene_matrix & X, int N){+// X = (trans(A)*A);+// }++ static inline void aat_product(const gene_matrix & A, gene_matrix & X, int N){+ X = (A*trans(A));+ }++ static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){+ X = (A*B);+ }++ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){+ X = (trans(A)*B);+ }++ static inline void axpy(const real coef, const gene_vector & X, gene_vector & Y, int N){+ Y += coef * X;+ }++ static inline void axpby(real a, const gene_vector & X, real b, gene_vector & Y, int N){+ Y = a*X + b*Y;+ }++// static inline void cholesky(const gene_matrix & X, gene_matrix & C, int N){+// C = X;+// recursive_cholesky(C);+// }++// static inline void lu_decomp(const gene_matrix & X, gene_matrix & R, int N){+// R = X;+// std::vector<int> ipvt(N);+// lu_factor(R, ipvt);+// }++ static inline void trisolve_lower(const gene_matrix & L, const gene_vector& B, gene_vector & X, int N){+ X = lower_trisolve(L, B);+ }++ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){+ cible = source;+ }++ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){+ cible = source;+ }++};++#endif
+ eigen3/bench/btl/libs/tvmet/CMakeLists.txt view
@@ -0,0 +1,6 @@++find_package(Tvmet)+if (TVMET_FOUND)+ include_directories(${TVMET_INCLUDE_DIR})+ btl_add_bench(btl_tvmet main.cpp OFF)+endif (TVMET_FOUND)
+ eigen3/bench/btl/libs/tvmet/main.cpp view
@@ -0,0 +1,40 @@+//=====================================================+// File : main.cpp+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:30 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "tvmet_interface.hh"+#include "static/bench_static.hh"+#include "action_matrix_vector_product.hh"+#include "action_matrix_matrix_product.hh"+#include "action_atv_product.hh"+#include "action_axpy.hh"++BTL_MAIN;++int main()+{+ bench_static<Action_axpy,tvmet_interface>();+ bench_static<Action_matrix_matrix_product,tvmet_interface>();+ bench_static<Action_matrix_vector_product,tvmet_interface>();+ bench_static<Action_atv_product,tvmet_interface>();++ return 0;+}++
+ eigen3/bench/btl/libs/tvmet/tvmet_interface.hh view
@@ -0,0 +1,104 @@+//=====================================================+// File : tvmet_interface.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:30 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef TVMET_INTERFACE_HH+#define TVMET_INTERFACE_HH++#include <tvmet/tvmet.h>+#include <tvmet/Vector.h>+#include <tvmet/Matrix.h>++#include <vector>++using namespace tvmet;++template<class real, int SIZE>+class tvmet_interface{++public :++ typedef real real_type ;++ typedef std::vector<real> stl_vector;+ typedef std::vector<stl_vector > stl_matrix;++ typedef Vector<real,SIZE> gene_vector;+ typedef Matrix<real,SIZE,SIZE> gene_matrix;++ static inline std::string name() { return "tiny_tvmet"; }++ static void free_matrix(gene_matrix & A, int N){}++ static void free_vector(gene_vector & B){}++ static inline void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){+ for (int j=0; j<A_stl.size() ; j++)+ for (int i=0; i<A_stl[j].size() ; i++)+ A(i,j) = A_stl[j][i];+ }++ static inline void vector_from_stl(gene_vector & B, stl_vector & B_stl){+ for (int i=0; i<B_stl.size() ; i++)+ B[i]=B_stl[i];+ }++ static inline void vector_to_stl(gene_vector & B, stl_vector & B_stl){+ for (int i=0; i<B_stl.size() ; i++){+ B_stl[i]=B[i];+ }+ }++ static inline void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){+ int N = A_stl.size();+ for (int j=0;j<N;j++){+ A_stl[j].resize(N);+ for (int i=0;i<N;i++)+ A_stl[j][i] = A(i,j);+ }+ }+++ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){+ cible = source;+ }++ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){+ cible = source;+ }++ static inline void matrix_matrix_product(const gene_matrix & A, const gene_matrix & B, gene_matrix & X, int N){+ X = prod(A,B);+ }++ static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){+ X = prod(A,B);+ }++ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){+ X = prod(trans(A),B);+ }++ static inline void axpy(const real coef, const gene_vector & X, gene_vector & Y, int N){+ Y+=coef*X;+ }++};+++#endif
+ eigen3/bench/btl/libs/ublas/CMakeLists.txt view
@@ -0,0 +1,7 @@++find_package(Boost)+if (Boost_FOUND)+ include_directories(${Boost_INCLUDE_DIRS})+ include_directories(${Boost_INCLUDES})+ btl_add_bench(btl_ublas main.cpp)+endif (Boost_FOUND)
+ eigen3/bench/btl/libs/ublas/main.cpp view
@@ -0,0 +1,44 @@+//=====================================================+// File : main.cpp+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:27 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#include "utilities.h"+#include "ublas_interface.hh"+#include "bench.hh"+#include "basic_actions.hh"++BTL_MAIN;++int main()+{+ bench<Action_axpy<ublas_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);+ bench<Action_axpby<ublas_interface<REAL_TYPE> > >(MIN_AXPY,MAX_AXPY,NB_POINT);++ bench<Action_matrix_vector_product<ublas_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);+ bench<Action_atv_product<ublas_interface<REAL_TYPE> > >(MIN_MV,MAX_MV,NB_POINT);++ bench<Action_matrix_matrix_product<ublas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+// bench<Action_ata_product<ublas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);+// bench<Action_aat_product<ublas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ bench<Action_trisolve<ublas_interface<REAL_TYPE> > >(MIN_MM,MAX_MM,NB_POINT);++ return 0;+}++
+ eigen3/bench/btl/libs/ublas/ublas_interface.hh view
@@ -0,0 +1,141 @@+//=====================================================+// File : ublas_interface.hh+// Author : L. Plagne <laurent.plagne@edf.fr)>+// Copyright (C) EDF R&D, lun sep 30 14:23:27 CEST 2002+//=====================================================+//+// This program is free software; you can redistribute it and/or+// modify it under the terms of the GNU General Public License+// as published by the Free Software Foundation; either version 2+// of the License, or (at your option) any later version.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU General Public License for more details.+// You should have received a copy of the GNU General Public License+// along with this program; if not, write to the Free Software+// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.+//+#ifndef UBLAS_INTERFACE_HH+#define UBLAS_INTERFACE_HH++#include <boost/numeric/ublas/vector.hpp>+#include <boost/numeric/ublas/matrix.hpp>+#include <boost/numeric/ublas/io.hpp>+#include <boost/numeric/ublas/triangular.hpp>++using namespace boost::numeric;++template <class real>+class ublas_interface{++public :++ typedef real real_type ;++ typedef std::vector<real> stl_vector;+ typedef std::vector<stl_vector> stl_matrix;++ typedef typename boost::numeric::ublas::matrix<real,boost::numeric::ublas::column_major> gene_matrix;+ typedef typename boost::numeric::ublas::vector<real> gene_vector;++ static inline std::string name( void ) { return "ublas"; }++ static void free_matrix(gene_matrix & A, int N) {}++ static void free_vector(gene_vector & B) {}++ static inline void matrix_from_stl(gene_matrix & A, stl_matrix & A_stl){+ A.resize(A_stl.size(),A_stl[0].size());+ for (int j=0; j<A_stl.size() ; j++)+ for (int i=0; i<A_stl[j].size() ; i++)+ A(i,j)=A_stl[j][i];+ }++ static inline void vector_from_stl(gene_vector & B, stl_vector & B_stl){+ B.resize(B_stl.size());+ for (int i=0; i<B_stl.size() ; i++)+ B(i)=B_stl[i];+ }++ static inline void vector_to_stl(gene_vector & B, stl_vector & B_stl){+ for (int i=0; i<B_stl.size() ; i++)+ B_stl[i]=B(i);+ }++ static inline void matrix_to_stl(gene_matrix & A, stl_matrix & A_stl){+ int N=A_stl.size();+ for (int j=0;j<N;j++)+ {+ A_stl[j].resize(N);+ for (int i=0;i<N;i++)+ A_stl[j][i]=A(i,j);+ }+ }++ static inline void copy_vector(const gene_vector & source, gene_vector & cible, int N){+ for (int i=0;i<N;i++){+ cible(i) = source(i);+ }+ }++ static inline void copy_matrix(const gene_matrix & source, gene_matrix & cible, int N){+ for (int i=0;i<N;i++){+ for (int j=0;j<N;j++){+ cible(i,j) = source(i,j);+ }+ }+ }++ static inline void matrix_vector_product_slow(gene_matrix & A, gene_vector & B, gene_vector & X, int N){+ X = prod(A,B);+ }++ static inline void matrix_matrix_product_slow(gene_matrix & A, gene_matrix & B, gene_matrix & X, int N){+ X = prod(A,B);+ }++ static inline void axpy_slow(const real coef, const gene_vector & X, gene_vector & Y, int N){+ Y+=coef*X;+ }++ // alias free assignements++ static inline void matrix_vector_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){+ X.assign(prod(A,B));+ }++ static inline void atv_product(gene_matrix & A, gene_vector & B, gene_vector & X, int N){+ X.assign(prod(trans(A),B));+ }++ static inline void matrix_matrix_product(gene_matrix & A, gene_matrix & B, gene_matrix & X, int N){+ X.assign(prod(A,B));+ }++ static inline void axpy(const real coef, const gene_vector & X, gene_vector & Y, int N){+ Y.plus_assign(coef*X);+ }++ static inline void axpby(real a, const gene_vector & X, real b, gene_vector & Y, int N){+ Y = a*X + b*Y;+ }++ static inline void ata_product(gene_matrix & A, gene_matrix & X, int N){+ // X = prod(trans(A),A);+ X.assign(prod(trans(A),A));+ }++ static inline void aat_product(gene_matrix & A, gene_matrix & X, int N){+ // X = prod(A,trans(A));+ X.assign(prod(A,trans(A)));+ }++ static inline void trisolve_lower(const gene_matrix & L, const gene_vector& B, gene_vector & X, int N){+ X = solve(L, B, ublas::lower_tag ());+ }++};++#endif
+ eigen3/bench/check_cache_queries.cpp view
@@ -0,0 +1,101 @@++#define EIGEN_INTERNAL_DEBUG_CACHE_QUERY+#include <iostream>+#include "../Eigen/Core"++using namespace Eigen;+using namespace std;++#define DUMP_CPUID(CODE) {\+ int abcd[4]; \+ abcd[0] = abcd[1] = abcd[2] = abcd[3] = 0;\+ EIGEN_CPUID(abcd, CODE, 0); \+ std::cout << "The code " << CODE << " gives " \+ << (int*)(abcd[0]) << " " << (int*)(abcd[1]) << " " \+ << (int*)(abcd[2]) << " " << (int*)(abcd[3]) << " " << std::endl; \+ }+ +int main()+{+ cout << "Eigen's L1 = " << internal::queryL1CacheSize() << endl;+ cout << "Eigen's L2/L3 = " << internal::queryTopLevelCacheSize() << endl;+ int l1, l2, l3;+ internal::queryCacheSizes(l1, l2, l3);+ cout << "Eigen's L1, L2, L3 = " << l1 << " " << l2 << " " << l3 << endl;+ + #ifdef EIGEN_CPUID++ int abcd[4];+ int string[8];+ char* string_char = (char*)(string);++ // vendor ID+ EIGEN_CPUID(abcd,0x0,0);+ string[0] = abcd[1];+ string[1] = abcd[3];+ string[2] = abcd[2];+ string[3] = 0;+ cout << endl;+ cout << "vendor id = " << string_char << endl;+ cout << endl;+ int max_funcs = abcd[0];++ internal::queryCacheSizes_intel_codes(l1, l2, l3);+ cout << "Eigen's intel codes L1, L2, L3 = " << l1 << " " << l2 << " " << l3 << endl;+ if(max_funcs>=4)+ {+ internal::queryCacheSizes_intel_direct(l1, l2, l3);+ cout << "Eigen's intel direct L1, L2, L3 = " << l1 << " " << l2 << " " << l3 << endl;+ }+ internal::queryCacheSizes_amd(l1, l2, l3);+ cout << "Eigen's amd L1, L2, L3 = " << l1 << " " << l2 << " " << l3 << endl;+ cout << endl;+ + // dump Intel direct method+ if(max_funcs>=4)+ {+ l1 = l2 = l3 = 0;+ int cache_id = 0;+ int cache_type = 0;+ do {+ abcd[0] = abcd[1] = abcd[2] = abcd[3] = 0;+ EIGEN_CPUID(abcd,0x4,cache_id);+ cache_type = (abcd[0] & 0x0F) >> 0;+ int cache_level = (abcd[0] & 0xE0) >> 5; // A[7:5]+ int ways = (abcd[1] & 0xFFC00000) >> 22; // B[31:22]+ int partitions = (abcd[1] & 0x003FF000) >> 12; // B[21:12]+ int line_size = (abcd[1] & 0x00000FFF) >> 0; // B[11:0]+ int sets = (abcd[2]); // C[31:0]+ int cache_size = (ways+1) * (partitions+1) * (line_size+1) * (sets+1);+ + cout << "cache[" << cache_id << "].type = " << cache_type << "\n";+ cout << "cache[" << cache_id << "].level = " << cache_level << "\n";+ cout << "cache[" << cache_id << "].ways = " << ways << "\n";+ cout << "cache[" << cache_id << "].partitions = " << partitions << "\n";+ cout << "cache[" << cache_id << "].line_size = " << line_size << "\n";+ cout << "cache[" << cache_id << "].sets = " << sets << "\n";+ cout << "cache[" << cache_id << "].size = " << cache_size << "\n";+ + cache_id++;+ } while(cache_type>0 && cache_id<16);+ }+ + // dump everything+ std::cout << endl <<"Raw dump:" << endl;+ for(int i=0; i<max_funcs; ++i)+ DUMP_CPUID(i);++ DUMP_CPUID(0x80000000);+ DUMP_CPUID(0x80000001);+ DUMP_CPUID(0x80000002);+ DUMP_CPUID(0x80000003);+ DUMP_CPUID(0x80000004);+ DUMP_CPUID(0x80000005);+ DUMP_CPUID(0x80000006);+ DUMP_CPUID(0x80000007);+ DUMP_CPUID(0x80000008);+ #else+ cout << "EIGEN_CPUID is not defined" << endl;+ #endif+ return 0;+}
+ eigen3/bench/eig33.cpp view
@@ -0,0 +1,196 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++// The computeRoots function included in this is based on materials+// covered by the following copyright and license:+// +// Geometric Tools, LLC+// Copyright (c) 1998-2010+// Distributed under the Boost Software License, Version 1.0.+// +// Permission is hereby granted, free of charge, to any person or organization+// obtaining a copy of the software and accompanying documentation covered by+// this license (the "Software") to use, reproduce, display, distribute,+// execute, and transmit the Software, and to prepare derivative works of the+// Software, and to permit third-parties to whom the Software is furnished to+// do so, all subject to the following:+// +// The copyright notices in the Software and this entire statement, including+// the above license grant, this restriction and the following disclaimer,+// must be included in all copies of the Software, in whole or in part, and+// all derivative works of the Software, unless such copies or derivative+// works are solely in the form of machine-executable object code generated by+// a source language processor.+// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT+// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE+// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER+// DEALINGS IN THE SOFTWARE.++#include <iostream>+#include <Eigen/Core>+#include <Eigen/Eigenvalues>+#include <Eigen/Geometry>+#include <bench/BenchTimer.h>++using namespace Eigen;+using namespace std;++template<typename Matrix, typename Roots>+inline void computeRoots(const Matrix& m, Roots& roots)+{+ typedef typename Matrix::Scalar Scalar;+ const Scalar s_inv3 = 1.0/3.0;+ const Scalar s_sqrt3 = internal::sqrt(Scalar(3.0));++ // The characteristic equation is x^3 - c2*x^2 + c1*x - c0 = 0. The+ // eigenvalues are the roots to this equation, all guaranteed to be+ // real-valued, because the matrix is symmetric.+ Scalar c0 = m(0,0)*m(1,1)*m(2,2) + Scalar(2)*m(0,1)*m(0,2)*m(1,2) - m(0,0)*m(1,2)*m(1,2) - m(1,1)*m(0,2)*m(0,2) - m(2,2)*m(0,1)*m(0,1);+ Scalar c1 = m(0,0)*m(1,1) - m(0,1)*m(0,1) + m(0,0)*m(2,2) - m(0,2)*m(0,2) + m(1,1)*m(2,2) - m(1,2)*m(1,2);+ Scalar c2 = m(0,0) + m(1,1) + m(2,2);++ // Construct the parameters used in classifying the roots of the equation+ // and in solving the equation for the roots in closed form.+ Scalar c2_over_3 = c2*s_inv3;+ Scalar a_over_3 = (c1 - c2*c2_over_3)*s_inv3;+ if (a_over_3 > Scalar(0))+ a_over_3 = Scalar(0);++ Scalar half_b = Scalar(0.5)*(c0 + c2_over_3*(Scalar(2)*c2_over_3*c2_over_3 - c1));++ Scalar q = half_b*half_b + a_over_3*a_over_3*a_over_3;+ if (q > Scalar(0))+ q = Scalar(0);++ // Compute the eigenvalues by solving for the roots of the polynomial.+ Scalar rho = internal::sqrt(-a_over_3);+ Scalar theta = std::atan2(internal::sqrt(-q),half_b)*s_inv3;+ Scalar cos_theta = internal::cos(theta);+ Scalar sin_theta = internal::sin(theta);+ roots(0) = c2_over_3 + Scalar(2)*rho*cos_theta;+ roots(1) = c2_over_3 - rho*(cos_theta + s_sqrt3*sin_theta);+ roots(2) = c2_over_3 - rho*(cos_theta - s_sqrt3*sin_theta);++ // Sort in increasing order.+ if (roots(0) >= roots(1))+ std::swap(roots(0),roots(1));+ if (roots(1) >= roots(2))+ {+ std::swap(roots(1),roots(2));+ if (roots(0) >= roots(1))+ std::swap(roots(0),roots(1));+ }+}++template<typename Matrix, typename Vector>+void eigen33(const Matrix& mat, Matrix& evecs, Vector& evals)+{+ typedef typename Matrix::Scalar Scalar;+ // Scale the matrix so its entries are in [-1,1]. The scaling is applied+ // only when at least one matrix entry has magnitude larger than 1.++ Scalar scale = mat.cwiseAbs()/*.template triangularView<Lower>()*/.maxCoeff();+ scale = std::max(scale,Scalar(1));+ Matrix scaledMat = mat / scale;++ // Compute the eigenvalues+// scaledMat.setZero();+ computeRoots(scaledMat,evals);++ // compute the eigen vectors+ // **here we assume 3 differents eigenvalues**++ // "optimized version" which appears to be slower with gcc!+// Vector base;+// Scalar alpha, beta;+// base << scaledMat(1,0) * scaledMat(2,1),+// scaledMat(1,0) * scaledMat(2,0),+// -scaledMat(1,0) * scaledMat(1,0);+// for(int k=0; k<2; ++k)+// {+// alpha = scaledMat(0,0) - evals(k);+// beta = scaledMat(1,1) - evals(k);+// evecs.col(k) = (base + Vector(-beta*scaledMat(2,0), -alpha*scaledMat(2,1), alpha*beta)).normalized();+// }+// evecs.col(2) = evecs.col(0).cross(evecs.col(1)).normalized();++// // naive version+// Matrix tmp;+// tmp = scaledMat;+// tmp.diagonal().array() -= evals(0);+// evecs.col(0) = tmp.row(0).cross(tmp.row(1)).normalized();+// +// tmp = scaledMat;+// tmp.diagonal().array() -= evals(1);+// evecs.col(1) = tmp.row(0).cross(tmp.row(1)).normalized();+// +// tmp = scaledMat;+// tmp.diagonal().array() -= evals(2);+// evecs.col(2) = tmp.row(0).cross(tmp.row(1)).normalized();+ + // a more stable version:+ if((evals(2)-evals(0))<=Eigen::NumTraits<Scalar>::epsilon())+ {+ evecs.setIdentity();+ }+ else+ {+ Matrix tmp;+ tmp = scaledMat;+ tmp.diagonal ().array () -= evals (2);+ evecs.col (2) = tmp.row (0).cross (tmp.row (1)).normalized ();+ + tmp = scaledMat;+ tmp.diagonal ().array () -= evals (1);+ evecs.col(1) = tmp.row (0).cross(tmp.row (1));+ Scalar n1 = evecs.col(1).norm();+ if(n1<=Eigen::NumTraits<Scalar>::epsilon())+ evecs.col(1) = evecs.col(2).unitOrthogonal();+ else+ evecs.col(1) /= n1;+ + // make sure that evecs[1] is orthogonal to evecs[2]+ evecs.col(1) = evecs.col(2).cross(evecs.col(1).cross(evecs.col(2))).normalized();+ evecs.col(0) = evecs.col(2).cross(evecs.col(1));+ }+ + // Rescale back to the original size.+ evals *= scale;+}++int main()+{+ BenchTimer t;+ int tries = 10;+ int rep = 400000;+ typedef Matrix3f Mat;+ typedef Vector3f Vec;+ Mat A = Mat::Random(3,3);+ A = A.adjoint() * A;++ SelfAdjointEigenSolver<Mat> eig(A);+ BENCH(t, tries, rep, eig.compute(A));+ std::cout << "Eigen: " << t.best() << "s\n";++ Mat evecs;+ Vec evals;+ BENCH(t, tries, rep, eigen33(A,evecs,evals));+ std::cout << "Direct: " << t.best() << "s\n\n";++ std::cerr << "Eigenvalue/eigenvector diffs:\n";+ std::cerr << (evals - eig.eigenvalues()).transpose() << "\n";+ for(int k=0;k<3;++k)+ if(evecs.col(k).dot(eig.eigenvectors().col(k))<0)+ evecs.col(k) = -evecs.col(k);+ std::cerr << evecs - eig.eigenvectors() << "\n\n";+}
+ eigen3/bench/geometry.cpp view
@@ -0,0 +1,126 @@++#include <iostream>+#include <Eigen/Geometry>+#include <bench/BenchTimer.h>++using namespace std;+using namespace Eigen;++#ifndef SCALAR+#define SCALAR float+#endif++#ifndef SIZE+#define SIZE 8+#endif++typedef SCALAR Scalar;+typedef NumTraits<Scalar>::Real RealScalar;+typedef Matrix<RealScalar,Dynamic,Dynamic> A;+typedef Matrix</*Real*/Scalar,Dynamic,Dynamic> B;+typedef Matrix<Scalar,Dynamic,Dynamic> C;+typedef Matrix<RealScalar,Dynamic,Dynamic> M;++template<typename Transformation, typename Data>+EIGEN_DONT_INLINE void transform(const Transformation& t, Data& data)+{+ EIGEN_ASM_COMMENT("begin");+ data = t * data;+ EIGEN_ASM_COMMENT("end");+}++template<typename Scalar, typename Data>+EIGEN_DONT_INLINE void transform(const Quaternion<Scalar>& t, Data& data)+{+ EIGEN_ASM_COMMENT("begin quat");+ for(int i=0;i<data.cols();++i)+ data.col(i) = t * data.col(i);+ EIGEN_ASM_COMMENT("end quat");+}++template<typename T> struct ToRotationMatrixWrapper+{+ enum {Dim = T::Dim};+ typedef typename T::Scalar Scalar;+ ToRotationMatrixWrapper(const T& o) : object(o) {}+ T object;+};++template<typename QType, typename Data>+EIGEN_DONT_INLINE void transform(const ToRotationMatrixWrapper<QType>& t, Data& data)+{+ EIGEN_ASM_COMMENT("begin quat via mat");+ data = t.object.toRotationMatrix() * data;+ EIGEN_ASM_COMMENT("end quat via mat");+}++template<typename Scalar, int Dim, typename Data>+EIGEN_DONT_INLINE void transform(const Transform<Scalar,Dim,Projective>& t, Data& data)+{+ data = (t * data.colwise().homogeneous()).template block<Dim,Data::ColsAtCompileTime>(0,0);+}++template<typename T> struct get_dim { enum { Dim = T::Dim }; };+template<typename S, int R, int C, int O, int MR, int MC>+struct get_dim<Matrix<S,R,C,O,MR,MC> > { enum { Dim = R }; };++template<typename Transformation, int N>+struct bench_impl+{+ static EIGEN_DONT_INLINE void run(const Transformation& t)+ {+ Matrix<typename Transformation::Scalar,get_dim<Transformation>::Dim,N> data;+ data.setRandom();+ bench_impl<Transformation,N-1>::run(t);+ BenchTimer timer;+ BENCH(timer,10,100000,transform(t,data));+ cout.width(9);+ cout << timer.best() << " ";+ }+};+++template<typename Transformation>+struct bench_impl<Transformation,0>+{+ static EIGEN_DONT_INLINE void run(const Transformation&) {}+};++template<typename Transformation>+EIGEN_DONT_INLINE void bench(const std::string& msg, const Transformation& t)+{+ cout << msg << " ";+ bench_impl<Transformation,SIZE>::run(t);+ std::cout << "\n";+}++int main(int argc, char ** argv)+{+ Matrix<Scalar,3,4> mat34; mat34.setRandom();+ Transform<Scalar,3,Isometry> iso3(mat34);+ Transform<Scalar,3,Affine> aff3(mat34);+ Transform<Scalar,3,AffineCompact> caff3(mat34);+ Transform<Scalar,3,Projective> proj3(mat34);+ Quaternion<Scalar> quat;quat.setIdentity();+ ToRotationMatrixWrapper<Quaternion<Scalar> > quatmat(quat);+ Matrix<Scalar,3,3> mat33; mat33.setRandom();+ + cout.precision(4);+ std::cout+ << "N ";+ for(int i=0;i<SIZE;++i)+ {+ cout.width(9);+ cout << i+1 << " ";+ }+ cout << "\n";+ + bench("matrix 3x3", mat33);+ bench("quaternion", quat);+ bench("quat-mat ", quatmat);+ bench("isometry3 ", iso3);+ bench("affine3 ", aff3);+ bench("c affine3 ", caff3);+ bench("proj3 ", proj3);+}+
+ eigen3/bench/product_threshold.cpp view
@@ -0,0 +1,143 @@++#include <iostream>+#include <Eigen/Core>+#include <bench/BenchTimer.h>++using namespace Eigen;+using namespace std;++#define END 9++template<int S> struct map_size { enum { ret = S }; };+template<> struct map_size<10> { enum { ret = 20 }; };+template<> struct map_size<11> { enum { ret = 50 }; };+template<> struct map_size<12> { enum { ret = 100 }; };+template<> struct map_size<13> { enum { ret = 300 }; };++template<int M, int N,int K> struct alt_prod+{+ enum {+ ret = M==1 && N==1 ? InnerProduct+ : K==1 ? OuterProduct+ : M==1 ? GemvProduct+ : N==1 ? GemvProduct+ : GemmProduct+ };+};+ +void print_mode(int mode)+{+ if(mode==InnerProduct) std::cout << "i";+ if(mode==OuterProduct) std::cout << "o";+ if(mode==CoeffBasedProductMode) std::cout << "c";+ if(mode==LazyCoeffBasedProductMode) std::cout << "l";+ if(mode==GemvProduct) std::cout << "v";+ if(mode==GemmProduct) std::cout << "m";+}++template<int Mode, typename Lhs, typename Rhs, typename Res>+EIGEN_DONT_INLINE void prod(const Lhs& a, const Rhs& b, Res& c)+{+ c.noalias() += typename ProductReturnType<Lhs,Rhs,Mode>::Type(a,b);+}++template<int M, int N, int K, typename Scalar, int Mode>+EIGEN_DONT_INLINE void bench_prod()+{+ typedef Matrix<Scalar,M,K> Lhs; Lhs a; a.setRandom();+ typedef Matrix<Scalar,K,N> Rhs; Rhs b; b.setRandom();+ typedef Matrix<Scalar,M,N> Res; Res c; c.setRandom();++ BenchTimer t;+ double n = 2.*double(M)*double(N)*double(K);+ int rep = 100000./n;+ rep /= 2;+ if(rep<1) rep = 1;+ do {+ rep *= 2;+ t.reset();+ BENCH(t,1,rep,prod<CoeffBasedProductMode>(a,b,c));+ } while(t.best()<0.1);+ + t.reset();+ BENCH(t,5,rep,prod<Mode>(a,b,c));++ print_mode(Mode);+ std::cout << int(1e-6*n*rep/t.best()) << "\t";+}++template<int N> struct print_n;+template<int M, int N, int K> struct loop_on_m;+template<int M, int N, int K, typename Scalar, int Mode> struct loop_on_n;++template<int M, int N, int K>+struct loop_on_k+{+ static void run()+ {+ std::cout << "K=" << K << "\t";+ print_n<N>::run();+ std::cout << "\n";++ loop_on_m<M,N,K>::run();+ std::cout << "\n\n";++ loop_on_k<M,N,K+1>::run();+ }+};++template<int M, int N>+struct loop_on_k<M,N,END> { static void run(){} };+++template<int M, int N, int K>+struct loop_on_m+{+ static void run()+ {+ std::cout << M << "f\t";+ loop_on_n<M,N,K,float,CoeffBasedProductMode>::run();+ std::cout << "\n";+ + std::cout << M << "f\t";+ loop_on_n<M,N,K,float,-1>::run();+ std::cout << "\n";++ loop_on_m<M+1,N,K>::run();+ }+};++template<int N, int K>+struct loop_on_m<END,N,K> { static void run(){} };++template<int M, int N, int K, typename Scalar, int Mode>+struct loop_on_n+{+ static void run()+ {+ bench_prod<M,N,K,Scalar,Mode==-1? alt_prod<M,N,K>::ret : Mode>();+ + loop_on_n<M,N+1,K,Scalar,Mode>::run();+ }+};++template<int M, int K, typename Scalar, int Mode>+struct loop_on_n<M,END,K,Scalar,Mode> { static void run(){} };++template<int N> struct print_n+{+ static void run()+ {+ std::cout << map_size<N>::ret << "\t";+ print_n<N+1>::run();+ }+};++template<> struct print_n<END> { static void run(){} };++int main()+{+ loop_on_k<1,1,1>::run();+ + return 0; +}
+ eigen3/bench/quat_slerp.cpp view
@@ -0,0 +1,247 @@++#include <iostream>+#include <Eigen/Geometry>+#include <bench/BenchTimer.h>+using namespace Eigen;+using namespace std;++++template<typename Q>+EIGEN_DONT_INLINE Q nlerp(const Q& a, const Q& b, typename Q::Scalar t)+{+ return Q((a.coeffs() * (1.0-t) + b.coeffs() * t).normalized());+}++template<typename Q>+EIGEN_DONT_INLINE Q slerp_eigen(const Q& a, const Q& b, typename Q::Scalar t)+{+ return a.slerp(t,b);+}++template<typename Q>+EIGEN_DONT_INLINE Q slerp_legacy(const Q& a, const Q& b, typename Q::Scalar t)+{+ typedef typename Q::Scalar Scalar;+ static const Scalar one = Scalar(1) - dummy_precision<Scalar>();+ Scalar d = a.dot(b);+ Scalar absD = internal::abs(d);+ if (absD>=one)+ return a;++ // theta is the angle between the 2 quaternions+ Scalar theta = std::acos(absD);+ Scalar sinTheta = internal::sin(theta);++ Scalar scale0 = internal::sin( ( Scalar(1) - t ) * theta) / sinTheta;+ Scalar scale1 = internal::sin( ( t * theta) ) / sinTheta;+ if (d<0)+ scale1 = -scale1;++ return Q(scale0 * a.coeffs() + scale1 * b.coeffs());+}++template<typename Q>+EIGEN_DONT_INLINE Q slerp_legacy_nlerp(const Q& a, const Q& b, typename Q::Scalar t)+{+ typedef typename Q::Scalar Scalar;+ static const Scalar one = Scalar(1) - epsilon<Scalar>();+ Scalar d = a.dot(b);+ Scalar absD = internal::abs(d);+ + Scalar scale0;+ Scalar scale1;+ + if (absD>=one)+ {+ scale0 = Scalar(1) - t;+ scale1 = t;+ }+ else+ {+ // theta is the angle between the 2 quaternions+ Scalar theta = std::acos(absD);+ Scalar sinTheta = internal::sin(theta);++ scale0 = internal::sin( ( Scalar(1) - t ) * theta) / sinTheta;+ scale1 = internal::sin( ( t * theta) ) / sinTheta;+ if (d<0)+ scale1 = -scale1;+ }++ return Q(scale0 * a.coeffs() + scale1 * b.coeffs());+}++template<typename T>+inline T sin_over_x(T x)+{+ if (T(1) + x*x == T(1))+ return T(1);+ else+ return std::sin(x)/x;+}++template<typename Q>+EIGEN_DONT_INLINE Q slerp_rw(const Q& a, const Q& b, typename Q::Scalar t)+{+ typedef typename Q::Scalar Scalar;+ + Scalar d = a.dot(b);+ Scalar theta;+ if (d<0.0)+ theta = /*M_PI -*/ Scalar(2)*std::asin( (a.coeffs()+b.coeffs()).norm()/2 );+ else+ theta = Scalar(2)*std::asin( (a.coeffs()-b.coeffs()).norm()/2 );+ + // theta is the angle between the 2 quaternions+// Scalar theta = std::acos(absD);+ Scalar sinOverTheta = sin_over_x(theta);++ Scalar scale0 = (Scalar(1)-t)*sin_over_x( ( Scalar(1) - t ) * theta) / sinOverTheta;+ Scalar scale1 = t * sin_over_x( ( t * theta) ) / sinOverTheta;+ if (d<0)+ scale1 = -scale1;++ return Quaternion<Scalar>(scale0 * a.coeffs() + scale1 * b.coeffs());+}++template<typename Q>+EIGEN_DONT_INLINE Q slerp_gael(const Q& a, const Q& b, typename Q::Scalar t)+{+ typedef typename Q::Scalar Scalar;+ + Scalar d = a.dot(b);+ Scalar theta;+// theta = Scalar(2) * atan2((a.coeffs()-b.coeffs()).norm(),(a.coeffs()+b.coeffs()).norm());+// if (d<0.0)+// theta = M_PI-theta;+ + if (d<0.0)+ theta = /*M_PI -*/ Scalar(2)*std::asin( (-a.coeffs()-b.coeffs()).norm()/2 );+ else+ theta = Scalar(2)*std::asin( (a.coeffs()-b.coeffs()).norm()/2 );+ + + Scalar scale0;+ Scalar scale1;+ if(theta*theta-Scalar(6)==-Scalar(6))+ {+ scale0 = Scalar(1) - t;+ scale1 = t;+ }+ else+ {+ Scalar sinTheta = std::sin(theta);+ scale0 = internal::sin( ( Scalar(1) - t ) * theta) / sinTheta;+ scale1 = internal::sin( ( t * theta) ) / sinTheta;+ if (d<0)+ scale1 = -scale1;+ }++ return Quaternion<Scalar>(scale0 * a.coeffs() + scale1 * b.coeffs());+}++int main()+{+ typedef double RefScalar;+ typedef float TestScalar;+ + typedef Quaternion<RefScalar> Qd;+ typedef Quaternion<TestScalar> Qf;+ + unsigned int g_seed = (unsigned int) time(NULL);+ std::cout << g_seed << "\n";+// g_seed = 1259932496;+ srand(g_seed);+ + Matrix<RefScalar,Dynamic,1> maxerr(7);+ maxerr.setZero();+ + Matrix<RefScalar,Dynamic,1> avgerr(7);+ avgerr.setZero();+ + cout << "double=>float=>double nlerp eigen legacy(snap) legacy(nlerp) rightway gael's criteria\n";+ + int rep = 100;+ int iters = 40;+ for (int w=0; w<rep; ++w)+ {+ Qf a, b;+ a.coeffs().setRandom();+ a.normalize();+ b.coeffs().setRandom();+ b.normalize();+ + Qf c[6];+ + Qd ar(a.cast<RefScalar>());+ Qd br(b.cast<RefScalar>());+ Qd cr;+ + + + cout.precision(8);+ cout << std::scientific;+ for (int i=0; i<iters; ++i)+ {+ RefScalar t = 0.65;+ cr = slerp_rw(ar,br,t);+ + Qf refc = cr.cast<TestScalar>();+ c[0] = nlerp(a,b,t);+ c[1] = slerp_eigen(a,b,t);+ c[2] = slerp_legacy(a,b,t);+ c[3] = slerp_legacy_nlerp(a,b,t);+ c[4] = slerp_rw(a,b,t);+ c[5] = slerp_gael(a,b,t);+ + VectorXd err(7);+ err[0] = (cr.coeffs()-refc.cast<RefScalar>().coeffs()).norm();+// std::cout << err[0] << " ";+ for (int k=0; k<6; ++k)+ {+ err[k+1] = (c[k].coeffs()-refc.coeffs()).norm();+// std::cout << err[k+1] << " ";+ }+ maxerr = maxerr.cwise().max(err);+ avgerr += err;+// std::cout << "\n";+ b = cr.cast<TestScalar>();+ br = cr;+ }+// std::cout << "\n";+ }+ avgerr /= RefScalar(rep*iters);+ cout << "\n\nAccuracy:\n"+ << " max: " << maxerr.transpose() << "\n";+ cout << " avg: " << avgerr.transpose() << "\n";+ + // perf bench+ Quaternionf a,b;+ a.coeffs().setRandom();+ a.normalize();+ b.coeffs().setRandom();+ b.normalize();+ //b = a;+ float s = 0.65;+ + #define BENCH(FUNC) {\+ BenchTimer t; \+ for(int k=0; k<2; ++k) {\+ t.start(); \+ for(int i=0; i<1000000; ++i) \+ FUNC(a,b,s); \+ t.stop(); \+ } \+ cout << " " << #FUNC << " => \t " << t.value() << "s\n"; \+ }+ + cout << "\nSpeed:\n" << std::fixed;+ BENCH(nlerp);+ BENCH(slerp_eigen);+ BENCH(slerp_legacy);+ BENCH(slerp_legacy_nlerp);+ BENCH(slerp_rw);+ BENCH(slerp_gael);+}+
+ eigen3/bench/quatmul.cpp view
@@ -0,0 +1,47 @@+#include <iostream>+#include <Eigen/Core>+#include <Eigen/Geometry>+#include <bench/BenchTimer.h>++using namespace Eigen; ++template<typename Quat>+EIGEN_DONT_INLINE void quatmul_default(const Quat& a, const Quat& b, Quat& c)+{+ c = a * b;+}++template<typename Quat>+EIGEN_DONT_INLINE void quatmul_novec(const Quat& a, const Quat& b, Quat& c)+{+ c = internal::quat_product<0, Quat, Quat, typename Quat::Scalar, Aligned>::run(a,b);+}++template<typename Quat> void bench(const std::string& label)+{+ int tries = 10;+ int rep = 1000000;+ BenchTimer t;+ + Quat a(4, 1, 2, 3);+ Quat b(2, 3, 4, 5);+ Quat c;+ + std::cout.precision(3);+ + BENCH(t, tries, rep, quatmul_default(a,b,c));+ std::cout << label << " default " << 1e3*t.best(CPU_TIMER) << "ms \t" << 1e-6*double(rep)/(t.best(CPU_TIMER)) << " M mul/s\n";+ + BENCH(t, tries, rep, quatmul_novec(a,b,c));+ std::cout << label << " novec " << 1e3*t.best(CPU_TIMER) << "ms \t" << 1e-6*double(rep)/(t.best(CPU_TIMER)) << " M mul/s\n";+}++int main()+{+ bench<Quaternionf>("float ");+ bench<Quaterniond>("double");++ return 0;++}+
+ eigen3/bench/sparse_cholesky.cpp view
@@ -0,0 +1,216 @@+// #define EIGEN_TAUCS_SUPPORT+// #define EIGEN_CHOLMOD_SUPPORT+#include <iostream>+#include <Eigen/Sparse>++// g++ -DSIZE=10000 -DDENSITY=0.001 sparse_cholesky.cpp -I.. -DDENSEMATRI -O3 -g0 -DNDEBUG -DNBTRIES=1 -I /home/gael/Coding/LinearAlgebra/taucs_full/src/ -I/home/gael/Coding/LinearAlgebra/taucs_full/build/linux/ -L/home/gael/Coding/LinearAlgebra/taucs_full/lib/linux/ -ltaucs /home/gael/Coding/LinearAlgebra/GotoBLAS/libgoto.a -lpthread -I /home/gael/Coding/LinearAlgebra/SuiteSparse/CHOLMOD/Include/ $CHOLLIB -I /home/gael/Coding/LinearAlgebra/SuiteSparse/UFconfig/ /home/gael/Coding/LinearAlgebra/SuiteSparse/CCOLAMD/Lib/libccolamd.a /home/gael/Coding/LinearAlgebra/SuiteSparse/CHOLMOD/Lib/libcholmod.a -lmetis /home/gael/Coding/LinearAlgebra/SuiteSparse/AMD/Lib/libamd.a /home/gael/Coding/LinearAlgebra/SuiteSparse/CAMD/Lib/libcamd.a /home/gael/Coding/LinearAlgebra/SuiteSparse/CCOLAMD/Lib/libccolamd.a /home/gael/Coding/LinearAlgebra/SuiteSparse/COLAMD/Lib/libcolamd.a -llapack && ./a.out++#define NOGMM+#define NOMTL++#ifndef SIZE+#define SIZE 10+#endif++#ifndef DENSITY+#define DENSITY 0.01+#endif++#ifndef REPEAT+#define REPEAT 1+#endif++#include "BenchSparseUtil.h"++#ifndef MINDENSITY+#define MINDENSITY 0.0004+#endif++#ifndef NBTRIES+#define NBTRIES 10+#endif++#define BENCH(X) \+ timer.reset(); \+ for (int _j=0; _j<NBTRIES; ++_j) { \+ timer.start(); \+ for (int _k=0; _k<REPEAT; ++_k) { \+ X \+ } timer.stop(); }++// typedef SparseMatrix<Scalar,UpperTriangular> EigenSparseTriMatrix;+typedef SparseMatrix<Scalar,SelfAdjoint|LowerTriangular> EigenSparseSelfAdjointMatrix;++void fillSpdMatrix(float density, int rows, int cols, EigenSparseSelfAdjointMatrix& dst)+{+ dst.startFill(rows*cols*density);+ for(int j = 0; j < cols; j++)+ {+ dst.fill(j,j) = internal::random<Scalar>(10,20);+ for(int i = j+1; i < rows; i++)+ {+ Scalar v = (internal::random<float>(0,1) < density) ? internal::random<Scalar>() : 0;+ if (v!=0)+ dst.fill(i,j) = v;+ }++ }+ dst.endFill();+}++#include <Eigen/Cholesky>++template<int Backend>+void doEigen(const char* name, const EigenSparseSelfAdjointMatrix& sm1, int flags = 0)+{+ std::cout << name << "..." << std::flush;+ BenchTimer timer;+ timer.start();+ SparseLLT<EigenSparseSelfAdjointMatrix,Backend> chol(sm1, flags);+ timer.stop();+ std::cout << ":\t" << timer.value() << endl;++ std::cout << " nnz: " << sm1.nonZeros() << " => " << chol.matrixL().nonZeros() << "\n";+// std::cout << "sparse\n" << chol.matrixL() << "%\n";+}++int main(int argc, char *argv[])+{+ int rows = SIZE;+ int cols = SIZE;+ float density = DENSITY;+ BenchTimer timer;++ VectorXf b = VectorXf::Random(cols);+ VectorXf x = VectorXf::Random(cols);++ bool densedone = false;++ //for (float density = DENSITY; density>=MINDENSITY; density*=0.5)+// float density = 0.5;+ {+ EigenSparseSelfAdjointMatrix sm1(rows, cols);+ std::cout << "Generate sparse matrix (might take a while)...\n";+ fillSpdMatrix(density, rows, cols, sm1);+ std::cout << "DONE\n\n";++ // dense matrices+ #ifdef DENSEMATRIX+ if (!densedone)+ {+ densedone = true;+ std::cout << "Eigen Dense\t" << density*100 << "%\n";+ DenseMatrix m1(rows,cols);+ eiToDense(sm1, m1);+ m1 = (m1 + m1.transpose()).eval();+ m1.diagonal() *= 0.5;++// BENCH(LLT<DenseMatrix> chol(m1);)+// std::cout << "dense:\t" << timer.value() << endl;++ BenchTimer timer;+ timer.start();+ LLT<DenseMatrix> chol(m1);+ timer.stop();+ std::cout << "dense:\t" << timer.value() << endl;+ int count = 0;+ for (int j=0; j<cols; ++j)+ for (int i=j; i<rows; ++i)+ if (!internal::isMuchSmallerThan(internal::abs(chol.matrixL()(i,j)), 0.1))+ count++;+ std::cout << "dense: " << "nnz = " << count << "\n";+// std::cout << "dense:\n" << m1 << "\n\n" << chol.matrixL() << endl;+ }+ #endif++ // eigen sparse matrices+ doEigen<Eigen::DefaultBackend>("Eigen/Sparse", sm1, Eigen::IncompleteFactorization);++ #ifdef EIGEN_CHOLMOD_SUPPORT+ doEigen<Eigen::Cholmod>("Eigen/Cholmod", sm1, Eigen::IncompleteFactorization);+ #endif++ #ifdef EIGEN_TAUCS_SUPPORT+ doEigen<Eigen::Taucs>("Eigen/Taucs", sm1, Eigen::IncompleteFactorization);+ #endif++ #if 0+ // TAUCS+ {+ taucs_ccs_matrix A = sm1.asTaucsMatrix();++ //BENCH(taucs_ccs_matrix* chol = taucs_ccs_factor_llt(&A, 0, 0);)+// BENCH(taucs_supernodal_factor_to_ccs(taucs_ccs_factor_llt_ll(&A));)+// std::cout << "taucs:\t" << timer.value() << endl;++ taucs_ccs_matrix* chol = taucs_ccs_factor_llt(&A, 0, 0);++ for (int j=0; j<cols; ++j)+ {+ for (int i=chol->colptr[j]; i<chol->colptr[j+1]; ++i)+ std::cout << chol->values.d[i] << " ";+ }+ }++ // CHOLMOD+ #ifdef EIGEN_CHOLMOD_SUPPORT+ {+ cholmod_common c;+ cholmod_start (&c);+ cholmod_sparse A;+ cholmod_factor *L;++ A = sm1.asCholmodMatrix();+ BenchTimer timer;+// timer.reset();+ timer.start();+ std::vector<int> perm(cols);+// std::vector<int> set(ncols);+ for (int i=0; i<cols; ++i)+ perm[i] = i;+// c.nmethods = 1;+// c.method[0] = 1;++ c.nmethods = 1;+ c.method [0].ordering = CHOLMOD_NATURAL;+ c.postorder = 0;+ c.final_ll = 1;++ L = cholmod_analyze_p(&A, &perm[0], &perm[0], cols, &c);+ timer.stop();+ std::cout << "cholmod/analyze:\t" << timer.value() << endl;+ timer.reset();+ timer.start();+ cholmod_factorize(&A, L, &c);+ timer.stop();+ std::cout << "cholmod/factorize:\t" << timer.value() << endl;++ cholmod_sparse* cholmat = cholmod_factor_to_sparse(L, &c);++ cholmod_print_factor(L, "Factors", &c);++ cholmod_print_sparse(cholmat, "Chol", &c);+ cholmod_write_sparse(stdout, cholmat, 0, 0, &c);+//+// cholmod_print_sparse(&A, "A", &c);+// cholmod_write_sparse(stdout, &A, 0, 0, &c);+++// for (int j=0; j<cols; ++j)+// {+// for (int i=chol->colptr[j]; i<chol->colptr[j+1]; ++i)+// std::cout << chol->values.s[i] << " ";+// }+ }+ #endif++ #endif++++ }+++ return 0;+}+
+ eigen3/bench/sparse_dense_product.cpp view
@@ -0,0 +1,187 @@++//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.005 -DSIZE=10000 && ./a.out+//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.05 -DSIZE=2000 && ./a.out+// -DNOGMM -DNOMTL -DCSPARSE+// -I /home/gael/Coding/LinearAlgebra/CSparse/Include/ /home/gael/Coding/LinearAlgebra/CSparse/Lib/libcsparse.a+#ifndef SIZE+#define SIZE 650000+#endif++#ifndef DENSITY+#define DENSITY 0.01+#endif++#ifndef REPEAT+#define REPEAT 1+#endif++#include "BenchSparseUtil.h"++#ifndef MINDENSITY+#define MINDENSITY 0.0004+#endif++#ifndef NBTRIES+#define NBTRIES 10+#endif++#define BENCH(X) \+ timer.reset(); \+ for (int _j=0; _j<NBTRIES; ++_j) { \+ timer.start(); \+ for (int _k=0; _k<REPEAT; ++_k) { \+ X \+ } timer.stop(); }+++#ifdef CSPARSE+cs* cs_sorted_multiply(const cs* a, const cs* b)+{+ cs* A = cs_transpose (a, 1) ;+ cs* B = cs_transpose (b, 1) ;+ cs* D = cs_multiply (B,A) ; /* D = B'*A' */+ cs_spfree (A) ;+ cs_spfree (B) ;+ cs_dropzeros (D) ; /* drop zeros from D */+ cs* C = cs_transpose (D, 1) ; /* C = D', so that C is sorted */+ cs_spfree (D) ;+ return C;+}+#endif++int main(int argc, char *argv[])+{+ int rows = SIZE;+ int cols = SIZE;+ float density = DENSITY;++ EigenSparseMatrix sm1(rows,cols);+ DenseVector v1(cols), v2(cols);+ v1.setRandom();++ BenchTimer timer;+ for (float density = DENSITY; density>=MINDENSITY; density*=0.5)+ {+ //fillMatrix(density, rows, cols, sm1);+ fillMatrix2(7, rows, cols, sm1);++ // dense matrices+ #ifdef DENSEMATRIX+ {+ std::cout << "Eigen Dense\t" << density*100 << "%\n";+ DenseMatrix m1(rows,cols);+ eiToDense(sm1, m1);++ timer.reset();+ timer.start();+ for (int k=0; k<REPEAT; ++k)+ v2 = m1 * v1;+ timer.stop();+ std::cout << " a * v:\t" << timer.best() << " " << double(REPEAT)/timer.best() << " * / sec " << endl;++ timer.reset();+ timer.start();+ for (int k=0; k<REPEAT; ++k)+ v2 = m1.transpose() * v1;+ timer.stop();+ std::cout << " a' * v:\t" << timer.best() << endl;+ }+ #endif++ // eigen sparse matrices+ {+ std::cout << "Eigen sparse\t" << sm1.nonZeros()/float(sm1.rows()*sm1.cols())*100 << "%\n";++ BENCH(asm("#myc"); v2 = sm1 * v1; asm("#myd");)+ std::cout << " a * v:\t" << timer.best()/REPEAT << " " << double(REPEAT)/timer.best(REAL_TIMER) << " * / sec " << endl;+++ BENCH( { asm("#mya"); v2 = sm1.transpose() * v1; asm("#myb"); })++ std::cout << " a' * v:\t" << timer.best()/REPEAT << endl;+ }++// {+// DynamicSparseMatrix<Scalar> m1(sm1);+// std::cout << "Eigen dyn-sparse\t" << m1.nonZeros()/float(m1.rows()*m1.cols())*100 << "%\n";+//+// BENCH(for (int k=0; k<REPEAT; ++k) v2 = m1 * v1;)+// std::cout << " a * v:\t" << timer.value() << endl;+//+// BENCH(for (int k=0; k<REPEAT; ++k) v2 = m1.transpose() * v1;)+// std::cout << " a' * v:\t" << timer.value() << endl;+// }++ // GMM+++ #ifndef NOGMM+ {+ std::cout << "GMM++ sparse\t" << density*100 << "%\n";+ //GmmDynSparse gmmT3(rows,cols);+ GmmSparse m1(rows,cols);+ eiToGmm(sm1, m1);++ std::vector<Scalar> gmmV1(cols), gmmV2(cols);+ Map<Matrix<Scalar,Dynamic,1> >(&gmmV1[0], cols) = v1;+ Map<Matrix<Scalar,Dynamic,1> >(&gmmV2[0], cols) = v2;++ BENCH( asm("#myx"); gmm::mult(m1, gmmV1, gmmV2); asm("#myy"); )+ std::cout << " a * v:\t" << timer.value() << endl;++ BENCH( gmm::mult(gmm::transposed(m1), gmmV1, gmmV2); )+ std::cout << " a' * v:\t" << timer.value() << endl;+ }+ #endif+ + #ifndef NOUBLAS+ {+ std::cout << "ublas sparse\t" << density*100 << "%\n";+ UBlasSparse m1(rows,cols);+ eiToUblas(sm1, m1);+ + boost::numeric::ublas::vector<Scalar> uv1, uv2;+ eiToUblasVec(v1,uv1);+ eiToUblasVec(v2,uv2);++// std::vector<Scalar> gmmV1(cols), gmmV2(cols);+// Map<Matrix<Scalar,Dynamic,1> >(&gmmV1[0], cols) = v1;+// Map<Matrix<Scalar,Dynamic,1> >(&gmmV2[0], cols) = v2;++ BENCH( uv2 = boost::numeric::ublas::prod(m1, uv1); )+ std::cout << " a * v:\t" << timer.value() << endl;++// BENCH( boost::ublas::prod(gmm::transposed(m1), gmmV1, gmmV2); )+// std::cout << " a' * v:\t" << timer.value() << endl;+ }+ #endif++ // MTL4+ #ifndef NOMTL+ {+ std::cout << "MTL4\t" << density*100 << "%\n";+ MtlSparse m1(rows,cols);+ eiToMtl(sm1, m1);+ mtl::dense_vector<Scalar> mtlV1(cols, 1.0);+ mtl::dense_vector<Scalar> mtlV2(cols, 1.0);++ timer.reset();+ timer.start();+ for (int k=0; k<REPEAT; ++k)+ mtlV2 = m1 * mtlV1;+ timer.stop();+ std::cout << " a * v:\t" << timer.value() << endl;++ timer.reset();+ timer.start();+ for (int k=0; k<REPEAT; ++k)+ mtlV2 = trans(m1) * mtlV1;+ timer.stop();+ std::cout << " a' * v:\t" << timer.value() << endl;+ }+ #endif++ std::cout << "\n\n";+ }++ return 0;+}+
+ eigen3/bench/sparse_lu.cpp view
@@ -0,0 +1,132 @@++// g++ -I.. sparse_lu.cpp -O3 -g0 -I /usr/include/superlu/ -lsuperlu -lgfortran -DSIZE=1000 -DDENSITY=.05 && ./a.out++#define EIGEN_SUPERLU_SUPPORT+#define EIGEN_UMFPACK_SUPPORT+#include <Eigen/Sparse>++#define NOGMM+#define NOMTL++#ifndef SIZE+#define SIZE 10+#endif++#ifndef DENSITY+#define DENSITY 0.01+#endif++#ifndef REPEAT+#define REPEAT 1+#endif++#include "BenchSparseUtil.h"++#ifndef MINDENSITY+#define MINDENSITY 0.0004+#endif++#ifndef NBTRIES+#define NBTRIES 10+#endif++#define BENCH(X) \+ timer.reset(); \+ for (int _j=0; _j<NBTRIES; ++_j) { \+ timer.start(); \+ for (int _k=0; _k<REPEAT; ++_k) { \+ X \+ } timer.stop(); }++typedef Matrix<Scalar,Dynamic,1> VectorX;++#include <Eigen/LU>++template<int Backend>+void doEigen(const char* name, const EigenSparseMatrix& sm1, const VectorX& b, VectorX& x, int flags = 0)+{+ std::cout << name << "..." << std::flush;+ BenchTimer timer; timer.start();+ SparseLU<EigenSparseMatrix,Backend> lu(sm1, flags);+ timer.stop();+ if (lu.succeeded())+ std::cout << ":\t" << timer.value() << endl;+ else+ {+ std::cout << ":\t FAILED" << endl;+ return;+ }++ bool ok;+ timer.reset(); timer.start();+ ok = lu.solve(b,&x);+ timer.stop();+ if (ok)+ std::cout << " solve:\t" << timer.value() << endl;+ else+ std::cout << " solve:\t" << " FAILED" << endl;++ //std::cout << x.transpose() << "\n";+}++int main(int argc, char *argv[])+{+ int rows = SIZE;+ int cols = SIZE;+ float density = DENSITY;+ BenchTimer timer;++ VectorX b = VectorX::Random(cols);+ VectorX x = VectorX::Random(cols);++ bool densedone = false;++ //for (float density = DENSITY; density>=MINDENSITY; density*=0.5)+// float density = 0.5;+ {+ EigenSparseMatrix sm1(rows, cols);+ fillMatrix(density, rows, cols, sm1);++ // dense matrices+ #ifdef DENSEMATRIX+ if (!densedone)+ {+ densedone = true;+ std::cout << "Eigen Dense\t" << density*100 << "%\n";+ DenseMatrix m1(rows,cols);+ eiToDense(sm1, m1);++ BenchTimer timer;+ timer.start();+ FullPivLU<DenseMatrix> lu(m1);+ timer.stop();+ std::cout << "Eigen/dense:\t" << timer.value() << endl;++ timer.reset();+ timer.start();+ lu.solve(b,&x);+ timer.stop();+ std::cout << " solve:\t" << timer.value() << endl;+// std::cout << b.transpose() << "\n";+// std::cout << x.transpose() << "\n";+ }+ #endif++ #ifdef EIGEN_UMFPACK_SUPPORT+ x.setZero();+ doEigen<Eigen::UmfPack>("Eigen/UmfPack (auto)", sm1, b, x, 0);+ #endif++ #ifdef EIGEN_SUPERLU_SUPPORT+ x.setZero();+ doEigen<Eigen::SuperLU>("Eigen/SuperLU (nat)", sm1, b, x, Eigen::NaturalOrdering);+// doEigen<Eigen::SuperLU>("Eigen/SuperLU (MD AT+A)", sm1, b, x, Eigen::MinimumDegree_AT_PLUS_A);+// doEigen<Eigen::SuperLU>("Eigen/SuperLU (MD ATA)", sm1, b, x, Eigen::MinimumDegree_ATA);+ doEigen<Eigen::SuperLU>("Eigen/SuperLU (COLAMD)", sm1, b, x, Eigen::ColApproxMinimumDegree);+ #endif++ }++ return 0;+}+
+ eigen3/bench/sparse_product.cpp view
@@ -0,0 +1,323 @@++//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.005 -DSIZE=10000 && ./a.out+//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.05 -DSIZE=2000 && ./a.out+// -DNOGMM -DNOMTL -DCSPARSE+// -I /home/gael/Coding/LinearAlgebra/CSparse/Include/ /home/gael/Coding/LinearAlgebra/CSparse/Lib/libcsparse.a++#include <typeinfo>++#ifndef SIZE+#define SIZE 1000000+#endif++#ifndef NNZPERCOL+#define NNZPERCOL 6+#endif++#ifndef REPEAT+#define REPEAT 1+#endif++#include <algorithm>+#include "BenchTimer.h"+#include "BenchUtil.h"+#include "BenchSparseUtil.h"++#ifndef NBTRIES+#define NBTRIES 1+#endif++#define BENCH(X) \+ timer.reset(); \+ for (int _j=0; _j<NBTRIES; ++_j) { \+ timer.start(); \+ for (int _k=0; _k<REPEAT; ++_k) { \+ X \+ } timer.stop(); }++// #ifdef MKL+//+// #include "mkl_types.h"+// #include "mkl_spblas.h"+//+// template<typename Lhs,typename Rhs,typename Res>+// void mkl_multiply(const Lhs& lhs, const Rhs& rhs, Res& res)+// {+// char n = 'N';+// float alpha = 1;+// char matdescra[6];+// matdescra[0] = 'G';+// matdescra[1] = 0;+// matdescra[2] = 0;+// matdescra[3] = 'C';+// mkl_scscmm(&n, lhs.rows(), rhs.cols(), lhs.cols(), &alpha, matdescra,+// lhs._valuePtr(), lhs._innerIndexPtr(), lhs.outerIndexPtr(),+// pntre, b, &ldb, &beta, c, &ldc);+// // mkl_somatcopy('C', 'T', lhs.rows(), lhs.cols(), 1,+// // lhs._valuePtr(), lhs.rows(), DST, dst_stride);+// }+//+// #endif+++#ifdef CSPARSE+cs* cs_sorted_multiply(const cs* a, const cs* b)+{+// return cs_multiply(a,b);++ cs* A = cs_transpose(a, 1);+ cs* B = cs_transpose(b, 1);+ cs* D = cs_multiply(B,A); /* D = B'*A' */+ cs_spfree (A) ;+ cs_spfree (B) ;+ cs_dropzeros (D) ; /* drop zeros from D */+ cs* C = cs_transpose (D, 1) ; /* C = D', so that C is sorted */+ cs_spfree (D) ;+ return C;++// cs* A = cs_transpose(a, 1);+// cs* C = cs_transpose(A, 1);+// return C;+}++cs* cs_sorted_multiply2(const cs* a, const cs* b)+{+ cs* D = cs_multiply(a,b);+ cs* E = cs_transpose(D,1);+ cs_spfree(D);+ cs* C = cs_transpose(E,1);+ cs_spfree(E);+ return C;+}+#endif++void bench_sort();++int main(int argc, char *argv[])+{+// bench_sort();++ int rows = SIZE;+ int cols = SIZE;+ float density = DENSITY;++ EigenSparseMatrix sm1(rows,cols), sm2(rows,cols), sm3(rows,cols), sm4(rows,cols);++ BenchTimer timer;+ for (int nnzPerCol = NNZPERCOL; nnzPerCol>1; nnzPerCol/=1.1)+ {+ sm1.setZero();+ sm2.setZero();+ fillMatrix2(nnzPerCol, rows, cols, sm1);+ fillMatrix2(nnzPerCol, rows, cols, sm2);+// std::cerr << "filling OK\n";++ // dense matrices+ #ifdef DENSEMATRIX+ {+ std::cout << "Eigen Dense\t" << nnzPerCol << "%\n";+ DenseMatrix m1(rows,cols), m2(rows,cols), m3(rows,cols);+ eiToDense(sm1, m1);+ eiToDense(sm2, m2);++ timer.reset();+ timer.start();+ for (int k=0; k<REPEAT; ++k)+ m3 = m1 * m2;+ timer.stop();+ std::cout << " a * b:\t" << timer.value() << endl;++ timer.reset();+ timer.start();+ for (int k=0; k<REPEAT; ++k)+ m3 = m1.transpose() * m2;+ timer.stop();+ std::cout << " a' * b:\t" << timer.value() << endl;++ timer.reset();+ timer.start();+ for (int k=0; k<REPEAT; ++k)+ m3 = m1.transpose() * m2.transpose();+ timer.stop();+ std::cout << " a' * b':\t" << timer.value() << endl;++ timer.reset();+ timer.start();+ for (int k=0; k<REPEAT; ++k)+ m3 = m1 * m2.transpose();+ timer.stop();+ std::cout << " a * b':\t" << timer.value() << endl;+ }+ #endif++ // eigen sparse matrices+ {+ std::cout << "Eigen sparse\t" << sm1.nonZeros()/(float(sm1.rows())*float(sm1.cols()))*100 << "% * "+ << sm2.nonZeros()/(float(sm2.rows())*float(sm2.cols()))*100 << "%\n";++ BENCH(sm3 = sm1 * sm2; )+ std::cout << " a * b:\t" << timer.value() << endl;++// BENCH(sm3 = sm1.transpose() * sm2; )+// std::cout << " a' * b:\t" << timer.value() << endl;+// //+// BENCH(sm3 = sm1.transpose() * sm2.transpose(); )+// std::cout << " a' * b':\t" << timer.value() << endl;+// //+// BENCH(sm3 = sm1 * sm2.transpose(); )+// std::cout << " a * b' :\t" << timer.value() << endl;+++// std::cout << "\n";+//+// BENCH( sm3._experimentalNewProduct(sm1, sm2); )+// std::cout << " a * b:\t" << timer.value() << endl;+//+// BENCH(sm3._experimentalNewProduct(sm1.transpose(),sm2); )+// std::cout << " a' * b:\t" << timer.value() << endl;+// //+// BENCH(sm3._experimentalNewProduct(sm1.transpose(),sm2.transpose()); )+// std::cout << " a' * b':\t" << timer.value() << endl;+// //+// BENCH(sm3._experimentalNewProduct(sm1, sm2.transpose());)+// std::cout << " a * b' :\t" << timer.value() << endl;+ }++ // eigen dyn-sparse matrices+ /*{+ DynamicSparseMatrix<Scalar> m1(sm1), m2(sm2), m3(sm3);+ std::cout << "Eigen dyn-sparse\t" << m1.nonZeros()/(float(m1.rows())*float(m1.cols()))*100 << "% * "+ << m2.nonZeros()/(float(m2.rows())*float(m2.cols()))*100 << "%\n";++// timer.reset();+// timer.start();+ BENCH(for (int k=0; k<REPEAT; ++k) m3 = m1 * m2;)+// timer.stop();+ std::cout << " a * b:\t" << timer.value() << endl;+// std::cout << sm3 << "\n";++ timer.reset();+ timer.start();+// std::cerr << "transpose...\n";+// EigenSparseMatrix sm4 = sm1.transpose();+// std::cout << sm4.nonZeros() << " == " << sm1.nonZeros() << "\n";+// exit(1);+// std::cerr << "transpose OK\n";+// std::cout << sm1 << "\n\n" << sm1.transpose() << "\n\n" << sm4.transpose() << "\n\n";+ BENCH(for (int k=0; k<REPEAT; ++k) m3 = m1.transpose() * m2;)+// timer.stop();+ std::cout << " a' * b:\t" << timer.value() << endl;++// timer.reset();+// timer.start();+ BENCH( for (int k=0; k<REPEAT; ++k) m3 = m1.transpose() * m2.transpose(); )+// timer.stop();+ std::cout << " a' * b':\t" << timer.value() << endl;++// timer.reset();+// timer.start();+ BENCH( for (int k=0; k<REPEAT; ++k) m3 = m1 * m2.transpose(); )+// timer.stop();+ std::cout << " a * b' :\t" << timer.value() << endl;+ }*/++ // CSparse+ #ifdef CSPARSE+ {+ std::cout << "CSparse \t" << nnzPerCol << "%\n";+ cs *m1, *m2, *m3;+ eiToCSparse(sm1, m1);+ eiToCSparse(sm2, m2);++ BENCH(+ {+ m3 = cs_sorted_multiply(m1, m2);+ if (!m3)+ {+ std::cerr << "cs_multiply failed\n";+ }+// cs_print(m3, 0);+ cs_spfree(m3);+ }+ );+// timer.stop();+ std::cout << " a * b:\t" << timer.value() << endl;++// BENCH( { m3 = cs_sorted_multiply2(m1, m2); cs_spfree(m3); } );+// std::cout << " a * b:\t" << timer.value() << endl;+ }+ #endif++ #ifndef NOUBLAS+ {+ std::cout << "ublas\t" << nnzPerCol << "%\n";+ UBlasSparse m1(rows,cols), m2(rows,cols), m3(rows,cols);+ eiToUblas(sm1, m1);+ eiToUblas(sm2, m2);++ BENCH(boost::numeric::ublas::prod(m1, m2, m3););+ std::cout << " a * b:\t" << timer.value() << endl;+ }+ #endif++ // GMM+++ #ifndef NOGMM+ {+ std::cout << "GMM++ sparse\t" << nnzPerCol << "%\n";+ GmmDynSparse gmmT3(rows,cols);+ GmmSparse m1(rows,cols), m2(rows,cols), m3(rows,cols);+ eiToGmm(sm1, m1);+ eiToGmm(sm2, m2);++ BENCH(gmm::mult(m1, m2, gmmT3););+ std::cout << " a * b:\t" << timer.value() << endl;++// BENCH(gmm::mult(gmm::transposed(m1), m2, gmmT3););+// std::cout << " a' * b:\t" << timer.value() << endl;+//+// if (rows<500)+// {+// BENCH(gmm::mult(gmm::transposed(m1), gmm::transposed(m2), gmmT3););+// std::cout << " a' * b':\t" << timer.value() << endl;+//+// BENCH(gmm::mult(m1, gmm::transposed(m2), gmmT3););+// std::cout << " a * b':\t" << timer.value() << endl;+// }+// else+// {+// std::cout << " a' * b':\t" << "forever" << endl;+// std::cout << " a * b':\t" << "forever" << endl;+// }+ }+ #endif++ // MTL4+ #ifndef NOMTL+ {+ std::cout << "MTL4\t" << nnzPerCol << "%\n";+ MtlSparse m1(rows,cols), m2(rows,cols), m3(rows,cols);+ eiToMtl(sm1, m1);+ eiToMtl(sm2, m2);++ BENCH(m3 = m1 * m2;);+ std::cout << " a * b:\t" << timer.value() << endl;++// BENCH(m3 = trans(m1) * m2;);+// std::cout << " a' * b:\t" << timer.value() << endl;+//+// BENCH(m3 = trans(m1) * trans(m2););+// std::cout << " a' * b':\t" << timer.value() << endl;+//+// BENCH(m3 = m1 * trans(m2););+// std::cout << " a * b' :\t" << timer.value() << endl;+ }+ #endif++ std::cout << "\n\n";+ }++ return 0;+}+++
+ eigen3/bench/sparse_randomsetter.cpp view
@@ -0,0 +1,125 @@++#define NOGMM+#define NOMTL++#include <map>+#include <ext/hash_map>+#include <google/dense_hash_map>+#include <google/sparse_hash_map>++#ifndef SIZE+#define SIZE 10000+#endif++#ifndef DENSITY+#define DENSITY 0.01+#endif++#ifndef REPEAT+#define REPEAT 1+#endif++#include "BenchSparseUtil.h"++#ifndef MINDENSITY+#define MINDENSITY 0.0004+#endif++#ifndef NBTRIES+#define NBTRIES 10+#endif++#define BENCH(X) \+ timer.reset(); \+ for (int _j=0; _j<NBTRIES; ++_j) { \+ timer.start(); \+ for (int _k=0; _k<REPEAT; ++_k) { \+ X \+ } timer.stop(); }+++static double rtime;+static double nentries;++template<typename SetterType>+void dostuff(const char* name, EigenSparseMatrix& sm1)+{+ int rows = sm1.rows();+ int cols = sm1.cols();+ sm1.setZero();+ BenchTimer t;+ SetterType* set1 = new SetterType(sm1);+ t.reset(); t.start();+ for (int k=0; k<nentries; ++k)+ (*set1)(internal::random<int>(0,rows-1),internal::random<int>(0,cols-1)) += 1;+ t.stop();+ std::cout << "std::map => \t" << t.value()-rtime+ << " nnz=" << set1->nonZeros() << std::flush;++ // getchar();++ t.reset(); t.start(); delete set1; t.stop();+ std::cout << " back: \t" << t.value() << "\n";+}+ +int main(int argc, char *argv[])+{+ int rows = SIZE;+ int cols = SIZE;+ float density = DENSITY;++ EigenSparseMatrix sm1(rows,cols), sm2(rows,cols);+++ nentries = rows*cols*density;+ std::cout << "n = " << nentries << "\n";+ int dummy;+ BenchTimer t;++ t.reset(); t.start();+ for (int k=0; k<nentries; ++k)+ dummy = internal::random<int>(0,rows-1) + internal::random<int>(0,cols-1);+ t.stop();+ rtime = t.value();+ std::cout << "rtime = " << rtime << " (" << dummy << ")\n\n";+ const int Bits = 6;+ for (;;)+ {+ dostuff<RandomSetter<EigenSparseMatrix,StdMapTraits,Bits> >("std::map ", sm1);+ dostuff<RandomSetter<EigenSparseMatrix,GnuHashMapTraits,Bits> >("gnu::hash_map", sm1);+ dostuff<RandomSetter<EigenSparseMatrix,GoogleDenseHashMapTraits,Bits> >("google::dense", sm1);+ dostuff<RandomSetter<EigenSparseMatrix,GoogleSparseHashMapTraits,Bits> >("google::sparse", sm1);++// {+// RandomSetter<EigenSparseMatrix,GnuHashMapTraits,Bits> set1(sm1);+// t.reset(); t.start();+// for (int k=0; k<n; ++k)+// set1(internal::random<int>(0,rows-1),internal::random<int>(0,cols-1)) += 1;+// t.stop();+// std::cout << "gnu::hash_map => \t" << t.value()-rtime+// << " nnz=" << set1.nonZeros() << "\n";getchar();+// }+// {+// RandomSetter<EigenSparseMatrix,GoogleDenseHashMapTraits,Bits> set1(sm1);+// t.reset(); t.start();+// for (int k=0; k<n; ++k)+// set1(internal::random<int>(0,rows-1),internal::random<int>(0,cols-1)) += 1;+// t.stop();+// std::cout << "google::dense => \t" << t.value()-rtime+// << " nnz=" << set1.nonZeros() << "\n";getchar();+// }+// {+// RandomSetter<EigenSparseMatrix,GoogleSparseHashMapTraits,Bits> set1(sm1);+// t.reset(); t.start();+// for (int k=0; k<n; ++k)+// set1(internal::random<int>(0,rows-1),internal::random<int>(0,cols-1)) += 1;+// t.stop();+// std::cout << "google::sparse => \t" << t.value()-rtime+// << " nnz=" << set1.nonZeros() << "\n";getchar();+// }+ std::cout << "\n\n";+ }++ return 0;+}+
+ eigen3/bench/sparse_setter.cpp view
@@ -0,0 +1,485 @@++//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.005 -DSIZE=10000 && ./a.out+//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.05 -DSIZE=2000 && ./a.out+// -DNOGMM -DNOMTL -DCSPARSE+// -I /home/gael/Coding/LinearAlgebra/CSparse/Include/ /home/gael/Coding/LinearAlgebra/CSparse/Lib/libcsparse.a+#ifndef SIZE+#define SIZE 100000+#endif++#ifndef NBPERROW+#define NBPERROW 24+#endif++#ifndef REPEAT+#define REPEAT 2+#endif++#ifndef NBTRIES+#define NBTRIES 2+#endif++#ifndef KK+#define KK 10+#endif++#ifndef NOGOOGLE+#define EIGEN_GOOGLEHASH_SUPPORT+#include <google/sparse_hash_map>+#endif++#include "BenchSparseUtil.h"++#define CHECK_MEM+// #define CHECK_MEM std/**/::cout << "check mem\n"; getchar();++#define BENCH(X) \+ timer.reset(); \+ for (int _j=0; _j<NBTRIES; ++_j) { \+ timer.start(); \+ for (int _k=0; _k<REPEAT; ++_k) { \+ X \+ } timer.stop(); }++typedef std::vector<Vector2i> Coordinates;+typedef std::vector<float> Values;++EIGEN_DONT_INLINE Scalar* setinnerrand_eigen(const Coordinates& coords, const Values& vals);+EIGEN_DONT_INLINE Scalar* setrand_eigen_dynamic(const Coordinates& coords, const Values& vals);+EIGEN_DONT_INLINE Scalar* setrand_eigen_compact(const Coordinates& coords, const Values& vals);+EIGEN_DONT_INLINE Scalar* setrand_eigen_sumeq(const Coordinates& coords, const Values& vals);+EIGEN_DONT_INLINE Scalar* setrand_eigen_gnu_hash(const Coordinates& coords, const Values& vals);+EIGEN_DONT_INLINE Scalar* setrand_eigen_google_dense(const Coordinates& coords, const Values& vals);+EIGEN_DONT_INLINE Scalar* setrand_eigen_google_sparse(const Coordinates& coords, const Values& vals);+EIGEN_DONT_INLINE Scalar* setrand_scipy(const Coordinates& coords, const Values& vals);+EIGEN_DONT_INLINE Scalar* setrand_ublas_mapped(const Coordinates& coords, const Values& vals);+EIGEN_DONT_INLINE Scalar* setrand_ublas_coord(const Coordinates& coords, const Values& vals);+EIGEN_DONT_INLINE Scalar* setrand_ublas_compressed(const Coordinates& coords, const Values& vals);+EIGEN_DONT_INLINE Scalar* setrand_ublas_genvec(const Coordinates& coords, const Values& vals);+EIGEN_DONT_INLINE Scalar* setrand_mtl(const Coordinates& coords, const Values& vals);++int main(int argc, char *argv[])+{+ int rows = SIZE;+ int cols = SIZE;+ bool fullyrand = true;++ BenchTimer timer;+ Coordinates coords;+ Values values;+ if(fullyrand)+ {+ Coordinates pool;+ pool.reserve(cols*NBPERROW);+ std::cerr << "fill pool" << "\n";+ for (int i=0; i<cols*NBPERROW; )+ {+// DynamicSparseMatrix<int> stencil(SIZE,SIZE);+ Vector2i ij(internal::random<int>(0,rows-1),internal::random<int>(0,cols-1));+// if(stencil.coeffRef(ij.x(), ij.y())==0)+ {+// stencil.coeffRef(ij.x(), ij.y()) = 1;+ pool.push_back(ij);++ }+ ++i;+ }+ std::cerr << "pool ok" << "\n";+ int n = cols*NBPERROW*KK;+ coords.reserve(n);+ values.reserve(n);+ for (int i=0; i<n; ++i)+ {+ int i = internal::random<int>(0,pool.size());+ coords.push_back(pool[i]);+ values.push_back(internal::random<Scalar>());+ }+ }+ else+ {+ for (int j=0; j<cols; ++j)+ for (int i=0; i<NBPERROW; ++i)+ {+ coords.push_back(Vector2i(internal::random<int>(0,rows-1),j));+ values.push_back(internal::random<Scalar>());+ }+ }+ std::cout << "nnz = " << coords.size() << "\n";+ CHECK_MEM++ // dense matrices+ #ifdef DENSEMATRIX+ {+ BENCH(setrand_eigen_dense(coords,values);)+ std::cout << "Eigen Dense\t" << timer.value() << "\n";+ }+ #endif++ // eigen sparse matrices+// if (!fullyrand)+// {+// BENCH(setinnerrand_eigen(coords,values);)+// std::cout << "Eigen fillrand\t" << timer.value() << "\n";+// }+ {+ BENCH(setrand_eigen_dynamic(coords,values);)+ std::cout << "Eigen dynamic\t" << timer.value() << "\n";+ }+// {+// BENCH(setrand_eigen_compact(coords,values);)+// std::cout << "Eigen compact\t" << timer.value() << "\n";+// }+ {+ BENCH(setrand_eigen_sumeq(coords,values);)+ std::cout << "Eigen sumeq\t" << timer.value() << "\n";+ }+ {+// BENCH(setrand_eigen_gnu_hash(coords,values);)+// std::cout << "Eigen std::map\t" << timer.value() << "\n";+ }+ {+ BENCH(setrand_scipy(coords,values);)+ std::cout << "scipy\t" << timer.value() << "\n";+ }+ #ifndef NOGOOGLE+ {+ BENCH(setrand_eigen_google_dense(coords,values);)+ std::cout << "Eigen google dense\t" << timer.value() << "\n";+ }+ {+ BENCH(setrand_eigen_google_sparse(coords,values);)+ std::cout << "Eigen google sparse\t" << timer.value() << "\n";+ }+ #endif++ #ifndef NOUBLAS+ {+// BENCH(setrand_ublas_mapped(coords,values);)+// std::cout << "ublas mapped\t" << timer.value() << "\n";+ }+ {+ BENCH(setrand_ublas_genvec(coords,values);)+ std::cout << "ublas vecofvec\t" << timer.value() << "\n";+ }+ /*{+ timer.reset();+ timer.start();+ for (int k=0; k<REPEAT; ++k)+ setrand_ublas_compressed(coords,values);+ timer.stop();+ std::cout << "ublas comp\t" << timer.value() << "\n";+ }+ {+ timer.reset();+ timer.start();+ for (int k=0; k<REPEAT; ++k)+ setrand_ublas_coord(coords,values);+ timer.stop();+ std::cout << "ublas coord\t" << timer.value() << "\n";+ }*/+ #endif+++ // MTL4+ #ifndef NOMTL+ {+ BENCH(setrand_mtl(coords,values));+ std::cout << "MTL\t" << timer.value() << "\n";+ }+ #endif++ return 0;+}++EIGEN_DONT_INLINE Scalar* setinnerrand_eigen(const Coordinates& coords, const Values& vals)+{+ using namespace Eigen;+ SparseMatrix<Scalar> mat(SIZE,SIZE);+ //mat.startFill(2000000/*coords.size()*/);+ for (int i=0; i<coords.size(); ++i)+ {+ mat.insert(coords[i].x(), coords[i].y()) = vals[i];+ }+ mat.finalize();+ CHECK_MEM;+ return 0;+}++EIGEN_DONT_INLINE Scalar* setrand_eigen_dynamic(const Coordinates& coords, const Values& vals)+{+ using namespace Eigen;+ DynamicSparseMatrix<Scalar> mat(SIZE,SIZE);+ mat.reserve(coords.size()/10);+ for (int i=0; i<coords.size(); ++i)+ {+ mat.coeffRef(coords[i].x(), coords[i].y()) += vals[i];+ }+ mat.finalize();+ CHECK_MEM;+ return &mat.coeffRef(coords[0].x(), coords[0].y());+}++EIGEN_DONT_INLINE Scalar* setrand_eigen_sumeq(const Coordinates& coords, const Values& vals)+{+ using namespace Eigen;+ int n = coords.size()/KK;+ DynamicSparseMatrix<Scalar> mat(SIZE,SIZE);+ for (int j=0; j<KK; ++j)+ {+ DynamicSparseMatrix<Scalar> aux(SIZE,SIZE);+ mat.reserve(n);+ for (int i=j*n; i<(j+1)*n; ++i)+ {+ aux.insert(coords[i].x(), coords[i].y()) += vals[i];+ }+ aux.finalize();+ mat += aux;+ }+ return &mat.coeffRef(coords[0].x(), coords[0].y());+}++EIGEN_DONT_INLINE Scalar* setrand_eigen_compact(const Coordinates& coords, const Values& vals)+{+ using namespace Eigen;+ DynamicSparseMatrix<Scalar> setter(SIZE,SIZE);+ setter.reserve(coords.size()/10);+ for (int i=0; i<coords.size(); ++i)+ {+ setter.coeffRef(coords[i].x(), coords[i].y()) += vals[i];+ }+ SparseMatrix<Scalar> mat = setter;+ CHECK_MEM;+ return &mat.coeffRef(coords[0].x(), coords[0].y());+}++EIGEN_DONT_INLINE Scalar* setrand_eigen_gnu_hash(const Coordinates& coords, const Values& vals)+{+ using namespace Eigen;+ SparseMatrix<Scalar> mat(SIZE,SIZE);+ {+ RandomSetter<SparseMatrix<Scalar>, StdMapTraits > setter(mat);+ for (int i=0; i<coords.size(); ++i)+ {+ setter(coords[i].x(), coords[i].y()) += vals[i];+ }+ CHECK_MEM;+ }+ return &mat.coeffRef(coords[0].x(), coords[0].y());+}++#ifndef NOGOOGLE+EIGEN_DONT_INLINE Scalar* setrand_eigen_google_dense(const Coordinates& coords, const Values& vals)+{+ using namespace Eigen;+ SparseMatrix<Scalar> mat(SIZE,SIZE);+ {+ RandomSetter<SparseMatrix<Scalar>, GoogleDenseHashMapTraits> setter(mat);+ for (int i=0; i<coords.size(); ++i)+ setter(coords[i].x(), coords[i].y()) += vals[i];+ CHECK_MEM;+ }+ return &mat.coeffRef(coords[0].x(), coords[0].y());+}++EIGEN_DONT_INLINE Scalar* setrand_eigen_google_sparse(const Coordinates& coords, const Values& vals)+{+ using namespace Eigen;+ SparseMatrix<Scalar> mat(SIZE,SIZE);+ {+ RandomSetter<SparseMatrix<Scalar>, GoogleSparseHashMapTraits> setter(mat);+ for (int i=0; i<coords.size(); ++i)+ setter(coords[i].x(), coords[i].y()) += vals[i];+ CHECK_MEM;+ }+ return &mat.coeffRef(coords[0].x(), coords[0].y());+}+#endif+++template <class T>+void coo_tocsr(const int n_row,+ const int n_col,+ const int nnz,+ const Coordinates Aij,+ const Values Ax,+ int Bp[],+ int Bj[],+ T Bx[])+{+ //compute number of non-zero entries per row of A coo_tocsr+ std::fill(Bp, Bp + n_row, 0);++ for (int n = 0; n < nnz; n++){+ Bp[Aij[n].x()]++;+ }++ //cumsum the nnz per row to get Bp[]+ for(int i = 0, cumsum = 0; i < n_row; i++){+ int temp = Bp[i];+ Bp[i] = cumsum;+ cumsum += temp;+ }+ Bp[n_row] = nnz;++ //write Aj,Ax into Bj,Bx+ for(int n = 0; n < nnz; n++){+ int row = Aij[n].x();+ int dest = Bp[row];++ Bj[dest] = Aij[n].y();+ Bx[dest] = Ax[n];++ Bp[row]++;+ }++ for(int i = 0, last = 0; i <= n_row; i++){+ int temp = Bp[i];+ Bp[i] = last;+ last = temp;+ }++ //now Bp,Bj,Bx form a CSR representation (with possible duplicates)+}++template< class T1, class T2 >+bool kv_pair_less(const std::pair<T1,T2>& x, const std::pair<T1,T2>& y){+ return x.first < y.first;+}+++template<class I, class T>+void csr_sort_indices(const I n_row,+ const I Ap[],+ I Aj[],+ T Ax[])+{+ std::vector< std::pair<I,T> > temp;++ for(I i = 0; i < n_row; i++){+ I row_start = Ap[i];+ I row_end = Ap[i+1];++ temp.clear();++ for(I jj = row_start; jj < row_end; jj++){+ temp.push_back(std::make_pair(Aj[jj],Ax[jj]));+ }++ std::sort(temp.begin(),temp.end(),kv_pair_less<I,T>);++ for(I jj = row_start, n = 0; jj < row_end; jj++, n++){+ Aj[jj] = temp[n].first;+ Ax[jj] = temp[n].second;+ }+ }+}++template <class I, class T>+void csr_sum_duplicates(const I n_row,+ const I n_col,+ I Ap[],+ I Aj[],+ T Ax[])+{+ I nnz = 0;+ I row_end = 0;+ for(I i = 0; i < n_row; i++){+ I jj = row_end;+ row_end = Ap[i+1];+ while( jj < row_end ){+ I j = Aj[jj];+ T x = Ax[jj];+ jj++;+ while( jj < row_end && Aj[jj] == j ){+ x += Ax[jj];+ jj++;+ }+ Aj[nnz] = j;+ Ax[nnz] = x;+ nnz++;+ }+ Ap[i+1] = nnz;+ }+}++EIGEN_DONT_INLINE Scalar* setrand_scipy(const Coordinates& coords, const Values& vals)+{+ using namespace Eigen;+ SparseMatrix<Scalar> mat(SIZE,SIZE);+ mat.resizeNonZeros(coords.size());+// std::cerr << "setrand_scipy...\n";+ coo_tocsr<Scalar>(SIZE,SIZE, coords.size(), coords, vals, mat._outerIndexPtr(), mat._innerIndexPtr(), mat._valuePtr());+// std::cerr << "coo_tocsr ok\n";++ csr_sort_indices(SIZE, mat._outerIndexPtr(), mat._innerIndexPtr(), mat._valuePtr());++ csr_sum_duplicates(SIZE, SIZE, mat._outerIndexPtr(), mat._innerIndexPtr(), mat._valuePtr());++ mat.resizeNonZeros(mat._outerIndexPtr()[SIZE]);++ return &mat.coeffRef(coords[0].x(), coords[0].y());+}+++#ifndef NOUBLAS+EIGEN_DONT_INLINE Scalar* setrand_ublas_mapped(const Coordinates& coords, const Values& vals)+{+ using namespace boost;+ using namespace boost::numeric;+ using namespace boost::numeric::ublas;+ mapped_matrix<Scalar> aux(SIZE,SIZE);+ for (int i=0; i<coords.size(); ++i)+ {+ aux(coords[i].x(), coords[i].y()) += vals[i];+ }+ CHECK_MEM;+ compressed_matrix<Scalar> mat(aux);+ return 0;// &mat(coords[0].x(), coords[0].y());+}+/*EIGEN_DONT_INLINE Scalar* setrand_ublas_coord(const Coordinates& coords, const Values& vals)+{+ using namespace boost;+ using namespace boost::numeric;+ using namespace boost::numeric::ublas;+ coordinate_matrix<Scalar> aux(SIZE,SIZE);+ for (int i=0; i<coords.size(); ++i)+ {+ aux(coords[i].x(), coords[i].y()) = vals[i];+ }+ compressed_matrix<Scalar> mat(aux);+ return 0;//&mat(coords[0].x(), coords[0].y());+}+EIGEN_DONT_INLINE Scalar* setrand_ublas_compressed(const Coordinates& coords, const Values& vals)+{+ using namespace boost;+ using namespace boost::numeric;+ using namespace boost::numeric::ublas;+ compressed_matrix<Scalar> mat(SIZE,SIZE);+ for (int i=0; i<coords.size(); ++i)+ {+ mat(coords[i].x(), coords[i].y()) = vals[i];+ }+ return 0;//&mat(coords[0].x(), coords[0].y());+}*/+EIGEN_DONT_INLINE Scalar* setrand_ublas_genvec(const Coordinates& coords, const Values& vals)+{+ using namespace boost;+ using namespace boost::numeric;+ using namespace boost::numeric::ublas;++// ublas::vector<coordinate_vector<Scalar> > foo;+ generalized_vector_of_vector<Scalar, row_major, ublas::vector<coordinate_vector<Scalar> > > aux(SIZE,SIZE);+ for (int i=0; i<coords.size(); ++i)+ {+ aux(coords[i].x(), coords[i].y()) += vals[i];+ }+ CHECK_MEM;+ compressed_matrix<Scalar,row_major> mat(aux);+ return 0;//&mat(coords[0].x(), coords[0].y());+}+#endif++#ifndef NOMTL+EIGEN_DONT_INLINE void setrand_mtl(const Coordinates& coords, const Values& vals);+#endif+
+ eigen3/bench/sparse_transpose.cpp view
@@ -0,0 +1,104 @@++//g++ -O3 -g0 -DNDEBUG sparse_transpose.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.005 -DSIZE=10000 && ./a.out+// -DNOGMM -DNOMTL+// -DCSPARSE -I /home/gael/Coding/LinearAlgebra/CSparse/Include/ /home/gael/Coding/LinearAlgebra/CSparse/Lib/libcsparse.a++#ifndef SIZE+#define SIZE 10000+#endif++#ifndef DENSITY+#define DENSITY 0.01+#endif++#ifndef REPEAT+#define REPEAT 1+#endif++#include "BenchSparseUtil.h"++#ifndef MINDENSITY+#define MINDENSITY 0.0004+#endif++#ifndef NBTRIES+#define NBTRIES 10+#endif++#define BENCH(X) \+ timer.reset(); \+ for (int _j=0; _j<NBTRIES; ++_j) { \+ timer.start(); \+ for (int _k=0; _k<REPEAT; ++_k) { \+ X \+ } timer.stop(); }++int main(int argc, char *argv[])+{+ int rows = SIZE;+ int cols = SIZE;+ float density = DENSITY;++ EigenSparseMatrix sm1(rows,cols), sm3(rows,cols);++ BenchTimer timer;+ for (float density = DENSITY; density>=MINDENSITY; density*=0.5)+ {+ fillMatrix(density, rows, cols, sm1);++ // dense matrices+ #ifdef DENSEMATRIX+ {+ DenseMatrix m1(rows,cols), m3(rows,cols);+ eiToDense(sm1, m1);+ BENCH(for (int k=0; k<REPEAT; ++k) m3 = m1.transpose();)+ std::cout << " Eigen dense:\t" << timer.value() << endl;+ }+ #endif++ std::cout << "Non zeros: " << sm1.nonZeros()/float(sm1.rows()*sm1.cols())*100 << "%\n";++ // eigen sparse matrices+ {+ BENCH(for (int k=0; k<REPEAT; ++k) sm3 = sm1.transpose();)+ std::cout << " Eigen:\t" << timer.value() << endl;+ }++ // CSparse+ #ifdef CSPARSE+ {+ cs *m1, *m3;+ eiToCSparse(sm1, m1);++ BENCH(for (int k=0; k<REPEAT; ++k) { m3 = cs_transpose(m1,1); cs_spfree(m3);})+ std::cout << " CSparse:\t" << timer.value() << endl;+ }+ #endif++ // GMM+++ #ifndef NOGMM+ {+ GmmDynSparse gmmT3(rows,cols);+ GmmSparse m1(rows,cols), m3(rows,cols);+ eiToGmm(sm1, m1);+ BENCH(for (int k=0; k<REPEAT; ++k) gmm::copy(gmm::transposed(m1),m3);)+ std::cout << " GMM:\t\t" << timer.value() << endl;+ }+ #endif++ // MTL4+ #ifndef NOMTL+ {+ MtlSparse m1(rows,cols), m3(rows,cols);+ eiToMtl(sm1, m1);+ BENCH(for (int k=0; k<REPEAT; ++k) m3 = trans(m1);)+ std::cout << " MTL4:\t\t" << timer.value() << endl;+ }+ #endif++ std::cout << "\n\n";+ }++ return 0;+}+
+ eigen3/bench/sparse_trisolver.cpp view
@@ -0,0 +1,220 @@++//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.005 -DSIZE=10000 && ./a.out+//g++ -O3 -g0 -DNDEBUG sparse_product.cpp -I.. -I/home/gael/Coding/LinearAlgebra/mtl4/ -DDENSITY=0.05 -DSIZE=2000 && ./a.out+// -DNOGMM -DNOMTL+// -I /home/gael/Coding/LinearAlgebra/CSparse/Include/ /home/gael/Coding/LinearAlgebra/CSparse/Lib/libcsparse.a++#ifndef SIZE+#define SIZE 10000+#endif++#ifndef DENSITY+#define DENSITY 0.01+#endif++#ifndef REPEAT+#define REPEAT 1+#endif++#include "BenchSparseUtil.h"++#ifndef MINDENSITY+#define MINDENSITY 0.0004+#endif++#ifndef NBTRIES+#define NBTRIES 10+#endif++#define BENCH(X) \+ timer.reset(); \+ for (int _j=0; _j<NBTRIES; ++_j) { \+ timer.start(); \+ for (int _k=0; _k<REPEAT; ++_k) { \+ X \+ } timer.stop(); }++typedef SparseMatrix<Scalar,UpperTriangular> EigenSparseTriMatrix;+typedef SparseMatrix<Scalar,RowMajorBit|UpperTriangular> EigenSparseTriMatrixRow;++void fillMatrix(float density, int rows, int cols, EigenSparseTriMatrix& dst)+{+ dst.startFill(rows*cols*density);+ for(int j = 0; j < cols; j++)+ {+ for(int i = 0; i < j; i++)+ {+ Scalar v = (internal::random<float>(0,1) < density) ? internal::random<Scalar>() : 0;+ if (v!=0)+ dst.fill(i,j) = v;+ }+ dst.fill(j,j) = internal::random<Scalar>();+ }+ dst.endFill();+}++int main(int argc, char *argv[])+{+ int rows = SIZE;+ int cols = SIZE;+ float density = DENSITY;+ BenchTimer timer;+ #if 1+ EigenSparseTriMatrix sm1(rows,cols);+ typedef Matrix<Scalar,Dynamic,1> DenseVector;+ DenseVector b = DenseVector::Random(cols);+ DenseVector x = DenseVector::Random(cols);++ bool densedone = false;++ for (float density = DENSITY; density>=MINDENSITY; density*=0.5)+ {+ EigenSparseTriMatrix sm1(rows, cols);+ fillMatrix(density, rows, cols, sm1);++ // dense matrices+ #ifdef DENSEMATRIX+ if (!densedone)+ {+ densedone = true;+ std::cout << "Eigen Dense\t" << density*100 << "%\n";+ DenseMatrix m1(rows,cols);+ Matrix<Scalar,Dynamic,Dynamic,Dynamic,Dynamic,RowMajorBit> m2(rows,cols);+ eiToDense(sm1, m1);+ m2 = m1;++ BENCH(x = m1.marked<UpperTriangular>().solveTriangular(b);)+ std::cout << " colmajor^-1 * b:\t" << timer.value() << endl;+// std::cerr << x.transpose() << "\n";++ BENCH(x = m2.marked<UpperTriangular>().solveTriangular(b);)+ std::cout << " rowmajor^-1 * b:\t" << timer.value() << endl;+// std::cerr << x.transpose() << "\n";+ }+ #endif++ // eigen sparse matrices+ {+ std::cout << "Eigen sparse\t" << density*100 << "%\n";+ EigenSparseTriMatrixRow sm2 = sm1;++ BENCH(x = sm1.solveTriangular(b);)+ std::cout << " colmajor^-1 * b:\t" << timer.value() << endl;+// std::cerr << x.transpose() << "\n";++ BENCH(x = sm2.solveTriangular(b);)+ std::cout << " rowmajor^-1 * b:\t" << timer.value() << endl;+// std::cerr << x.transpose() << "\n";++// x = b;+// BENCH(sm1.inverseProductInPlace(x);)+// std::cout << " colmajor^-1 * b:\t" << timer.value() << " (inplace)" << endl;+// std::cerr << x.transpose() << "\n";+//+// x = b;+// BENCH(sm2.inverseProductInPlace(x);)+// std::cout << " rowmajor^-1 * b:\t" << timer.value() << " (inplace)" << endl;+// std::cerr << x.transpose() << "\n";+ }++++ // CSparse+ #ifdef CSPARSE+ {+ std::cout << "CSparse \t" << density*100 << "%\n";+ cs *m1;+ eiToCSparse(sm1, m1);++ BENCH(x = b; if (!cs_lsolve (m1, x.data())){std::cerr << "cs_lsolve failed\n"; break;}; )+ std::cout << " colmajor^-1 * b:\t" << timer.value() << endl;+ }+ #endif++ // GMM+++ #ifndef NOGMM+ {+ std::cout << "GMM++ sparse\t" << density*100 << "%\n";+ GmmSparse m1(rows,cols);+ gmm::csr_matrix<Scalar> m2;+ eiToGmm(sm1, m1);+ gmm::copy(m1,m2);+ std::vector<Scalar> gmmX(cols), gmmB(cols);+ Map<Matrix<Scalar,Dynamic,1> >(&gmmX[0], cols) = x;+ Map<Matrix<Scalar,Dynamic,1> >(&gmmB[0], cols) = b;++ gmmX = gmmB;+ BENCH(gmm::upper_tri_solve(m1, gmmX, false);)+ std::cout << " colmajor^-1 * b:\t" << timer.value() << endl;+// std::cerr << Map<Matrix<Scalar,Dynamic,1> >(&gmmX[0], cols).transpose() << "\n";++ gmmX = gmmB;+ BENCH(gmm::upper_tri_solve(m2, gmmX, false);)+ timer.stop();+ std::cout << " rowmajor^-1 * b:\t" << timer.value() << endl;+// std::cerr << Map<Matrix<Scalar,Dynamic,1> >(&gmmX[0], cols).transpose() << "\n";+ }+ #endif++ // MTL4+ #ifndef NOMTL+ {+ std::cout << "MTL4\t" << density*100 << "%\n";+ MtlSparse m1(rows,cols);+ MtlSparseRowMajor m2(rows,cols);+ eiToMtl(sm1, m1);+ m2 = m1;+ mtl::dense_vector<Scalar> x(rows, 1.0);+ mtl::dense_vector<Scalar> b(rows, 1.0);++ BENCH(x = mtl::upper_trisolve(m1,b);)+ std::cout << " colmajor^-1 * b:\t" << timer.value() << endl;+// std::cerr << x << "\n";++ BENCH(x = mtl::upper_trisolve(m2,b);)+ std::cout << " rowmajor^-1 * b:\t" << timer.value() << endl;+// std::cerr << x << "\n";+ }+ #endif+++ std::cout << "\n\n";+ }+ #endif++ #if 0+ // bench small matrices (in-place versus return bye value)+ {+ timer.reset();+ for (int _j=0; _j<10; ++_j) {+ Matrix4f m = Matrix4f::Random();+ Vector4f b = Vector4f::Random();+ Vector4f x = Vector4f::Random();+ timer.start();+ for (int _k=0; _k<1000000; ++_k) {+ b = m.inverseProduct(b);+ }+ timer.stop();+ }+ std::cout << "4x4 :\t" << timer.value() << endl;+ }++ {+ timer.reset();+ for (int _j=0; _j<10; ++_j) {+ Matrix4f m = Matrix4f::Random();+ Vector4f b = Vector4f::Random();+ Vector4f x = Vector4f::Random();+ timer.start();+ for (int _k=0; _k<1000000; ++_k) {+ m.inverseProductInPlace(x);+ }+ timer.stop();+ }+ std::cout << "4x4 IP :\t" << timer.value() << endl;+ }+ #endif++ return 0;+}+
+ eigen3/bench/spbench/CMakeLists.txt view
@@ -0,0 +1,78 @@+++set(BLAS_FOUND TRUE)+set(LAPACK_FOUND TRUE)+set(BLAS_LIBRARIES eigen_blas_static)+set(LAPACK_LIBRARIES eigen_lapack_static)++set(SPARSE_LIBS "")++# find_library(PARDISO_LIBRARIES pardiso412-GNU450-X86-64)+# if(PARDISO_LIBRARIES)+# add_definitions("-DEIGEN_PARDISO_SUPPORT")+# set(SPARSE_LIBS ${SPARSE_LIBS} ${PARDISO_LIBRARIES})+# endif(PARDISO_LIBRARIES)++find_package(Cholmod)+if(CHOLMOD_FOUND AND BLAS_FOUND AND LAPACK_FOUND)+ add_definitions("-DEIGEN_CHOLMOD_SUPPORT")+ include_directories(${CHOLMOD_INCLUDES})+ set(SPARSE_LIBS ${SPARSE_LIBS} ${CHOLMOD_LIBRARIES} ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})+ set(CHOLMOD_ALL_LIBS ${CHOLMOD_LIBRARIES} ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})+endif()++find_package(Umfpack)+if(UMFPACK_FOUND AND BLAS_FOUND)+ add_definitions("-DEIGEN_UMFPACK_SUPPORT")+ include_directories(${UMFPACK_INCLUDES})+ set(SPARSE_LIBS ${SPARSE_LIBS} ${UMFPACK_LIBRARIES} ${BLAS_LIBRARIES})+ set(UMFPACK_ALL_LIBS ${UMFPACK_LIBRARIES} ${BLAS_LIBRARIES})+endif()++find_package(SuperLU)+if(SUPERLU_FOUND AND BLAS_FOUND)+ add_definitions("-DEIGEN_SUPERLU_SUPPORT")+ include_directories(${SUPERLU_INCLUDES})+ set(SPARSE_LIBS ${SPARSE_LIBS} ${SUPERLU_LIBRARIES} ${BLAS_LIBRARIES})+ set(SUPERLU_ALL_LIBS ${SUPERLU_LIBRARIES} ${BLAS_LIBRARIES})+endif()+++find_package(Pastix)+find_package(Scotch)+find_package(Metis)+if(PASTIX_FOUND AND BLAS_FOUND)+ add_definitions("-DEIGEN_PASTIX_SUPPORT")+ include_directories(${PASTIX_INCLUDES})+ if(SCOTCH_FOUND)+ include_directories(${SCOTCH_INCLUDES})+ set(PASTIX_LIBRARIES ${PASTIX_LIBRARIES} ${SCOTCH_LIBRARIES})+ elseif(METIS_FOUND)+ include_directories(${METIS_INCLUDES})+ set(PASTIX_LIBRARIES ${PASTIX_LIBRARIES} ${METIS_LIBRARIES}) + endif(SCOTCH_FOUND)+ set(SPARSE_LIBS ${SPARSE_LIBS} ${PASTIX_LIBRARIES} ${ORDERING_LIBRARIES} ${BLAS_LIBRARIES})+ set(PASTIX_ALL_LIBS ${PASTIX_LIBRARIES} ${BLAS_LIBRARIES})+endif(PASTIX_FOUND AND BLAS_FOUND)++if(METIS_FOUND)+ include_directories(${METIS_INCLUDES})+ set (SPARSE_LIBS ${SPARSE_LIBS} ${METIS_LIBRARIES})+ add_definitions("-DEIGEN_METIS_SUPPORT")+endif(METIS_FOUND)++find_library(RT_LIBRARY rt)+if(RT_LIBRARY)+ set(SPARSE_LIBS ${SPARSE_LIBS} ${RT_LIBRARY})+endif(RT_LIBRARY)++add_executable(spbenchsolver spbenchsolver.cpp)+target_link_libraries (spbenchsolver ${SPARSE_LIBS})++add_executable(spsolver sp_solver.cpp)+target_link_libraries (spsolver ${SPARSE_LIBS})+++add_executable(test_sparseLU test_sparseLU.cpp)+target_link_libraries (test_sparseLU ${SPARSE_LIBS})+
+ eigen3/bench/spbench/sp_solver.cpp view
@@ -0,0 +1,125 @@+// Small bench routine for Eigen available in Eigen+// (C) Desire NUENTSA WAKAM, INRIA++#include <iostream>+#include <fstream>+#include <iomanip>+#include <Eigen/Jacobi>+#include <Eigen/Householder>+#include <Eigen/IterativeLinearSolvers>+#include <Eigen/LU>+#include <unsupported/Eigen/SparseExtra>+//#include <Eigen/SparseLU>+#include <Eigen/SuperLUSupport>+// #include <unsupported/Eigen/src/IterativeSolvers/Scaling.h>+#include <bench/BenchTimer.h>+#include <unsupported/Eigen/IterativeSolvers>+using namespace std;+using namespace Eigen;++int main(int argc, char **args)+{+ SparseMatrix<double, ColMajor> A; + typedef SparseMatrix<double, ColMajor>::Index Index;+ typedef Matrix<double, Dynamic, Dynamic> DenseMatrix;+ typedef Matrix<double, Dynamic, 1> DenseRhs;+ VectorXd b, x, tmp;+ BenchTimer timer,totaltime; + //SparseLU<SparseMatrix<double, ColMajor> > solver;+// SuperLU<SparseMatrix<double, ColMajor> > solver;+ ConjugateGradient<SparseMatrix<double, ColMajor>, Lower,IncompleteCholesky<double,Lower> > solver; + ifstream matrix_file; + string line;+ int n;+ // Set parameters+// solver.iparm(IPARM_THREAD_NBR) = 4;+ /* Fill the matrix with sparse matrix stored in Matrix-Market coordinate column-oriented format */+ if (argc < 2) assert(false && "please, give the matrix market file ");+ + timer.start();+ totaltime.start();+ loadMarket(A, args[1]);+ cout << "End charging matrix " << endl;+ bool iscomplex=false, isvector=false;+ int sym;+ getMarketHeader(args[1], sym, iscomplex, isvector);+ if (iscomplex) { cout<< " Not for complex matrices \n"; return -1; }+ if (isvector) { cout << "The provided file is not a matrix file\n"; return -1;}+ if (sym != 0) { // symmetric matrices, only the lower part is stored+ SparseMatrix<double, ColMajor> temp; + temp = A;+ A = temp.selfadjointView<Lower>();+ }+ timer.stop();+ + n = A.cols();+ // ====== TESTS FOR SPARSE TUTORIAL ======+// cout<< "OuterSize " << A.outerSize() << " inner " << A.innerSize() << endl; +// SparseMatrix<double, RowMajor> mat1(A); +// SparseMatrix<double, RowMajor> mat2;+// cout << " norm of A " << mat1.norm() << endl; ;+// PermutationMatrix<Dynamic, Dynamic, int> perm(n);+// perm.resize(n,1);+// perm.indices().setLinSpaced(n, 0, n-1);+// mat2 = perm * mat1;+// mat.subrows();+// mat2.resize(n,n); +// mat2.reserve(10);+// mat2.setConstant();+// std::cout<< "NORM " << mat1.squaredNorm()<< endl; ++ cout<< "Time to load the matrix " << timer.value() <<endl;+ /* Fill the right hand side */++// solver.set_restart(374);+ if (argc > 2)+ loadMarketVector(b, args[2]);+ else + {+ b.resize(n);+ tmp.resize(n);+// tmp.setRandom();+ for (int i = 0; i < n; i++) tmp(i) = i; + b = A * tmp ;+ }+// Scaling<SparseMatrix<double> > scal; +// scal.computeRef(A);+// b = scal.LeftScaling().cwiseProduct(b);++ /* Compute the factorization */+ cout<< "Starting the factorization "<< endl; + timer.reset();+ timer.start(); + cout<< "Size of Input Matrix "<< b.size()<<"\n\n";+ cout<< "Rows and columns "<< A.rows() <<" " <<A.cols() <<"\n";+ solver.compute(A);+// solver.analyzePattern(A);+// solver.factorize(A);+ if (solver.info() != Success) {+ std::cout<< "The solver failed \n";+ return -1; + }+ timer.stop(); + float time_comp = timer.value(); + cout <<" Compute Time " << time_comp<< endl; + + timer.reset();+ timer.start();+ x = solver.solve(b);+// x = scal.RightScaling().cwiseProduct(x);+ timer.stop();+ float time_solve = timer.value(); + cout<< " Time to solve " << time_solve << endl; + + /* Check the accuracy */+ VectorXd tmp2 = b - A*x;+ double tempNorm = tmp2.norm()/b.norm();+ cout << "Relative norm of the computed solution : " << tempNorm <<"\n";+// cout << "Iterations : " << solver.iterations() << "\n"; + + totaltime.stop();+ cout << "Total time " << totaltime.value() << "\n";+// std::cout<<x.transpose()<<"\n";+ + return 0;+}
+ eigen3/bench/spbench/spbench.dtd view
@@ -0,0 +1,31 @@+<!ELEMENT BENCH (AVAILSOLVER+,LINEARSYSTEM+)>+ <!ELEMENT AVAILSOLVER (SOLVER+)>+ <!ELEMENT SOLVER (TYPE,PACKAGE)>+ <!ELEMENT TYPE (#PCDATA)> <!-- One of LU, LLT, LDLT, ITER -->+ <!ELEMENT PACKAGE (#PCDATA)> <!-- Derived from a library -->+ <!ELEMENT LINEARSYSTEM (MATRIX,SOLVER_STAT+,BEST_SOLVER,GLOBAL_PARAMS*)>+ <!ELEMENT MATRIX (NAME,SIZE,ENTRIES,PATTERN?,SYMMETRY,POSDEF?,ARITHMETIC,RHS*)>+ <!ELEMENT NAME (#PCDATA)>+ <!ELEMENT SIZE (#PCDATA)>+ <!ELEMENT ENTRIES (#PCDATA)> <!-- The number of nonzeros elements -->+ <!ELEMENT PATTERN (#PCDATA)> <!-- Is structural pattern symmetric or not -->+ <!ELEMENT SYMMETRY (#PCDATA)> <!-- symmmetry with numerical values -->+ <!ELEMENT POSDEF (#PCDATA)> <!-- Is the matrix positive definite or not -->+ <!ELEMENT ARITHMETIC (#PCDATA)> + <!ELEMENT RHS (SOURCE)> <!-- A matrix can have one or more right hand side associated. -->+ <!ELEMENT SOURCE (#PCDATA)> <!-- Source of the right hand side, either generated or provided -->+ <!ELEMENT SOLVER_STAT (PARAMS*,TIME,ERROR,ITER?)>+ <!ELEMENT PARAMS (#PCDATA)>+ <!ELEMENT TIME (COMPUTE,SOLVE,TOTAL)>+ <!ELEMENT COMPUTE (#PCDATA)> <!-- Time to analyze,to factorize, or to setup the preconditioner-->+ <!ELEMENT SOLVE (#PCDATA)> <!-- Time to solve with all the available rhs -->+ <!ELEMENT TOTAL (#PCDATA)>+ <!ELEMENT ERROR (#PCDATA)> <!-- Either the relative error or the relative residual norm -->+ <!ELEMENT ITER (#PCDATA)> <!-- Number of iterations -->+ <!ELEMENT BEST_SOLVER CDATA> <!-- Id of the best solver -->+ <!ELEMENT GLOBAL_PARAMS (#PCDATA)> <!-- Parameters shared by all solvers -->++<!ATTLIST SOLVER ID CDATA #REQUIRED>+<!ATTLIST SOLVER_STAT ID CDATA #REQUIRED>+<!ATTLIST BEST_SOLVER ID CDATA #REQUIRED>+<!ATTLIST RHS ID CDATA #IMPLIED>
+ eigen3/bench/spbench/spbenchsolver.cpp view
@@ -0,0 +1,87 @@+#include <bench/spbench/spbenchsolver.h>++void bench_printhelp()+{+ cout<< " \nbenchsolver : performs a benchmark of all the solvers available in Eigen \n\n";+ cout<< " MATRIX FOLDER : \n";+ cout<< " The matrices for the benchmark should be collected in a folder specified with an environment variable EIGEN_MATRIXDIR \n";+ cout<< " The matrices are stored using the matrix market coordinate format \n";+ cout<< " The matrix and associated right-hand side (rhs) files are named respectively \n";+ cout<< " as MatrixName.mtx and MatrixName_b.mtx. If the rhs does not exist, a random one is generated. \n";+ cout<< " If a matrix is SPD, the matrix should be named as MatrixName_SPD.mtx \n";+ cout<< " If a true solution exists, it should be named as MatrixName_x.mtx; \n" ;+ cout<< " it will be used to compute the norm of the error relative to the computed solutions\n\n";+ cout<< " OPTIONS : \n"; + cout<< " -h or --help \n print this help and return\n\n";+ cout<< " -d matrixdir \n Use matrixdir as the matrix folder instead of the one specified in the environment variable EIGEN_MATRIXDIR\n\n"; + cout<< " -o outputfile.xml \n Output the statistics to a xml file \n\n";+ cout<< " --eps <RelErr> Sets the relative tolerance for iterative solvers (default 1e-08) \n\n";+ cout<< " --maxits <MaxIts> Sets the maximum number of iterations (default 1000) \n\n";+ +}+int main(int argc, char ** args)+{+ + bool help = ( get_options(argc, args, "-h") || get_options(argc, args, "--help") );+ if(help) {+ bench_printhelp();+ return 0;+ }++ // Get the location of the test matrices+ string matrix_dir;+ if (!get_options(argc, args, "-d", &matrix_dir))+ {+ if(getenv("EIGEN_MATRIXDIR") == NULL){+ std::cerr << "Please, specify the location of the matrices with -d mat_folder or the environment variable EIGEN_MATRIXDIR \n";+ std::cerr << " Run with --help to see the list of all the available options \n";+ return -1;+ }+ matrix_dir = getenv("EIGEN_MATRIXDIR");+ }+ + std::ofstream statbuf;+ string statFile ;+ + // Get the file to write the statistics+ bool statFileExists = get_options(argc, args, "-o", &statFile);+ if(statFileExists)+ {+ statbuf.open(statFile.c_str(), std::ios::out);+ if(statbuf.good()){+ statFileExists = true; + printStatheader(statbuf);+ statbuf.close();+ }+ else+ std::cerr << "Unable to open the provided file for writting... \n";+ } + + // Get the maximum number of iterations and the tolerance+ int maxiters = 1000; + double tol = 1e-08; + string inval; + if (get_options(argc, args, "--eps", &inval))+ tol = atof(inval.c_str()); + if(get_options(argc, args, "--maxits", &inval))+ maxiters = atoi(inval.c_str()); + + string current_dir; + // Test the real-arithmetics matrices+ Browse_Matrices<double>(matrix_dir, statFileExists, statFile,maxiters, tol);+ + // Test the complex-arithmetics matrices+ Browse_Matrices<std::complex<double> >(matrix_dir, statFileExists, statFile, maxiters, tol); + + if(statFileExists)+ {+ statbuf.open(statFile.c_str(), std::ios::app); + statbuf << "</BENCH> \n";+ cout << "\n Output written in " << statFile << " ...\n";+ statbuf.close();+ }++ return 0;+}++
+ eigen3/bench/spbench/spbenchsolver.h view
@@ -0,0 +1,554 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.+++#include <iostream>+#include <fstream>+#include <Eigen/SparseCore>+#include <bench/BenchTimer.h>+#include <cstdlib>+#include <string>+#include <Eigen/Cholesky>+#include <Eigen/Jacobi>+#include <Eigen/Householder>+#include <Eigen/IterativeLinearSolvers>+#include <unsupported/Eigen/IterativeSolvers>+#include <Eigen/LU>+#include <unsupported/Eigen/SparseExtra>+#include <Eigen/SparseLU>++#include "spbenchstyle.h"++#ifdef EIGEN_METIS_SUPPORT+#include <Eigen/MetisSupport>+#endif++#ifdef EIGEN_CHOLMOD_SUPPORT+#include <Eigen/CholmodSupport>+#endif++#ifdef EIGEN_UMFPACK_SUPPORT+#include <Eigen/UmfPackSupport>+#endif++#ifdef EIGEN_PARDISO_SUPPORT+#include <Eigen/PardisoSupport>+#endif++#ifdef EIGEN_SUPERLU_SUPPORT+#include <Eigen/SuperLUSupport>+#endif++#ifdef EIGEN_PASTIX_SUPPORT+#include <Eigen/PaStiXSupport>+#endif++// CONSTANTS+#define EIGEN_UMFPACK 10+#define EIGEN_SUPERLU 20+#define EIGEN_PASTIX 30+#define EIGEN_PARDISO 40+#define EIGEN_SPARSELU_COLAMD 50+#define EIGEN_SPARSELU_METIS 51+#define EIGEN_BICGSTAB 60+#define EIGEN_BICGSTAB_ILUT 61+#define EIGEN_GMRES 70+#define EIGEN_GMRES_ILUT 71+#define EIGEN_SIMPLICIAL_LDLT 80+#define EIGEN_CHOLMOD_LDLT 90+#define EIGEN_PASTIX_LDLT 100+#define EIGEN_PARDISO_LDLT 110+#define EIGEN_SIMPLICIAL_LLT 120+#define EIGEN_CHOLMOD_SUPERNODAL_LLT 130+#define EIGEN_CHOLMOD_SIMPLICIAL_LLT 140+#define EIGEN_PASTIX_LLT 150+#define EIGEN_PARDISO_LLT 160+#define EIGEN_CG 170+#define EIGEN_CG_PRECOND 180++using namespace Eigen;+using namespace std; +++// Global variables for input parameters+int MaximumIters; // Maximum number of iterations+double RelErr; // Relative error of the computed solution+double best_time_val; // Current best time overall solvers +int best_time_id; // id of the best solver for the current system ++template<typename T> inline typename NumTraits<T>::Real test_precision() { return NumTraits<T>::dummy_precision(); }+template<> inline float test_precision<float>() { return 1e-3f; } +template<> inline double test_precision<double>() { return 1e-6; } +template<> inline float test_precision<std::complex<float> >() { return test_precision<float>(); }+template<> inline double test_precision<std::complex<double> >() { return test_precision<double>(); }++void printStatheader(std::ofstream& out)+{+ // Print XML header+ // NOTE It would have been much easier to write these XML documents using external libraries like tinyXML or Xerces-C++.+ + out << "<?xml version='1.0' encoding='UTF-8'?> \n";+ out << "<?xml-stylesheet type='text/xsl' href='#stylesheet' ?> \n"; + out << "<!DOCTYPE BENCH [\n<!ATTLIST xsl:stylesheet\n id\t ID #REQUIRED>\n]>";+ out << "\n\n<!-- Generated by the Eigen library -->\n"; + + out << "\n<BENCH> \n" ; //root XML element + // Print the xsl style section+ printBenchStyle(out); + // List all available solvers + out << " <AVAILSOLVER> \n";+#ifdef EIGEN_UMFPACK_SUPPORT+ out <<" <SOLVER ID='" << EIGEN_UMFPACK << "'>\n"; + out << " <TYPE> LU </TYPE> \n";+ out << " <PACKAGE> UMFPACK </PACKAGE> \n"; + out << " </SOLVER> \n"; +#endif+#ifdef EIGEN_SUPERLU_SUPPORT+ out <<" <SOLVER ID='" << EIGEN_SUPERLU << "'>\n"; + out << " <TYPE> LU </TYPE> \n";+ out << " <PACKAGE> SUPERLU </PACKAGE> \n"; + out << " </SOLVER> \n"; +#endif+#ifdef EIGEN_CHOLMOD_SUPPORT+ out <<" <SOLVER ID='" << EIGEN_CHOLMOD_SIMPLICIAL_LLT << "'>\n"; + out << " <TYPE> LLT SP</TYPE> \n";+ out << " <PACKAGE> CHOLMOD </PACKAGE> \n";+ out << " </SOLVER> \n"; + + out <<" <SOLVER ID='" << EIGEN_CHOLMOD_SUPERNODAL_LLT << "'>\n"; + out << " <TYPE> LLT</TYPE> \n";+ out << " <PACKAGE> CHOLMOD </PACKAGE> \n";+ out << " </SOLVER> \n";+ + out <<" <SOLVER ID='" << EIGEN_CHOLMOD_LDLT << "'>\n"; + out << " <TYPE> LDLT </TYPE> \n";+ out << " <PACKAGE> CHOLMOD </PACKAGE> \n"; + out << " </SOLVER> \n"; +#endif+#ifdef EIGEN_PARDISO_SUPPORT+ out <<" <SOLVER ID='" << EIGEN_PARDISO << "'>\n"; + out << " <TYPE> LU </TYPE> \n";+ out << " <PACKAGE> PARDISO </PACKAGE> \n"; + out << " </SOLVER> \n"; + + out <<" <SOLVER ID='" << EIGEN_PARDISO_LLT << "'>\n"; + out << " <TYPE> LLT </TYPE> \n";+ out << " <PACKAGE> PARDISO </PACKAGE> \n"; + out << " </SOLVER> \n"; + + out <<" <SOLVER ID='" << EIGEN_PARDISO_LDLT << "'>\n"; + out << " <TYPE> LDLT </TYPE> \n";+ out << " <PACKAGE> PARDISO </PACKAGE> \n"; + out << " </SOLVER> \n"; +#endif+#ifdef EIGEN_PASTIX_SUPPORT+ out <<" <SOLVER ID='" << EIGEN_PASTIX << "'>\n"; + out << " <TYPE> LU </TYPE> \n";+ out << " <PACKAGE> PASTIX </PACKAGE> \n"; + out << " </SOLVER> \n"; + + out <<" <SOLVER ID='" << EIGEN_PASTIX_LLT << "'>\n"; + out << " <TYPE> LLT </TYPE> \n";+ out << " <PACKAGE> PASTIX </PACKAGE> \n"; + out << " </SOLVER> \n"; + + out <<" <SOLVER ID='" << EIGEN_PASTIX_LDLT << "'>\n"; + out << " <TYPE> LDLT </TYPE> \n";+ out << " <PACKAGE> PASTIX </PACKAGE> \n"; + out << " </SOLVER> \n"; +#endif+ + out <<" <SOLVER ID='" << EIGEN_BICGSTAB << "'>\n"; + out << " <TYPE> BICGSTAB </TYPE> \n";+ out << " <PACKAGE> EIGEN </PACKAGE> \n"; + out << " </SOLVER> \n"; + + out <<" <SOLVER ID='" << EIGEN_BICGSTAB_ILUT << "'>\n"; + out << " <TYPE> BICGSTAB_ILUT </TYPE> \n";+ out << " <PACKAGE> EIGEN </PACKAGE> \n"; + out << " </SOLVER> \n"; + + out <<" <SOLVER ID='" << EIGEN_GMRES_ILUT << "'>\n"; + out << " <TYPE> GMRES_ILUT </TYPE> \n";+ out << " <PACKAGE> EIGEN </PACKAGE> \n"; + out << " </SOLVER> \n"; + + out <<" <SOLVER ID='" << EIGEN_SIMPLICIAL_LDLT << "'>\n"; + out << " <TYPE> LDLT </TYPE> \n";+ out << " <PACKAGE> EIGEN </PACKAGE> \n"; + out << " </SOLVER> \n"; + + out <<" <SOLVER ID='" << EIGEN_SIMPLICIAL_LLT << "'>\n"; + out << " <TYPE> LLT </TYPE> \n";+ out << " <PACKAGE> EIGEN </PACKAGE> \n"; + out << " </SOLVER> \n"; + + out <<" <SOLVER ID='" << EIGEN_CG << "'>\n"; + out << " <TYPE> CG </TYPE> \n";+ out << " <PACKAGE> EIGEN </PACKAGE> \n"; + out << " </SOLVER> \n"; + + out <<" <SOLVER ID='" << EIGEN_SPARSELU_COLAMD << "'>\n"; + out << " <TYPE> LU_COLAMD </TYPE> \n";+ out << " <PACKAGE> EIGEN </PACKAGE> \n"; + out << " </SOLVER> \n"; + +#ifdef EIGEN_METIS_SUPPORT+ out <<" <SOLVER ID='" << EIGEN_SPARSELU_METIS << "'>\n"; + out << " <TYPE> LU_METIS </TYPE> \n";+ out << " <PACKAGE> EIGEN </PACKAGE> \n"; + out << " </SOLVER> \n"; +#endif+ out << " </AVAILSOLVER> \n"; + +}+++template<typename Solver, typename Scalar>+void call_solver(Solver &solver, const int solver_id, const typename Solver::MatrixType& A, const Matrix<Scalar, Dynamic, 1>& b, const Matrix<Scalar, Dynamic, 1>& refX,std::ofstream& statbuf)+{+ + double total_time;+ double compute_time;+ double solve_time; + double rel_error;+ Matrix<Scalar, Dynamic, 1> x; + BenchTimer timer; + timer.reset();+ timer.start();+ solver.compute(A); + if (solver.info() != Success)+ {+ std::cerr << "Solver failed ... \n";+ return;+ }+ timer.stop();+ compute_time = timer.value();+ statbuf << " <TIME>\n"; + statbuf << " <COMPUTE> " << timer.value() << "</COMPUTE>\n";+ std::cout<< "COMPUTE TIME : " << timer.value() <<std::endl; + + timer.reset();+ timer.start();+ x = solver.solve(b); + if (solver.info() == NumericalIssue)+ {+ std::cerr << "Solver failed ... \n";+ return;+ }+ timer.stop();+ solve_time = timer.value();+ statbuf << " <SOLVE> " << timer.value() << "</SOLVE>\n"; + std::cout<< "SOLVE TIME : " << timer.value() <<std::endl; + + total_time = solve_time + compute_time;+ statbuf << " <TOTAL> " << total_time << "</TOTAL>\n"; + std::cout<< "TOTAL TIME : " << total_time <<std::endl; + statbuf << " </TIME>\n"; + + // Verify the relative error+ if(refX.size() != 0)+ rel_error = (refX - x).norm()/refX.norm();+ else + {+ // Compute the relative residual norm+ Matrix<Scalar, Dynamic, 1> temp; + temp = A * x; + rel_error = (b-temp).norm()/b.norm();+ }+ statbuf << " <ERROR> " << rel_error << "</ERROR>\n"; + std::cout<< "REL. ERROR : " << rel_error << "\n\n" ;+ if ( rel_error <= RelErr )+ {+ // check the best time if convergence+ if(!best_time_val || (best_time_val > total_time))+ {+ best_time_val = total_time;+ best_time_id = solver_id;+ }+ }+}++template<typename Solver, typename Scalar>+void call_directsolver(Solver& solver, const int solver_id, const typename Solver::MatrixType& A, const Matrix<Scalar, Dynamic, 1>& b, const Matrix<Scalar, Dynamic, 1>& refX, std::string& statFile)+{+ std::ofstream statbuf(statFile.c_str(), std::ios::app);+ statbuf << " <SOLVER_STAT ID='" << solver_id <<"'>\n"; + call_solver(solver, solver_id, A, b, refX,statbuf);+ statbuf << " </SOLVER_STAT>\n";+ statbuf.close();+}++template<typename Solver, typename Scalar>+void call_itersolver(Solver &solver, const int solver_id, const typename Solver::MatrixType& A, const Matrix<Scalar, Dynamic, 1>& b, const Matrix<Scalar, Dynamic, 1>& refX, std::string& statFile)+{+ solver.setTolerance(RelErr); + solver.setMaxIterations(MaximumIters);+ + std::ofstream statbuf(statFile.c_str(), std::ios::app);+ statbuf << " <SOLVER_STAT ID='" << solver_id <<"'>\n"; + call_solver(solver, solver_id, A, b, refX,statbuf); + statbuf << " <ITER> "<< solver.iterations() << "</ITER>\n";+ statbuf << " </SOLVER_STAT>\n";+ std::cout << "ITERATIONS : " << solver.iterations() <<"\n\n\n"; + +}+++template <typename Scalar>+void SelectSolvers(const SparseMatrix<Scalar>&A, unsigned int sym, Matrix<Scalar, Dynamic, 1>& b, const Matrix<Scalar, Dynamic, 1>& refX, std::string& statFile)+{+ typedef SparseMatrix<Scalar, ColMajor> SpMat; + // First, deal with Nonsymmetric and symmetric matrices+ best_time_id = 0; + best_time_val = 0.0;+ //UMFPACK+ #ifdef EIGEN_UMFPACK_SUPPORT+ {+ cout << "Solving with UMFPACK LU ... \n"; + UmfPackLU<SpMat> solver; + call_directsolver(solver, EIGEN_UMFPACK, A, b, refX,statFile); + }+ #endif+ //SuperLU+ #ifdef EIGEN_SUPERLU_SUPPORT+ {+ cout << "\nSolving with SUPERLU ... \n"; + SuperLU<SpMat> solver;+ call_directsolver(solver, EIGEN_SUPERLU, A, b, refX,statFile); + }+ #endif+ + // PaStix LU+ #ifdef EIGEN_PASTIX_SUPPORT+ {+ cout << "\nSolving with PASTIX LU ... \n"; + PastixLU<SpMat> solver; + call_directsolver(solver, EIGEN_PASTIX, A, b, refX,statFile) ;+ }+ #endif++ //PARDISO LU+ #ifdef EIGEN_PARDISO_SUPPORT+ {+ cout << "\nSolving with PARDISO LU ... \n"; + PardisoLU<SpMat> solver; + call_directsolver(solver, EIGEN_PARDISO, A, b, refX,statFile);+ }+ #endif+ + // Eigen SparseLU METIS+ cout << "\n Solving with Sparse LU AND COLAMD ... \n";+ SparseLU<SpMat, COLAMDOrdering<int> > solver;+ call_directsolver(solver, EIGEN_SPARSELU_COLAMD, A, b, refX, statFile); + // Eigen SparseLU METIS+ #ifdef EIGEN_METIS_SUPPORT+ {+ cout << "\n Solving with Sparse LU AND METIS ... \n";+ SparseLU<SpMat, MetisOrdering<int> > solver;+ call_directsolver(solver, EIGEN_SPARSELU_METIS, A, b, refX, statFile); + }+ #endif+ + //BiCGSTAB+ {+ cout << "\nSolving with BiCGSTAB ... \n"; + BiCGSTAB<SpMat> solver; + call_itersolver(solver, EIGEN_BICGSTAB, A, b, refX,statFile);+ }+ //BiCGSTAB+ILUT+ {+ cout << "\nSolving with BiCGSTAB and ILUT ... \n"; + BiCGSTAB<SpMat, IncompleteLUT<Scalar> > solver; + call_itersolver(solver, EIGEN_BICGSTAB_ILUT, A, b, refX,statFile); + }+ + + //GMRES+// {+// cout << "\nSolving with GMRES ... \n"; +// GMRES<SpMat> solver; +// call_itersolver(solver, EIGEN_GMRES, A, b, refX,statFile); +// }+ //GMRES+ILUT+ {+ cout << "\nSolving with GMRES and ILUT ... \n"; + GMRES<SpMat, IncompleteLUT<Scalar> > solver; + call_itersolver(solver, EIGEN_GMRES_ILUT, A, b, refX,statFile);+ }+ + // Hermitian and not necessarily positive-definites+ if (sym != NonSymmetric)+ {+ // Internal Cholesky+ {+ cout << "\nSolving with Simplicial LDLT ... \n"; + SimplicialLDLT<SpMat, Lower> solver;+ call_directsolver(solver, EIGEN_SIMPLICIAL_LDLT, A, b, refX,statFile); + }+ + // CHOLMOD+ #ifdef EIGEN_CHOLMOD_SUPPORT+ {+ cout << "\nSolving with CHOLMOD LDLT ... \n"; + CholmodDecomposition<SpMat, Lower> solver;+ solver.setMode(CholmodLDLt);+ call_directsolver(solver,EIGEN_CHOLMOD_LDLT, A, b, refX,statFile);+ }+ #endif+ + //PASTIX LLT+ #ifdef EIGEN_PASTIX_SUPPORT+ {+ cout << "\nSolving with PASTIX LDLT ... \n"; + PastixLDLT<SpMat, Lower> solver; + call_directsolver(solver,EIGEN_PASTIX_LDLT, A, b, refX,statFile); + }+ #endif+ + //PARDISO LLT+ #ifdef EIGEN_PARDISO_SUPPORT+ {+ cout << "\nSolving with PARDISO LDLT ... \n"; + PardisoLDLT<SpMat, Lower> solver; + call_directsolver(solver,EIGEN_PARDISO_LDLT, A, b, refX,statFile); + }+ #endif+ }++ // Now, symmetric POSITIVE DEFINITE matrices+ if (sym == SPD)+ {+ + //Internal Sparse Cholesky+ {+ cout << "\nSolving with SIMPLICIAL LLT ... \n"; + SimplicialLLT<SpMat, Lower> solver; + call_directsolver(solver,EIGEN_SIMPLICIAL_LLT, A, b, refX,statFile); + }+ + // CHOLMOD+ #ifdef EIGEN_CHOLMOD_SUPPORT+ {+ // CholMOD SuperNodal LLT+ cout << "\nSolving with CHOLMOD LLT (Supernodal)... \n"; + CholmodDecomposition<SpMat, Lower> solver;+ solver.setMode(CholmodSupernodalLLt);+ call_directsolver(solver,EIGEN_CHOLMOD_SUPERNODAL_LLT, A, b, refX,statFile);+ // CholMod Simplicial LLT+ cout << "\nSolving with CHOLMOD LLT (Simplicial) ... \n"; + solver.setMode(CholmodSimplicialLLt);+ call_directsolver(solver,EIGEN_CHOLMOD_SIMPLICIAL_LLT, A, b, refX,statFile);+ }+ #endif+ + //PASTIX LLT+ #ifdef EIGEN_PASTIX_SUPPORT+ {+ cout << "\nSolving with PASTIX LLT ... \n"; + PastixLLT<SpMat, Lower> solver; + call_directsolver(solver,EIGEN_PASTIX_LLT, A, b, refX,statFile);+ }+ #endif+ + //PARDISO LLT+ #ifdef EIGEN_PARDISO_SUPPORT+ {+ cout << "\nSolving with PARDISO LLT ... \n"; + PardisoLLT<SpMat, Lower> solver; + call_directsolver(solver,EIGEN_PARDISO_LLT, A, b, refX,statFile); + }+ #endif+ + // Internal CG+ {+ cout << "\nSolving with CG ... \n"; + ConjugateGradient<SpMat, Lower> solver; + call_itersolver(solver,EIGEN_CG, A, b, refX,statFile);+ }+ //CG+IdentityPreconditioner+// {+// cout << "\nSolving with CG and IdentityPreconditioner ... \n"; +// ConjugateGradient<SpMat, Lower, IdentityPreconditioner> solver; +// call_itersolver(solver,EIGEN_CG_PRECOND, A, b, refX,statFile);+// }+ } // End SPD matrices +}++/* Browse all the matrices available in the specified folder + * and solve the associated linear system.+ * The results of each solve are printed in the standard output+ * and optionally in the provided html file+ */+template <typename Scalar>+void Browse_Matrices(const string folder, bool statFileExists, std::string& statFile, int maxiters, double tol)+{+ MaximumIters = maxiters; // Maximum number of iterations, global variable + RelErr = tol; //Relative residual error as stopping criterion for iterative solvers+ MatrixMarketIterator<Scalar> it(folder);+ for ( ; it; ++it)+ {+ //print the infos for this linear system + if(statFileExists)+ {+ std::ofstream statbuf(statFile.c_str(), std::ios::app);+ statbuf << "<LINEARSYSTEM> \n";+ statbuf << " <MATRIX> \n";+ statbuf << " <NAME> " << it.matname() << " </NAME>\n"; + statbuf << " <SIZE> " << it.matrix().rows() << " </SIZE>\n"; + statbuf << " <ENTRIES> " << it.matrix().nonZeros() << "</ENTRIES>\n";+ if (it.sym()!=NonSymmetric)+ {+ statbuf << " <SYMMETRY> Symmetric </SYMMETRY>\n" ; + if (it.sym() == SPD) + statbuf << " <POSDEF> YES </POSDEF>\n"; + else + statbuf << " <POSDEF> NO </POSDEF>\n"; + + }+ else+ {+ statbuf << " <SYMMETRY> NonSymmetric </SYMMETRY>\n" ; + statbuf << " <POSDEF> NO </POSDEF>\n"; + }+ statbuf << " </MATRIX> \n";+ statbuf.close();+ }+ + cout<< "\n\n===================================================== \n";+ cout<< " ====== SOLVING WITH MATRIX " << it.matname() << " ====\n";+ cout<< " =================================================== \n\n";+ Matrix<Scalar, Dynamic, 1> refX;+ if(it.hasrefX()) refX = it.refX();+ // Call all suitable solvers for this linear system + SelectSolvers<Scalar>(it.matrix(), it.sym(), it.rhs(), refX, statFile);+ + if(statFileExists)+ {+ std::ofstream statbuf(statFile.c_str(), std::ios::app);+ statbuf << " <BEST_SOLVER ID='"<< best_time_id+ << "'></BEST_SOLVER>\n"; + statbuf << " </LINEARSYSTEM> \n"; + statbuf.close();+ }+ } +} ++bool get_options(int argc, char **args, string option, string* value=0)+{+ int idx = 1, found=false; + while (idx<argc && !found){+ if (option.compare(args[idx]) == 0){+ found = true; + if(value) *value = args[idx+1];+ }+ idx+=2;+ }+ return found; +}
+ eigen3/bench/spbench/spbenchstyle.h view
@@ -0,0 +1,94 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef SPBENCHSTYLE_H+#define SPBENCHSTYLE_H++void printBenchStyle(std::ofstream& out)+{+ out << "<xsl:stylesheet id='stylesheet' version='1.0' \+ xmlns:xsl='http://www.w3.org/1999/XSL/Transform' >\n \+ <xsl:template match='xsl:stylesheet' />\n \+ <xsl:template match='/'> <!-- Root of the document -->\n \+ <html>\n \+ <head> \n \+ <style type='text/css'> \n \+ td { white-space: nowrap;}\n \+ </style>\n \+ </head>\n \+ <body>";+ out<<"<table border='1' width='100%' height='100%'>\n \+ <TR> <!-- Write the table header -->\n \+ <TH>Matrix</TH> <TH>N</TH> <TH> NNZ</TH> <TH> Sym</TH> <TH> SPD</TH> <TH> </TH>\n \+ <xsl:for-each select='BENCH/AVAILSOLVER/SOLVER'>\n \+ <xsl:sort select='@ID' data-type='number'/>\n \+ <TH>\n \+ <xsl:value-of select='TYPE' />\n \+ <xsl:text></xsl:text>\n \+ <xsl:value-of select='PACKAGE' />\n \+ <xsl:text></xsl:text>\n \+ </TH>\n \+ </xsl:for-each>\n \+ </TR>";+ + out<<" <xsl:for-each select='BENCH/LINEARSYSTEM'>\n \+ <TR> <!-- print statistics for one linear system-->\n \+ <TH rowspan='4'> <xsl:value-of select='MATRIX/NAME' /> </TH>\n \+ <TD rowspan='4'> <xsl:value-of select='MATRIX/SIZE' /> </TD>\n \+ <TD rowspan='4'> <xsl:value-of select='MATRIX/ENTRIES' /> </TD>\n \+ <TD rowspan='4'> <xsl:value-of select='MATRIX/SYMMETRY' /> </TD>\n \+ <TD rowspan='4'> <xsl:value-of select='MATRIX/POSDEF' /> </TD>\n \+ <TH> Compute Time </TH>\n \+ <xsl:for-each select='SOLVER_STAT'>\n \+ <xsl:sort select='@ID' data-type='number'/>\n \+ <TD> <xsl:value-of select='TIME/COMPUTE' /> </TD>\n \+ </xsl:for-each>\n \+ </TR>";+ out<<" <TR>\n \+ <TH> Solve Time </TH>\n \+ <xsl:for-each select='SOLVER_STAT'>\n \+ <xsl:sort select='@ID' data-type='number'/>\n \+ <TD> <xsl:value-of select='TIME/SOLVE' /> </TD>\n \+ </xsl:for-each>\n \+ </TR>\n \+ <TR>\n \+ <TH> Total Time </TH>\n \+ <xsl:for-each select='SOLVER_STAT'>\n \+ <xsl:sort select='@ID' data-type='number'/>\n \+ <xsl:choose>\n \+ <xsl:when test='@ID=../BEST_SOLVER/@ID'>\n \+ <TD style='background-color:red'> <xsl:value-of select='TIME/TOTAL' /> </TD>\n \+ </xsl:when>\n \+ <xsl:otherwise>\n \+ <TD> <xsl:value-of select='TIME/TOTAL' /></TD>\n \+ </xsl:otherwise>\n \+ </xsl:choose>\n \+ </xsl:for-each>\n \+ </TR>";+ out<<" <TR>\n \+ <TH> Error </TH>\n \+ <xsl:for-each select='SOLVER_STAT'>\n \+ <xsl:sort select='@ID' data-type='number'/>\n \+ <TD> <xsl:value-of select='ERROR' />\n \+ <xsl:if test='ITER'>\n \+ <xsl:text>(</xsl:text>\n \+ <xsl:value-of select='ITER' />\n \+ <xsl:text>)</xsl:text>\n \+ </xsl:if> </TD>\n \+ </xsl:for-each>\n \+ </TR>\n \+ </xsl:for-each>\n \+ </table>\n \+ </body>\n \+ </html>\n \+ </xsl:template>\n \+ </xsl:stylesheet>\n\n";+ +}+#endif
+ eigen3/bench/spbench/test_sparseLU.cpp view
@@ -0,0 +1,93 @@+// Small bench routine for Eigen available in Eigen+// (C) Desire NUENTSA WAKAM, INRIA++#include <iostream>+#include <fstream>+#include <iomanip>+#include <unsupported/Eigen/SparseExtra>+#include <Eigen/SparseLU>+#include <bench/BenchTimer.h>+#ifdef EIGEN_METIS_SUPPORT+#include <Eigen/MetisSupport>+#endif++using namespace std;+using namespace Eigen;++int main(int argc, char **args)+{+// typedef complex<double> scalar; + typedef double scalar; + SparseMatrix<scalar, ColMajor> A; + typedef SparseMatrix<scalar, ColMajor>::Index Index;+ typedef Matrix<scalar, Dynamic, Dynamic> DenseMatrix;+ typedef Matrix<scalar, Dynamic, 1> DenseRhs;+ Matrix<scalar, Dynamic, 1> b, x, tmp;+// SparseLU<SparseMatrix<scalar, ColMajor>, AMDOrdering<int> > solver;+// #ifdef EIGEN_METIS_SUPPORT+// SparseLU<SparseMatrix<scalar, ColMajor>, MetisOrdering<int> > solver; +// std::cout<< "ORDERING : METIS\n"; +// #else+ SparseLU<SparseMatrix<scalar, ColMajor>, COLAMDOrdering<int> > solver;+ std::cout<< "ORDERING : COLAMD\n"; +// #endif+ + ifstream matrix_file; + string line;+ int n;+ BenchTimer timer; + + // Set parameters+ /* Fill the matrix with sparse matrix stored in Matrix-Market coordinate column-oriented format */+ if (argc < 2) assert(false && "please, give the matrix market file ");+ loadMarket(A, args[1]);+ cout << "End charging matrix " << endl;+ bool iscomplex=false, isvector=false;+ int sym;+ getMarketHeader(args[1], sym, iscomplex, isvector);+// if (iscomplex) { cout<< " Not for complex matrices \n"; return -1; }+ if (isvector) { cout << "The provided file is not a matrix file\n"; return -1;}+ if (sym != 0) { // symmetric matrices, only the lower part is stored+ SparseMatrix<scalar, ColMajor> temp; + temp = A;+ A = temp.selfadjointView<Lower>();+ }+ n = A.cols();+ /* Fill the right hand side */++ if (argc > 2)+ loadMarketVector(b, args[2]);+ else + {+ b.resize(n);+ tmp.resize(n);+// tmp.setRandom();+ for (int i = 0; i < n; i++) tmp(i) = i; + b = A * tmp ;+ }++ /* Compute the factorization */+// solver.isSymmetric(true);+ timer.start(); +// solver.compute(A);+ solver.analyzePattern(A); + timer.stop(); + cout << "Time to analyze " << timer.value() << std::endl;+ timer.reset(); + timer.start(); + solver.factorize(A); + timer.stop(); + cout << "Factorize Time " << timer.value() << std::endl;+ timer.reset(); + timer.start(); + x = solver.solve(b);+ timer.stop();+ cout << "solve time " << timer.value() << std::endl; + /* Check the accuracy */+ Matrix<scalar, Dynamic, 1> tmp2 = b - A*x;+ scalar tempNorm = tmp2.norm()/b.norm();+ cout << "Relative norm of the computed solution : " << tempNorm <<"\n";+ cout << "Number of nonzeros in the factor : " << solver.nnzL() + solver.nnzU() << std::endl; + + return 0;+}
+ eigen3/bench/spmv.cpp view
@@ -0,0 +1,233 @@++//g++-4.4 -DNOMTL -Wl,-rpath /usr/local/lib/oski -L /usr/local/lib/oski/ -l oski -l oski_util -l oski_util_Tid -DOSKI -I ~/Coding/LinearAlgebra/mtl4/ spmv.cpp -I .. -O2 -DNDEBUG -lrt -lm -l oski_mat_CSC_Tid -loskilt && ./a.out r200000 c200000 n100 t1 p1++#define SCALAR double++#include <iostream>+#include <algorithm>+#include "BenchTimer.h"+#include "BenchSparseUtil.h"++#define SPMV_BENCH(CODE) BENCH(t,tries,repeats,CODE);++// #ifdef MKL+//+// #include "mkl_types.h"+// #include "mkl_spblas.h"+//+// template<typename Lhs,typename Rhs,typename Res>+// void mkl_multiply(const Lhs& lhs, const Rhs& rhs, Res& res)+// {+// char n = 'N';+// float alpha = 1;+// char matdescra[6];+// matdescra[0] = 'G';+// matdescra[1] = 0;+// matdescra[2] = 0;+// matdescra[3] = 'C';+// mkl_scscmm(&n, lhs.rows(), rhs.cols(), lhs.cols(), &alpha, matdescra,+// lhs._valuePtr(), lhs._innerIndexPtr(), lhs.outerIndexPtr(),+// pntre, b, &ldb, &beta, c, &ldc);+// // mkl_somatcopy('C', 'T', lhs.rows(), lhs.cols(), 1,+// // lhs._valuePtr(), lhs.rows(), DST, dst_stride);+// }+//+// #endif++int main(int argc, char *argv[])+{+ int size = 10000;+ int rows = size;+ int cols = size;+ int nnzPerCol = 40;+ int tries = 2;+ int repeats = 2;++ bool need_help = false;+ for(int i = 1; i < argc; i++)+ {+ if(argv[i][0] == 'r')+ {+ rows = atoi(argv[i]+1);+ }+ else if(argv[i][0] == 'c')+ {+ cols = atoi(argv[i]+1);+ }+ else if(argv[i][0] == 'n')+ {+ nnzPerCol = atoi(argv[i]+1);+ }+ else if(argv[i][0] == 't')+ {+ tries = atoi(argv[i]+1);+ }+ else if(argv[i][0] == 'p')+ {+ repeats = atoi(argv[i]+1);+ }+ else+ {+ need_help = true;+ }+ }+ if(need_help)+ {+ std::cout << argv[0] << " r<nb rows> c<nb columns> n<non zeros per column> t<nb tries> p<nb repeats>\n";+ return 1;+ }++ std::cout << "SpMV " << rows << " x " << cols << " with " << nnzPerCol << " non zeros per column. (" << repeats << " repeats, and " << tries << " tries)\n\n";++ EigenSparseMatrix sm(rows,cols);+ DenseVector dv(cols), res(rows);+ dv.setRandom();++ BenchTimer t;+ while (nnzPerCol>=4)+ {+ std::cout << "nnz: " << nnzPerCol << "\n";+ sm.setZero();+ fillMatrix2(nnzPerCol, rows, cols, sm);++ // dense matrices+ #ifdef DENSEMATRIX+ {+ DenseMatrix dm(rows,cols), (rows,cols);+ eiToDense(sm, dm);++ SPMV_BENCH(res = dm * sm);+ std::cout << "Dense " << t.value()/repeats << "\t";++ SPMV_BENCH(res = dm.transpose() * sm);+ std::cout << t.value()/repeats << endl;+ }+ #endif++ // eigen sparse matrices+ {+ SPMV_BENCH(res.noalias() += sm * dv; )+ std::cout << "Eigen " << t.value()/repeats << "\t";++ SPMV_BENCH(res.noalias() += sm.transpose() * dv; )+ std::cout << t.value()/repeats << endl;+ }++ // CSparse+ #ifdef CSPARSE+ {+ std::cout << "CSparse \n";+ cs *csm;+ eiToCSparse(sm, csm);++// BENCH();+// timer.stop();+// std::cout << " a * b:\t" << timer.value() << endl;++// BENCH( { m3 = cs_sorted_multiply2(m1, m2); cs_spfree(m3); } );+// std::cout << " a * b:\t" << timer.value() << endl;+ }+ #endif++ #ifdef OSKI+ {+ oski_matrix_t om;+ oski_vecview_t ov, ores;+ oski_Init();+ om = oski_CreateMatCSC(sm._outerIndexPtr(), sm._innerIndexPtr(), sm._valuePtr(), rows, cols,+ SHARE_INPUTMAT, 1, INDEX_ZERO_BASED);+ ov = oski_CreateVecView(dv.data(), cols, STRIDE_UNIT);+ ores = oski_CreateVecView(res.data(), rows, STRIDE_UNIT);++ SPMV_BENCH( oski_MatMult(om, OP_NORMAL, 1, ov, 0, ores) );+ std::cout << "OSKI " << t.value()/repeats << "\t";++ SPMV_BENCH( oski_MatMult(om, OP_TRANS, 1, ov, 0, ores) );+ std::cout << t.value()/repeats << "\n";++ // tune+ t.reset();+ t.start();+ oski_SetHintMatMult(om, OP_NORMAL, 1.0, SYMBOLIC_VEC, 0.0, SYMBOLIC_VEC, ALWAYS_TUNE_AGGRESSIVELY);+ oski_TuneMat(om);+ t.stop();+ double tuning = t.value();++ SPMV_BENCH( oski_MatMult(om, OP_NORMAL, 1, ov, 0, ores) );+ std::cout << "OSKI tuned " << t.value()/repeats << "\t";++ SPMV_BENCH( oski_MatMult(om, OP_TRANS, 1, ov, 0, ores) );+ std::cout << t.value()/repeats << "\t(" << tuning << ")\n";+++ oski_DestroyMat(om);+ oski_DestroyVecView(ov);+ oski_DestroyVecView(ores);+ oski_Close();+ }+ #endif++ #ifndef NOUBLAS+ {+ using namespace boost::numeric;+ UblasMatrix um(rows,cols);+ eiToUblas(sm, um);++ boost::numeric::ublas::vector<Scalar> uv(cols), ures(rows);+ Map<Matrix<Scalar,Dynamic,1> >(&uv[0], cols) = dv;+ Map<Matrix<Scalar,Dynamic,1> >(&ures[0], rows) = res;++ SPMV_BENCH(ublas::axpy_prod(um, uv, ures, true));+ std::cout << "ublas " << t.value()/repeats << "\t";++ SPMV_BENCH(ublas::axpy_prod(boost::numeric::ublas::trans(um), uv, ures, true));+ std::cout << t.value()/repeats << endl;+ }+ #endif++ // GMM+++ #ifndef NOGMM+ {+ GmmSparse gm(rows,cols);+ eiToGmm(sm, gm);++ std::vector<Scalar> gv(cols), gres(rows);+ Map<Matrix<Scalar,Dynamic,1> >(&gv[0], cols) = dv;+ Map<Matrix<Scalar,Dynamic,1> >(&gres[0], rows) = res;++ SPMV_BENCH(gmm::mult(gm, gv, gres));+ std::cout << "GMM++ " << t.value()/repeats << "\t";++ SPMV_BENCH(gmm::mult(gmm::transposed(gm), gv, gres));+ std::cout << t.value()/repeats << endl;+ }+ #endif++ // MTL4+ #ifndef NOMTL+ {+ MtlSparse mm(rows,cols);+ eiToMtl(sm, mm);+ mtl::dense_vector<Scalar> mv(cols, 1.0);+ mtl::dense_vector<Scalar> mres(rows, 1.0);++ SPMV_BENCH(mres = mm * mv);+ std::cout << "MTL4 " << t.value()/repeats << "\t";++ SPMV_BENCH(mres = trans(mm) * mv);+ std::cout << t.value()/repeats << endl;+ }+ #endif++ std::cout << "\n";++ if(nnzPerCol==1)+ break;+ nnzPerCol -= nnzPerCol/2;+ }++ return 0;+}+++
+ eigen3/bench/vdw_new.cpp view
@@ -0,0 +1,56 @@+#include <iostream>+#include <Eigen/Core>++using namespace Eigen;++#ifndef SCALAR+#define SCALAR float+#endif++#ifndef SIZE+#define SIZE 10000+#endif++#ifndef REPEAT+#define REPEAT 10000+#endif++typedef Matrix<SCALAR, Eigen::Dynamic, 1> Vec;++using namespace std;++SCALAR E_VDW(const Vec &interactions1, const Vec &interactions2)+{+ return (interactions2.cwise()/interactions1)+ .cwise().cube()+ .cwise().square()+ .cwise().square()+ .sum();+}++int main() +{+ //+ // 1 2 3 4 ... (interactions)+ // ka . . . . ...+ // rab . . . . ...+ // energy . . . . ...+ // ... ... ... ... ... ...+ // (variables+ // for+ // interaction)+ //+ Vec interactions1(SIZE), interactions2(SIZE); // SIZE is the number of vdw interactions in our system+ // SetupCalculations()+ SCALAR rab = 1.0; + interactions1.setConstant(2.4);+ interactions2.setConstant(rab);+ + // Energy()+ SCALAR energy = 0.0;+ for (unsigned int i = 0; i<REPEAT; ++i) {+ energy += E_VDW(interactions1, interactions2);+ energy *= 1 + 1e-20 * i; // prevent compiler from optimizing the loop+ }+ cout << "energy = " << energy << endl;+}
+ eigen3/blas/BandTriangularSolver.h view
@@ -0,0 +1,97 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_BAND_TRIANGULARSOLVER_H+#define EIGEN_BAND_TRIANGULARSOLVER_H++namespace internal {++ /* \internal+ * Solve Ax=b with A a band triangular matrix+ * TODO: extend it to matrices for x abd b */+template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, int StorageOrder>+struct band_solve_triangular_selector;+++template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar>+struct band_solve_triangular_selector<Index,Mode,LhsScalar,ConjLhs,RhsScalar,RowMajor>+{+ typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,RowMajor>, 0, OuterStride<> > LhsMap;+ typedef Map<Matrix<RhsScalar,Dynamic,1> > RhsMap;+ enum { IsLower = (Mode&Lower) ? 1 : 0 };+ static void run(Index size, Index k, const LhsScalar* _lhs, Index lhsStride, RhsScalar* _other)+ {+ const LhsMap lhs(_lhs,size,k+1,OuterStride<>(lhsStride));+ RhsMap other(_other,size,1);+ typename internal::conditional<+ ConjLhs,+ const CwiseUnaryOp<typename internal::scalar_conjugate_op<LhsScalar>,LhsMap>,+ const LhsMap&>+ ::type cjLhs(lhs);+ + for(int col=0 ; col<other.cols() ; ++col)+ {+ for(int ii=0; ii<size; ++ii)+ {+ int i = IsLower ? ii : size-ii-1;+ int actual_k = (std::min)(k,ii);+ int actual_start = IsLower ? k-actual_k : 1;+ + if(actual_k>0)+ other.coeffRef(i,col) -= cjLhs.row(i).segment(actual_start,actual_k).transpose()+ .cwiseProduct(other.col(col).segment(IsLower ? i-actual_k : i+1,actual_k)).sum();++ if((Mode&UnitDiag)==0)+ other.coeffRef(i,col) /= cjLhs(i,IsLower ? k : 0);+ }+ }+ }+ +};++template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar>+struct band_solve_triangular_selector<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ColMajor>+{+ typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> > LhsMap;+ typedef Map<Matrix<RhsScalar,Dynamic,1> > RhsMap;+ enum { IsLower = (Mode&Lower) ? 1 : 0 };+ static void run(Index size, Index k, const LhsScalar* _lhs, Index lhsStride, RhsScalar* _other)+ {+ const LhsMap lhs(_lhs,k+1,size,OuterStride<>(lhsStride));+ RhsMap other(_other,size,1);+ typename internal::conditional<+ ConjLhs,+ const CwiseUnaryOp<typename internal::scalar_conjugate_op<LhsScalar>,LhsMap>,+ const LhsMap&>+ ::type cjLhs(lhs);+ + for(int col=0 ; col<other.cols() ; ++col)+ {+ for(int ii=0; ii<size; ++ii)+ {+ int i = IsLower ? ii : size-ii-1;+ int actual_k = (std::min)(k,size-ii-1);+ int actual_start = IsLower ? 1 : k-actual_k;+ + if((Mode&UnitDiag)==0)+ other.coeffRef(i,col) /= cjLhs(IsLower ? 0 : k, i);++ if(actual_k>0)+ other.col(col).segment(IsLower ? i+1 : i-actual_k, actual_k)+ -= other.coeff(i,col) * cjLhs.col(i).segment(actual_start,actual_k);+ + }+ }+ }+};+++} // end namespace internal++#endif // EIGEN_BAND_TRIANGULARSOLVER_H
+ eigen3/blas/CMakeLists.txt view
@@ -0,0 +1,60 @@++project(EigenBlas CXX)++include("../cmake/language_support.cmake")++workaround_9220(Fortran EIGEN_Fortran_COMPILER_WORKS)++if(EIGEN_Fortran_COMPILER_WORKS)+ enable_language(Fortran OPTIONAL)+ if(NOT CMAKE_Fortran_COMPILER)+ set(EIGEN_Fortran_COMPILER_WORKS OFF)+ endif()+endif()++add_custom_target(blas)++set(EigenBlas_SRCS single.cpp double.cpp complex_single.cpp complex_double.cpp xerbla.cpp)++if(EIGEN_Fortran_COMPILER_WORKS)++set(EigenBlas_SRCS ${EigenBlas_SRCS}+ complexdots.f+ srotm.f srotmg.f drotm.f drotmg.f+ lsame.f dspmv.f ssbmv.f+ chbmv.f sspmv.f+ zhbmv.f chpmv.f dsbmv.f+ zhpmv.f+ dtbmv.f stbmv.f ctbmv.f ztbmv.f+)+else()++message(WARNING " No fortran compiler has been detected, the blas build will be incomplete.")++endif()++add_library(eigen_blas_static ${EigenBlas_SRCS})+add_library(eigen_blas SHARED ${EigenBlas_SRCS})++if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)+ target_link_libraries(eigen_blas_static ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})+ target_link_libraries(eigen_blas ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})+endif()++add_dependencies(blas eigen_blas eigen_blas_static)++install(TARGETS eigen_blas eigen_blas_static+ RUNTIME DESTINATION bin+ LIBRARY DESTINATION lib+ ARCHIVE DESTINATION lib)++if(EIGEN_Fortran_COMPILER_WORKS)++if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)+ add_subdirectory(testing) # can't do EXCLUDE_FROM_ALL here, breaks CTest+else()+ add_subdirectory(testing EXCLUDE_FROM_ALL)+endif()++endif()+
+ eigen3/blas/GeneralRank1Update.h view
@@ -0,0 +1,44 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Chen-Pang He <jdh8@ms63.hinet.net>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_GENERAL_RANK1UPDATE_H+#define EIGEN_GENERAL_RANK1UPDATE_H++namespace internal {++/* Optimized matrix += alpha * uv' */+template<typename Scalar, typename Index, int StorageOrder, bool ConjLhs, bool ConjRhs>+struct general_rank1_update;++template<typename Scalar, typename Index, bool ConjLhs, bool ConjRhs>+struct general_rank1_update<Scalar,Index,ColMajor,ConjLhs,ConjRhs>+{+ static void run(Index rows, Index cols, Scalar* mat, Index stride, const Scalar* u, const Scalar* v, Scalar alpha)+ {+ typedef Map<const Matrix<Scalar,Dynamic,1> > OtherMap;+ typedef typename conj_expr_if<ConjLhs,OtherMap>::type ConjRhsType;+ conj_if<ConjRhs> cj;++ for (Index i=0; i<cols; ++i)+ Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i,rows) += alpha * cj(v[i]) * ConjRhsType(OtherMap(u,rows));+ }+};++template<typename Scalar, typename Index, bool ConjLhs, bool ConjRhs>+struct general_rank1_update<Scalar,Index,RowMajor,ConjLhs,ConjRhs>+{+ static void run(Index rows, Index cols, Scalar* mat, Index stride, const Scalar* u, const Scalar* v, Scalar alpha)+ {+ general_rank1_update<Scalar,Index,ColMajor,ConjRhs,ConjRhs>::run(rows,cols,mat,stride,u,v,alpha);+ }+};++} // end namespace internal++#endif // EIGEN_GENERAL_RANK1UPDATE_H
+ eigen3/blas/PackedSelfadjointProduct.h view
@@ -0,0 +1,53 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Chen-Pang He <jdh8@ms63.hinet.net>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_SELFADJOINT_PACKED_PRODUCT_H+#define EIGEN_SELFADJOINT_PACKED_PRODUCT_H++namespace internal {++/* Optimized matrix += alpha * uv'+ * The matrix is in packed form.+ */+template<typename Scalar, typename Index, int StorageOrder, int UpLo, bool ConjLhs, bool ConjRhs>+struct selfadjoint_packed_rank1_update;++template<typename Scalar, typename Index, int UpLo, bool ConjLhs, bool ConjRhs>+struct selfadjoint_packed_rank1_update<Scalar,Index,ColMajor,UpLo,ConjLhs,ConjRhs>+{+ typedef typename NumTraits<Scalar>::Real RealScalar;+ static void run(Index size, Scalar* mat, const Scalar* vec, RealScalar alpha)+ {+ typedef Map<const Matrix<Scalar,Dynamic,1> > OtherMap;+ typedef typename conj_expr_if<ConjLhs,OtherMap>::type ConjRhsType;+ conj_if<ConjRhs> cj;++ for (Index i=0; i<size; ++i)+ {+ Map<Matrix<Scalar,Dynamic,1> >(mat, UpLo==Lower ? size-i : (i+1)) += alpha * cj(vec[i]) * ConjRhsType(OtherMap(vec+(UpLo==Lower ? i : 0), UpLo==Lower ? size-i : (i+1)));+ //FIXME This should be handled outside.+ mat[UpLo==Lower ? 0 : i] = numext::real(mat[UpLo==Lower ? 0 : i]);+ mat += UpLo==Lower ? size-i : (i+1);+ }+ }+};++template<typename Scalar, typename Index, int UpLo, bool ConjLhs, bool ConjRhs>+struct selfadjoint_packed_rank1_update<Scalar,Index,RowMajor,UpLo,ConjLhs,ConjRhs>+{+ typedef typename NumTraits<Scalar>::Real RealScalar;+ static void run(Index size, Scalar* mat, const Scalar* vec, RealScalar alpha)+ {+ selfadjoint_packed_rank1_update<Scalar,Index,ColMajor,UpLo==Lower?Upper:Lower,ConjRhs,ConjLhs>::run(size,mat,vec,alpha);+ }+};++} // end namespace internal++#endif // EIGEN_SELFADJOINT_PACKED_PRODUCT_H
+ eigen3/blas/PackedTriangularMatrixVector.h view
@@ -0,0 +1,79 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Chen-Pang He <jdh8@ms63.hinet.net>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_PACKED_TRIANGULAR_MATRIX_VECTOR_H+#define EIGEN_PACKED_TRIANGULAR_MATRIX_VECTOR_H++namespace internal {++template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs, int StorageOrder>+struct packed_triangular_matrix_vector_product;++template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs>+struct packed_triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,ColMajor>+{+ typedef typename scalar_product_traits<LhsScalar, RhsScalar>::ReturnType ResScalar;+ enum {+ IsLower = (Mode & Lower) ==Lower,+ HasUnitDiag = (Mode & UnitDiag)==UnitDiag,+ HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag+ };+ static void run(Index size, const LhsScalar* lhs, const RhsScalar* rhs, ResScalar* res, ResScalar alpha)+ {+ internal::conj_if<ConjRhs> cj;+ typedef Map<const Matrix<LhsScalar,Dynamic,1> > LhsMap;+ typedef typename conj_expr_if<ConjLhs,LhsMap>::type ConjLhsType;+ typedef Map<Matrix<ResScalar,Dynamic,1> > ResMap;++ for (Index i=0; i<size; ++i)+ {+ Index s = IsLower&&(HasUnitDiag||HasZeroDiag) ? 1 : 0;+ Index r = IsLower ? size-i: i+1;+ if (EIGEN_IMPLIES(HasUnitDiag||HasZeroDiag, (--r)>0))+ ResMap(res+(IsLower ? s+i : 0),r) += alpha * cj(rhs[i]) * ConjLhsType(LhsMap(lhs+s,r));+ if (HasUnitDiag)+ res[i] += alpha * cj(rhs[i]);+ lhs += IsLower ? size-i: i+1;+ }+ };+};++template<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs>+struct packed_triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,RowMajor>+{+ typedef typename scalar_product_traits<LhsScalar, RhsScalar>::ReturnType ResScalar;+ enum {+ IsLower = (Mode & Lower) ==Lower,+ HasUnitDiag = (Mode & UnitDiag)==UnitDiag,+ HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag+ };+ static void run(Index size, const LhsScalar* lhs, const RhsScalar* rhs, ResScalar* res, ResScalar alpha)+ {+ internal::conj_if<ConjRhs> cj;+ typedef Map<const Matrix<LhsScalar,Dynamic,1> > LhsMap;+ typedef typename conj_expr_if<ConjLhs,LhsMap>::type ConjLhsType;+ typedef Map<const Matrix<RhsScalar,Dynamic,1> > RhsMap;+ typedef typename conj_expr_if<ConjRhs,RhsMap>::type ConjRhsType;++ for (Index i=0; i<size; ++i)+ {+ Index s = !IsLower&&(HasUnitDiag||HasZeroDiag) ? 1 : 0;+ Index r = IsLower ? i+1 : size-i;+ if (EIGEN_IMPLIES(HasUnitDiag||HasZeroDiag, (--r)>0))+ res[i] += alpha * (ConjLhsType(LhsMap(lhs+s,r)).cwiseProduct(ConjRhsType(RhsMap(rhs+(IsLower ? 0 : s+i),r)))).sum();+ if (HasUnitDiag)+ res[i] += alpha * cj(rhs[i]);+ lhs += IsLower ? i+1 : size-i;+ }+ };+};++} // end namespace internal++#endif // EIGEN_PACKED_TRIANGULAR_MATRIX_VECTOR_H
+ eigen3/blas/PackedTriangularSolverVector.h view
@@ -0,0 +1,88 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Chen-Pang He <jdh8@ms63.hinet.net>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_PACKED_TRIANGULAR_SOLVER_VECTOR_H+#define EIGEN_PACKED_TRIANGULAR_SOLVER_VECTOR_H++namespace internal {++template<typename LhsScalar, typename RhsScalar, typename Index, int Side, int Mode, bool Conjugate, int StorageOrder>+struct packed_triangular_solve_vector;++// forward and backward substitution, row-major, rhs is a vector+template<typename LhsScalar, typename RhsScalar, typename Index, int Mode, bool Conjugate>+struct packed_triangular_solve_vector<LhsScalar, RhsScalar, Index, OnTheLeft, Mode, Conjugate, RowMajor>+{+ enum {+ IsLower = (Mode&Lower)==Lower+ };+ static void run(Index size, const LhsScalar* lhs, RhsScalar* rhs)+ {+ internal::conj_if<Conjugate> cj;+ typedef Map<const Matrix<LhsScalar,Dynamic,1> > LhsMap;+ typedef typename conj_expr_if<Conjugate,LhsMap>::type ConjLhsType;++ lhs += IsLower ? 0 : (size*(size+1)>>1)-1;+ for(Index pi=0; pi<size; ++pi)+ {+ Index i = IsLower ? pi : size-pi-1;+ Index s = IsLower ? 0 : 1;+ if (pi>0)+ rhs[i] -= (ConjLhsType(LhsMap(lhs+s,pi))+ .cwiseProduct(Map<const Matrix<RhsScalar,Dynamic,1> >(rhs+(IsLower ? 0 : i+1),pi))).sum();+ if (!(Mode & UnitDiag))+ rhs[i] /= cj(lhs[IsLower ? i : 0]);+ IsLower ? lhs += pi+1 : lhs -= pi+2;+ }+ }+};++// forward and backward substitution, column-major, rhs is a vector+template<typename LhsScalar, typename RhsScalar, typename Index, int Mode, bool Conjugate>+struct packed_triangular_solve_vector<LhsScalar, RhsScalar, Index, OnTheLeft, Mode, Conjugate, ColMajor>+{+ enum {+ IsLower = (Mode&Lower)==Lower+ };+ static void run(Index size, const LhsScalar* lhs, RhsScalar* rhs)+ {+ internal::conj_if<Conjugate> cj;+ typedef Map<const Matrix<LhsScalar,Dynamic,1> > LhsMap;+ typedef typename conj_expr_if<Conjugate,LhsMap>::type ConjLhsType;++ lhs += IsLower ? 0 : size*(size-1)>>1;+ for(Index pi=0; pi<size; ++pi)+ {+ Index i = IsLower ? pi : size-pi-1;+ Index r = size - pi - 1;+ if (!(Mode & UnitDiag))+ rhs[i] /= cj(lhs[IsLower ? 0 : i]);+ if (r>0)+ Map<Matrix<RhsScalar,Dynamic,1> >(rhs+(IsLower? i+1 : 0),r) -=+ rhs[i] * ConjLhsType(LhsMap(lhs+(IsLower? 1 : 0),r));+ IsLower ? lhs += size-pi : lhs -= r;+ }+ }+};++template<typename LhsScalar, typename RhsScalar, typename Index, int Mode, bool Conjugate, int StorageOrder>+struct packed_triangular_solve_vector<LhsScalar, RhsScalar, Index, OnTheRight, Mode, Conjugate, StorageOrder>+{+ static void run(Index size, const LhsScalar* lhs, RhsScalar* rhs)+ {+ packed_triangular_solve_vector<LhsScalar,RhsScalar,Index,OnTheLeft,+ ((Mode&Upper)==Upper ? Lower : Upper) | (Mode&UnitDiag),+ Conjugate,StorageOrder==RowMajor?ColMajor:RowMajor+ >::run(size, lhs, rhs);+ }+};++} // end namespace internal++#endif // EIGEN_PACKED_TRIANGULAR_SOLVER_VECTOR_H
+ eigen3/blas/README.txt view
@@ -0,0 +1,6 @@++This directory contains a BLAS library built on top of Eigen.++This module is not built by default. In order to compile it, you need to+type 'make blas' from within your build dir.+
+ eigen3/blas/Rank2Update.h view
@@ -0,0 +1,57 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Chen-Pang He <jdh8@ms63.hinet.net>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_RANK2UPDATE_H+#define EIGEN_RANK2UPDATE_H++namespace internal {++/* Optimized selfadjoint matrix += alpha * uv' + conj(alpha)*vu'+ * This is the low-level version of SelfadjointRank2Update.h+ */+template<typename Scalar, typename Index, int UpLo>+struct rank2_update_selector+{+ static void run(Index size, Scalar* mat, Index stride, const Scalar* u, const Scalar* v, Scalar alpha)+ {+ typedef Map<const Matrix<Scalar,Dynamic,1> > OtherMap;+ for (Index i=0; i<size; ++i)+ {+ Map<Matrix<Scalar,Dynamic,1> >(mat+stride*i+(UpLo==Lower ? i : 0), UpLo==Lower ? size-i : (i+1)) +=+ numext::conj(alpha) * numext::conj(u[i]) * OtherMap(v+(UpLo==Lower ? i : 0), UpLo==Lower ? size-i : (i+1))+ + alpha * numext::conj(v[i]) * OtherMap(u+(UpLo==Lower ? i : 0), UpLo==Lower ? size-i : (i+1));+ }+ }+};++/* Optimized selfadjoint matrix += alpha * uv' + conj(alpha)*vu'+ * The matrix is in packed form.+ */+template<typename Scalar, typename Index, int UpLo>+struct packed_rank2_update_selector+{+ static void run(Index size, Scalar* mat, const Scalar* u, const Scalar* v, Scalar alpha)+ {+ typedef Map<const Matrix<Scalar,Dynamic,1> > OtherMap;+ Index offset = 0;+ for (Index i=0; i<size; ++i)+ {+ Map<Matrix<Scalar,Dynamic,1> >(mat+offset, UpLo==Lower ? size-i : (i+1)) +=+ numext::conj(alpha) * numext::conj(u[i]) * OtherMap(v+(UpLo==Lower ? i : 0), UpLo==Lower ? size-i : (i+1))+ + alpha * numext::conj(v[i]) * OtherMap(u+(UpLo==Lower ? i : 0), UpLo==Lower ? size-i : (i+1));+ //FIXME This should be handled outside.+ mat[offset+(UpLo==Lower ? 0 : i)] = numext::real(mat[offset+(UpLo==Lower ? 0 : i)]);+ offset += UpLo==Lower ? size-i : (i+1);+ }+ }+};++} // end namespace internal++#endif // EIGEN_RANK2UPDATE_H
+ eigen3/blas/chbmv.f view
@@ -0,0 +1,310 @@+ SUBROUTINE CHBMV(UPLO,N,K,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)+* .. Scalar Arguments ..+ COMPLEX ALPHA,BETA+ INTEGER INCX,INCY,K,LDA,N+ CHARACTER UPLO+* ..+* .. Array Arguments ..+ COMPLEX A(LDA,*),X(*),Y(*)+* ..+*+* Purpose+* =======+*+* CHBMV performs the matrix-vector operation+*+* y := alpha*A*x + beta*y,+*+* where alpha and beta are scalars, x and y are n element vectors and+* A is an n by n hermitian band matrix, with k super-diagonals.+*+* Arguments+* ==========+*+* UPLO - CHARACTER*1.+* On entry, UPLO specifies whether the upper or lower+* triangular part of the band matrix A is being supplied as+* follows:+*+* UPLO = 'U' or 'u' The upper triangular part of A is+* being supplied.+*+* UPLO = 'L' or 'l' The lower triangular part of A is+* being supplied.+*+* Unchanged on exit.+*+* N - INTEGER.+* On entry, N specifies the order of the matrix A.+* N must be at least zero.+* Unchanged on exit.+*+* K - INTEGER.+* On entry, K specifies the number of super-diagonals of the+* matrix A. K must satisfy 0 .le. K.+* Unchanged on exit.+*+* ALPHA - COMPLEX .+* On entry, ALPHA specifies the scalar alpha.+* Unchanged on exit.+*+* A - COMPLEX array of DIMENSION ( LDA, n ).+* Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )+* by n part of the array A must contain the upper triangular+* band part of the hermitian matrix, supplied column by+* column, with the leading diagonal of the matrix in row+* ( k + 1 ) of the array, the first super-diagonal starting at+* position 2 in row k, and so on. The top left k by k triangle+* of the array A is not referenced.+* The following program segment will transfer the upper+* triangular part of a hermitian band matrix from conventional+* full matrix storage to band storage:+*+* DO 20, J = 1, N+* M = K + 1 - J+* DO 10, I = MAX( 1, J - K ), J+* A( M + I, J ) = matrix( I, J )+* 10 CONTINUE+* 20 CONTINUE+*+* Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )+* by n part of the array A must contain the lower triangular+* band part of the hermitian matrix, supplied column by+* column, with the leading diagonal of the matrix in row 1 of+* the array, the first sub-diagonal starting at position 1 in+* row 2, and so on. The bottom right k by k triangle of the+* array A is not referenced.+* The following program segment will transfer the lower+* triangular part of a hermitian band matrix from conventional+* full matrix storage to band storage:+*+* DO 20, J = 1, N+* M = 1 - J+* DO 10, I = J, MIN( N, J + K )+* A( M + I, J ) = matrix( I, J )+* 10 CONTINUE+* 20 CONTINUE+*+* Note that the imaginary parts of the diagonal elements need+* not be set and are assumed to be zero.+* Unchanged on exit.+*+* LDA - INTEGER.+* On entry, LDA specifies the first dimension of A as declared+* in the calling (sub) program. LDA must be at least+* ( k + 1 ).+* Unchanged on exit.+*+* X - COMPLEX array of DIMENSION at least+* ( 1 + ( n - 1 )*abs( INCX ) ).+* Before entry, the incremented array X must contain the+* vector x.+* Unchanged on exit.+*+* INCX - INTEGER.+* On entry, INCX specifies the increment for the elements of+* X. INCX must not be zero.+* Unchanged on exit.+*+* BETA - COMPLEX .+* On entry, BETA specifies the scalar beta.+* Unchanged on exit.+*+* Y - COMPLEX array of DIMENSION at least+* ( 1 + ( n - 1 )*abs( INCY ) ).+* Before entry, the incremented array Y must contain the+* vector y. On exit, Y is overwritten by the updated vector y.+*+* INCY - INTEGER.+* On entry, INCY specifies the increment for the elements of+* Y. INCY must not be zero.+* Unchanged on exit.+*+* Further Details+* ===============+*+* Level 2 Blas routine.+*+* -- Written on 22-October-1986.+* Jack Dongarra, Argonne National Lab.+* Jeremy Du Croz, Nag Central Office.+* Sven Hammarling, Nag Central Office.+* Richard Hanson, Sandia National Labs.+*+* =====================================================================+*+* .. Parameters ..+ COMPLEX ONE+ PARAMETER (ONE= (1.0E+0,0.0E+0))+ COMPLEX ZERO+ PARAMETER (ZERO= (0.0E+0,0.0E+0))+* ..+* .. Local Scalars ..+ COMPLEX TEMP1,TEMP2+ INTEGER I,INFO,IX,IY,J,JX,JY,KPLUS1,KX,KY,L+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. External Subroutines ..+ EXTERNAL XERBLA+* ..+* .. Intrinsic Functions ..+ INTRINSIC CONJG,MAX,MIN,REAL+* ..+*+* Test the input parameters.+*+ INFO = 0+ IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN+ INFO = 1+ ELSE IF (N.LT.0) THEN+ INFO = 2+ ELSE IF (K.LT.0) THEN+ INFO = 3+ ELSE IF (LDA.LT. (K+1)) THEN+ INFO = 6+ ELSE IF (INCX.EQ.0) THEN+ INFO = 8+ ELSE IF (INCY.EQ.0) THEN+ INFO = 11+ END IF+ IF (INFO.NE.0) THEN+ CALL XERBLA('CHBMV ',INFO)+ RETURN+ END IF+*+* Quick return if possible.+*+ IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN+*+* Set up the start points in X and Y.+*+ IF (INCX.GT.0) THEN+ KX = 1+ ELSE+ KX = 1 - (N-1)*INCX+ END IF+ IF (INCY.GT.0) THEN+ KY = 1+ ELSE+ KY = 1 - (N-1)*INCY+ END IF+*+* Start the operations. In this version the elements of the array A+* are accessed sequentially with one pass through A.+*+* First form y := beta*y.+*+ IF (BETA.NE.ONE) THEN+ IF (INCY.EQ.1) THEN+ IF (BETA.EQ.ZERO) THEN+ DO 10 I = 1,N+ Y(I) = ZERO+ 10 CONTINUE+ ELSE+ DO 20 I = 1,N+ Y(I) = BETA*Y(I)+ 20 CONTINUE+ END IF+ ELSE+ IY = KY+ IF (BETA.EQ.ZERO) THEN+ DO 30 I = 1,N+ Y(IY) = ZERO+ IY = IY + INCY+ 30 CONTINUE+ ELSE+ DO 40 I = 1,N+ Y(IY) = BETA*Y(IY)+ IY = IY + INCY+ 40 CONTINUE+ END IF+ END IF+ END IF+ IF (ALPHA.EQ.ZERO) RETURN+ IF (LSAME(UPLO,'U')) THEN+*+* Form y when upper triangle of A is stored.+*+ KPLUS1 = K + 1+ IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN+ DO 60 J = 1,N+ TEMP1 = ALPHA*X(J)+ TEMP2 = ZERO+ L = KPLUS1 - J+ DO 50 I = MAX(1,J-K),J - 1+ Y(I) = Y(I) + TEMP1*A(L+I,J)+ TEMP2 = TEMP2 + CONJG(A(L+I,J))*X(I)+ 50 CONTINUE+ Y(J) = Y(J) + TEMP1*REAL(A(KPLUS1,J)) + ALPHA*TEMP2+ 60 CONTINUE+ ELSE+ JX = KX+ JY = KY+ DO 80 J = 1,N+ TEMP1 = ALPHA*X(JX)+ TEMP2 = ZERO+ IX = KX+ IY = KY+ L = KPLUS1 - J+ DO 70 I = MAX(1,J-K),J - 1+ Y(IY) = Y(IY) + TEMP1*A(L+I,J)+ TEMP2 = TEMP2 + CONJG(A(L+I,J))*X(IX)+ IX = IX + INCX+ IY = IY + INCY+ 70 CONTINUE+ Y(JY) = Y(JY) + TEMP1*REAL(A(KPLUS1,J)) + ALPHA*TEMP2+ JX = JX + INCX+ JY = JY + INCY+ IF (J.GT.K) THEN+ KX = KX + INCX+ KY = KY + INCY+ END IF+ 80 CONTINUE+ END IF+ ELSE+*+* Form y when lower triangle of A is stored.+*+ IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN+ DO 100 J = 1,N+ TEMP1 = ALPHA*X(J)+ TEMP2 = ZERO+ Y(J) = Y(J) + TEMP1*REAL(A(1,J))+ L = 1 - J+ DO 90 I = J + 1,MIN(N,J+K)+ Y(I) = Y(I) + TEMP1*A(L+I,J)+ TEMP2 = TEMP2 + CONJG(A(L+I,J))*X(I)+ 90 CONTINUE+ Y(J) = Y(J) + ALPHA*TEMP2+ 100 CONTINUE+ ELSE+ JX = KX+ JY = KY+ DO 120 J = 1,N+ TEMP1 = ALPHA*X(JX)+ TEMP2 = ZERO+ Y(JY) = Y(JY) + TEMP1*REAL(A(1,J))+ L = 1 - J+ IX = JX+ IY = JY+ DO 110 I = J + 1,MIN(N,J+K)+ IX = IX + INCX+ IY = IY + INCY+ Y(IY) = Y(IY) + TEMP1*A(L+I,J)+ TEMP2 = TEMP2 + CONJG(A(L+I,J))*X(IX)+ 110 CONTINUE+ Y(JY) = Y(JY) + ALPHA*TEMP2+ JX = JX + INCX+ JY = JY + INCY+ 120 CONTINUE+ END IF+ END IF+*+ RETURN+*+* End of CHBMV .+*+ END
+ eigen3/blas/chpmv.f view
@@ -0,0 +1,272 @@+ SUBROUTINE CHPMV(UPLO,N,ALPHA,AP,X,INCX,BETA,Y,INCY)+* .. Scalar Arguments ..+ COMPLEX ALPHA,BETA+ INTEGER INCX,INCY,N+ CHARACTER UPLO+* ..+* .. Array Arguments ..+ COMPLEX AP(*),X(*),Y(*)+* ..+*+* Purpose+* =======+*+* CHPMV performs the matrix-vector operation+*+* y := alpha*A*x + beta*y,+*+* where alpha and beta are scalars, x and y are n element vectors and+* A is an n by n hermitian matrix, supplied in packed form.+*+* Arguments+* ==========+*+* UPLO - CHARACTER*1.+* On entry, UPLO specifies whether the upper or lower+* triangular part of the matrix A is supplied in the packed+* array AP as follows:+*+* UPLO = 'U' or 'u' The upper triangular part of A is+* supplied in AP.+*+* UPLO = 'L' or 'l' The lower triangular part of A is+* supplied in AP.+*+* Unchanged on exit.+*+* N - INTEGER.+* On entry, N specifies the order of the matrix A.+* N must be at least zero.+* Unchanged on exit.+*+* ALPHA - COMPLEX .+* On entry, ALPHA specifies the scalar alpha.+* Unchanged on exit.+*+* AP - COMPLEX array of DIMENSION at least+* ( ( n*( n + 1 ) )/2 ).+* Before entry with UPLO = 'U' or 'u', the array AP must+* contain the upper triangular part of the hermitian matrix+* packed sequentially, column by column, so that AP( 1 )+* contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 )+* and a( 2, 2 ) respectively, and so on.+* Before entry with UPLO = 'L' or 'l', the array AP must+* contain the lower triangular part of the hermitian matrix+* packed sequentially, column by column, so that AP( 1 )+* contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 )+* and a( 3, 1 ) respectively, and so on.+* Note that the imaginary parts of the diagonal elements need+* not be set and are assumed to be zero.+* Unchanged on exit.+*+* X - COMPLEX array of dimension at least+* ( 1 + ( n - 1 )*abs( INCX ) ).+* Before entry, the incremented array X must contain the n+* element vector x.+* Unchanged on exit.+*+* INCX - INTEGER.+* On entry, INCX specifies the increment for the elements of+* X. INCX must not be zero.+* Unchanged on exit.+*+* BETA - COMPLEX .+* On entry, BETA specifies the scalar beta. When BETA is+* supplied as zero then Y need not be set on input.+* Unchanged on exit.+*+* Y - COMPLEX array of dimension at least+* ( 1 + ( n - 1 )*abs( INCY ) ).+* Before entry, the incremented array Y must contain the n+* element vector y. On exit, Y is overwritten by the updated+* vector y.+*+* INCY - INTEGER.+* On entry, INCY specifies the increment for the elements of+* Y. INCY must not be zero.+* Unchanged on exit.+*+* Further Details+* ===============+*+* Level 2 Blas routine.+*+* -- Written on 22-October-1986.+* Jack Dongarra, Argonne National Lab.+* Jeremy Du Croz, Nag Central Office.+* Sven Hammarling, Nag Central Office.+* Richard Hanson, Sandia National Labs.+*+* =====================================================================+*+* .. Parameters ..+ COMPLEX ONE+ PARAMETER (ONE= (1.0E+0,0.0E+0))+ COMPLEX ZERO+ PARAMETER (ZERO= (0.0E+0,0.0E+0))+* ..+* .. Local Scalars ..+ COMPLEX TEMP1,TEMP2+ INTEGER I,INFO,IX,IY,J,JX,JY,K,KK,KX,KY+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. External Subroutines ..+ EXTERNAL XERBLA+* ..+* .. Intrinsic Functions ..+ INTRINSIC CONJG,REAL+* ..+*+* Test the input parameters.+*+ INFO = 0+ IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN+ INFO = 1+ ELSE IF (N.LT.0) THEN+ INFO = 2+ ELSE IF (INCX.EQ.0) THEN+ INFO = 6+ ELSE IF (INCY.EQ.0) THEN+ INFO = 9+ END IF+ IF (INFO.NE.0) THEN+ CALL XERBLA('CHPMV ',INFO)+ RETURN+ END IF+*+* Quick return if possible.+*+ IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN+*+* Set up the start points in X and Y.+*+ IF (INCX.GT.0) THEN+ KX = 1+ ELSE+ KX = 1 - (N-1)*INCX+ END IF+ IF (INCY.GT.0) THEN+ KY = 1+ ELSE+ KY = 1 - (N-1)*INCY+ END IF+*+* Start the operations. In this version the elements of the array AP+* are accessed sequentially with one pass through AP.+*+* First form y := beta*y.+*+ IF (BETA.NE.ONE) THEN+ IF (INCY.EQ.1) THEN+ IF (BETA.EQ.ZERO) THEN+ DO 10 I = 1,N+ Y(I) = ZERO+ 10 CONTINUE+ ELSE+ DO 20 I = 1,N+ Y(I) = BETA*Y(I)+ 20 CONTINUE+ END IF+ ELSE+ IY = KY+ IF (BETA.EQ.ZERO) THEN+ DO 30 I = 1,N+ Y(IY) = ZERO+ IY = IY + INCY+ 30 CONTINUE+ ELSE+ DO 40 I = 1,N+ Y(IY) = BETA*Y(IY)+ IY = IY + INCY+ 40 CONTINUE+ END IF+ END IF+ END IF+ IF (ALPHA.EQ.ZERO) RETURN+ KK = 1+ IF (LSAME(UPLO,'U')) THEN+*+* Form y when AP contains the upper triangle.+*+ IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN+ DO 60 J = 1,N+ TEMP1 = ALPHA*X(J)+ TEMP2 = ZERO+ K = KK+ DO 50 I = 1,J - 1+ Y(I) = Y(I) + TEMP1*AP(K)+ TEMP2 = TEMP2 + CONJG(AP(K))*X(I)+ K = K + 1+ 50 CONTINUE+ Y(J) = Y(J) + TEMP1*REAL(AP(KK+J-1)) + ALPHA*TEMP2+ KK = KK + J+ 60 CONTINUE+ ELSE+ JX = KX+ JY = KY+ DO 80 J = 1,N+ TEMP1 = ALPHA*X(JX)+ TEMP2 = ZERO+ IX = KX+ IY = KY+ DO 70 K = KK,KK + J - 2+ Y(IY) = Y(IY) + TEMP1*AP(K)+ TEMP2 = TEMP2 + CONJG(AP(K))*X(IX)+ IX = IX + INCX+ IY = IY + INCY+ 70 CONTINUE+ Y(JY) = Y(JY) + TEMP1*REAL(AP(KK+J-1)) + ALPHA*TEMP2+ JX = JX + INCX+ JY = JY + INCY+ KK = KK + J+ 80 CONTINUE+ END IF+ ELSE+*+* Form y when AP contains the lower triangle.+*+ IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN+ DO 100 J = 1,N+ TEMP1 = ALPHA*X(J)+ TEMP2 = ZERO+ Y(J) = Y(J) + TEMP1*REAL(AP(KK))+ K = KK + 1+ DO 90 I = J + 1,N+ Y(I) = Y(I) + TEMP1*AP(K)+ TEMP2 = TEMP2 + CONJG(AP(K))*X(I)+ K = K + 1+ 90 CONTINUE+ Y(J) = Y(J) + ALPHA*TEMP2+ KK = KK + (N-J+1)+ 100 CONTINUE+ ELSE+ JX = KX+ JY = KY+ DO 120 J = 1,N+ TEMP1 = ALPHA*X(JX)+ TEMP2 = ZERO+ Y(JY) = Y(JY) + TEMP1*REAL(AP(KK))+ IX = JX+ IY = JY+ DO 110 K = KK + 1,KK + N - J+ IX = IX + INCX+ IY = IY + INCY+ Y(IY) = Y(IY) + TEMP1*AP(K)+ TEMP2 = TEMP2 + CONJG(AP(K))*X(IX)+ 110 CONTINUE+ Y(JY) = Y(JY) + ALPHA*TEMP2+ JX = JX + INCX+ JY = JY + INCY+ KK = KK + (N-J+1)+ 120 CONTINUE+ END IF+ END IF+*+ RETURN+*+* End of CHPMV .+*+ END
+ eigen3/blas/common.h view
@@ -0,0 +1,145 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_BLAS_COMMON_H+#define EIGEN_BLAS_COMMON_H++#include <Eigen/Core>+#include <Eigen/Jacobi>++#include <iostream>+#include <complex>++#ifndef SCALAR+#error the token SCALAR must be defined to compile this file+#endif++#include <Eigen/src/misc/blas.h>+++#define NOTR 0+#define TR 1+#define ADJ 2++#define LEFT 0+#define RIGHT 1++#define UP 0+#define LO 1++#define NUNIT 0+#define UNIT 1++#define INVALID 0xff++#define OP(X) ( ((X)=='N' || (X)=='n') ? NOTR \+ : ((X)=='T' || (X)=='t') ? TR \+ : ((X)=='C' || (X)=='c') ? ADJ \+ : INVALID)++#define SIDE(X) ( ((X)=='L' || (X)=='l') ? LEFT \+ : ((X)=='R' || (X)=='r') ? RIGHT \+ : INVALID)++#define UPLO(X) ( ((X)=='U' || (X)=='u') ? UP \+ : ((X)=='L' || (X)=='l') ? LO \+ : INVALID)++#define DIAG(X) ( ((X)=='N' || (X)=='n') ? NUNIT \+ : ((X)=='U' || (X)=='u') ? UNIT \+ : INVALID)+++inline bool check_op(const char* op)+{+ return OP(*op)!=0xff;+}++inline bool check_side(const char* side)+{+ return SIDE(*side)!=0xff;+}++inline bool check_uplo(const char* uplo)+{+ return UPLO(*uplo)!=0xff;+}+++namespace Eigen {+#include "BandTriangularSolver.h"+#include "GeneralRank1Update.h"+#include "PackedSelfadjointProduct.h"+#include "PackedTriangularMatrixVector.h"+#include "PackedTriangularSolverVector.h"+#include "Rank2Update.h"+}++using namespace Eigen;++typedef SCALAR Scalar;+typedef NumTraits<Scalar>::Real RealScalar;+typedef std::complex<RealScalar> Complex;++enum+{+ IsComplex = Eigen::NumTraits<SCALAR>::IsComplex,+ Conj = IsComplex+};++typedef Matrix<Scalar,Dynamic,Dynamic,ColMajor> PlainMatrixType;+typedef Map<Matrix<Scalar,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> > MatrixType;+typedef Map<Matrix<Scalar,Dynamic,1>, 0, InnerStride<Dynamic> > StridedVectorType;+typedef Map<Matrix<Scalar,Dynamic,1> > CompactVectorType;++template<typename T>+Map<Matrix<T,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> >+matrix(T* data, int rows, int cols, int stride)+{+ return Map<Matrix<T,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> >(data, rows, cols, OuterStride<>(stride));+}++template<typename T>+Map<Matrix<T,Dynamic,1>, 0, InnerStride<Dynamic> > vector(T* data, int size, int incr)+{+ return Map<Matrix<T,Dynamic,1>, 0, InnerStride<Dynamic> >(data, size, InnerStride<Dynamic>(incr));+}++template<typename T>+Map<Matrix<T,Dynamic,1> > vector(T* data, int size)+{+ return Map<Matrix<T,Dynamic,1> >(data, size);+}++template<typename T>+T* get_compact_vector(T* x, int n, int incx)+{+ if(incx==1)+ return x;++ T* ret = new Scalar[n];+ if(incx<0) vector(ret,n) = vector(x,n,-incx).reverse();+ else vector(ret,n) = vector(x,n, incx);+ return ret;+}++template<typename T>+T* copy_back(T* x_cpy, T* x, int n, int incx)+{+ if(x_cpy==x)+ return 0;++ if(incx<0) vector(x,n,-incx).reverse() = vector(x_cpy,n);+ else vector(x,n, incx) = vector(x_cpy,n);+ return x_cpy;+}++#define EIGEN_BLAS_FUNC(X) EIGEN_CAT(SCALAR_SUFFIX,X##_)++#endif // EIGEN_BLAS_COMMON_H
+ eigen3/blas/complex_double.cpp view
@@ -0,0 +1,20 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define SCALAR std::complex<double>+#define SCALAR_SUFFIX z+#define SCALAR_SUFFIX_UP "Z"+#define REAL_SCALAR_SUFFIX d+#define ISCOMPLEX 1++#include "level1_impl.h"+#include "level1_cplx_impl.h"+#include "level2_impl.h"+#include "level2_cplx_impl.h"+#include "level3_impl.h"
+ eigen3/blas/complex_single.cpp view
@@ -0,0 +1,20 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define SCALAR std::complex<float>+#define SCALAR_SUFFIX c+#define SCALAR_SUFFIX_UP "C"+#define REAL_SCALAR_SUFFIX s+#define ISCOMPLEX 1++#include "level1_impl.h"+#include "level1_cplx_impl.h"+#include "level2_impl.h"+#include "level2_cplx_impl.h"+#include "level3_impl.h"
+ eigen3/blas/complexdots.f view
@@ -0,0 +1,43 @@+ COMPLEX FUNCTION CDOTC(N,CX,INCX,CY,INCY)+ INTEGER INCX,INCY,N+ COMPLEX CX(*),CY(*)+ COMPLEX RES+ EXTERNAL CDOTCW+ + CALL CDOTCW(N,CX,INCX,CY,INCY,RES)+ CDOTC = RES+ RETURN+ END+ + COMPLEX FUNCTION CDOTU(N,CX,INCX,CY,INCY)+ INTEGER INCX,INCY,N+ COMPLEX CX(*),CY(*)+ COMPLEX RES+ EXTERNAL CDOTUW+ + CALL CDOTUW(N,CX,INCX,CY,INCY,RES)+ CDOTU = RES+ RETURN+ END+ + DOUBLE COMPLEX FUNCTION ZDOTC(N,CX,INCX,CY,INCY)+ INTEGER INCX,INCY,N+ DOUBLE COMPLEX CX(*),CY(*)+ DOUBLE COMPLEX RES+ EXTERNAL ZDOTCW+ + CALL ZDOTCW(N,CX,INCX,CY,INCY,RES)+ ZDOTC = RES+ RETURN+ END+ + DOUBLE COMPLEX FUNCTION ZDOTU(N,CX,INCX,CY,INCY)+ INTEGER INCX,INCY,N+ DOUBLE COMPLEX CX(*),CY(*)+ DOUBLE COMPLEX RES+ EXTERNAL ZDOTUW+ + CALL ZDOTUW(N,CX,INCX,CY,INCY,RES)+ ZDOTU = RES+ RETURN+ END
+ eigen3/blas/ctbmv.f view
@@ -0,0 +1,366 @@+ SUBROUTINE CTBMV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)+* .. Scalar Arguments ..+ INTEGER INCX,K,LDA,N+ CHARACTER DIAG,TRANS,UPLO+* ..+* .. Array Arguments ..+ COMPLEX A(LDA,*),X(*)+* ..+*+* Purpose+* =======+*+* CTBMV performs one of the matrix-vector operations+*+* x := A*x, or x := A'*x, or x := conjg( A' )*x,+*+* where x is an n element vector and A is an n by n unit, or non-unit,+* upper or lower triangular band matrix, with ( k + 1 ) diagonals.+*+* Arguments+* ==========+*+* UPLO - CHARACTER*1.+* On entry, UPLO specifies whether the matrix is an upper or+* lower triangular matrix as follows:+*+* UPLO = 'U' or 'u' A is an upper triangular matrix.+*+* UPLO = 'L' or 'l' A is a lower triangular matrix.+*+* Unchanged on exit.+*+* TRANS - CHARACTER*1.+* On entry, TRANS specifies the operation to be performed as+* follows:+*+* TRANS = 'N' or 'n' x := A*x.+*+* TRANS = 'T' or 't' x := A'*x.+*+* TRANS = 'C' or 'c' x := conjg( A' )*x.+*+* Unchanged on exit.+*+* DIAG - CHARACTER*1.+* On entry, DIAG specifies whether or not A is unit+* triangular as follows:+*+* DIAG = 'U' or 'u' A is assumed to be unit triangular.+*+* DIAG = 'N' or 'n' A is not assumed to be unit+* triangular.+*+* Unchanged on exit.+*+* N - INTEGER.+* On entry, N specifies the order of the matrix A.+* N must be at least zero.+* Unchanged on exit.+*+* K - INTEGER.+* On entry with UPLO = 'U' or 'u', K specifies the number of+* super-diagonals of the matrix A.+* On entry with UPLO = 'L' or 'l', K specifies the number of+* sub-diagonals of the matrix A.+* K must satisfy 0 .le. K.+* Unchanged on exit.+*+* A - COMPLEX array of DIMENSION ( LDA, n ).+* Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )+* by n part of the array A must contain the upper triangular+* band part of the matrix of coefficients, supplied column by+* column, with the leading diagonal of the matrix in row+* ( k + 1 ) of the array, the first super-diagonal starting at+* position 2 in row k, and so on. The top left k by k triangle+* of the array A is not referenced.+* The following program segment will transfer an upper+* triangular band matrix from conventional full matrix storage+* to band storage:+*+* DO 20, J = 1, N+* M = K + 1 - J+* DO 10, I = MAX( 1, J - K ), J+* A( M + I, J ) = matrix( I, J )+* 10 CONTINUE+* 20 CONTINUE+*+* Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )+* by n part of the array A must contain the lower triangular+* band part of the matrix of coefficients, supplied column by+* column, with the leading diagonal of the matrix in row 1 of+* the array, the first sub-diagonal starting at position 1 in+* row 2, and so on. The bottom right k by k triangle of the+* array A is not referenced.+* The following program segment will transfer a lower+* triangular band matrix from conventional full matrix storage+* to band storage:+*+* DO 20, J = 1, N+* M = 1 - J+* DO 10, I = J, MIN( N, J + K )+* A( M + I, J ) = matrix( I, J )+* 10 CONTINUE+* 20 CONTINUE+*+* Note that when DIAG = 'U' or 'u' the elements of the array A+* corresponding to the diagonal elements of the matrix are not+* referenced, but are assumed to be unity.+* Unchanged on exit.+*+* LDA - INTEGER.+* On entry, LDA specifies the first dimension of A as declared+* in the calling (sub) program. LDA must be at least+* ( k + 1 ).+* Unchanged on exit.+*+* X - COMPLEX array of dimension at least+* ( 1 + ( n - 1 )*abs( INCX ) ).+* Before entry, the incremented array X must contain the n+* element vector x. On exit, X is overwritten with the+* tranformed vector x.+*+* INCX - INTEGER.+* On entry, INCX specifies the increment for the elements of+* X. INCX must not be zero.+* Unchanged on exit.+*+* Further Details+* ===============+*+* Level 2 Blas routine.+*+* -- Written on 22-October-1986.+* Jack Dongarra, Argonne National Lab.+* Jeremy Du Croz, Nag Central Office.+* Sven Hammarling, Nag Central Office.+* Richard Hanson, Sandia National Labs.+*+* =====================================================================+*+* .. Parameters ..+ COMPLEX ZERO+ PARAMETER (ZERO= (0.0E+0,0.0E+0))+* ..+* .. Local Scalars ..+ COMPLEX TEMP+ INTEGER I,INFO,IX,J,JX,KPLUS1,KX,L+ LOGICAL NOCONJ,NOUNIT+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. External Subroutines ..+ EXTERNAL XERBLA+* ..+* .. Intrinsic Functions ..+ INTRINSIC CONJG,MAX,MIN+* ..+*+* Test the input parameters.+*+ INFO = 0+ IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN+ INFO = 1+ ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.+ + .NOT.LSAME(TRANS,'C')) THEN+ INFO = 2+ ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN+ INFO = 3+ ELSE IF (N.LT.0) THEN+ INFO = 4+ ELSE IF (K.LT.0) THEN+ INFO = 5+ ELSE IF (LDA.LT. (K+1)) THEN+ INFO = 7+ ELSE IF (INCX.EQ.0) THEN+ INFO = 9+ END IF+ IF (INFO.NE.0) THEN+ CALL XERBLA('CTBMV ',INFO)+ RETURN+ END IF+*+* Quick return if possible.+*+ IF (N.EQ.0) RETURN+*+ NOCONJ = LSAME(TRANS,'T')+ NOUNIT = LSAME(DIAG,'N')+*+* Set up the start point in X if the increment is not unity. This+* will be ( N - 1 )*INCX too small for descending loops.+*+ IF (INCX.LE.0) THEN+ KX = 1 - (N-1)*INCX+ ELSE IF (INCX.NE.1) THEN+ KX = 1+ END IF+*+* Start the operations. In this version the elements of A are+* accessed sequentially with one pass through A.+*+ IF (LSAME(TRANS,'N')) THEN+*+* Form x := A*x.+*+ IF (LSAME(UPLO,'U')) THEN+ KPLUS1 = K + 1+ IF (INCX.EQ.1) THEN+ DO 20 J = 1,N+ IF (X(J).NE.ZERO) THEN+ TEMP = X(J)+ L = KPLUS1 - J+ DO 10 I = MAX(1,J-K),J - 1+ X(I) = X(I) + TEMP*A(L+I,J)+ 10 CONTINUE+ IF (NOUNIT) X(J) = X(J)*A(KPLUS1,J)+ END IF+ 20 CONTINUE+ ELSE+ JX = KX+ DO 40 J = 1,N+ IF (X(JX).NE.ZERO) THEN+ TEMP = X(JX)+ IX = KX+ L = KPLUS1 - J+ DO 30 I = MAX(1,J-K),J - 1+ X(IX) = X(IX) + TEMP*A(L+I,J)+ IX = IX + INCX+ 30 CONTINUE+ IF (NOUNIT) X(JX) = X(JX)*A(KPLUS1,J)+ END IF+ JX = JX + INCX+ IF (J.GT.K) KX = KX + INCX+ 40 CONTINUE+ END IF+ ELSE+ IF (INCX.EQ.1) THEN+ DO 60 J = N,1,-1+ IF (X(J).NE.ZERO) THEN+ TEMP = X(J)+ L = 1 - J+ DO 50 I = MIN(N,J+K),J + 1,-1+ X(I) = X(I) + TEMP*A(L+I,J)+ 50 CONTINUE+ IF (NOUNIT) X(J) = X(J)*A(1,J)+ END IF+ 60 CONTINUE+ ELSE+ KX = KX + (N-1)*INCX+ JX = KX+ DO 80 J = N,1,-1+ IF (X(JX).NE.ZERO) THEN+ TEMP = X(JX)+ IX = KX+ L = 1 - J+ DO 70 I = MIN(N,J+K),J + 1,-1+ X(IX) = X(IX) + TEMP*A(L+I,J)+ IX = IX - INCX+ 70 CONTINUE+ IF (NOUNIT) X(JX) = X(JX)*A(1,J)+ END IF+ JX = JX - INCX+ IF ((N-J).GE.K) KX = KX - INCX+ 80 CONTINUE+ END IF+ END IF+ ELSE+*+* Form x := A'*x or x := conjg( A' )*x.+*+ IF (LSAME(UPLO,'U')) THEN+ KPLUS1 = K + 1+ IF (INCX.EQ.1) THEN+ DO 110 J = N,1,-1+ TEMP = X(J)+ L = KPLUS1 - J+ IF (NOCONJ) THEN+ IF (NOUNIT) TEMP = TEMP*A(KPLUS1,J)+ DO 90 I = J - 1,MAX(1,J-K),-1+ TEMP = TEMP + A(L+I,J)*X(I)+ 90 CONTINUE+ ELSE+ IF (NOUNIT) TEMP = TEMP*CONJG(A(KPLUS1,J))+ DO 100 I = J - 1,MAX(1,J-K),-1+ TEMP = TEMP + CONJG(A(L+I,J))*X(I)+ 100 CONTINUE+ END IF+ X(J) = TEMP+ 110 CONTINUE+ ELSE+ KX = KX + (N-1)*INCX+ JX = KX+ DO 140 J = N,1,-1+ TEMP = X(JX)+ KX = KX - INCX+ IX = KX+ L = KPLUS1 - J+ IF (NOCONJ) THEN+ IF (NOUNIT) TEMP = TEMP*A(KPLUS1,J)+ DO 120 I = J - 1,MAX(1,J-K),-1+ TEMP = TEMP + A(L+I,J)*X(IX)+ IX = IX - INCX+ 120 CONTINUE+ ELSE+ IF (NOUNIT) TEMP = TEMP*CONJG(A(KPLUS1,J))+ DO 130 I = J - 1,MAX(1,J-K),-1+ TEMP = TEMP + CONJG(A(L+I,J))*X(IX)+ IX = IX - INCX+ 130 CONTINUE+ END IF+ X(JX) = TEMP+ JX = JX - INCX+ 140 CONTINUE+ END IF+ ELSE+ IF (INCX.EQ.1) THEN+ DO 170 J = 1,N+ TEMP = X(J)+ L = 1 - J+ IF (NOCONJ) THEN+ IF (NOUNIT) TEMP = TEMP*A(1,J)+ DO 150 I = J + 1,MIN(N,J+K)+ TEMP = TEMP + A(L+I,J)*X(I)+ 150 CONTINUE+ ELSE+ IF (NOUNIT) TEMP = TEMP*CONJG(A(1,J))+ DO 160 I = J + 1,MIN(N,J+K)+ TEMP = TEMP + CONJG(A(L+I,J))*X(I)+ 160 CONTINUE+ END IF+ X(J) = TEMP+ 170 CONTINUE+ ELSE+ JX = KX+ DO 200 J = 1,N+ TEMP = X(JX)+ KX = KX + INCX+ IX = KX+ L = 1 - J+ IF (NOCONJ) THEN+ IF (NOUNIT) TEMP = TEMP*A(1,J)+ DO 180 I = J + 1,MIN(N,J+K)+ TEMP = TEMP + A(L+I,J)*X(IX)+ IX = IX + INCX+ 180 CONTINUE+ ELSE+ IF (NOUNIT) TEMP = TEMP*CONJG(A(1,J))+ DO 190 I = J + 1,MIN(N,J+K)+ TEMP = TEMP + CONJG(A(L+I,J))*X(IX)+ IX = IX + INCX+ 190 CONTINUE+ END IF+ X(JX) = TEMP+ JX = JX + INCX+ 200 CONTINUE+ END IF+ END IF+ END IF+*+ RETURN+*+* End of CTBMV .+*+ END
+ eigen3/blas/double.cpp view
@@ -0,0 +1,33 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2012 Chen-Pang He <jdh8@ms63.hinet.net>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define SCALAR double+#define SCALAR_SUFFIX d+#define SCALAR_SUFFIX_UP "D"+#define ISCOMPLEX 0++#include "level1_impl.h"+#include "level1_real_impl.h"+#include "level2_impl.h"+#include "level2_real_impl.h"+#include "level3_impl.h"++double BLASFUNC(dsdot)(int* n, float* x, int* incx, float* y, int* incy)+{+ if(*n<=0) return 0;++ if(*incx==1 && *incy==1) return (vector(x,*n).cast<double>().cwiseProduct(vector(y,*n).cast<double>())).sum();+ else if(*incx>0 && *incy>0) return (vector(x,*n,*incx).cast<double>().cwiseProduct(vector(y,*n,*incy).cast<double>())).sum();+ else if(*incx<0 && *incy>0) return (vector(x,*n,-*incx).reverse().cast<double>().cwiseProduct(vector(y,*n,*incy).cast<double>())).sum();+ else if(*incx>0 && *incy<0) return (vector(x,*n,*incx).cast<double>().cwiseProduct(vector(y,*n,-*incy).reverse().cast<double>())).sum();+ else if(*incx<0 && *incy<0) return (vector(x,*n,-*incx).reverse().cast<double>().cwiseProduct(vector(y,*n,-*incy).reverse().cast<double>())).sum();+ else return 0;+}+
+ eigen3/blas/drotm.f view
@@ -0,0 +1,147 @@+ SUBROUTINE DROTM(N,DX,INCX,DY,INCY,DPARAM)+* .. Scalar Arguments ..+ INTEGER INCX,INCY,N+* ..+* .. Array Arguments ..+ DOUBLE PRECISION DPARAM(5),DX(*),DY(*)+* ..+*+* Purpose+* =======+*+* APPLY THE MODIFIED GIVENS TRANSFORMATION, H, TO THE 2 BY N MATRIX+*+* (DX**T) , WHERE **T INDICATES TRANSPOSE. THE ELEMENTS OF DX ARE IN+* (DY**T)+*+* DX(LX+I*INCX), I = 0 TO N-1, WHERE LX = 1 IF INCX .GE. 0, ELSE+* LX = (-INCX)*N, AND SIMILARLY FOR SY USING LY AND INCY.+* WITH DPARAM(1)=DFLAG, H HAS ONE OF THE FOLLOWING FORMS..+*+* DFLAG=-1.D0 DFLAG=0.D0 DFLAG=1.D0 DFLAG=-2.D0+*+* (DH11 DH12) (1.D0 DH12) (DH11 1.D0) (1.D0 0.D0)+* H=( ) ( ) ( ) ( )+* (DH21 DH22), (DH21 1.D0), (-1.D0 DH22), (0.D0 1.D0).+* SEE DROTMG FOR A DESCRIPTION OF DATA STORAGE IN DPARAM.+*+* Arguments+* =========+*+* N (input) INTEGER+* number of elements in input vector(s)+*+* DX (input/output) DOUBLE PRECISION array, dimension N+* double precision vector with N elements+*+* INCX (input) INTEGER+* storage spacing between elements of DX+*+* DY (input/output) DOUBLE PRECISION array, dimension N+* double precision vector with N elements+*+* INCY (input) INTEGER+* storage spacing between elements of DY+*+* DPARAM (input/output) DOUBLE PRECISION array, dimension 5 +* DPARAM(1)=DFLAG+* DPARAM(2)=DH11+* DPARAM(3)=DH21+* DPARAM(4)=DH12+* DPARAM(5)=DH22+*+* =====================================================================+*+* .. Local Scalars ..+ DOUBLE PRECISION DFLAG,DH11,DH12,DH21,DH22,TWO,W,Z,ZERO+ INTEGER I,KX,KY,NSTEPS+* ..+* .. Data statements ..+ DATA ZERO,TWO/0.D0,2.D0/+* ..+*+ DFLAG = DPARAM(1)+ IF (N.LE.0 .OR. (DFLAG+TWO.EQ.ZERO)) GO TO 140+ IF (.NOT. (INCX.EQ.INCY.AND.INCX.GT.0)) GO TO 70+*+ NSTEPS = N*INCX+ IF (DFLAG) 50,10,30+ 10 CONTINUE+ DH12 = DPARAM(4)+ DH21 = DPARAM(3)+ DO 20 I = 1,NSTEPS,INCX+ W = DX(I)+ Z = DY(I)+ DX(I) = W + Z*DH12+ DY(I) = W*DH21 + Z+ 20 CONTINUE+ GO TO 140+ 30 CONTINUE+ DH11 = DPARAM(2)+ DH22 = DPARAM(5)+ DO 40 I = 1,NSTEPS,INCX+ W = DX(I)+ Z = DY(I)+ DX(I) = W*DH11 + Z+ DY(I) = -W + DH22*Z+ 40 CONTINUE+ GO TO 140+ 50 CONTINUE+ DH11 = DPARAM(2)+ DH12 = DPARAM(4)+ DH21 = DPARAM(3)+ DH22 = DPARAM(5)+ DO 60 I = 1,NSTEPS,INCX+ W = DX(I)+ Z = DY(I)+ DX(I) = W*DH11 + Z*DH12+ DY(I) = W*DH21 + Z*DH22+ 60 CONTINUE+ GO TO 140+ 70 CONTINUE+ KX = 1+ KY = 1+ IF (INCX.LT.0) KX = 1 + (1-N)*INCX+ IF (INCY.LT.0) KY = 1 + (1-N)*INCY+*+ IF (DFLAG) 120,80,100+ 80 CONTINUE+ DH12 = DPARAM(4)+ DH21 = DPARAM(3)+ DO 90 I = 1,N+ W = DX(KX)+ Z = DY(KY)+ DX(KX) = W + Z*DH12+ DY(KY) = W*DH21 + Z+ KX = KX + INCX+ KY = KY + INCY+ 90 CONTINUE+ GO TO 140+ 100 CONTINUE+ DH11 = DPARAM(2)+ DH22 = DPARAM(5)+ DO 110 I = 1,N+ W = DX(KX)+ Z = DY(KY)+ DX(KX) = W*DH11 + Z+ DY(KY) = -W + DH22*Z+ KX = KX + INCX+ KY = KY + INCY+ 110 CONTINUE+ GO TO 140+ 120 CONTINUE+ DH11 = DPARAM(2)+ DH12 = DPARAM(4)+ DH21 = DPARAM(3)+ DH22 = DPARAM(5)+ DO 130 I = 1,N+ W = DX(KX)+ Z = DY(KY)+ DX(KX) = W*DH11 + Z*DH12+ DY(KY) = W*DH21 + Z*DH22+ KX = KX + INCX+ KY = KY + INCY+ 130 CONTINUE+ 140 CONTINUE+ RETURN+ END
+ eigen3/blas/drotmg.f view
@@ -0,0 +1,206 @@+ SUBROUTINE DROTMG(DD1,DD2,DX1,DY1,DPARAM)+* .. Scalar Arguments ..+ DOUBLE PRECISION DD1,DD2,DX1,DY1+* ..+* .. Array Arguments ..+ DOUBLE PRECISION DPARAM(5)+* ..+*+* Purpose+* =======+*+* CONSTRUCT THE MODIFIED GIVENS TRANSFORMATION MATRIX H WHICH ZEROS+* THE SECOND COMPONENT OF THE 2-VECTOR (DSQRT(DD1)*DX1,DSQRT(DD2)*+* DY2)**T.+* WITH DPARAM(1)=DFLAG, H HAS ONE OF THE FOLLOWING FORMS..+*+* DFLAG=-1.D0 DFLAG=0.D0 DFLAG=1.D0 DFLAG=-2.D0+*+* (DH11 DH12) (1.D0 DH12) (DH11 1.D0) (1.D0 0.D0)+* H=( ) ( ) ( ) ( )+* (DH21 DH22), (DH21 1.D0), (-1.D0 DH22), (0.D0 1.D0).+* LOCATIONS 2-4 OF DPARAM CONTAIN DH11, DH21, DH12, AND DH22+* RESPECTIVELY. (VALUES OF 1.D0, -1.D0, OR 0.D0 IMPLIED BY THE+* VALUE OF DPARAM(1) ARE NOT STORED IN DPARAM.)+*+* THE VALUES OF GAMSQ AND RGAMSQ SET IN THE DATA STATEMENT MAY BE+* INEXACT. THIS IS OK AS THEY ARE ONLY USED FOR TESTING THE SIZE+* OF DD1 AND DD2. ALL ACTUAL SCALING OF DATA IS DONE USING GAM.+*+*+* Arguments+* =========+*+* DD1 (input/output) DOUBLE PRECISION+*+* DD2 (input/output) DOUBLE PRECISION +*+* DX1 (input/output) DOUBLE PRECISION +*+* DY1 (input) DOUBLE PRECISION+*+* DPARAM (input/output) DOUBLE PRECISION array, dimension 5+* DPARAM(1)=DFLAG+* DPARAM(2)=DH11+* DPARAM(3)=DH21+* DPARAM(4)=DH12+* DPARAM(5)=DH22+*+* =====================================================================+*+* .. Local Scalars ..+ DOUBLE PRECISION DFLAG,DH11,DH12,DH21,DH22,DP1,DP2,DQ1,DQ2,DTEMP,+ + DU,GAM,GAMSQ,ONE,RGAMSQ,TWO,ZERO+ INTEGER IGO+* ..+* .. Intrinsic Functions ..+ INTRINSIC DABS+* ..+* .. Data statements ..+*+ DATA ZERO,ONE,TWO/0.D0,1.D0,2.D0/+ DATA GAM,GAMSQ,RGAMSQ/4096.D0,16777216.D0,5.9604645D-8/+* ..++ IF (.NOT.DD1.LT.ZERO) GO TO 10+* GO ZERO-H-D-AND-DX1..+ GO TO 60+ 10 CONTINUE+* CASE-DD1-NONNEGATIVE+ DP2 = DD2*DY1+ IF (.NOT.DP2.EQ.ZERO) GO TO 20+ DFLAG = -TWO+ GO TO 260+* REGULAR-CASE..+ 20 CONTINUE+ DP1 = DD1*DX1+ DQ2 = DP2*DY1+ DQ1 = DP1*DX1+*+ IF (.NOT.DABS(DQ1).GT.DABS(DQ2)) GO TO 40+ DH21 = -DY1/DX1+ DH12 = DP2/DP1+*+ DU = ONE - DH12*DH21+*+ IF (.NOT.DU.LE.ZERO) GO TO 30+* GO ZERO-H-D-AND-DX1..+ GO TO 60+ 30 CONTINUE+ DFLAG = ZERO+ DD1 = DD1/DU+ DD2 = DD2/DU+ DX1 = DX1*DU+* GO SCALE-CHECK..+ GO TO 100+ 40 CONTINUE+ IF (.NOT.DQ2.LT.ZERO) GO TO 50+* GO ZERO-H-D-AND-DX1..+ GO TO 60+ 50 CONTINUE+ DFLAG = ONE+ DH11 = DP1/DP2+ DH22 = DX1/DY1+ DU = ONE + DH11*DH22+ DTEMP = DD2/DU+ DD2 = DD1/DU+ DD1 = DTEMP+ DX1 = DY1*DU+* GO SCALE-CHECK+ GO TO 100+* PROCEDURE..ZERO-H-D-AND-DX1..+ 60 CONTINUE+ DFLAG = -ONE+ DH11 = ZERO+ DH12 = ZERO+ DH21 = ZERO+ DH22 = ZERO+*+ DD1 = ZERO+ DD2 = ZERO+ DX1 = ZERO+* RETURN..+ GO TO 220+* PROCEDURE..FIX-H..+ 70 CONTINUE+ IF (.NOT.DFLAG.GE.ZERO) GO TO 90+*+ IF (.NOT.DFLAG.EQ.ZERO) GO TO 80+ DH11 = ONE+ DH22 = ONE+ DFLAG = -ONE+ GO TO 90+ 80 CONTINUE+ DH21 = -ONE+ DH12 = ONE+ DFLAG = -ONE+ 90 CONTINUE+ GO TO IGO(120,150,180,210)+* PROCEDURE..SCALE-CHECK+ 100 CONTINUE+ 110 CONTINUE+ IF (.NOT.DD1.LE.RGAMSQ) GO TO 130+ IF (DD1.EQ.ZERO) GO TO 160+ ASSIGN 120 TO IGO+* FIX-H..+ GO TO 70+ 120 CONTINUE+ DD1 = DD1*GAM**2+ DX1 = DX1/GAM+ DH11 = DH11/GAM+ DH12 = DH12/GAM+ GO TO 110+ 130 CONTINUE+ 140 CONTINUE+ IF (.NOT.DD1.GE.GAMSQ) GO TO 160+ ASSIGN 150 TO IGO+* FIX-H..+ GO TO 70+ 150 CONTINUE+ DD1 = DD1/GAM**2+ DX1 = DX1*GAM+ DH11 = DH11*GAM+ DH12 = DH12*GAM+ GO TO 140+ 160 CONTINUE+ 170 CONTINUE+ IF (.NOT.DABS(DD2).LE.RGAMSQ) GO TO 190+ IF (DD2.EQ.ZERO) GO TO 220+ ASSIGN 180 TO IGO+* FIX-H..+ GO TO 70+ 180 CONTINUE+ DD2 = DD2*GAM**2+ DH21 = DH21/GAM+ DH22 = DH22/GAM+ GO TO 170+ 190 CONTINUE+ 200 CONTINUE+ IF (.NOT.DABS(DD2).GE.GAMSQ) GO TO 220+ ASSIGN 210 TO IGO+* FIX-H..+ GO TO 70+ 210 CONTINUE+ DD2 = DD2/GAM**2+ DH21 = DH21*GAM+ DH22 = DH22*GAM+ GO TO 200+ 220 CONTINUE+ IF (DFLAG) 250,230,240+ 230 CONTINUE+ DPARAM(3) = DH21+ DPARAM(4) = DH12+ GO TO 260+ 240 CONTINUE+ DPARAM(2) = DH11+ DPARAM(5) = DH22+ GO TO 260+ 250 CONTINUE+ DPARAM(2) = DH11+ DPARAM(3) = DH21+ DPARAM(4) = DH12+ DPARAM(5) = DH22+ 260 CONTINUE+ DPARAM(1) = DFLAG+ RETURN+ END
+ eigen3/blas/dsbmv.f view
@@ -0,0 +1,304 @@+ SUBROUTINE DSBMV(UPLO,N,K,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)+* .. Scalar Arguments ..+ DOUBLE PRECISION ALPHA,BETA+ INTEGER INCX,INCY,K,LDA,N+ CHARACTER UPLO+* ..+* .. Array Arguments ..+ DOUBLE PRECISION A(LDA,*),X(*),Y(*)+* ..+*+* Purpose+* =======+*+* DSBMV performs the matrix-vector operation+*+* y := alpha*A*x + beta*y,+*+* where alpha and beta are scalars, x and y are n element vectors and+* A is an n by n symmetric band matrix, with k super-diagonals.+*+* Arguments+* ==========+*+* UPLO - CHARACTER*1.+* On entry, UPLO specifies whether the upper or lower+* triangular part of the band matrix A is being supplied as+* follows:+*+* UPLO = 'U' or 'u' The upper triangular part of A is+* being supplied.+*+* UPLO = 'L' or 'l' The lower triangular part of A is+* being supplied.+*+* Unchanged on exit.+*+* N - INTEGER.+* On entry, N specifies the order of the matrix A.+* N must be at least zero.+* Unchanged on exit.+*+* K - INTEGER.+* On entry, K specifies the number of super-diagonals of the+* matrix A. K must satisfy 0 .le. K.+* Unchanged on exit.+*+* ALPHA - DOUBLE PRECISION.+* On entry, ALPHA specifies the scalar alpha.+* Unchanged on exit.+*+* A - DOUBLE PRECISION array of DIMENSION ( LDA, n ).+* Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )+* by n part of the array A must contain the upper triangular+* band part of the symmetric matrix, supplied column by+* column, with the leading diagonal of the matrix in row+* ( k + 1 ) of the array, the first super-diagonal starting at+* position 2 in row k, and so on. The top left k by k triangle+* of the array A is not referenced.+* The following program segment will transfer the upper+* triangular part of a symmetric band matrix from conventional+* full matrix storage to band storage:+*+* DO 20, J = 1, N+* M = K + 1 - J+* DO 10, I = MAX( 1, J - K ), J+* A( M + I, J ) = matrix( I, J )+* 10 CONTINUE+* 20 CONTINUE+*+* Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )+* by n part of the array A must contain the lower triangular+* band part of the symmetric matrix, supplied column by+* column, with the leading diagonal of the matrix in row 1 of+* the array, the first sub-diagonal starting at position 1 in+* row 2, and so on. The bottom right k by k triangle of the+* array A is not referenced.+* The following program segment will transfer the lower+* triangular part of a symmetric band matrix from conventional+* full matrix storage to band storage:+*+* DO 20, J = 1, N+* M = 1 - J+* DO 10, I = J, MIN( N, J + K )+* A( M + I, J ) = matrix( I, J )+* 10 CONTINUE+* 20 CONTINUE+*+* Unchanged on exit.+*+* LDA - INTEGER.+* On entry, LDA specifies the first dimension of A as declared+* in the calling (sub) program. LDA must be at least+* ( k + 1 ).+* Unchanged on exit.+*+* X - DOUBLE PRECISION array of DIMENSION at least+* ( 1 + ( n - 1 )*abs( INCX ) ).+* Before entry, the incremented array X must contain the+* vector x.+* Unchanged on exit.+*+* INCX - INTEGER.+* On entry, INCX specifies the increment for the elements of+* X. INCX must not be zero.+* Unchanged on exit.+*+* BETA - DOUBLE PRECISION.+* On entry, BETA specifies the scalar beta.+* Unchanged on exit.+*+* Y - DOUBLE PRECISION array of DIMENSION at least+* ( 1 + ( n - 1 )*abs( INCY ) ).+* Before entry, the incremented array Y must contain the+* vector y. On exit, Y is overwritten by the updated vector y.+*+* INCY - INTEGER.+* On entry, INCY specifies the increment for the elements of+* Y. INCY must not be zero.+* Unchanged on exit.+*+*+* Level 2 Blas routine.+*+* -- Written on 22-October-1986.+* Jack Dongarra, Argonne National Lab.+* Jeremy Du Croz, Nag Central Office.+* Sven Hammarling, Nag Central Office.+* Richard Hanson, Sandia National Labs.+*+* =====================================================================+*+* .. Parameters ..+ DOUBLE PRECISION ONE,ZERO+ PARAMETER (ONE=1.0D+0,ZERO=0.0D+0)+* ..+* .. Local Scalars ..+ DOUBLE PRECISION TEMP1,TEMP2+ INTEGER I,INFO,IX,IY,J,JX,JY,KPLUS1,KX,KY,L+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. External Subroutines ..+ EXTERNAL XERBLA+* ..+* .. Intrinsic Functions ..+ INTRINSIC MAX,MIN+* ..+*+* Test the input parameters.+*+ INFO = 0+ IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN+ INFO = 1+ ELSE IF (N.LT.0) THEN+ INFO = 2+ ELSE IF (K.LT.0) THEN+ INFO = 3+ ELSE IF (LDA.LT. (K+1)) THEN+ INFO = 6+ ELSE IF (INCX.EQ.0) THEN+ INFO = 8+ ELSE IF (INCY.EQ.0) THEN+ INFO = 11+ END IF+ IF (INFO.NE.0) THEN+ CALL XERBLA('DSBMV ',INFO)+ RETURN+ END IF+*+* Quick return if possible.+*+ IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN+*+* Set up the start points in X and Y.+*+ IF (INCX.GT.0) THEN+ KX = 1+ ELSE+ KX = 1 - (N-1)*INCX+ END IF+ IF (INCY.GT.0) THEN+ KY = 1+ ELSE+ KY = 1 - (N-1)*INCY+ END IF+*+* Start the operations. In this version the elements of the array A+* are accessed sequentially with one pass through A.+*+* First form y := beta*y.+*+ IF (BETA.NE.ONE) THEN+ IF (INCY.EQ.1) THEN+ IF (BETA.EQ.ZERO) THEN+ DO 10 I = 1,N+ Y(I) = ZERO+ 10 CONTINUE+ ELSE+ DO 20 I = 1,N+ Y(I) = BETA*Y(I)+ 20 CONTINUE+ END IF+ ELSE+ IY = KY+ IF (BETA.EQ.ZERO) THEN+ DO 30 I = 1,N+ Y(IY) = ZERO+ IY = IY + INCY+ 30 CONTINUE+ ELSE+ DO 40 I = 1,N+ Y(IY) = BETA*Y(IY)+ IY = IY + INCY+ 40 CONTINUE+ END IF+ END IF+ END IF+ IF (ALPHA.EQ.ZERO) RETURN+ IF (LSAME(UPLO,'U')) THEN+*+* Form y when upper triangle of A is stored.+*+ KPLUS1 = K + 1+ IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN+ DO 60 J = 1,N+ TEMP1 = ALPHA*X(J)+ TEMP2 = ZERO+ L = KPLUS1 - J+ DO 50 I = MAX(1,J-K),J - 1+ Y(I) = Y(I) + TEMP1*A(L+I,J)+ TEMP2 = TEMP2 + A(L+I,J)*X(I)+ 50 CONTINUE+ Y(J) = Y(J) + TEMP1*A(KPLUS1,J) + ALPHA*TEMP2+ 60 CONTINUE+ ELSE+ JX = KX+ JY = KY+ DO 80 J = 1,N+ TEMP1 = ALPHA*X(JX)+ TEMP2 = ZERO+ IX = KX+ IY = KY+ L = KPLUS1 - J+ DO 70 I = MAX(1,J-K),J - 1+ Y(IY) = Y(IY) + TEMP1*A(L+I,J)+ TEMP2 = TEMP2 + A(L+I,J)*X(IX)+ IX = IX + INCX+ IY = IY + INCY+ 70 CONTINUE+ Y(JY) = Y(JY) + TEMP1*A(KPLUS1,J) + ALPHA*TEMP2+ JX = JX + INCX+ JY = JY + INCY+ IF (J.GT.K) THEN+ KX = KX + INCX+ KY = KY + INCY+ END IF+ 80 CONTINUE+ END IF+ ELSE+*+* Form y when lower triangle of A is stored.+*+ IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN+ DO 100 J = 1,N+ TEMP1 = ALPHA*X(J)+ TEMP2 = ZERO+ Y(J) = Y(J) + TEMP1*A(1,J)+ L = 1 - J+ DO 90 I = J + 1,MIN(N,J+K)+ Y(I) = Y(I) + TEMP1*A(L+I,J)+ TEMP2 = TEMP2 + A(L+I,J)*X(I)+ 90 CONTINUE+ Y(J) = Y(J) + ALPHA*TEMP2+ 100 CONTINUE+ ELSE+ JX = KX+ JY = KY+ DO 120 J = 1,N+ TEMP1 = ALPHA*X(JX)+ TEMP2 = ZERO+ Y(JY) = Y(JY) + TEMP1*A(1,J)+ L = 1 - J+ IX = JX+ IY = JY+ DO 110 I = J + 1,MIN(N,J+K)+ IX = IX + INCX+ IY = IY + INCY+ Y(IY) = Y(IY) + TEMP1*A(L+I,J)+ TEMP2 = TEMP2 + A(L+I,J)*X(IX)+ 110 CONTINUE+ Y(JY) = Y(JY) + ALPHA*TEMP2+ JX = JX + INCX+ JY = JY + INCY+ 120 CONTINUE+ END IF+ END IF+*+ RETURN+*+* End of DSBMV .+*+ END
+ eigen3/blas/dspmv.f view
@@ -0,0 +1,265 @@+ SUBROUTINE DSPMV(UPLO,N,ALPHA,AP,X,INCX,BETA,Y,INCY)+* .. Scalar Arguments ..+ DOUBLE PRECISION ALPHA,BETA+ INTEGER INCX,INCY,N+ CHARACTER UPLO+* ..+* .. Array Arguments ..+ DOUBLE PRECISION AP(*),X(*),Y(*)+* ..+*+* Purpose+* =======+*+* DSPMV performs the matrix-vector operation+*+* y := alpha*A*x + beta*y,+*+* where alpha and beta are scalars, x and y are n element vectors and+* A is an n by n symmetric matrix, supplied in packed form.+*+* Arguments+* ==========+*+* UPLO - CHARACTER*1.+* On entry, UPLO specifies whether the upper or lower+* triangular part of the matrix A is supplied in the packed+* array AP as follows:+*+* UPLO = 'U' or 'u' The upper triangular part of A is+* supplied in AP.+*+* UPLO = 'L' or 'l' The lower triangular part of A is+* supplied in AP.+*+* Unchanged on exit.+*+* N - INTEGER.+* On entry, N specifies the order of the matrix A.+* N must be at least zero.+* Unchanged on exit.+*+* ALPHA - DOUBLE PRECISION.+* On entry, ALPHA specifies the scalar alpha.+* Unchanged on exit.+*+* AP - DOUBLE PRECISION array of DIMENSION at least+* ( ( n*( n + 1 ) )/2 ).+* Before entry with UPLO = 'U' or 'u', the array AP must+* contain the upper triangular part of the symmetric matrix+* packed sequentially, column by column, so that AP( 1 )+* contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 )+* and a( 2, 2 ) respectively, and so on.+* Before entry with UPLO = 'L' or 'l', the array AP must+* contain the lower triangular part of the symmetric matrix+* packed sequentially, column by column, so that AP( 1 )+* contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 )+* and a( 3, 1 ) respectively, and so on.+* Unchanged on exit.+*+* X - DOUBLE PRECISION array of dimension at least+* ( 1 + ( n - 1 )*abs( INCX ) ).+* Before entry, the incremented array X must contain the n+* element vector x.+* Unchanged on exit.+*+* INCX - INTEGER.+* On entry, INCX specifies the increment for the elements of+* X. INCX must not be zero.+* Unchanged on exit.+*+* BETA - DOUBLE PRECISION.+* On entry, BETA specifies the scalar beta. When BETA is+* supplied as zero then Y need not be set on input.+* Unchanged on exit.+*+* Y - DOUBLE PRECISION array of dimension at least+* ( 1 + ( n - 1 )*abs( INCY ) ).+* Before entry, the incremented array Y must contain the n+* element vector y. On exit, Y is overwritten by the updated+* vector y.+*+* INCY - INTEGER.+* On entry, INCY specifies the increment for the elements of+* Y. INCY must not be zero.+* Unchanged on exit.+*+* Further Details+* ===============+*+* Level 2 Blas routine.+*+* -- Written on 22-October-1986.+* Jack Dongarra, Argonne National Lab.+* Jeremy Du Croz, Nag Central Office.+* Sven Hammarling, Nag Central Office.+* Richard Hanson, Sandia National Labs.+*+* =====================================================================+*+* .. Parameters ..+ DOUBLE PRECISION ONE,ZERO+ PARAMETER (ONE=1.0D+0,ZERO=0.0D+0)+* ..+* .. Local Scalars ..+ DOUBLE PRECISION TEMP1,TEMP2+ INTEGER I,INFO,IX,IY,J,JX,JY,K,KK,KX,KY+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. External Subroutines ..+ EXTERNAL XERBLA+* ..+*+* Test the input parameters.+*+ INFO = 0+ IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN+ INFO = 1+ ELSE IF (N.LT.0) THEN+ INFO = 2+ ELSE IF (INCX.EQ.0) THEN+ INFO = 6+ ELSE IF (INCY.EQ.0) THEN+ INFO = 9+ END IF+ IF (INFO.NE.0) THEN+ CALL XERBLA('DSPMV ',INFO)+ RETURN+ END IF+*+* Quick return if possible.+*+ IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN+*+* Set up the start points in X and Y.+*+ IF (INCX.GT.0) THEN+ KX = 1+ ELSE+ KX = 1 - (N-1)*INCX+ END IF+ IF (INCY.GT.0) THEN+ KY = 1+ ELSE+ KY = 1 - (N-1)*INCY+ END IF+*+* Start the operations. In this version the elements of the array AP+* are accessed sequentially with one pass through AP.+*+* First form y := beta*y.+*+ IF (BETA.NE.ONE) THEN+ IF (INCY.EQ.1) THEN+ IF (BETA.EQ.ZERO) THEN+ DO 10 I = 1,N+ Y(I) = ZERO+ 10 CONTINUE+ ELSE+ DO 20 I = 1,N+ Y(I) = BETA*Y(I)+ 20 CONTINUE+ END IF+ ELSE+ IY = KY+ IF (BETA.EQ.ZERO) THEN+ DO 30 I = 1,N+ Y(IY) = ZERO+ IY = IY + INCY+ 30 CONTINUE+ ELSE+ DO 40 I = 1,N+ Y(IY) = BETA*Y(IY)+ IY = IY + INCY+ 40 CONTINUE+ END IF+ END IF+ END IF+ IF (ALPHA.EQ.ZERO) RETURN+ KK = 1+ IF (LSAME(UPLO,'U')) THEN+*+* Form y when AP contains the upper triangle.+*+ IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN+ DO 60 J = 1,N+ TEMP1 = ALPHA*X(J)+ TEMP2 = ZERO+ K = KK+ DO 50 I = 1,J - 1+ Y(I) = Y(I) + TEMP1*AP(K)+ TEMP2 = TEMP2 + AP(K)*X(I)+ K = K + 1+ 50 CONTINUE+ Y(J) = Y(J) + TEMP1*AP(KK+J-1) + ALPHA*TEMP2+ KK = KK + J+ 60 CONTINUE+ ELSE+ JX = KX+ JY = KY+ DO 80 J = 1,N+ TEMP1 = ALPHA*X(JX)+ TEMP2 = ZERO+ IX = KX+ IY = KY+ DO 70 K = KK,KK + J - 2+ Y(IY) = Y(IY) + TEMP1*AP(K)+ TEMP2 = TEMP2 + AP(K)*X(IX)+ IX = IX + INCX+ IY = IY + INCY+ 70 CONTINUE+ Y(JY) = Y(JY) + TEMP1*AP(KK+J-1) + ALPHA*TEMP2+ JX = JX + INCX+ JY = JY + INCY+ KK = KK + J+ 80 CONTINUE+ END IF+ ELSE+*+* Form y when AP contains the lower triangle.+*+ IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN+ DO 100 J = 1,N+ TEMP1 = ALPHA*X(J)+ TEMP2 = ZERO+ Y(J) = Y(J) + TEMP1*AP(KK)+ K = KK + 1+ DO 90 I = J + 1,N+ Y(I) = Y(I) + TEMP1*AP(K)+ TEMP2 = TEMP2 + AP(K)*X(I)+ K = K + 1+ 90 CONTINUE+ Y(J) = Y(J) + ALPHA*TEMP2+ KK = KK + (N-J+1)+ 100 CONTINUE+ ELSE+ JX = KX+ JY = KY+ DO 120 J = 1,N+ TEMP1 = ALPHA*X(JX)+ TEMP2 = ZERO+ Y(JY) = Y(JY) + TEMP1*AP(KK)+ IX = JX+ IY = JY+ DO 110 K = KK + 1,KK + N - J+ IX = IX + INCX+ IY = IY + INCY+ Y(IY) = Y(IY) + TEMP1*AP(K)+ TEMP2 = TEMP2 + AP(K)*X(IX)+ 110 CONTINUE+ Y(JY) = Y(JY) + ALPHA*TEMP2+ JX = JX + INCX+ JY = JY + INCY+ KK = KK + (N-J+1)+ 120 CONTINUE+ END IF+ END IF+*+ RETURN+*+* End of DSPMV .+*+ END
+ eigen3/blas/dtbmv.f view
@@ -0,0 +1,335 @@+ SUBROUTINE DTBMV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)+* .. Scalar Arguments ..+ INTEGER INCX,K,LDA,N+ CHARACTER DIAG,TRANS,UPLO+* ..+* .. Array Arguments ..+ DOUBLE PRECISION A(LDA,*),X(*)+* ..+*+* Purpose+* =======+*+* DTBMV performs one of the matrix-vector operations+*+* x := A*x, or x := A'*x,+*+* where x is an n element vector and A is an n by n unit, or non-unit,+* upper or lower triangular band matrix, with ( k + 1 ) diagonals.+*+* Arguments+* ==========+*+* UPLO - CHARACTER*1.+* On entry, UPLO specifies whether the matrix is an upper or+* lower triangular matrix as follows:+*+* UPLO = 'U' or 'u' A is an upper triangular matrix.+*+* UPLO = 'L' or 'l' A is a lower triangular matrix.+*+* Unchanged on exit.+*+* TRANS - CHARACTER*1.+* On entry, TRANS specifies the operation to be performed as+* follows:+*+* TRANS = 'N' or 'n' x := A*x.+*+* TRANS = 'T' or 't' x := A'*x.+*+* TRANS = 'C' or 'c' x := A'*x.+*+* Unchanged on exit.+*+* DIAG - CHARACTER*1.+* On entry, DIAG specifies whether or not A is unit+* triangular as follows:+*+* DIAG = 'U' or 'u' A is assumed to be unit triangular.+*+* DIAG = 'N' or 'n' A is not assumed to be unit+* triangular.+*+* Unchanged on exit.+*+* N - INTEGER.+* On entry, N specifies the order of the matrix A.+* N must be at least zero.+* Unchanged on exit.+*+* K - INTEGER.+* On entry with UPLO = 'U' or 'u', K specifies the number of+* super-diagonals of the matrix A.+* On entry with UPLO = 'L' or 'l', K specifies the number of+* sub-diagonals of the matrix A.+* K must satisfy 0 .le. K.+* Unchanged on exit.+*+* A - DOUBLE PRECISION array of DIMENSION ( LDA, n ).+* Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )+* by n part of the array A must contain the upper triangular+* band part of the matrix of coefficients, supplied column by+* column, with the leading diagonal of the matrix in row+* ( k + 1 ) of the array, the first super-diagonal starting at+* position 2 in row k, and so on. The top left k by k triangle+* of the array A is not referenced.+* The following program segment will transfer an upper+* triangular band matrix from conventional full matrix storage+* to band storage:+*+* DO 20, J = 1, N+* M = K + 1 - J+* DO 10, I = MAX( 1, J - K ), J+* A( M + I, J ) = matrix( I, J )+* 10 CONTINUE+* 20 CONTINUE+*+* Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )+* by n part of the array A must contain the lower triangular+* band part of the matrix of coefficients, supplied column by+* column, with the leading diagonal of the matrix in row 1 of+* the array, the first sub-diagonal starting at position 1 in+* row 2, and so on. The bottom right k by k triangle of the+* array A is not referenced.+* The following program segment will transfer a lower+* triangular band matrix from conventional full matrix storage+* to band storage:+*+* DO 20, J = 1, N+* M = 1 - J+* DO 10, I = J, MIN( N, J + K )+* A( M + I, J ) = matrix( I, J )+* 10 CONTINUE+* 20 CONTINUE+*+* Note that when DIAG = 'U' or 'u' the elements of the array A+* corresponding to the diagonal elements of the matrix are not+* referenced, but are assumed to be unity.+* Unchanged on exit.+*+* LDA - INTEGER.+* On entry, LDA specifies the first dimension of A as declared+* in the calling (sub) program. LDA must be at least+* ( k + 1 ).+* Unchanged on exit.+*+* X - DOUBLE PRECISION array of dimension at least+* ( 1 + ( n - 1 )*abs( INCX ) ).+* Before entry, the incremented array X must contain the n+* element vector x. On exit, X is overwritten with the+* tranformed vector x.+*+* INCX - INTEGER.+* On entry, INCX specifies the increment for the elements of+* X. INCX must not be zero.+* Unchanged on exit.+*+* Further Details+* ===============+*+* Level 2 Blas routine.+*+* -- Written on 22-October-1986.+* Jack Dongarra, Argonne National Lab.+* Jeremy Du Croz, Nag Central Office.+* Sven Hammarling, Nag Central Office.+* Richard Hanson, Sandia National Labs.+*+* =====================================================================+*+* .. Parameters ..+ DOUBLE PRECISION ZERO+ PARAMETER (ZERO=0.0D+0)+* ..+* .. Local Scalars ..+ DOUBLE PRECISION TEMP+ INTEGER I,INFO,IX,J,JX,KPLUS1,KX,L+ LOGICAL NOUNIT+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. External Subroutines ..+ EXTERNAL XERBLA+* ..+* .. Intrinsic Functions ..+ INTRINSIC MAX,MIN+* ..+*+* Test the input parameters.+*+ INFO = 0+ IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN+ INFO = 1+ ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.+ + .NOT.LSAME(TRANS,'C')) THEN+ INFO = 2+ ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN+ INFO = 3+ ELSE IF (N.LT.0) THEN+ INFO = 4+ ELSE IF (K.LT.0) THEN+ INFO = 5+ ELSE IF (LDA.LT. (K+1)) THEN+ INFO = 7+ ELSE IF (INCX.EQ.0) THEN+ INFO = 9+ END IF+ IF (INFO.NE.0) THEN+ CALL XERBLA('DTBMV ',INFO)+ RETURN+ END IF+*+* Quick return if possible.+*+ IF (N.EQ.0) RETURN+*+ NOUNIT = LSAME(DIAG,'N')+*+* Set up the start point in X if the increment is not unity. This+* will be ( N - 1 )*INCX too small for descending loops.+*+ IF (INCX.LE.0) THEN+ KX = 1 - (N-1)*INCX+ ELSE IF (INCX.NE.1) THEN+ KX = 1+ END IF+*+* Start the operations. In this version the elements of A are+* accessed sequentially with one pass through A.+*+ IF (LSAME(TRANS,'N')) THEN+*+* Form x := A*x.+*+ IF (LSAME(UPLO,'U')) THEN+ KPLUS1 = K + 1+ IF (INCX.EQ.1) THEN+ DO 20 J = 1,N+ IF (X(J).NE.ZERO) THEN+ TEMP = X(J)+ L = KPLUS1 - J+ DO 10 I = MAX(1,J-K),J - 1+ X(I) = X(I) + TEMP*A(L+I,J)+ 10 CONTINUE+ IF (NOUNIT) X(J) = X(J)*A(KPLUS1,J)+ END IF+ 20 CONTINUE+ ELSE+ JX = KX+ DO 40 J = 1,N+ IF (X(JX).NE.ZERO) THEN+ TEMP = X(JX)+ IX = KX+ L = KPLUS1 - J+ DO 30 I = MAX(1,J-K),J - 1+ X(IX) = X(IX) + TEMP*A(L+I,J)+ IX = IX + INCX+ 30 CONTINUE+ IF (NOUNIT) X(JX) = X(JX)*A(KPLUS1,J)+ END IF+ JX = JX + INCX+ IF (J.GT.K) KX = KX + INCX+ 40 CONTINUE+ END IF+ ELSE+ IF (INCX.EQ.1) THEN+ DO 60 J = N,1,-1+ IF (X(J).NE.ZERO) THEN+ TEMP = X(J)+ L = 1 - J+ DO 50 I = MIN(N,J+K),J + 1,-1+ X(I) = X(I) + TEMP*A(L+I,J)+ 50 CONTINUE+ IF (NOUNIT) X(J) = X(J)*A(1,J)+ END IF+ 60 CONTINUE+ ELSE+ KX = KX + (N-1)*INCX+ JX = KX+ DO 80 J = N,1,-1+ IF (X(JX).NE.ZERO) THEN+ TEMP = X(JX)+ IX = KX+ L = 1 - J+ DO 70 I = MIN(N,J+K),J + 1,-1+ X(IX) = X(IX) + TEMP*A(L+I,J)+ IX = IX - INCX+ 70 CONTINUE+ IF (NOUNIT) X(JX) = X(JX)*A(1,J)+ END IF+ JX = JX - INCX+ IF ((N-J).GE.K) KX = KX - INCX+ 80 CONTINUE+ END IF+ END IF+ ELSE+*+* Form x := A'*x.+*+ IF (LSAME(UPLO,'U')) THEN+ KPLUS1 = K + 1+ IF (INCX.EQ.1) THEN+ DO 100 J = N,1,-1+ TEMP = X(J)+ L = KPLUS1 - J+ IF (NOUNIT) TEMP = TEMP*A(KPLUS1,J)+ DO 90 I = J - 1,MAX(1,J-K),-1+ TEMP = TEMP + A(L+I,J)*X(I)+ 90 CONTINUE+ X(J) = TEMP+ 100 CONTINUE+ ELSE+ KX = KX + (N-1)*INCX+ JX = KX+ DO 120 J = N,1,-1+ TEMP = X(JX)+ KX = KX - INCX+ IX = KX+ L = KPLUS1 - J+ IF (NOUNIT) TEMP = TEMP*A(KPLUS1,J)+ DO 110 I = J - 1,MAX(1,J-K),-1+ TEMP = TEMP + A(L+I,J)*X(IX)+ IX = IX - INCX+ 110 CONTINUE+ X(JX) = TEMP+ JX = JX - INCX+ 120 CONTINUE+ END IF+ ELSE+ IF (INCX.EQ.1) THEN+ DO 140 J = 1,N+ TEMP = X(J)+ L = 1 - J+ IF (NOUNIT) TEMP = TEMP*A(1,J)+ DO 130 I = J + 1,MIN(N,J+K)+ TEMP = TEMP + A(L+I,J)*X(I)+ 130 CONTINUE+ X(J) = TEMP+ 140 CONTINUE+ ELSE+ JX = KX+ DO 160 J = 1,N+ TEMP = X(JX)+ KX = KX + INCX+ IX = KX+ L = 1 - J+ IF (NOUNIT) TEMP = TEMP*A(1,J)+ DO 150 I = J + 1,MIN(N,J+K)+ TEMP = TEMP + A(L+I,J)*X(IX)+ IX = IX + INCX+ 150 CONTINUE+ X(JX) = TEMP+ JX = JX + INCX+ 160 CONTINUE+ END IF+ END IF+ END IF+*+ RETURN+*+* End of DTBMV .+*+ END
+ eigen3/blas/level1_cplx_impl.h view
@@ -0,0 +1,127 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "common.h"++struct scalar_norm1_op {+ typedef RealScalar result_type;+ EIGEN_EMPTY_STRUCT_CTOR(scalar_norm1_op)+ inline RealScalar operator() (const Scalar& a) const { return numext::norm1(a); }+};+namespace Eigen {+ namespace internal {+ template<> struct functor_traits<scalar_norm1_op >+ {+ enum { Cost = 3 * NumTraits<Scalar>::AddCost, PacketAccess = 0 };+ };+ }+}++// computes the sum of magnitudes of all vector elements or, for a complex vector x, the sum+// res = |Rex1| + |Imx1| + |Rex2| + |Imx2| + ... + |Rexn| + |Imxn|, where x is a vector of order n+RealScalar EIGEN_CAT(EIGEN_CAT(REAL_SCALAR_SUFFIX,SCALAR_SUFFIX),asum_)(int *n, RealScalar *px, int *incx)+{+// std::cerr << "__asum " << *n << " " << *incx << "\n";+ Complex* x = reinterpret_cast<Complex*>(px);++ if(*n<=0) return 0;++ if(*incx==1) return vector(x,*n).unaryExpr<scalar_norm1_op>().sum();+ else return vector(x,*n,std::abs(*incx)).unaryExpr<scalar_norm1_op>().sum();+}++// computes a dot product of a conjugated vector with another vector.+int EIGEN_BLAS_FUNC(dotcw)(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar* pres)+{+// std::cerr << "_dotc " << *n << " " << *incx << " " << *incy << "\n";++ if(*n<=0) return 0;++ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);+ Scalar* res = reinterpret_cast<Scalar*>(pres);++ if(*incx==1 && *incy==1) *res = (vector(x,*n).dot(vector(y,*n)));+ else if(*incx>0 && *incy>0) *res = (vector(x,*n,*incx).dot(vector(y,*n,*incy)));+ else if(*incx<0 && *incy>0) *res = (vector(x,*n,-*incx).reverse().dot(vector(y,*n,*incy)));+ else if(*incx>0 && *incy<0) *res = (vector(x,*n,*incx).dot(vector(y,*n,-*incy).reverse()));+ else if(*incx<0 && *incy<0) *res = (vector(x,*n,-*incx).reverse().dot(vector(y,*n,-*incy).reverse()));+ return 0;+}++// computes a vector-vector dot product without complex conjugation.+int EIGEN_BLAS_FUNC(dotuw)(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar* pres)+{+// std::cerr << "_dotu " << *n << " " << *incx << " " << *incy << "\n";++ if(*n<=0) return 0;++ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);+ Scalar* res = reinterpret_cast<Scalar*>(pres);++ if(*incx==1 && *incy==1) *res = (vector(x,*n).cwiseProduct(vector(y,*n))).sum();+ else if(*incx>0 && *incy>0) *res = (vector(x,*n,*incx).cwiseProduct(vector(y,*n,*incy))).sum();+ else if(*incx<0 && *incy>0) *res = (vector(x,*n,-*incx).reverse().cwiseProduct(vector(y,*n,*incy))).sum();+ else if(*incx>0 && *incy<0) *res = (vector(x,*n,*incx).cwiseProduct(vector(y,*n,-*incy).reverse())).sum();+ else if(*incx<0 && *incy<0) *res = (vector(x,*n,-*incx).reverse().cwiseProduct(vector(y,*n,-*incy).reverse())).sum();+ return 0;+}++RealScalar EIGEN_CAT(EIGEN_CAT(REAL_SCALAR_SUFFIX,SCALAR_SUFFIX),nrm2_)(int *n, RealScalar *px, int *incx)+{+// std::cerr << "__nrm2 " << *n << " " << *incx << "\n";+ if(*n<=0) return 0;++ Scalar* x = reinterpret_cast<Scalar*>(px);++ if(*incx==1)+ return vector(x,*n).stableNorm();++ return vector(x,*n,*incx).stableNorm();+}++int EIGEN_CAT(EIGEN_CAT(SCALAR_SUFFIX,REAL_SCALAR_SUFFIX),rot_)(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *pc, RealScalar *ps)+{+ if(*n<=0) return 0;++ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);+ RealScalar c = *pc;+ RealScalar s = *ps;++ StridedVectorType vx(vector(x,*n,std::abs(*incx)));+ StridedVectorType vy(vector(y,*n,std::abs(*incy)));++ Reverse<StridedVectorType> rvx(vx);+ Reverse<StridedVectorType> rvy(vy);++ // TODO implement mixed real-scalar rotations+ if(*incx<0 && *incy>0) internal::apply_rotation_in_the_plane(rvx, vy, JacobiRotation<Scalar>(c,s));+ else if(*incx>0 && *incy<0) internal::apply_rotation_in_the_plane(vx, rvy, JacobiRotation<Scalar>(c,s));+ else internal::apply_rotation_in_the_plane(vx, vy, JacobiRotation<Scalar>(c,s));++ return 0;+}++int EIGEN_CAT(EIGEN_CAT(SCALAR_SUFFIX,REAL_SCALAR_SUFFIX),scal_)(int *n, RealScalar *palpha, RealScalar *px, int *incx)+{+ if(*n<=0) return 0;++ Scalar* x = reinterpret_cast<Scalar*>(px);+ RealScalar alpha = *palpha;++// std::cerr << "__scal " << *n << " " << alpha << " " << *incx << "\n";++ if(*incx==1) vector(x,*n) *= alpha;+ else vector(x,*n,std::abs(*incx)) *= alpha;++ return 0;+}+
+ eigen3/blas/level1_impl.h view
@@ -0,0 +1,167 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "common.h"++int EIGEN_BLAS_FUNC(axpy)(int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *py, int *incy)+{+ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);++ if(*n<=0) return 0;++ if(*incx==1 && *incy==1) vector(y,*n) += alpha * vector(x,*n);+ else if(*incx>0 && *incy>0) vector(y,*n,*incy) += alpha * vector(x,*n,*incx);+ else if(*incx>0 && *incy<0) vector(y,*n,-*incy).reverse() += alpha * vector(x,*n,*incx);+ else if(*incx<0 && *incy>0) vector(y,*n,*incy) += alpha * vector(x,*n,-*incx).reverse();+ else if(*incx<0 && *incy<0) vector(y,*n,-*incy).reverse() += alpha * vector(x,*n,-*incx).reverse();++ return 0;+}++int EIGEN_BLAS_FUNC(copy)(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)+{+ if(*n<=0) return 0;++ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);++ // be carefull, *incx==0 is allowed !!+ if(*incx==1 && *incy==1)+ vector(y,*n) = vector(x,*n);+ else+ {+ if(*incx<0) x = x - (*n-1)*(*incx);+ if(*incy<0) y = y - (*n-1)*(*incy);+ for(int i=0;i<*n;++i)+ {+ *y = *x;+ x += *incx;+ y += *incy;+ }+ }++ return 0;+}++int EIGEN_CAT(EIGEN_CAT(i,SCALAR_SUFFIX),amax_)(int *n, RealScalar *px, int *incx)+{+ if(*n<=0) return 0;+ Scalar* x = reinterpret_cast<Scalar*>(px);++ DenseIndex ret;+ if(*incx==1) vector(x,*n).cwiseAbs().maxCoeff(&ret);+ else vector(x,*n,std::abs(*incx)).cwiseAbs().maxCoeff(&ret);+ return ret+1;+}++int EIGEN_CAT(EIGEN_CAT(i,SCALAR_SUFFIX),amin_)(int *n, RealScalar *px, int *incx)+{+ if(*n<=0) return 0;+ Scalar* x = reinterpret_cast<Scalar*>(px);+ + DenseIndex ret;+ if(*incx==1) vector(x,*n).cwiseAbs().minCoeff(&ret);+ else vector(x,*n,std::abs(*incx)).cwiseAbs().minCoeff(&ret);+ return ret+1;+}++int EIGEN_BLAS_FUNC(rotg)(RealScalar *pa, RealScalar *pb, RealScalar *pc, RealScalar *ps)+{+ using std::sqrt;+ using std::abs;+ + Scalar& a = *reinterpret_cast<Scalar*>(pa);+ Scalar& b = *reinterpret_cast<Scalar*>(pb);+ RealScalar* c = pc;+ Scalar* s = reinterpret_cast<Scalar*>(ps);++ #if !ISCOMPLEX+ Scalar r,z;+ Scalar aa = abs(a);+ Scalar ab = abs(b);+ if((aa+ab)==Scalar(0))+ {+ *c = 1;+ *s = 0;+ r = 0;+ z = 0;+ }+ else+ {+ r = sqrt(a*a + b*b);+ Scalar amax = aa>ab ? a : b;+ r = amax>0 ? r : -r;+ *c = a/r;+ *s = b/r;+ z = 1;+ if (aa > ab) z = *s;+ if (ab > aa && *c!=RealScalar(0))+ z = Scalar(1)/ *c;+ }+ *pa = r;+ *pb = z;+ #else+ Scalar alpha;+ RealScalar norm,scale;+ if(abs(a)==RealScalar(0))+ {+ *c = RealScalar(0);+ *s = Scalar(1);+ a = b;+ }+ else+ {+ scale = abs(a) + abs(b);+ norm = scale*sqrt((numext::abs2(a/scale)) + (numext::abs2(b/scale)));+ alpha = a/abs(a);+ *c = abs(a)/norm;+ *s = alpha*numext::conj(b)/norm;+ a = alpha*norm;+ }+ #endif++// JacobiRotation<Scalar> r;+// r.makeGivens(a,b);+// *c = r.c();+// *s = r.s();++ return 0;+}++int EIGEN_BLAS_FUNC(scal)(int *n, RealScalar *palpha, RealScalar *px, int *incx)+{+ if(*n<=0) return 0;++ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);++ if(*incx==1) vector(x,*n) *= alpha;+ else vector(x,*n,std::abs(*incx)) *= alpha;++ return 0;+}++int EIGEN_BLAS_FUNC(swap)(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)+{+ if(*n<=0) return 0;++ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);++ if(*incx==1 && *incy==1) vector(y,*n).swap(vector(x,*n));+ else if(*incx>0 && *incy>0) vector(y,*n,*incy).swap(vector(x,*n,*incx));+ else if(*incx>0 && *incy<0) vector(y,*n,-*incy).reverse().swap(vector(x,*n,*incx));+ else if(*incx<0 && *incy>0) vector(y,*n,*incy).swap(vector(x,*n,-*incx).reverse());+ else if(*incx<0 && *incy<0) vector(y,*n,-*incy).reverse().swap(vector(x,*n,-*incx).reverse());++ return 1;+}+
+ eigen3/blas/level1_real_impl.h view
@@ -0,0 +1,100 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "common.h"++// computes the sum of magnitudes of all vector elements or, for a complex vector x, the sum+// res = |Rex1| + |Imx1| + |Rex2| + |Imx2| + ... + |Rexn| + |Imxn|, where x is a vector of order n+RealScalar EIGEN_BLAS_FUNC(asum)(int *n, RealScalar *px, int *incx)+{+// std::cerr << "_asum " << *n << " " << *incx << "\n";++ Scalar* x = reinterpret_cast<Scalar*>(px);++ if(*n<=0) return 0;++ if(*incx==1) return vector(x,*n).cwiseAbs().sum();+ else return vector(x,*n,std::abs(*incx)).cwiseAbs().sum();+}++// computes a vector-vector dot product.+Scalar EIGEN_BLAS_FUNC(dot)(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy)+{+// std::cerr << "_dot " << *n << " " << *incx << " " << *incy << "\n";++ if(*n<=0) return 0;++ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);++ if(*incx==1 && *incy==1) return (vector(x,*n).cwiseProduct(vector(y,*n))).sum();+ else if(*incx>0 && *incy>0) return (vector(x,*n,*incx).cwiseProduct(vector(y,*n,*incy))).sum();+ else if(*incx<0 && *incy>0) return (vector(x,*n,-*incx).reverse().cwiseProduct(vector(y,*n,*incy))).sum();+ else if(*incx>0 && *incy<0) return (vector(x,*n,*incx).cwiseProduct(vector(y,*n,-*incy).reverse())).sum();+ else if(*incx<0 && *incy<0) return (vector(x,*n,-*incx).reverse().cwiseProduct(vector(y,*n,-*incy).reverse())).sum();+ else return 0;+}++// computes the Euclidean norm of a vector.+// FIXME+Scalar EIGEN_BLAS_FUNC(nrm2)(int *n, RealScalar *px, int *incx)+{+// std::cerr << "_nrm2 " << *n << " " << *incx << "\n";+ if(*n<=0) return 0;++ Scalar* x = reinterpret_cast<Scalar*>(px);++ if(*incx==1) return vector(x,*n).stableNorm();+ else return vector(x,*n,std::abs(*incx)).stableNorm();+}++int EIGEN_BLAS_FUNC(rot)(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *pc, RealScalar *ps)+{+// std::cerr << "_rot " << *n << " " << *incx << " " << *incy << "\n";+ if(*n<=0) return 0;++ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);+ Scalar c = *reinterpret_cast<Scalar*>(pc);+ Scalar s = *reinterpret_cast<Scalar*>(ps);++ StridedVectorType vx(vector(x,*n,std::abs(*incx)));+ StridedVectorType vy(vector(y,*n,std::abs(*incy)));++ Reverse<StridedVectorType> rvx(vx);+ Reverse<StridedVectorType> rvy(vy);++ if(*incx<0 && *incy>0) internal::apply_rotation_in_the_plane(rvx, vy, JacobiRotation<Scalar>(c,s));+ else if(*incx>0 && *incy<0) internal::apply_rotation_in_the_plane(vx, rvy, JacobiRotation<Scalar>(c,s));+ else internal::apply_rotation_in_the_plane(vx, vy, JacobiRotation<Scalar>(c,s));+++ return 0;+}++/*+// performs rotation of points in the modified plane.+int EIGEN_BLAS_FUNC(rotm)(int *n, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *param)+{+ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);++ // TODO++ return 0;+}++// computes the modified parameters for a Givens rotation.+int EIGEN_BLAS_FUNC(rotmg)(RealScalar *d1, RealScalar *d2, RealScalar *x1, RealScalar *x2, RealScalar *param)+{+ // TODO++ return 0;+}+*/
+ eigen3/blas/level2_cplx_impl.h view
@@ -0,0 +1,394 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "common.h"++/** ZHEMV performs the matrix-vector operation+ *+ * y := alpha*A*x + beta*y,+ *+ * where alpha and beta are scalars, x and y are n element vectors and+ * A is an n by n hermitian matrix.+ */+int EIGEN_BLAS_FUNC(hemv)(char *uplo, int *n, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *px, int *incx, RealScalar *pbeta, RealScalar *py, int *incy)+{+ typedef void (*functype)(int, const Scalar*, int, const Scalar*, int, Scalar*, Scalar);+ static functype func[2];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<2; ++k)+ func[k] = 0;++ func[UP] = (internal::selfadjoint_matrix_vector_product<Scalar,int,ColMajor,Upper,false,false>::run);+ func[LO] = (internal::selfadjoint_matrix_vector_product<Scalar,int,ColMajor,Lower,false,false>::run);++ init = true;+ }++ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);+ Scalar beta = *reinterpret_cast<Scalar*>(pbeta);++ // check arguments+ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(*n<0) info = 2;+ else if(*lda<std::max(1,*n)) info = 5;+ else if(*incx==0) info = 7;+ else if(*incy==0) info = 10;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"HEMV ",&info,6);++ if(*n==0)+ return 1;++ Scalar* actual_x = get_compact_vector(x,*n,*incx);+ Scalar* actual_y = get_compact_vector(y,*n,*incy);++ if(beta!=Scalar(1))+ {+ if(beta==Scalar(0)) vector(actual_y, *n).setZero();+ else vector(actual_y, *n) *= beta;+ }++ if(alpha!=Scalar(0))+ {+ int code = UPLO(*uplo);+ if(code>=2 || func[code]==0)+ return 0;++ func[code](*n, a, *lda, actual_x, 1, actual_y, alpha);+ }++ if(actual_x!=x) delete[] actual_x;+ if(actual_y!=y) delete[] copy_back(actual_y,y,*n,*incy);++ return 1;+}++/** ZHBMV performs the matrix-vector operation+ *+ * y := alpha*A*x + beta*y,+ *+ * where alpha and beta are scalars, x and y are n element vectors and+ * A is an n by n hermitian band matrix, with k super-diagonals.+ */+// int EIGEN_BLAS_FUNC(hbmv)(char *uplo, int *n, int *k, RealScalar *alpha, RealScalar *a, int *lda,+// RealScalar *x, int *incx, RealScalar *beta, RealScalar *y, int *incy)+// {+// return 1;+// }++/** ZHPMV performs the matrix-vector operation+ *+ * y := alpha*A*x + beta*y,+ *+ * where alpha and beta are scalars, x and y are n element vectors and+ * A is an n by n hermitian matrix, supplied in packed form.+ */+// int EIGEN_BLAS_FUNC(hpmv)(char *uplo, int *n, RealScalar *alpha, RealScalar *ap, RealScalar *x, int *incx, RealScalar *beta, RealScalar *y, int *incy)+// {+// return 1;+// }++/** ZHPR performs the hermitian rank 1 operation+ *+ * A := alpha*x*conjg( x' ) + A,+ *+ * where alpha is a real scalar, x is an n element vector and A is an+ * n by n hermitian matrix, supplied in packed form.+ */+int EIGEN_BLAS_FUNC(hpr)(char *uplo, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *pap)+{+ typedef void (*functype)(int, Scalar*, const Scalar*, RealScalar);+ static functype func[2];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<2; ++k)+ func[k] = 0;++ func[UP] = (internal::selfadjoint_packed_rank1_update<Scalar,int,ColMajor,Upper,false,Conj>::run);+ func[LO] = (internal::selfadjoint_packed_rank1_update<Scalar,int,ColMajor,Lower,false,Conj>::run);++ init = true;+ }++ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* ap = reinterpret_cast<Scalar*>(pap);+ RealScalar alpha = *palpha;++ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(*n<0) info = 2;+ else if(*incx==0) info = 5;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"HPR ",&info,6);++ if(alpha==Scalar(0))+ return 1;++ Scalar* x_cpy = get_compact_vector(x, *n, *incx);++ int code = UPLO(*uplo);+ if(code>=2 || func[code]==0)+ return 0;++ func[code](*n, ap, x_cpy, alpha);++ if(x_cpy!=x) delete[] x_cpy;++ return 1;+}++/** ZHPR2 performs the hermitian rank 2 operation+ *+ * A := alpha*x*conjg( y' ) + conjg( alpha )*y*conjg( x' ) + A,+ *+ * where alpha is a scalar, x and y are n element vectors and A is an+ * n by n hermitian matrix, supplied in packed form.+ */+int EIGEN_BLAS_FUNC(hpr2)(char *uplo, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *pap)+{+ typedef void (*functype)(int, Scalar*, const Scalar*, const Scalar*, Scalar);+ static functype func[2];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<2; ++k)+ func[k] = 0;++ func[UP] = (internal::packed_rank2_update_selector<Scalar,int,Upper>::run);+ func[LO] = (internal::packed_rank2_update_selector<Scalar,int,Lower>::run);++ init = true;+ }++ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);+ Scalar* ap = reinterpret_cast<Scalar*>(pap);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);++ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(*n<0) info = 2;+ else if(*incx==0) info = 5;+ else if(*incy==0) info = 7;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"HPR2 ",&info,6);++ if(alpha==Scalar(0))+ return 1;++ Scalar* x_cpy = get_compact_vector(x, *n, *incx);+ Scalar* y_cpy = get_compact_vector(y, *n, *incy);++ int code = UPLO(*uplo);+ if(code>=2 || func[code]==0)+ return 0;++ func[code](*n, ap, x_cpy, y_cpy, alpha);++ if(x_cpy!=x) delete[] x_cpy;+ if(y_cpy!=y) delete[] y_cpy;++ return 1;+}++/** ZHER performs the hermitian rank 1 operation+ *+ * A := alpha*x*conjg( x' ) + A,+ *+ * where alpha is a real scalar, x is an n element vector and A is an+ * n by n hermitian matrix.+ */+int EIGEN_BLAS_FUNC(her)(char *uplo, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *pa, int *lda)+{+ typedef void (*functype)(int, Scalar*, int, const Scalar*, const Scalar*, const Scalar&);+ static functype func[2];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<2; ++k)+ func[k] = 0;++ func[UP] = (selfadjoint_rank1_update<Scalar,int,ColMajor,Upper,false,Conj>::run);+ func[LO] = (selfadjoint_rank1_update<Scalar,int,ColMajor,Lower,false,Conj>::run);++ init = true;+ }++ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* a = reinterpret_cast<Scalar*>(pa);+ RealScalar alpha = *reinterpret_cast<RealScalar*>(palpha);++ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(*n<0) info = 2;+ else if(*incx==0) info = 5;+ else if(*lda<std::max(1,*n)) info = 7;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"HER ",&info,6);++ if(alpha==RealScalar(0))+ return 1;++ Scalar* x_cpy = get_compact_vector(x, *n, *incx);++ int code = UPLO(*uplo);+ if(code>=2 || func[code]==0)+ return 0;++ func[code](*n, a, *lda, x_cpy, x_cpy, alpha);++ matrix(a,*n,*n,*lda).diagonal().imag().setZero();++ if(x_cpy!=x) delete[] x_cpy;++ return 1;+}++/** ZHER2 performs the hermitian rank 2 operation+ *+ * A := alpha*x*conjg( y' ) + conjg( alpha )*y*conjg( x' ) + A,+ *+ * where alpha is a scalar, x and y are n element vectors and A is an n+ * by n hermitian matrix.+ */+int EIGEN_BLAS_FUNC(her2)(char *uplo, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *pa, int *lda)+{+ typedef void (*functype)(int, Scalar*, int, const Scalar*, const Scalar*, Scalar);+ static functype func[2];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<2; ++k)+ func[k] = 0;++ func[UP] = (internal::rank2_update_selector<Scalar,int,Upper>::run);+ func[LO] = (internal::rank2_update_selector<Scalar,int,Lower>::run);++ init = true;+ }++ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);+ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);++ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(*n<0) info = 2;+ else if(*incx==0) info = 5;+ else if(*incy==0) info = 7;+ else if(*lda<std::max(1,*n)) info = 9;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"HER2 ",&info,6);++ if(alpha==Scalar(0))+ return 1;++ Scalar* x_cpy = get_compact_vector(x, *n, *incx);+ Scalar* y_cpy = get_compact_vector(y, *n, *incy);++ int code = UPLO(*uplo);+ if(code>=2 || func[code]==0)+ return 0;++ func[code](*n, a, *lda, x_cpy, y_cpy, alpha);++ matrix(a,*n,*n,*lda).diagonal().imag().setZero();++ if(x_cpy!=x) delete[] x_cpy;+ if(y_cpy!=y) delete[] y_cpy;++ return 1;+}++/** ZGERU performs the rank 1 operation+ *+ * A := alpha*x*y' + A,+ *+ * where alpha is a scalar, x is an m element vector, y is an n element+ * vector and A is an m by n matrix.+ */+int EIGEN_BLAS_FUNC(geru)(int *m, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *pa, int *lda)+{+ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);+ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);++ int info = 0;+ if(*m<0) info = 1;+ else if(*n<0) info = 2;+ else if(*incx==0) info = 5;+ else if(*incy==0) info = 7;+ else if(*lda<std::max(1,*m)) info = 9;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"GERU ",&info,6);++ if(alpha==Scalar(0))+ return 1;++ Scalar* x_cpy = get_compact_vector(x,*m,*incx);+ Scalar* y_cpy = get_compact_vector(y,*n,*incy);++ internal::general_rank1_update<Scalar,int,ColMajor,false,false>::run(*m, *n, a, *lda, x_cpy, y_cpy, alpha);++ if(x_cpy!=x) delete[] x_cpy;+ if(y_cpy!=y) delete[] y_cpy;++ return 1;+}++/** ZGERC performs the rank 1 operation+ *+ * A := alpha*x*conjg( y' ) + A,+ *+ * where alpha is a scalar, x is an m element vector, y is an n element+ * vector and A is an m by n matrix.+ */+int EIGEN_BLAS_FUNC(gerc)(int *m, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *pa, int *lda)+{+ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);+ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);++ int info = 0;+ if(*m<0) info = 1;+ else if(*n<0) info = 2;+ else if(*incx==0) info = 5;+ else if(*incy==0) info = 7;+ else if(*lda<std::max(1,*m)) info = 9;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"GERC ",&info,6);++ if(alpha==Scalar(0))+ return 1;++ Scalar* x_cpy = get_compact_vector(x,*m,*incx);+ Scalar* y_cpy = get_compact_vector(y,*n,*incy);++ internal::general_rank1_update<Scalar,int,ColMajor,false,Conj>::run(*m, *n, a, *lda, x_cpy, y_cpy, alpha);++ if(x_cpy!=x) delete[] x_cpy;+ if(y_cpy!=y) delete[] y_cpy;++ return 1;+}
+ eigen3/blas/level2_impl.h view
@@ -0,0 +1,524 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "common.h"++int EIGEN_BLAS_FUNC(gemv)(char *opa, int *m, int *n, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pb, int *incb, RealScalar *pbeta, RealScalar *pc, int *incc)+{+ typedef void (*functype)(int, int, const Scalar *, int, const Scalar *, int , Scalar *, int, Scalar);+ static functype func[4];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<4; ++k)+ func[k] = 0;++ func[NOTR] = (internal::general_matrix_vector_product<int,Scalar,ColMajor,false,Scalar,false>::run);+ func[TR ] = (internal::general_matrix_vector_product<int,Scalar,RowMajor,false,Scalar,false>::run);+ func[ADJ ] = (internal::general_matrix_vector_product<int,Scalar,RowMajor,Conj, Scalar,false>::run);++ init = true;+ }++ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* b = reinterpret_cast<Scalar*>(pb);+ Scalar* c = reinterpret_cast<Scalar*>(pc);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);+ Scalar beta = *reinterpret_cast<Scalar*>(pbeta);++ // check arguments+ int info = 0;+ if(OP(*opa)==INVALID) info = 1;+ else if(*m<0) info = 2;+ else if(*n<0) info = 3;+ else if(*lda<std::max(1,*m)) info = 6;+ else if(*incb==0) info = 8;+ else if(*incc==0) info = 11;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"GEMV ",&info,6);++ if(*m==0 || *n==0 || (alpha==Scalar(0) && beta==Scalar(1)))+ return 0;++ int actual_m = *m;+ int actual_n = *n;+ int code = OP(*opa);+ if(code!=NOTR)+ std::swap(actual_m,actual_n);++ Scalar* actual_b = get_compact_vector(b,actual_n,*incb);+ Scalar* actual_c = get_compact_vector(c,actual_m,*incc);++ if(beta!=Scalar(1))+ {+ if(beta==Scalar(0)) vector(actual_c, actual_m).setZero();+ else vector(actual_c, actual_m) *= beta;+ }++ if(code>=4 || func[code]==0)+ return 0;++ func[code](actual_m, actual_n, a, *lda, actual_b, 1, actual_c, 1, alpha);++ if(actual_b!=b) delete[] actual_b;+ if(actual_c!=c) delete[] copy_back(actual_c,c,actual_m,*incc);++ return 1;+}++int EIGEN_BLAS_FUNC(trsv)(char *uplo, char *opa, char *diag, int *n, RealScalar *pa, int *lda, RealScalar *pb, int *incb)+{+ typedef void (*functype)(int, const Scalar *, int, Scalar *);+ static functype func[16];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<16; ++k)+ func[k] = 0;++ func[NOTR | (UP << 2) | (NUNIT << 3)] = (internal::triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Upper|0, false,ColMajor>::run);+ func[TR | (UP << 2) | (NUNIT << 3)] = (internal::triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Lower|0, false,RowMajor>::run);+ func[ADJ | (UP << 2) | (NUNIT << 3)] = (internal::triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Lower|0, Conj, RowMajor>::run);++ func[NOTR | (LO << 2) | (NUNIT << 3)] = (internal::triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Lower|0, false,ColMajor>::run);+ func[TR | (LO << 2) | (NUNIT << 3)] = (internal::triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Upper|0, false,RowMajor>::run);+ func[ADJ | (LO << 2) | (NUNIT << 3)] = (internal::triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Upper|0, Conj, RowMajor>::run);++ func[NOTR | (UP << 2) | (UNIT << 3)] = (internal::triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Upper|UnitDiag,false,ColMajor>::run);+ func[TR | (UP << 2) | (UNIT << 3)] = (internal::triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Lower|UnitDiag,false,RowMajor>::run);+ func[ADJ | (UP << 2) | (UNIT << 3)] = (internal::triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Lower|UnitDiag,Conj, RowMajor>::run);++ func[NOTR | (LO << 2) | (UNIT << 3)] = (internal::triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Lower|UnitDiag,false,ColMajor>::run);+ func[TR | (LO << 2) | (UNIT << 3)] = (internal::triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Upper|UnitDiag,false,RowMajor>::run);+ func[ADJ | (LO << 2) | (UNIT << 3)] = (internal::triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Upper|UnitDiag,Conj, RowMajor>::run);++ init = true;+ }++ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* b = reinterpret_cast<Scalar*>(pb);++ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(OP(*opa)==INVALID) info = 2;+ else if(DIAG(*diag)==INVALID) info = 3;+ else if(*n<0) info = 4;+ else if(*lda<std::max(1,*n)) info = 6;+ else if(*incb==0) info = 8;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"TRSV ",&info,6);++ Scalar* actual_b = get_compact_vector(b,*n,*incb);++ int code = OP(*opa) | (UPLO(*uplo) << 2) | (DIAG(*diag) << 3);+ func[code](*n, a, *lda, actual_b);++ if(actual_b!=b) delete[] copy_back(actual_b,b,*n,*incb);++ return 0;+}++++int EIGEN_BLAS_FUNC(trmv)(char *uplo, char *opa, char *diag, int *n, RealScalar *pa, int *lda, RealScalar *pb, int *incb)+{+ typedef void (*functype)(int, int, const Scalar *, int, const Scalar *, int, Scalar *, int, const Scalar&);+ static functype func[16];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<16; ++k)+ func[k] = 0;++ func[NOTR | (UP << 2) | (NUNIT << 3)] = (internal::triangular_matrix_vector_product<int,Upper|0, Scalar,false,Scalar,false,ColMajor>::run);+ func[TR | (UP << 2) | (NUNIT << 3)] = (internal::triangular_matrix_vector_product<int,Lower|0, Scalar,false,Scalar,false,RowMajor>::run);+ func[ADJ | (UP << 2) | (NUNIT << 3)] = (internal::triangular_matrix_vector_product<int,Lower|0, Scalar,Conj, Scalar,false,RowMajor>::run);++ func[NOTR | (LO << 2) | (NUNIT << 3)] = (internal::triangular_matrix_vector_product<int,Lower|0, Scalar,false,Scalar,false,ColMajor>::run);+ func[TR | (LO << 2) | (NUNIT << 3)] = (internal::triangular_matrix_vector_product<int,Upper|0, Scalar,false,Scalar,false,RowMajor>::run);+ func[ADJ | (LO << 2) | (NUNIT << 3)] = (internal::triangular_matrix_vector_product<int,Upper|0, Scalar,Conj, Scalar,false,RowMajor>::run);++ func[NOTR | (UP << 2) | (UNIT << 3)] = (internal::triangular_matrix_vector_product<int,Upper|UnitDiag,Scalar,false,Scalar,false,ColMajor>::run);+ func[TR | (UP << 2) | (UNIT << 3)] = (internal::triangular_matrix_vector_product<int,Lower|UnitDiag,Scalar,false,Scalar,false,RowMajor>::run);+ func[ADJ | (UP << 2) | (UNIT << 3)] = (internal::triangular_matrix_vector_product<int,Lower|UnitDiag,Scalar,Conj, Scalar,false,RowMajor>::run);++ func[NOTR | (LO << 2) | (UNIT << 3)] = (internal::triangular_matrix_vector_product<int,Lower|UnitDiag,Scalar,false,Scalar,false,ColMajor>::run);+ func[TR | (LO << 2) | (UNIT << 3)] = (internal::triangular_matrix_vector_product<int,Upper|UnitDiag,Scalar,false,Scalar,false,RowMajor>::run);+ func[ADJ | (LO << 2) | (UNIT << 3)] = (internal::triangular_matrix_vector_product<int,Upper|UnitDiag,Scalar,Conj, Scalar,false,RowMajor>::run);++ init = true;+ }++ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* b = reinterpret_cast<Scalar*>(pb);++ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(OP(*opa)==INVALID) info = 2;+ else if(DIAG(*diag)==INVALID) info = 3;+ else if(*n<0) info = 4;+ else if(*lda<std::max(1,*n)) info = 6;+ else if(*incb==0) info = 8;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"TRMV ",&info,6);++ if(*n==0)+ return 1;++ Scalar* actual_b = get_compact_vector(b,*n,*incb);+ Matrix<Scalar,Dynamic,1> res(*n);+ res.setZero();++ int code = OP(*opa) | (UPLO(*uplo) << 2) | (DIAG(*diag) << 3);+ if(code>=16 || func[code]==0)+ return 0;++ func[code](*n, *n, a, *lda, actual_b, 1, res.data(), 1, Scalar(1));++ copy_back(res.data(),b,*n,*incb);+ if(actual_b!=b) delete[] actual_b;++ return 1;+}++/** GBMV performs one of the matrix-vector operations+ *+ * y := alpha*A*x + beta*y, or y := alpha*A'*x + beta*y,+ *+ * where alpha and beta are scalars, x and y are vectors and A is an+ * m by n band matrix, with kl sub-diagonals and ku super-diagonals.+ */+int EIGEN_BLAS_FUNC(gbmv)(char *trans, int *m, int *n, int *kl, int *ku, RealScalar *palpha, RealScalar *pa, int *lda,+ RealScalar *px, int *incx, RealScalar *pbeta, RealScalar *py, int *incy)+{+ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);+ Scalar beta = *reinterpret_cast<Scalar*>(pbeta);+ int coeff_rows = *kl+*ku+1;+ + int info = 0;+ if(OP(*trans)==INVALID) info = 1;+ else if(*m<0) info = 2;+ else if(*n<0) info = 3;+ else if(*kl<0) info = 4;+ else if(*ku<0) info = 5;+ else if(*lda<coeff_rows) info = 8;+ else if(*incx==0) info = 10;+ else if(*incy==0) info = 13;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"GBMV ",&info,6);+ + if(*m==0 || *n==0 || (alpha==Scalar(0) && beta==Scalar(1)))+ return 0;+ + int actual_m = *m;+ int actual_n = *n;+ if(OP(*trans)!=NOTR)+ std::swap(actual_m,actual_n);+ + Scalar* actual_x = get_compact_vector(x,actual_n,*incx);+ Scalar* actual_y = get_compact_vector(y,actual_m,*incy);+ + if(beta!=Scalar(1))+ {+ if(beta==Scalar(0)) vector(actual_y, actual_m).setZero();+ else vector(actual_y, actual_m) *= beta;+ }+ + MatrixType mat_coeffs(a,coeff_rows,*n,*lda);+ + int nb = std::min(*n,(*m)+(*ku));+ for(int j=0; j<nb; ++j)+ {+ int start = std::max(0,j - *ku);+ int end = std::min((*m)-1,j + *kl);+ int len = end - start + 1;+ int offset = (*ku) - j + start;+ if(OP(*trans)==NOTR)+ vector(actual_y+start,len) += (alpha*actual_x[j]) * mat_coeffs.col(j).segment(offset,len);+ else if(OP(*trans)==TR)+ actual_y[j] += alpha * ( mat_coeffs.col(j).segment(offset,len).transpose() * vector(actual_x+start,len) ).value();+ else+ actual_y[j] += alpha * ( mat_coeffs.col(j).segment(offset,len).adjoint() * vector(actual_x+start,len) ).value();+ } + + if(actual_x!=x) delete[] actual_x;+ if(actual_y!=y) delete[] copy_back(actual_y,y,actual_m,*incy);+ + return 0;+}++#if 0+/** TBMV performs one of the matrix-vector operations+ *+ * x := A*x, or x := A'*x,+ *+ * where x is an n element vector and A is an n by n unit, or non-unit,+ * upper or lower triangular band matrix, with ( k + 1 ) diagonals.+ */+int EIGEN_BLAS_FUNC(tbmv)(char *uplo, char *opa, char *diag, int *n, int *k, RealScalar *pa, int *lda, RealScalar *px, int *incx)+{+ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* x = reinterpret_cast<Scalar*>(px);+ int coeff_rows = *k + 1;+ + int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(OP(*opa)==INVALID) info = 2;+ else if(DIAG(*diag)==INVALID) info = 3;+ else if(*n<0) info = 4;+ else if(*k<0) info = 5;+ else if(*lda<coeff_rows) info = 7;+ else if(*incx==0) info = 9;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"TBMV ",&info,6);+ + if(*n==0)+ return 0;+ + int actual_n = *n;+ + Scalar* actual_x = get_compact_vector(x,actual_n,*incx);+ + MatrixType mat_coeffs(a,coeff_rows,*n,*lda);+ + int ku = UPLO(*uplo)==UPPER ? *k : 0;+ int kl = UPLO(*uplo)==LOWER ? *k : 0;+ + for(int j=0; j<*n; ++j)+ {+ int start = std::max(0,j - ku);+ int end = std::min((*m)-1,j + kl);+ int len = end - start + 1;+ int offset = (ku) - j + start;+ + if(OP(*trans)==NOTR)+ vector(actual_y+start,len) += (alpha*actual_x[j]) * mat_coeffs.col(j).segment(offset,len);+ else if(OP(*trans)==TR)+ actual_y[j] += alpha * ( mat_coeffs.col(j).segment(offset,len).transpose() * vector(actual_x+start,len) ).value();+ else+ actual_y[j] += alpha * ( mat_coeffs.col(j).segment(offset,len).adjoint() * vector(actual_x+start,len) ).value();+ } + + if(actual_x!=x) delete[] actual_x;+ if(actual_y!=y) delete[] copy_back(actual_y,y,actual_m,*incy);+ + return 0;+}+#endif++/** DTBSV solves one of the systems of equations+ *+ * A*x = b, or A'*x = b,+ *+ * where b and x are n element vectors and A is an n by n unit, or+ * non-unit, upper or lower triangular band matrix, with ( k + 1 )+ * diagonals.+ *+ * No test for singularity or near-singularity is included in this+ * routine. Such tests must be performed before calling this routine.+ */+int EIGEN_BLAS_FUNC(tbsv)(char *uplo, char *op, char *diag, int *n, int *k, RealScalar *pa, int *lda, RealScalar *px, int *incx)+{+ typedef void (*functype)(int, int, const Scalar *, int, Scalar *);+ static functype func[16];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<16; ++k)+ func[k] = 0;++ func[NOTR | (UP << 2) | (NUNIT << 3)] = (internal::band_solve_triangular_selector<int,Upper|0, Scalar,false,Scalar,ColMajor>::run);+ func[TR | (UP << 2) | (NUNIT << 3)] = (internal::band_solve_triangular_selector<int,Lower|0, Scalar,false,Scalar,RowMajor>::run);+ func[ADJ | (UP << 2) | (NUNIT << 3)] = (internal::band_solve_triangular_selector<int,Lower|0, Scalar,Conj, Scalar,RowMajor>::run);++ func[NOTR | (LO << 2) | (NUNIT << 3)] = (internal::band_solve_triangular_selector<int,Lower|0, Scalar,false,Scalar,ColMajor>::run);+ func[TR | (LO << 2) | (NUNIT << 3)] = (internal::band_solve_triangular_selector<int,Upper|0, Scalar,false,Scalar,RowMajor>::run);+ func[ADJ | (LO << 2) | (NUNIT << 3)] = (internal::band_solve_triangular_selector<int,Upper|0, Scalar,Conj, Scalar,RowMajor>::run);++ func[NOTR | (UP << 2) | (UNIT << 3)] = (internal::band_solve_triangular_selector<int,Upper|UnitDiag,Scalar,false,Scalar,ColMajor>::run);+ func[TR | (UP << 2) | (UNIT << 3)] = (internal::band_solve_triangular_selector<int,Lower|UnitDiag,Scalar,false,Scalar,RowMajor>::run);+ func[ADJ | (UP << 2) | (UNIT << 3)] = (internal::band_solve_triangular_selector<int,Lower|UnitDiag,Scalar,Conj, Scalar,RowMajor>::run);++ func[NOTR | (LO << 2) | (UNIT << 3)] = (internal::band_solve_triangular_selector<int,Lower|UnitDiag,Scalar,false,Scalar,ColMajor>::run);+ func[TR | (LO << 2) | (UNIT << 3)] = (internal::band_solve_triangular_selector<int,Upper|UnitDiag,Scalar,false,Scalar,RowMajor>::run);+ func[ADJ | (LO << 2) | (UNIT << 3)] = (internal::band_solve_triangular_selector<int,Upper|UnitDiag,Scalar,Conj, Scalar,RowMajor>::run);++ init = true;+ }++ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* x = reinterpret_cast<Scalar*>(px);+ int coeff_rows = *k+1;+ + int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(OP(*op)==INVALID) info = 2;+ else if(DIAG(*diag)==INVALID) info = 3;+ else if(*n<0) info = 4;+ else if(*k<0) info = 5;+ else if(*lda<coeff_rows) info = 7;+ else if(*incx==0) info = 9;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"TBSV ",&info,6);+ + if(*n==0 || (*k==0 && DIAG(*diag)==UNIT))+ return 0;+ + int actual_n = *n;+ + Scalar* actual_x = get_compact_vector(x,actual_n,*incx);+ + int code = OP(*op) | (UPLO(*uplo) << 2) | (DIAG(*diag) << 3);+ if(code>=16 || func[code]==0)+ return 0;++ func[code](*n, *k, a, *lda, actual_x);+ + if(actual_x!=x) delete[] copy_back(actual_x,x,actual_n,*incx);+ + return 0;+}++/** DTPMV performs one of the matrix-vector operations+ *+ * x := A*x, or x := A'*x,+ *+ * where x is an n element vector and A is an n by n unit, or non-unit,+ * upper or lower triangular matrix, supplied in packed form.+ */+int EIGEN_BLAS_FUNC(tpmv)(char *uplo, char *opa, char *diag, int *n, RealScalar *pap, RealScalar *px, int *incx)+{+ typedef void (*functype)(int, const Scalar*, const Scalar*, Scalar*, Scalar);+ static functype func[16];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<16; ++k)+ func[k] = 0;++ func[NOTR | (UP << 2) | (NUNIT << 3)] = (internal::packed_triangular_matrix_vector_product<int,Upper|0, Scalar,false,Scalar,false,ColMajor>::run);+ func[TR | (UP << 2) | (NUNIT << 3)] = (internal::packed_triangular_matrix_vector_product<int,Lower|0, Scalar,false,Scalar,false,RowMajor>::run);+ func[ADJ | (UP << 2) | (NUNIT << 3)] = (internal::packed_triangular_matrix_vector_product<int,Lower|0, Scalar,Conj, Scalar,false,RowMajor>::run);++ func[NOTR | (LO << 2) | (NUNIT << 3)] = (internal::packed_triangular_matrix_vector_product<int,Lower|0, Scalar,false,Scalar,false,ColMajor>::run);+ func[TR | (LO << 2) | (NUNIT << 3)] = (internal::packed_triangular_matrix_vector_product<int,Upper|0, Scalar,false,Scalar,false,RowMajor>::run);+ func[ADJ | (LO << 2) | (NUNIT << 3)] = (internal::packed_triangular_matrix_vector_product<int,Upper|0, Scalar,Conj, Scalar,false,RowMajor>::run);++ func[NOTR | (UP << 2) | (UNIT << 3)] = (internal::packed_triangular_matrix_vector_product<int,Upper|UnitDiag,Scalar,false,Scalar,false,ColMajor>::run);+ func[TR | (UP << 2) | (UNIT << 3)] = (internal::packed_triangular_matrix_vector_product<int,Lower|UnitDiag,Scalar,false,Scalar,false,RowMajor>::run);+ func[ADJ | (UP << 2) | (UNIT << 3)] = (internal::packed_triangular_matrix_vector_product<int,Lower|UnitDiag,Scalar,Conj, Scalar,false,RowMajor>::run);++ func[NOTR | (LO << 2) | (UNIT << 3)] = (internal::packed_triangular_matrix_vector_product<int,Lower|UnitDiag,Scalar,false,Scalar,false,ColMajor>::run);+ func[TR | (LO << 2) | (UNIT << 3)] = (internal::packed_triangular_matrix_vector_product<int,Upper|UnitDiag,Scalar,false,Scalar,false,RowMajor>::run);+ func[ADJ | (LO << 2) | (UNIT << 3)] = (internal::packed_triangular_matrix_vector_product<int,Upper|UnitDiag,Scalar,Conj, Scalar,false,RowMajor>::run);++ init = true;+ }++ Scalar* ap = reinterpret_cast<Scalar*>(pap);+ Scalar* x = reinterpret_cast<Scalar*>(px);++ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(OP(*opa)==INVALID) info = 2;+ else if(DIAG(*diag)==INVALID) info = 3;+ else if(*n<0) info = 4;+ else if(*incx==0) info = 7;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"TPMV ",&info,6);++ if(*n==0)+ return 1;++ Scalar* actual_x = get_compact_vector(x,*n,*incx);+ Matrix<Scalar,Dynamic,1> res(*n);+ res.setZero();++ int code = OP(*opa) | (UPLO(*uplo) << 2) | (DIAG(*diag) << 3);+ if(code>=16 || func[code]==0)+ return 0;++ func[code](*n, ap, actual_x, res.data(), Scalar(1));++ copy_back(res.data(),x,*n,*incx);+ if(actual_x!=x) delete[] actual_x;++ return 1;+}++/** DTPSV solves one of the systems of equations+ *+ * A*x = b, or A'*x = b,+ *+ * where b and x are n element vectors and A is an n by n unit, or+ * non-unit, upper or lower triangular matrix, supplied in packed form.+ *+ * No test for singularity or near-singularity is included in this+ * routine. Such tests must be performed before calling this routine.+ */+int EIGEN_BLAS_FUNC(tpsv)(char *uplo, char *opa, char *diag, int *n, RealScalar *pap, RealScalar *px, int *incx)+{+ typedef void (*functype)(int, const Scalar*, Scalar*);+ static functype func[16];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<16; ++k)+ func[k] = 0;++ func[NOTR | (UP << 2) | (NUNIT << 3)] = (internal::packed_triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Upper|0, false,ColMajor>::run);+ func[TR | (UP << 2) | (NUNIT << 3)] = (internal::packed_triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Lower|0, false,RowMajor>::run);+ func[ADJ | (UP << 2) | (NUNIT << 3)] = (internal::packed_triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Lower|0, Conj, RowMajor>::run);++ func[NOTR | (LO << 2) | (NUNIT << 3)] = (internal::packed_triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Lower|0, false,ColMajor>::run);+ func[TR | (LO << 2) | (NUNIT << 3)] = (internal::packed_triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Upper|0, false,RowMajor>::run);+ func[ADJ | (LO << 2) | (NUNIT << 3)] = (internal::packed_triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Upper|0, Conj, RowMajor>::run);++ func[NOTR | (UP << 2) | (UNIT << 3)] = (internal::packed_triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Upper|UnitDiag,false,ColMajor>::run);+ func[TR | (UP << 2) | (UNIT << 3)] = (internal::packed_triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Lower|UnitDiag,false,RowMajor>::run);+ func[ADJ | (UP << 2) | (UNIT << 3)] = (internal::packed_triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Lower|UnitDiag,Conj, RowMajor>::run);++ func[NOTR | (LO << 2) | (UNIT << 3)] = (internal::packed_triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Lower|UnitDiag,false,ColMajor>::run);+ func[TR | (LO << 2) | (UNIT << 3)] = (internal::packed_triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Upper|UnitDiag,false,RowMajor>::run);+ func[ADJ | (LO << 2) | (UNIT << 3)] = (internal::packed_triangular_solve_vector<Scalar,Scalar,int,OnTheLeft, Upper|UnitDiag,Conj, RowMajor>::run);++ init = true;+ }++ Scalar* ap = reinterpret_cast<Scalar*>(pap);+ Scalar* x = reinterpret_cast<Scalar*>(px);++ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(OP(*opa)==INVALID) info = 2;+ else if(DIAG(*diag)==INVALID) info = 3;+ else if(*n<0) info = 4;+ else if(*incx==0) info = 7;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"TPSV ",&info,6);++ Scalar* actual_x = get_compact_vector(x,*n,*incx);++ int code = OP(*opa) | (UPLO(*uplo) << 2) | (DIAG(*diag) << 3);+ func[code](*n, ap, actual_x);++ if(actual_x!=x) delete[] copy_back(actual_x,x,*n,*incx);++ return 1;+}+
+ eigen3/blas/level2_real_impl.h view
@@ -0,0 +1,370 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "common.h"++// y = alpha*A*x + beta*y+int EIGEN_BLAS_FUNC(symv) (char *uplo, int *n, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *px, int *incx, RealScalar *pbeta, RealScalar *py, int *incy)+{+ typedef void (*functype)(int, const Scalar*, int, const Scalar*, int, Scalar*, Scalar);+ static functype func[2];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<2; ++k)+ func[k] = 0;++ func[UP] = (internal::selfadjoint_matrix_vector_product<Scalar,int,ColMajor,Upper,false,false>::run);+ func[LO] = (internal::selfadjoint_matrix_vector_product<Scalar,int,ColMajor,Lower,false,false>::run);++ init = true;+ }++ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);+ Scalar beta = *reinterpret_cast<Scalar*>(pbeta);++ // check arguments+ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(*n<0) info = 2;+ else if(*lda<std::max(1,*n)) info = 5;+ else if(*incx==0) info = 7;+ else if(*incy==0) info = 10;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"SYMV ",&info,6);++ if(*n==0)+ return 0;++ Scalar* actual_x = get_compact_vector(x,*n,*incx);+ Scalar* actual_y = get_compact_vector(y,*n,*incy);++ if(beta!=Scalar(1))+ {+ if(beta==Scalar(0)) vector(actual_y, *n).setZero();+ else vector(actual_y, *n) *= beta;+ }++ int code = UPLO(*uplo);+ if(code>=2 || func[code]==0)+ return 0;++ func[code](*n, a, *lda, actual_x, 1, actual_y, alpha);++ if(actual_x!=x) delete[] actual_x;+ if(actual_y!=y) delete[] copy_back(actual_y,y,*n,*incy);++ return 1;+}++// C := alpha*x*x' + C+int EIGEN_BLAS_FUNC(syr)(char *uplo, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *pc, int *ldc)+{++// typedef void (*functype)(int, const Scalar *, int, Scalar *, int, Scalar);+// static functype func[2];++// static bool init = false;+// if(!init)+// {+// for(int k=0; k<2; ++k)+// func[k] = 0;+//+// func[UP] = (internal::selfadjoint_product<Scalar,ColMajor,ColMajor,false,UpperTriangular>::run);+// func[LO] = (internal::selfadjoint_product<Scalar,ColMajor,ColMajor,false,LowerTriangular>::run);++// init = true;+// }+ typedef void (*functype)(int, Scalar*, int, const Scalar*, const Scalar*, const Scalar&);+ static functype func[2];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<2; ++k)+ func[k] = 0;++ func[UP] = (selfadjoint_rank1_update<Scalar,int,ColMajor,Upper,false,Conj>::run);+ func[LO] = (selfadjoint_rank1_update<Scalar,int,ColMajor,Lower,false,Conj>::run);++ init = true;+ }++ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* c = reinterpret_cast<Scalar*>(pc);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);++ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(*n<0) info = 2;+ else if(*incx==0) info = 5;+ else if(*ldc<std::max(1,*n)) info = 7;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"SYR ",&info,6);++ if(*n==0 || alpha==Scalar(0)) return 1;++ // if the increment is not 1, let's copy it to a temporary vector to enable vectorization+ Scalar* x_cpy = get_compact_vector(x,*n,*incx);++ int code = UPLO(*uplo);+ if(code>=2 || func[code]==0)+ return 0;++ func[code](*n, c, *ldc, x_cpy, x_cpy, alpha);++ if(x_cpy!=x) delete[] x_cpy;++ return 1;+}++// C := alpha*x*y' + alpha*y*x' + C+int EIGEN_BLAS_FUNC(syr2)(char *uplo, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *pc, int *ldc)+{+// typedef void (*functype)(int, const Scalar *, int, const Scalar *, int, Scalar *, int, Scalar);+// static functype func[2];+//+// static bool init = false;+// if(!init)+// {+// for(int k=0; k<2; ++k)+// func[k] = 0;+//+// func[UP] = (internal::selfadjoint_product<Scalar,ColMajor,ColMajor,false,UpperTriangular>::run);+// func[LO] = (internal::selfadjoint_product<Scalar,ColMajor,ColMajor,false,LowerTriangular>::run);+//+// init = true;+// }+ typedef void (*functype)(int, Scalar*, int, const Scalar*, const Scalar*, Scalar);+ static functype func[2];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<2; ++k)+ func[k] = 0;++ func[UP] = (internal::rank2_update_selector<Scalar,int,Upper>::run);+ func[LO] = (internal::rank2_update_selector<Scalar,int,Lower>::run);++ init = true;+ }++ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);+ Scalar* c = reinterpret_cast<Scalar*>(pc);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);++ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(*n<0) info = 2;+ else if(*incx==0) info = 5;+ else if(*incy==0) info = 7;+ else if(*ldc<std::max(1,*n)) info = 9;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"SYR2 ",&info,6);++ if(alpha==Scalar(0))+ return 1;++ Scalar* x_cpy = get_compact_vector(x,*n,*incx);+ Scalar* y_cpy = get_compact_vector(y,*n,*incy);+ + int code = UPLO(*uplo);+ if(code>=2 || func[code]==0)+ return 0;++ func[code](*n, c, *ldc, x_cpy, y_cpy, alpha);++ if(x_cpy!=x) delete[] x_cpy;+ if(y_cpy!=y) delete[] y_cpy;++// int code = UPLO(*uplo);+// if(code>=2 || func[code]==0)+// return 0;++// func[code](*n, a, *inca, b, *incb, c, *ldc, alpha);+ return 1;+}++/** DSBMV performs the matrix-vector operation+ *+ * y := alpha*A*x + beta*y,+ *+ * where alpha and beta are scalars, x and y are n element vectors and+ * A is an n by n symmetric band matrix, with k super-diagonals.+ */+// int EIGEN_BLAS_FUNC(sbmv)( char *uplo, int *n, int *k, RealScalar *alpha, RealScalar *a, int *lda,+// RealScalar *x, int *incx, RealScalar *beta, RealScalar *y, int *incy)+// {+// return 1;+// }+++/** DSPMV performs the matrix-vector operation+ *+ * y := alpha*A*x + beta*y,+ *+ * where alpha and beta are scalars, x and y are n element vectors and+ * A is an n by n symmetric matrix, supplied in packed form.+ *+ */+// int EIGEN_BLAS_FUNC(spmv)(char *uplo, int *n, RealScalar *alpha, RealScalar *ap, RealScalar *x, int *incx, RealScalar *beta, RealScalar *y, int *incy)+// {+// return 1;+// }++/** DSPR performs the symmetric rank 1 operation+ *+ * A := alpha*x*x' + A,+ *+ * where alpha is a real scalar, x is an n element vector and A is an+ * n by n symmetric matrix, supplied in packed form.+ */+int EIGEN_BLAS_FUNC(spr)(char *uplo, int *n, Scalar *palpha, Scalar *px, int *incx, Scalar *pap)+{+ typedef void (*functype)(int, Scalar*, const Scalar*, Scalar);+ static functype func[2];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<2; ++k)+ func[k] = 0;++ func[UP] = (internal::selfadjoint_packed_rank1_update<Scalar,int,ColMajor,Upper,false,false>::run);+ func[LO] = (internal::selfadjoint_packed_rank1_update<Scalar,int,ColMajor,Lower,false,false>::run);++ init = true;+ }++ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* ap = reinterpret_cast<Scalar*>(pap);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);++ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(*n<0) info = 2;+ else if(*incx==0) info = 5;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"SPR ",&info,6);++ if(alpha==Scalar(0))+ return 1;++ Scalar* x_cpy = get_compact_vector(x, *n, *incx);++ int code = UPLO(*uplo);+ if(code>=2 || func[code]==0)+ return 0;++ func[code](*n, ap, x_cpy, alpha);++ if(x_cpy!=x) delete[] x_cpy;++ return 1;+}++/** DSPR2 performs the symmetric rank 2 operation+ *+ * A := alpha*x*y' + alpha*y*x' + A,+ *+ * where alpha is a scalar, x and y are n element vectors and A is an+ * n by n symmetric matrix, supplied in packed form.+ */+int EIGEN_BLAS_FUNC(spr2)(char *uplo, int *n, RealScalar *palpha, RealScalar *px, int *incx, RealScalar *py, int *incy, RealScalar *pap)+{+ typedef void (*functype)(int, Scalar*, const Scalar*, const Scalar*, Scalar);+ static functype func[2];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<2; ++k)+ func[k] = 0;++ func[UP] = (internal::packed_rank2_update_selector<Scalar,int,Upper>::run);+ func[LO] = (internal::packed_rank2_update_selector<Scalar,int,Lower>::run);++ init = true;+ }++ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);+ Scalar* ap = reinterpret_cast<Scalar*>(pap);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);++ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(*n<0) info = 2;+ else if(*incx==0) info = 5;+ else if(*incy==0) info = 7;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"SPR2 ",&info,6);++ if(alpha==Scalar(0))+ return 1;++ Scalar* x_cpy = get_compact_vector(x, *n, *incx);+ Scalar* y_cpy = get_compact_vector(y, *n, *incy);++ int code = UPLO(*uplo);+ if(code>=2 || func[code]==0)+ return 0;++ func[code](*n, ap, x_cpy, y_cpy, alpha);++ if(x_cpy!=x) delete[] x_cpy;+ if(y_cpy!=y) delete[] y_cpy;++ return 1;+}++/** DGER performs the rank 1 operation+ *+ * A := alpha*x*y' + A,+ *+ * where alpha is a scalar, x is an m element vector, y is an n element+ * vector and A is an m by n matrix.+ */+int EIGEN_BLAS_FUNC(ger)(int *m, int *n, Scalar *palpha, Scalar *px, int *incx, Scalar *py, int *incy, Scalar *pa, int *lda)+{+ Scalar* x = reinterpret_cast<Scalar*>(px);+ Scalar* y = reinterpret_cast<Scalar*>(py);+ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);++ int info = 0;+ if(*m<0) info = 1;+ else if(*n<0) info = 2;+ else if(*incx==0) info = 5;+ else if(*incy==0) info = 7;+ else if(*lda<std::max(1,*m)) info = 9;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"GER ",&info,6);++ if(alpha==Scalar(0))+ return 1;++ Scalar* x_cpy = get_compact_vector(x,*m,*incx);+ Scalar* y_cpy = get_compact_vector(y,*n,*incy);++ internal::general_rank1_update<Scalar,int,ColMajor,false,false>::run(*m, *n, a, *lda, x_cpy, y_cpy, alpha);++ if(x_cpy!=x) delete[] x_cpy;+ if(y_cpy!=y) delete[] y_cpy;++ return 1;+}++
+ eigen3/blas/level3_impl.h view
@@ -0,0 +1,634 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "common.h"++int EIGEN_BLAS_FUNC(gemm)(char *opa, char *opb, int *m, int *n, int *k, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pb, int *ldb, RealScalar *pbeta, RealScalar *pc, int *ldc)+{+// std::cerr << "in gemm " << *opa << " " << *opb << " " << *m << " " << *n << " " << *k << " " << *lda << " " << *ldb << " " << *ldc << " " << *palpha << " " << *pbeta << "\n";+ typedef void (*functype)(DenseIndex, DenseIndex, DenseIndex, const Scalar *, DenseIndex, const Scalar *, DenseIndex, Scalar *, DenseIndex, Scalar, internal::level3_blocking<Scalar,Scalar>&, Eigen::internal::GemmParallelInfo<DenseIndex>*);+ static functype func[12];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<12; ++k)+ func[k] = 0;+ func[NOTR | (NOTR << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,ColMajor,false,Scalar,ColMajor,false,ColMajor>::run);+ func[TR | (NOTR << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,RowMajor,false,Scalar,ColMajor,false,ColMajor>::run);+ func[ADJ | (NOTR << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,RowMajor,Conj, Scalar,ColMajor,false,ColMajor>::run);+ func[NOTR | (TR << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,ColMajor,false,Scalar,RowMajor,false,ColMajor>::run);+ func[TR | (TR << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,RowMajor,false,Scalar,RowMajor,false,ColMajor>::run);+ func[ADJ | (TR << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,RowMajor,Conj, Scalar,RowMajor,false,ColMajor>::run);+ func[NOTR | (ADJ << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,ColMajor,false,Scalar,RowMajor,Conj, ColMajor>::run);+ func[TR | (ADJ << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,RowMajor,false,Scalar,RowMajor,Conj, ColMajor>::run);+ func[ADJ | (ADJ << 2)] = (internal::general_matrix_matrix_product<DenseIndex,Scalar,RowMajor,Conj, Scalar,RowMajor,Conj, ColMajor>::run);+ init = true;+ }++ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* b = reinterpret_cast<Scalar*>(pb);+ Scalar* c = reinterpret_cast<Scalar*>(pc);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);+ Scalar beta = *reinterpret_cast<Scalar*>(pbeta);++ int info = 0;+ if(OP(*opa)==INVALID) info = 1;+ else if(OP(*opb)==INVALID) info = 2;+ else if(*m<0) info = 3;+ else if(*n<0) info = 4;+ else if(*k<0) info = 5;+ else if(*lda<std::max(1,(OP(*opa)==NOTR)?*m:*k)) info = 8;+ else if(*ldb<std::max(1,(OP(*opb)==NOTR)?*k:*n)) info = 10;+ else if(*ldc<std::max(1,*m)) info = 13;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"GEMM ",&info,6);++ if(beta!=Scalar(1))+ {+ if(beta==Scalar(0)) matrix(c, *m, *n, *ldc).setZero();+ else matrix(c, *m, *n, *ldc) *= beta;+ }++ internal::gemm_blocking_space<ColMajor,Scalar,Scalar,Dynamic,Dynamic,Dynamic> blocking(*m,*n,*k);++ int code = OP(*opa) | (OP(*opb) << 2);+ func[code](*m, *n, *k, a, *lda, b, *ldb, c, *ldc, alpha, blocking, 0);+ return 0;+}++int EIGEN_BLAS_FUNC(trsm)(char *side, char *uplo, char *opa, char *diag, int *m, int *n, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pb, int *ldb)+{+// std::cerr << "in trsm " << *side << " " << *uplo << " " << *opa << " " << *diag << " " << *m << "," << *n << " " << *palpha << " " << *lda << " " << *ldb<< "\n";+ typedef void (*functype)(DenseIndex, DenseIndex, const Scalar *, DenseIndex, Scalar *, DenseIndex, internal::level3_blocking<Scalar,Scalar>&);+ static functype func[32];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<32; ++k)+ func[k] = 0;++ func[NOTR | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|0, false,ColMajor,ColMajor>::run);+ func[TR | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|0, false,RowMajor,ColMajor>::run);+ func[ADJ | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|0, Conj, RowMajor,ColMajor>::run);++ func[NOTR | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|0, false,ColMajor,ColMajor>::run);+ func[TR | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|0, false,RowMajor,ColMajor>::run);+ func[ADJ | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|0, Conj, RowMajor,ColMajor>::run);++ func[NOTR | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|0, false,ColMajor,ColMajor>::run);+ func[TR | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|0, false,RowMajor,ColMajor>::run);+ func[ADJ | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|0, Conj, RowMajor,ColMajor>::run);++ func[NOTR | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|0, false,ColMajor,ColMajor>::run);+ func[TR | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|0, false,RowMajor,ColMajor>::run);+ func[ADJ | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|0, Conj, RowMajor,ColMajor>::run);+++ func[NOTR | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|UnitDiag,false,ColMajor,ColMajor>::run);+ func[TR | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|UnitDiag,false,RowMajor,ColMajor>::run);+ func[ADJ | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|UnitDiag,Conj, RowMajor,ColMajor>::run);++ func[NOTR | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|UnitDiag,false,ColMajor,ColMajor>::run);+ func[TR | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|UnitDiag,false,RowMajor,ColMajor>::run);+ func[ADJ | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|UnitDiag,Conj, RowMajor,ColMajor>::run);++ func[NOTR | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Lower|UnitDiag,false,ColMajor,ColMajor>::run);+ func[TR | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|UnitDiag,false,RowMajor,ColMajor>::run);+ func[ADJ | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheLeft, Upper|UnitDiag,Conj, RowMajor,ColMajor>::run);++ func[NOTR | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Lower|UnitDiag,false,ColMajor,ColMajor>::run);+ func[TR | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|UnitDiag,false,RowMajor,ColMajor>::run);+ func[ADJ | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (internal::triangular_solve_matrix<Scalar,DenseIndex,OnTheRight,Upper|UnitDiag,Conj, RowMajor,ColMajor>::run);++ init = true;+ }++ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* b = reinterpret_cast<Scalar*>(pb);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);++ int info = 0;+ if(SIDE(*side)==INVALID) info = 1;+ else if(UPLO(*uplo)==INVALID) info = 2;+ else if(OP(*opa)==INVALID) info = 3;+ else if(DIAG(*diag)==INVALID) info = 4;+ else if(*m<0) info = 5;+ else if(*n<0) info = 6;+ else if(*lda<std::max(1,(SIDE(*side)==LEFT)?*m:*n)) info = 9;+ else if(*ldb<std::max(1,*m)) info = 11;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"TRSM ",&info,6);++ int code = OP(*opa) | (SIDE(*side) << 2) | (UPLO(*uplo) << 3) | (DIAG(*diag) << 4);+ + if(SIDE(*side)==LEFT)+ {+ internal::gemm_blocking_space<ColMajor,Scalar,Scalar,Dynamic,Dynamic,Dynamic,4> blocking(*m,*n,*m);+ func[code](*m, *n, a, *lda, b, *ldb, blocking);+ }+ else+ {+ internal::gemm_blocking_space<ColMajor,Scalar,Scalar,Dynamic,Dynamic,Dynamic,4> blocking(*m,*n,*n);+ func[code](*n, *m, a, *lda, b, *ldb, blocking);+ }++ if(alpha!=Scalar(1))+ matrix(b,*m,*n,*ldb) *= alpha;++ return 0;+}+++// b = alpha*op(a)*b for side = 'L'or'l'+// b = alpha*b*op(a) for side = 'R'or'r'+int EIGEN_BLAS_FUNC(trmm)(char *side, char *uplo, char *opa, char *diag, int *m, int *n, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pb, int *ldb)+{+// std::cerr << "in trmm " << *side << " " << *uplo << " " << *opa << " " << *diag << " " << *m << " " << *n << " " << *lda << " " << *ldb << " " << *palpha << "\n";+ typedef void (*functype)(DenseIndex, DenseIndex, DenseIndex, const Scalar *, DenseIndex, const Scalar *, DenseIndex, Scalar *, DenseIndex, const Scalar&, internal::level3_blocking<Scalar,Scalar>&);+ static functype func[32];+ static bool init = false;+ if(!init)+ {+ for(int k=0; k<32; ++k)+ func[k] = 0;++ func[NOTR | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0, true, ColMajor,false,ColMajor,false,ColMajor>::run);+ func[TR | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0, true, RowMajor,false,ColMajor,false,ColMajor>::run);+ func[ADJ | (LEFT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0, true, RowMajor,Conj, ColMajor,false,ColMajor>::run);++ func[NOTR | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0, false,ColMajor,false,ColMajor,false,ColMajor>::run);+ func[TR | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0, false,ColMajor,false,RowMajor,false,ColMajor>::run);+ func[ADJ | (RIGHT << 2) | (UP << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0, false,ColMajor,false,RowMajor,Conj, ColMajor>::run);++ func[NOTR | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0, true, ColMajor,false,ColMajor,false,ColMajor>::run);+ func[TR | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0, true, RowMajor,false,ColMajor,false,ColMajor>::run);+ func[ADJ | (LEFT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0, true, RowMajor,Conj, ColMajor,false,ColMajor>::run);++ func[NOTR | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|0, false,ColMajor,false,ColMajor,false,ColMajor>::run);+ func[TR | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0, false,ColMajor,false,RowMajor,false,ColMajor>::run);+ func[ADJ | (RIGHT << 2) | (LO << 3) | (NUNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|0, false,ColMajor,false,RowMajor,Conj, ColMajor>::run);++ func[NOTR | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,true, ColMajor,false,ColMajor,false,ColMajor>::run);+ func[TR | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,true, RowMajor,false,ColMajor,false,ColMajor>::run);+ func[ADJ | (LEFT << 2) | (UP << 3) | (UNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,true, RowMajor,Conj, ColMajor,false,ColMajor>::run);++ func[NOTR | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,false,ColMajor,false,ColMajor,false,ColMajor>::run);+ func[TR | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,false,ColMajor,false,RowMajor,false,ColMajor>::run);+ func[ADJ | (RIGHT << 2) | (UP << 3) | (UNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,false,ColMajor,false,RowMajor,Conj, ColMajor>::run);++ func[NOTR | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,true, ColMajor,false,ColMajor,false,ColMajor>::run);+ func[TR | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,true, RowMajor,false,ColMajor,false,ColMajor>::run);+ func[ADJ | (LEFT << 2) | (LO << 3) | (UNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,true, RowMajor,Conj, ColMajor,false,ColMajor>::run);++ func[NOTR | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Lower|UnitDiag,false,ColMajor,false,ColMajor,false,ColMajor>::run);+ func[TR | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,false,ColMajor,false,RowMajor,false,ColMajor>::run);+ func[ADJ | (RIGHT << 2) | (LO << 3) | (UNIT << 4)] = (internal::product_triangular_matrix_matrix<Scalar,DenseIndex,Upper|UnitDiag,false,ColMajor,false,RowMajor,Conj, ColMajor>::run);++ init = true;+ }++ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* b = reinterpret_cast<Scalar*>(pb);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);++ int info = 0;+ if(SIDE(*side)==INVALID) info = 1;+ else if(UPLO(*uplo)==INVALID) info = 2;+ else if(OP(*opa)==INVALID) info = 3;+ else if(DIAG(*diag)==INVALID) info = 4;+ else if(*m<0) info = 5;+ else if(*n<0) info = 6;+ else if(*lda<std::max(1,(SIDE(*side)==LEFT)?*m:*n)) info = 9;+ else if(*ldb<std::max(1,*m)) info = 11;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"TRMM ",&info,6);++ int code = OP(*opa) | (SIDE(*side) << 2) | (UPLO(*uplo) << 3) | (DIAG(*diag) << 4);++ if(*m==0 || *n==0)+ return 1;++ // FIXME find a way to avoid this copy+ Matrix<Scalar,Dynamic,Dynamic,ColMajor> tmp = matrix(b,*m,*n,*ldb);+ matrix(b,*m,*n,*ldb).setZero();++ if(SIDE(*side)==LEFT)+ {+ internal::gemm_blocking_space<ColMajor,Scalar,Scalar,Dynamic,Dynamic,Dynamic,4> blocking(*m,*n,*m);+ func[code](*m, *n, *m, a, *lda, tmp.data(), tmp.outerStride(), b, *ldb, alpha, blocking);+ }+ else+ {+ internal::gemm_blocking_space<ColMajor,Scalar,Scalar,Dynamic,Dynamic,Dynamic,4> blocking(*m,*n,*n);+ func[code](*m, *n, *n, tmp.data(), tmp.outerStride(), a, *lda, b, *ldb, alpha, blocking);+ }+ return 1;+}++// c = alpha*a*b + beta*c for side = 'L'or'l'+// c = alpha*b*a + beta*c for side = 'R'or'r+int EIGEN_BLAS_FUNC(symm)(char *side, char *uplo, int *m, int *n, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pb, int *ldb, RealScalar *pbeta, RealScalar *pc, int *ldc)+{+// std::cerr << "in symm " << *side << " " << *uplo << " " << *m << "x" << *n << " lda:" << *lda << " ldb:" << *ldb << " ldc:" << *ldc << " alpha:" << *palpha << " beta:" << *pbeta << "\n";+ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* b = reinterpret_cast<Scalar*>(pb);+ Scalar* c = reinterpret_cast<Scalar*>(pc);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);+ Scalar beta = *reinterpret_cast<Scalar*>(pbeta);++ int info = 0;+ if(SIDE(*side)==INVALID) info = 1;+ else if(UPLO(*uplo)==INVALID) info = 2;+ else if(*m<0) info = 3;+ else if(*n<0) info = 4;+ else if(*lda<std::max(1,(SIDE(*side)==LEFT)?*m:*n)) info = 7;+ else if(*ldb<std::max(1,*m)) info = 9;+ else if(*ldc<std::max(1,*m)) info = 12;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"SYMM ",&info,6);++ if(beta!=Scalar(1))+ {+ if(beta==Scalar(0)) matrix(c, *m, *n, *ldc).setZero();+ else matrix(c, *m, *n, *ldc) *= beta;+ }++ if(*m==0 || *n==0)+ {+ return 1;+ }++ #if ISCOMPLEX+ // FIXME add support for symmetric complex matrix+ int size = (SIDE(*side)==LEFT) ? (*m) : (*n);+ Matrix<Scalar,Dynamic,Dynamic,ColMajor> matA(size,size);+ if(UPLO(*uplo)==UP)+ {+ matA.triangularView<Upper>() = matrix(a,size,size,*lda);+ matA.triangularView<Lower>() = matrix(a,size,size,*lda).transpose();+ }+ else if(UPLO(*uplo)==LO)+ {+ matA.triangularView<Lower>() = matrix(a,size,size,*lda);+ matA.triangularView<Upper>() = matrix(a,size,size,*lda).transpose();+ }+ if(SIDE(*side)==LEFT)+ matrix(c, *m, *n, *ldc) += alpha * matA * matrix(b, *m, *n, *ldb);+ else if(SIDE(*side)==RIGHT)+ matrix(c, *m, *n, *ldc) += alpha * matrix(b, *m, *n, *ldb) * matA;+ #else+ if(SIDE(*side)==LEFT)+ if(UPLO(*uplo)==UP) internal::product_selfadjoint_matrix<Scalar, DenseIndex, RowMajor,true,false, ColMajor,false,false, ColMajor>::run(*m, *n, a, *lda, b, *ldb, c, *ldc, alpha);+ else if(UPLO(*uplo)==LO) internal::product_selfadjoint_matrix<Scalar, DenseIndex, ColMajor,true,false, ColMajor,false,false, ColMajor>::run(*m, *n, a, *lda, b, *ldb, c, *ldc, alpha);+ else return 0;+ else if(SIDE(*side)==RIGHT)+ if(UPLO(*uplo)==UP) internal::product_selfadjoint_matrix<Scalar, DenseIndex, ColMajor,false,false, RowMajor,true,false, ColMajor>::run(*m, *n, b, *ldb, a, *lda, c, *ldc, alpha);+ else if(UPLO(*uplo)==LO) internal::product_selfadjoint_matrix<Scalar, DenseIndex, ColMajor,false,false, ColMajor,true,false, ColMajor>::run(*m, *n, b, *ldb, a, *lda, c, *ldc, alpha);+ else return 0;+ else+ return 0;+ #endif++ return 0;+}++// c = alpha*a*a' + beta*c for op = 'N'or'n'+// c = alpha*a'*a + beta*c for op = 'T'or't','C'or'c'+int EIGEN_BLAS_FUNC(syrk)(char *uplo, char *op, int *n, int *k, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pbeta, RealScalar *pc, int *ldc)+{+// std::cerr << "in syrk " << *uplo << " " << *op << " " << *n << " " << *k << " " << *palpha << " " << *lda << " " << *pbeta << " " << *ldc << "\n";+ #if !ISCOMPLEX+ typedef void (*functype)(DenseIndex, DenseIndex, const Scalar *, DenseIndex, const Scalar *, DenseIndex, Scalar *, DenseIndex, const Scalar&);+ static functype func[8];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<8; ++k)+ func[k] = 0;++ func[NOTR | (UP << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,ColMajor,false,Scalar,RowMajor,ColMajor,Conj, Upper>::run);+ func[TR | (UP << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,RowMajor,false,Scalar,ColMajor,ColMajor,Conj, Upper>::run);+ func[ADJ | (UP << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,RowMajor,Conj, Scalar,ColMajor,ColMajor,false,Upper>::run);++ func[NOTR | (LO << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,ColMajor,false,Scalar,RowMajor,ColMajor,Conj, Lower>::run);+ func[TR | (LO << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,RowMajor,false,Scalar,ColMajor,ColMajor,Conj, Lower>::run);+ func[ADJ | (LO << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,RowMajor,Conj, Scalar,ColMajor,ColMajor,false,Lower>::run);++ init = true;+ }+ #endif++ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* c = reinterpret_cast<Scalar*>(pc);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);+ Scalar beta = *reinterpret_cast<Scalar*>(pbeta);++ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(OP(*op)==INVALID) info = 2;+ else if(*n<0) info = 3;+ else if(*k<0) info = 4;+ else if(*lda<std::max(1,(OP(*op)==NOTR)?*n:*k)) info = 7;+ else if(*ldc<std::max(1,*n)) info = 10;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"SYRK ",&info,6);++ if(beta!=Scalar(1))+ {+ if(UPLO(*uplo)==UP)+ if(beta==Scalar(0)) matrix(c, *n, *n, *ldc).triangularView<Upper>().setZero();+ else matrix(c, *n, *n, *ldc).triangularView<Upper>() *= beta;+ else+ if(beta==Scalar(0)) matrix(c, *n, *n, *ldc).triangularView<Lower>().setZero();+ else matrix(c, *n, *n, *ldc).triangularView<Lower>() *= beta;+ }++ #if ISCOMPLEX+ // FIXME add support for symmetric complex matrix+ if(UPLO(*uplo)==UP)+ {+ if(OP(*op)==NOTR)+ matrix(c, *n, *n, *ldc).triangularView<Upper>() += alpha * matrix(a,*n,*k,*lda) * matrix(a,*n,*k,*lda).transpose();+ else+ matrix(c, *n, *n, *ldc).triangularView<Upper>() += alpha * matrix(a,*k,*n,*lda).transpose() * matrix(a,*k,*n,*lda);+ }+ else+ {+ if(OP(*op)==NOTR)+ matrix(c, *n, *n, *ldc).triangularView<Lower>() += alpha * matrix(a,*n,*k,*lda) * matrix(a,*n,*k,*lda).transpose();+ else+ matrix(c, *n, *n, *ldc).triangularView<Lower>() += alpha * matrix(a,*k,*n,*lda).transpose() * matrix(a,*k,*n,*lda);+ }+ #else+ int code = OP(*op) | (UPLO(*uplo) << 2);+ func[code](*n, *k, a, *lda, a, *lda, c, *ldc, alpha);+ #endif++ return 0;+}++// c = alpha*a*b' + alpha*b*a' + beta*c for op = 'N'or'n'+// c = alpha*a'*b + alpha*b'*a + beta*c for op = 'T'or't'+int EIGEN_BLAS_FUNC(syr2k)(char *uplo, char *op, int *n, int *k, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pb, int *ldb, RealScalar *pbeta, RealScalar *pc, int *ldc)+{+ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* b = reinterpret_cast<Scalar*>(pb);+ Scalar* c = reinterpret_cast<Scalar*>(pc);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);+ Scalar beta = *reinterpret_cast<Scalar*>(pbeta);++ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if(OP(*op)==INVALID) info = 2;+ else if(*n<0) info = 3;+ else if(*k<0) info = 4;+ else if(*lda<std::max(1,(OP(*op)==NOTR)?*n:*k)) info = 7;+ else if(*ldb<std::max(1,(OP(*op)==NOTR)?*n:*k)) info = 9;+ else if(*ldc<std::max(1,*n)) info = 12;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"SYR2K",&info,6);++ if(beta!=Scalar(1))+ {+ if(UPLO(*uplo)==UP)+ if(beta==Scalar(0)) matrix(c, *n, *n, *ldc).triangularView<Upper>().setZero();+ else matrix(c, *n, *n, *ldc).triangularView<Upper>() *= beta;+ else+ if(beta==Scalar(0)) matrix(c, *n, *n, *ldc).triangularView<Lower>().setZero();+ else matrix(c, *n, *n, *ldc).triangularView<Lower>() *= beta;+ }++ if(*k==0)+ return 1;++ if(OP(*op)==NOTR)+ {+ if(UPLO(*uplo)==UP)+ {+ matrix(c, *n, *n, *ldc).triangularView<Upper>()+ += alpha *matrix(a, *n, *k, *lda)*matrix(b, *n, *k, *ldb).transpose()+ + alpha*matrix(b, *n, *k, *ldb)*matrix(a, *n, *k, *lda).transpose();+ }+ else if(UPLO(*uplo)==LO)+ matrix(c, *n, *n, *ldc).triangularView<Lower>()+ += alpha*matrix(a, *n, *k, *lda)*matrix(b, *n, *k, *ldb).transpose()+ + alpha*matrix(b, *n, *k, *ldb)*matrix(a, *n, *k, *lda).transpose();+ }+ else if(OP(*op)==TR || OP(*op)==ADJ)+ {+ if(UPLO(*uplo)==UP)+ matrix(c, *n, *n, *ldc).triangularView<Upper>()+ += alpha*matrix(a, *k, *n, *lda).transpose()*matrix(b, *k, *n, *ldb)+ + alpha*matrix(b, *k, *n, *ldb).transpose()*matrix(a, *k, *n, *lda);+ else if(UPLO(*uplo)==LO)+ matrix(c, *n, *n, *ldc).triangularView<Lower>()+ += alpha*matrix(a, *k, *n, *lda).transpose()*matrix(b, *k, *n, *ldb)+ + alpha*matrix(b, *k, *n, *ldb).transpose()*matrix(a, *k, *n, *lda);+ }++ return 0;+}+++#if ISCOMPLEX++// c = alpha*a*b + beta*c for side = 'L'or'l'+// c = alpha*b*a + beta*c for side = 'R'or'r+int EIGEN_BLAS_FUNC(hemm)(char *side, char *uplo, int *m, int *n, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pb, int *ldb, RealScalar *pbeta, RealScalar *pc, int *ldc)+{+ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* b = reinterpret_cast<Scalar*>(pb);+ Scalar* c = reinterpret_cast<Scalar*>(pc);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);+ Scalar beta = *reinterpret_cast<Scalar*>(pbeta);++// std::cerr << "in hemm " << *side << " " << *uplo << " " << *m << " " << *n << " " << alpha << " " << *lda << " " << beta << " " << *ldc << "\n";++ int info = 0;+ if(SIDE(*side)==INVALID) info = 1;+ else if(UPLO(*uplo)==INVALID) info = 2;+ else if(*m<0) info = 3;+ else if(*n<0) info = 4;+ else if(*lda<std::max(1,(SIDE(*side)==LEFT)?*m:*n)) info = 7;+ else if(*ldb<std::max(1,*m)) info = 9;+ else if(*ldc<std::max(1,*m)) info = 12;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"HEMM ",&info,6);++ if(beta==Scalar(0)) matrix(c, *m, *n, *ldc).setZero();+ else if(beta!=Scalar(1)) matrix(c, *m, *n, *ldc) *= beta;++ if(*m==0 || *n==0)+ {+ return 1;+ }++ if(SIDE(*side)==LEFT)+ {+ if(UPLO(*uplo)==UP) internal::product_selfadjoint_matrix<Scalar,DenseIndex,RowMajor,true,Conj, ColMajor,false,false, ColMajor>+ ::run(*m, *n, a, *lda, b, *ldb, c, *ldc, alpha);+ else if(UPLO(*uplo)==LO) internal::product_selfadjoint_matrix<Scalar,DenseIndex,ColMajor,true,false, ColMajor,false,false, ColMajor>+ ::run(*m, *n, a, *lda, b, *ldb, c, *ldc, alpha);+ else return 0;+ }+ else if(SIDE(*side)==RIGHT)+ {+ if(UPLO(*uplo)==UP) matrix(c,*m,*n,*ldc) += alpha * matrix(b,*m,*n,*ldb) * matrix(a,*n,*n,*lda).selfadjointView<Upper>();/*internal::product_selfadjoint_matrix<Scalar,DenseIndex,ColMajor,false,false, RowMajor,true,Conj, ColMajor>+ ::run(*m, *n, b, *ldb, a, *lda, c, *ldc, alpha);*/+ else if(UPLO(*uplo)==LO) internal::product_selfadjoint_matrix<Scalar,DenseIndex,ColMajor,false,false, ColMajor,true,false, ColMajor>+ ::run(*m, *n, b, *ldb, a, *lda, c, *ldc, alpha);+ else return 0;+ }+ else+ {+ return 0;+ }++ return 0;+}++// c = alpha*a*conj(a') + beta*c for op = 'N'or'n'+// c = alpha*conj(a')*a + beta*c for op = 'C'or'c'+int EIGEN_BLAS_FUNC(herk)(char *uplo, char *op, int *n, int *k, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pbeta, RealScalar *pc, int *ldc)+{+ typedef void (*functype)(DenseIndex, DenseIndex, const Scalar *, DenseIndex, const Scalar *, DenseIndex, Scalar *, DenseIndex, const Scalar&);+ static functype func[8];++ static bool init = false;+ if(!init)+ {+ for(int k=0; k<8; ++k)+ func[k] = 0;++ func[NOTR | (UP << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,ColMajor,false,Scalar,RowMajor,Conj, ColMajor,Upper>::run);+ func[ADJ | (UP << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,RowMajor,Conj, Scalar,ColMajor,false,ColMajor,Upper>::run);++ func[NOTR | (LO << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,ColMajor,false,Scalar,RowMajor,Conj, ColMajor,Lower>::run);+ func[ADJ | (LO << 2)] = (internal::general_matrix_matrix_triangular_product<DenseIndex,Scalar,RowMajor,Conj, Scalar,ColMajor,false,ColMajor,Lower>::run);++ init = true;+ }++ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* c = reinterpret_cast<Scalar*>(pc);+ RealScalar alpha = *palpha;+ RealScalar beta = *pbeta;++// std::cerr << "in herk " << *uplo << " " << *op << " " << *n << " " << *k << " " << alpha << " " << *lda << " " << beta << " " << *ldc << "\n";++ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if((OP(*op)==INVALID) || (OP(*op)==TR)) info = 2;+ else if(*n<0) info = 3;+ else if(*k<0) info = 4;+ else if(*lda<std::max(1,(OP(*op)==NOTR)?*n:*k)) info = 7;+ else if(*ldc<std::max(1,*n)) info = 10;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"HERK ",&info,6);++ int code = OP(*op) | (UPLO(*uplo) << 2);++ if(beta!=RealScalar(1))+ {+ if(UPLO(*uplo)==UP)+ if(beta==Scalar(0)) matrix(c, *n, *n, *ldc).triangularView<Upper>().setZero();+ else matrix(c, *n, *n, *ldc).triangularView<StrictlyUpper>() *= beta;+ else+ if(beta==Scalar(0)) matrix(c, *n, *n, *ldc).triangularView<Lower>().setZero();+ else matrix(c, *n, *n, *ldc).triangularView<StrictlyLower>() *= beta;+ + if(beta!=Scalar(0))+ {+ matrix(c, *n, *n, *ldc).diagonal().real() *= beta;+ matrix(c, *n, *n, *ldc).diagonal().imag().setZero();+ }+ }++ if(*k>0 && alpha!=RealScalar(0))+ {+ func[code](*n, *k, a, *lda, a, *lda, c, *ldc, alpha);+ matrix(c, *n, *n, *ldc).diagonal().imag().setZero();+ }+ return 0;+}++// c = alpha*a*conj(b') + conj(alpha)*b*conj(a') + beta*c, for op = 'N'or'n'+// c = alpha*conj(a')*b + conj(alpha)*conj(b')*a + beta*c, for op = 'C'or'c'+int EIGEN_BLAS_FUNC(her2k)(char *uplo, char *op, int *n, int *k, RealScalar *palpha, RealScalar *pa, int *lda, RealScalar *pb, int *ldb, RealScalar *pbeta, RealScalar *pc, int *ldc)+{+ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* b = reinterpret_cast<Scalar*>(pb);+ Scalar* c = reinterpret_cast<Scalar*>(pc);+ Scalar alpha = *reinterpret_cast<Scalar*>(palpha);+ RealScalar beta = *pbeta;++ int info = 0;+ if(UPLO(*uplo)==INVALID) info = 1;+ else if((OP(*op)==INVALID) || (OP(*op)==TR)) info = 2;+ else if(*n<0) info = 3;+ else if(*k<0) info = 4;+ else if(*lda<std::max(1,(OP(*op)==NOTR)?*n:*k)) info = 7;+ else if(*lda<std::max(1,(OP(*op)==NOTR)?*n:*k)) info = 9;+ else if(*ldc<std::max(1,*n)) info = 12;+ if(info)+ return xerbla_(SCALAR_SUFFIX_UP"HER2K",&info,6);++ if(beta!=RealScalar(1))+ {+ if(UPLO(*uplo)==UP)+ if(beta==Scalar(0)) matrix(c, *n, *n, *ldc).triangularView<Upper>().setZero();+ else matrix(c, *n, *n, *ldc).triangularView<StrictlyUpper>() *= beta;+ else+ if(beta==Scalar(0)) matrix(c, *n, *n, *ldc).triangularView<Lower>().setZero();+ else matrix(c, *n, *n, *ldc).triangularView<StrictlyLower>() *= beta;++ if(beta!=Scalar(0))+ {+ matrix(c, *n, *n, *ldc).diagonal().real() *= beta;+ matrix(c, *n, *n, *ldc).diagonal().imag().setZero();+ }+ }+ else if(*k>0 && alpha!=Scalar(0))+ matrix(c, *n, *n, *ldc).diagonal().imag().setZero();++ if(*k==0)+ return 1;++ if(OP(*op)==NOTR)+ {+ if(UPLO(*uplo)==UP)+ {+ matrix(c, *n, *n, *ldc).triangularView<Upper>()+ += alpha *matrix(a, *n, *k, *lda)*matrix(b, *n, *k, *ldb).adjoint()+ + numext::conj(alpha)*matrix(b, *n, *k, *ldb)*matrix(a, *n, *k, *lda).adjoint();+ }+ else if(UPLO(*uplo)==LO)+ matrix(c, *n, *n, *ldc).triangularView<Lower>()+ += alpha*matrix(a, *n, *k, *lda)*matrix(b, *n, *k, *ldb).adjoint()+ + numext::conj(alpha)*matrix(b, *n, *k, *ldb)*matrix(a, *n, *k, *lda).adjoint();+ }+ else if(OP(*op)==ADJ)+ {+ if(UPLO(*uplo)==UP)+ matrix(c, *n, *n, *ldc).triangularView<Upper>()+ += alpha*matrix(a, *k, *n, *lda).adjoint()*matrix(b, *k, *n, *ldb)+ + numext::conj(alpha)*matrix(b, *k, *n, *ldb).adjoint()*matrix(a, *k, *n, *lda);+ else if(UPLO(*uplo)==LO)+ matrix(c, *n, *n, *ldc).triangularView<Lower>()+ += alpha*matrix(a, *k, *n, *lda).adjoint()*matrix(b, *k, *n, *ldb)+ + numext::conj(alpha)*matrix(b, *k, *n, *ldb).adjoint()*matrix(a, *k, *n, *lda);+ }++ return 1;+}++#endif // ISCOMPLEX
+ eigen3/blas/lsame.f view
@@ -0,0 +1,85 @@+ LOGICAL FUNCTION LSAME(CA,CB)+*+* -- LAPACK auxiliary routine (version 3.1) --+* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..+* November 2006+*+* .. Scalar Arguments ..+ CHARACTER CA,CB+* ..+*+* Purpose+* =======+*+* LSAME returns .TRUE. if CA is the same letter as CB regardless of+* case.+*+* Arguments+* =========+*+* CA (input) CHARACTER*1+*+* CB (input) CHARACTER*1+* CA and CB specify the single characters to be compared.+*+* =====================================================================+*+* .. Intrinsic Functions ..+ INTRINSIC ICHAR+* ..+* .. Local Scalars ..+ INTEGER INTA,INTB,ZCODE+* ..+*+* Test if the characters are equal+*+ LSAME = CA .EQ. CB+ IF (LSAME) RETURN+*+* Now test for equivalence if both characters are alphabetic.+*+ ZCODE = ICHAR('Z')+*+* Use 'Z' rather than 'A' so that ASCII can be detected on Prime+* machines, on which ICHAR returns a value with bit 8 set.+* ICHAR('A') on Prime machines returns 193 which is the same as+* ICHAR('A') on an EBCDIC machine.+*+ INTA = ICHAR(CA)+ INTB = ICHAR(CB)+*+ IF (ZCODE.EQ.90 .OR. ZCODE.EQ.122) THEN+*+* ASCII is assumed - ZCODE is the ASCII code of either lower or+* upper case 'Z'.+*+ IF (INTA.GE.97 .AND. INTA.LE.122) INTA = INTA - 32+ IF (INTB.GE.97 .AND. INTB.LE.122) INTB = INTB - 32+*+ ELSE IF (ZCODE.EQ.233 .OR. ZCODE.EQ.169) THEN+*+* EBCDIC is assumed - ZCODE is the EBCDIC code of either lower or+* upper case 'Z'.+*+ IF (INTA.GE.129 .AND. INTA.LE.137 .OR.+ + INTA.GE.145 .AND. INTA.LE.153 .OR.+ + INTA.GE.162 .AND. INTA.LE.169) INTA = INTA + 64+ IF (INTB.GE.129 .AND. INTB.LE.137 .OR.+ + INTB.GE.145 .AND. INTB.LE.153 .OR.+ + INTB.GE.162 .AND. INTB.LE.169) INTB = INTB + 64+*+ ELSE IF (ZCODE.EQ.218 .OR. ZCODE.EQ.250) THEN+*+* ASCII is assumed, on Prime machines - ZCODE is the ASCII code+* plus 128 of either lower or upper case 'Z'.+*+ IF (INTA.GE.225 .AND. INTA.LE.250) INTA = INTA - 32+ IF (INTB.GE.225 .AND. INTB.LE.250) INTB = INTB - 32+ END IF+ LSAME = INTA .EQ. INTB+*+* RETURN+*+* End of LSAME+*+ END
+ eigen3/blas/single.cpp view
@@ -0,0 +1,22 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define SCALAR float+#define SCALAR_SUFFIX s+#define SCALAR_SUFFIX_UP "S"+#define ISCOMPLEX 0++#include "level1_impl.h"+#include "level1_real_impl.h"+#include "level2_impl.h"+#include "level2_real_impl.h"+#include "level3_impl.h"++float BLASFUNC(sdsdot)(int* n, float* alpha, float* x, int* incx, float* y, int* incy)+{ return *alpha + BLASFUNC(dsdot)(n, x, incx, y, incy); }
+ eigen3/blas/srotm.f view
@@ -0,0 +1,148 @@+ SUBROUTINE SROTM(N,SX,INCX,SY,INCY,SPARAM)+* .. Scalar Arguments ..+ INTEGER INCX,INCY,N+* ..+* .. Array Arguments ..+ REAL SPARAM(5),SX(*),SY(*)+* ..+*+* Purpose+* =======+*+* APPLY THE MODIFIED GIVENS TRANSFORMATION, H, TO THE 2 BY N MATRIX+*+* (SX**T) , WHERE **T INDICATES TRANSPOSE. THE ELEMENTS OF SX ARE IN+* (DX**T)+*+* SX(LX+I*INCX), I = 0 TO N-1, WHERE LX = 1 IF INCX .GE. 0, ELSE+* LX = (-INCX)*N, AND SIMILARLY FOR SY USING USING LY AND INCY.+* WITH SPARAM(1)=SFLAG, H HAS ONE OF THE FOLLOWING FORMS..+*+* SFLAG=-1.E0 SFLAG=0.E0 SFLAG=1.E0 SFLAG=-2.E0+*+* (SH11 SH12) (1.E0 SH12) (SH11 1.E0) (1.E0 0.E0)+* H=( ) ( ) ( ) ( )+* (SH21 SH22), (SH21 1.E0), (-1.E0 SH22), (0.E0 1.E0).+* SEE SROTMG FOR A DESCRIPTION OF DATA STORAGE IN SPARAM.+*+*+* Arguments+* =========+*+* N (input) INTEGER+* number of elements in input vector(s)+*+* SX (input/output) REAL array, dimension N+* double precision vector with N elements+*+* INCX (input) INTEGER+* storage spacing between elements of SX+*+* SY (input/output) REAL array, dimension N+* double precision vector with N elements+*+* INCY (input) INTEGER+* storage spacing between elements of SY+*+* SPARAM (input/output) REAL array, dimension 5+* SPARAM(1)=SFLAG+* SPARAM(2)=SH11+* SPARAM(3)=SH21+* SPARAM(4)=SH12+* SPARAM(5)=SH22+*+* =====================================================================+*+* .. Local Scalars ..+ REAL SFLAG,SH11,SH12,SH21,SH22,TWO,W,Z,ZERO+ INTEGER I,KX,KY,NSTEPS+* ..+* .. Data statements ..+ DATA ZERO,TWO/0.E0,2.E0/+* ..+*+ SFLAG = SPARAM(1)+ IF (N.LE.0 .OR. (SFLAG+TWO.EQ.ZERO)) GO TO 140+ IF (.NOT. (INCX.EQ.INCY.AND.INCX.GT.0)) GO TO 70+*+ NSTEPS = N*INCX+ IF (SFLAG) 50,10,30+ 10 CONTINUE+ SH12 = SPARAM(4)+ SH21 = SPARAM(3)+ DO 20 I = 1,NSTEPS,INCX+ W = SX(I)+ Z = SY(I)+ SX(I) = W + Z*SH12+ SY(I) = W*SH21 + Z+ 20 CONTINUE+ GO TO 140+ 30 CONTINUE+ SH11 = SPARAM(2)+ SH22 = SPARAM(5)+ DO 40 I = 1,NSTEPS,INCX+ W = SX(I)+ Z = SY(I)+ SX(I) = W*SH11 + Z+ SY(I) = -W + SH22*Z+ 40 CONTINUE+ GO TO 140+ 50 CONTINUE+ SH11 = SPARAM(2)+ SH12 = SPARAM(4)+ SH21 = SPARAM(3)+ SH22 = SPARAM(5)+ DO 60 I = 1,NSTEPS,INCX+ W = SX(I)+ Z = SY(I)+ SX(I) = W*SH11 + Z*SH12+ SY(I) = W*SH21 + Z*SH22+ 60 CONTINUE+ GO TO 140+ 70 CONTINUE+ KX = 1+ KY = 1+ IF (INCX.LT.0) KX = 1 + (1-N)*INCX+ IF (INCY.LT.0) KY = 1 + (1-N)*INCY+*+ IF (SFLAG) 120,80,100+ 80 CONTINUE+ SH12 = SPARAM(4)+ SH21 = SPARAM(3)+ DO 90 I = 1,N+ W = SX(KX)+ Z = SY(KY)+ SX(KX) = W + Z*SH12+ SY(KY) = W*SH21 + Z+ KX = KX + INCX+ KY = KY + INCY+ 90 CONTINUE+ GO TO 140+ 100 CONTINUE+ SH11 = SPARAM(2)+ SH22 = SPARAM(5)+ DO 110 I = 1,N+ W = SX(KX)+ Z = SY(KY)+ SX(KX) = W*SH11 + Z+ SY(KY) = -W + SH22*Z+ KX = KX + INCX+ KY = KY + INCY+ 110 CONTINUE+ GO TO 140+ 120 CONTINUE+ SH11 = SPARAM(2)+ SH12 = SPARAM(4)+ SH21 = SPARAM(3)+ SH22 = SPARAM(5)+ DO 130 I = 1,N+ W = SX(KX)+ Z = SY(KY)+ SX(KX) = W*SH11 + Z*SH12+ SY(KY) = W*SH21 + Z*SH22+ KX = KX + INCX+ KY = KY + INCY+ 130 CONTINUE+ 140 CONTINUE+ RETURN+ END
+ eigen3/blas/srotmg.f view
@@ -0,0 +1,208 @@+ SUBROUTINE SROTMG(SD1,SD2,SX1,SY1,SPARAM)+* .. Scalar Arguments ..+ REAL SD1,SD2,SX1,SY1+* ..+* .. Array Arguments ..+ REAL SPARAM(5)+* ..+*+* Purpose+* =======+*+* CONSTRUCT THE MODIFIED GIVENS TRANSFORMATION MATRIX H WHICH ZEROS+* THE SECOND COMPONENT OF THE 2-VECTOR (SQRT(SD1)*SX1,SQRT(SD2)*+* SY2)**T.+* WITH SPARAM(1)=SFLAG, H HAS ONE OF THE FOLLOWING FORMS..+*+* SFLAG=-1.E0 SFLAG=0.E0 SFLAG=1.E0 SFLAG=-2.E0+*+* (SH11 SH12) (1.E0 SH12) (SH11 1.E0) (1.E0 0.E0)+* H=( ) ( ) ( ) ( )+* (SH21 SH22), (SH21 1.E0), (-1.E0 SH22), (0.E0 1.E0).+* LOCATIONS 2-4 OF SPARAM CONTAIN SH11,SH21,SH12, AND SH22+* RESPECTIVELY. (VALUES OF 1.E0, -1.E0, OR 0.E0 IMPLIED BY THE+* VALUE OF SPARAM(1) ARE NOT STORED IN SPARAM.)+*+* THE VALUES OF GAMSQ AND RGAMSQ SET IN THE DATA STATEMENT MAY BE+* INEXACT. THIS IS OK AS THEY ARE ONLY USED FOR TESTING THE SIZE+* OF SD1 AND SD2. ALL ACTUAL SCALING OF DATA IS DONE USING GAM.+*+*+* Arguments+* =========+*+*+* SD1 (input/output) REAL+*+* SD2 (input/output) REAL+*+* SX1 (input/output) REAL+*+* SY1 (input) REAL+*+*+* SPARAM (input/output) REAL array, dimension 5+* SPARAM(1)=SFLAG+* SPARAM(2)=SH11+* SPARAM(3)=SH21+* SPARAM(4)=SH12+* SPARAM(5)=SH22+*+* =====================================================================+*+* .. Local Scalars ..+ REAL GAM,GAMSQ,ONE,RGAMSQ,SFLAG,SH11,SH12,SH21,SH22,SP1,SP2,SQ1,+ + SQ2,STEMP,SU,TWO,ZERO+ INTEGER IGO+* ..+* .. Intrinsic Functions ..+ INTRINSIC ABS+* ..+* .. Data statements ..+*+ DATA ZERO,ONE,TWO/0.E0,1.E0,2.E0/+ DATA GAM,GAMSQ,RGAMSQ/4096.E0,1.67772E7,5.96046E-8/+* ..++ IF (.NOT.SD1.LT.ZERO) GO TO 10+* GO ZERO-H-D-AND-SX1..+ GO TO 60+ 10 CONTINUE+* CASE-SD1-NONNEGATIVE+ SP2 = SD2*SY1+ IF (.NOT.SP2.EQ.ZERO) GO TO 20+ SFLAG = -TWO+ GO TO 260+* REGULAR-CASE..+ 20 CONTINUE+ SP1 = SD1*SX1+ SQ2 = SP2*SY1+ SQ1 = SP1*SX1+*+ IF (.NOT.ABS(SQ1).GT.ABS(SQ2)) GO TO 40+ SH21 = -SY1/SX1+ SH12 = SP2/SP1+*+ SU = ONE - SH12*SH21+*+ IF (.NOT.SU.LE.ZERO) GO TO 30+* GO ZERO-H-D-AND-SX1..+ GO TO 60+ 30 CONTINUE+ SFLAG = ZERO+ SD1 = SD1/SU+ SD2 = SD2/SU+ SX1 = SX1*SU+* GO SCALE-CHECK..+ GO TO 100+ 40 CONTINUE+ IF (.NOT.SQ2.LT.ZERO) GO TO 50+* GO ZERO-H-D-AND-SX1..+ GO TO 60+ 50 CONTINUE+ SFLAG = ONE+ SH11 = SP1/SP2+ SH22 = SX1/SY1+ SU = ONE + SH11*SH22+ STEMP = SD2/SU+ SD2 = SD1/SU+ SD1 = STEMP+ SX1 = SY1*SU+* GO SCALE-CHECK+ GO TO 100+* PROCEDURE..ZERO-H-D-AND-SX1..+ 60 CONTINUE+ SFLAG = -ONE+ SH11 = ZERO+ SH12 = ZERO+ SH21 = ZERO+ SH22 = ZERO+*+ SD1 = ZERO+ SD2 = ZERO+ SX1 = ZERO+* RETURN..+ GO TO 220+* PROCEDURE..FIX-H..+ 70 CONTINUE+ IF (.NOT.SFLAG.GE.ZERO) GO TO 90+*+ IF (.NOT.SFLAG.EQ.ZERO) GO TO 80+ SH11 = ONE+ SH22 = ONE+ SFLAG = -ONE+ GO TO 90+ 80 CONTINUE+ SH21 = -ONE+ SH12 = ONE+ SFLAG = -ONE+ 90 CONTINUE+ GO TO IGO(120,150,180,210)+* PROCEDURE..SCALE-CHECK+ 100 CONTINUE+ 110 CONTINUE+ IF (.NOT.SD1.LE.RGAMSQ) GO TO 130+ IF (SD1.EQ.ZERO) GO TO 160+ ASSIGN 120 TO IGO+* FIX-H..+ GO TO 70+ 120 CONTINUE+ SD1 = SD1*GAM**2+ SX1 = SX1/GAM+ SH11 = SH11/GAM+ SH12 = SH12/GAM+ GO TO 110+ 130 CONTINUE+ 140 CONTINUE+ IF (.NOT.SD1.GE.GAMSQ) GO TO 160+ ASSIGN 150 TO IGO+* FIX-H..+ GO TO 70+ 150 CONTINUE+ SD1 = SD1/GAM**2+ SX1 = SX1*GAM+ SH11 = SH11*GAM+ SH12 = SH12*GAM+ GO TO 140+ 160 CONTINUE+ 170 CONTINUE+ IF (.NOT.ABS(SD2).LE.RGAMSQ) GO TO 190+ IF (SD2.EQ.ZERO) GO TO 220+ ASSIGN 180 TO IGO+* FIX-H..+ GO TO 70+ 180 CONTINUE+ SD2 = SD2*GAM**2+ SH21 = SH21/GAM+ SH22 = SH22/GAM+ GO TO 170+ 190 CONTINUE+ 200 CONTINUE+ IF (.NOT.ABS(SD2).GE.GAMSQ) GO TO 220+ ASSIGN 210 TO IGO+* FIX-H..+ GO TO 70+ 210 CONTINUE+ SD2 = SD2/GAM**2+ SH21 = SH21*GAM+ SH22 = SH22*GAM+ GO TO 200+ 220 CONTINUE+ IF (SFLAG) 250,230,240+ 230 CONTINUE+ SPARAM(3) = SH21+ SPARAM(4) = SH12+ GO TO 260+ 240 CONTINUE+ SPARAM(2) = SH11+ SPARAM(5) = SH22+ GO TO 260+ 250 CONTINUE+ SPARAM(2) = SH11+ SPARAM(3) = SH21+ SPARAM(4) = SH12+ SPARAM(5) = SH22+ 260 CONTINUE+ SPARAM(1) = SFLAG+ RETURN+ END
+ eigen3/blas/ssbmv.f view
@@ -0,0 +1,306 @@+ SUBROUTINE SSBMV(UPLO,N,K,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)+* .. Scalar Arguments ..+ REAL ALPHA,BETA+ INTEGER INCX,INCY,K,LDA,N+ CHARACTER UPLO+* ..+* .. Array Arguments ..+ REAL A(LDA,*),X(*),Y(*)+* ..+*+* Purpose+* =======+*+* SSBMV performs the matrix-vector operation+*+* y := alpha*A*x + beta*y,+*+* where alpha and beta are scalars, x and y are n element vectors and+* A is an n by n symmetric band matrix, with k super-diagonals.+*+* Arguments+* ==========+*+* UPLO - CHARACTER*1.+* On entry, UPLO specifies whether the upper or lower+* triangular part of the band matrix A is being supplied as+* follows:+*+* UPLO = 'U' or 'u' The upper triangular part of A is+* being supplied.+*+* UPLO = 'L' or 'l' The lower triangular part of A is+* being supplied.+*+* Unchanged on exit.+*+* N - INTEGER.+* On entry, N specifies the order of the matrix A.+* N must be at least zero.+* Unchanged on exit.+*+* K - INTEGER.+* On entry, K specifies the number of super-diagonals of the+* matrix A. K must satisfy 0 .le. K.+* Unchanged on exit.+*+* ALPHA - REAL .+* On entry, ALPHA specifies the scalar alpha.+* Unchanged on exit.+*+* A - REAL array of DIMENSION ( LDA, n ).+* Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )+* by n part of the array A must contain the upper triangular+* band part of the symmetric matrix, supplied column by+* column, with the leading diagonal of the matrix in row+* ( k + 1 ) of the array, the first super-diagonal starting at+* position 2 in row k, and so on. The top left k by k triangle+* of the array A is not referenced.+* The following program segment will transfer the upper+* triangular part of a symmetric band matrix from conventional+* full matrix storage to band storage:+*+* DO 20, J = 1, N+* M = K + 1 - J+* DO 10, I = MAX( 1, J - K ), J+* A( M + I, J ) = matrix( I, J )+* 10 CONTINUE+* 20 CONTINUE+*+* Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )+* by n part of the array A must contain the lower triangular+* band part of the symmetric matrix, supplied column by+* column, with the leading diagonal of the matrix in row 1 of+* the array, the first sub-diagonal starting at position 1 in+* row 2, and so on. The bottom right k by k triangle of the+* array A is not referenced.+* The following program segment will transfer the lower+* triangular part of a symmetric band matrix from conventional+* full matrix storage to band storage:+*+* DO 20, J = 1, N+* M = 1 - J+* DO 10, I = J, MIN( N, J + K )+* A( M + I, J ) = matrix( I, J )+* 10 CONTINUE+* 20 CONTINUE+*+* Unchanged on exit.+*+* LDA - INTEGER.+* On entry, LDA specifies the first dimension of A as declared+* in the calling (sub) program. LDA must be at least+* ( k + 1 ).+* Unchanged on exit.+*+* X - REAL array of DIMENSION at least+* ( 1 + ( n - 1 )*abs( INCX ) ).+* Before entry, the incremented array X must contain the+* vector x.+* Unchanged on exit.+*+* INCX - INTEGER.+* On entry, INCX specifies the increment for the elements of+* X. INCX must not be zero.+* Unchanged on exit.+*+* BETA - REAL .+* On entry, BETA specifies the scalar beta.+* Unchanged on exit.+*+* Y - REAL array of DIMENSION at least+* ( 1 + ( n - 1 )*abs( INCY ) ).+* Before entry, the incremented array Y must contain the+* vector y. On exit, Y is overwritten by the updated vector y.+*+* INCY - INTEGER.+* On entry, INCY specifies the increment for the elements of+* Y. INCY must not be zero.+* Unchanged on exit.+*+* Further Details+* ===============+*+* Level 2 Blas routine.+*+* -- Written on 22-October-1986.+* Jack Dongarra, Argonne National Lab.+* Jeremy Du Croz, Nag Central Office.+* Sven Hammarling, Nag Central Office.+* Richard Hanson, Sandia National Labs.+*+* =====================================================================+*+* .. Parameters ..+ REAL ONE,ZERO+ PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)+* ..+* .. Local Scalars ..+ REAL TEMP1,TEMP2+ INTEGER I,INFO,IX,IY,J,JX,JY,KPLUS1,KX,KY,L+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. External Subroutines ..+ EXTERNAL XERBLA+* ..+* .. Intrinsic Functions ..+ INTRINSIC MAX,MIN+* ..+*+* Test the input parameters.+*+ INFO = 0+ IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN+ INFO = 1+ ELSE IF (N.LT.0) THEN+ INFO = 2+ ELSE IF (K.LT.0) THEN+ INFO = 3+ ELSE IF (LDA.LT. (K+1)) THEN+ INFO = 6+ ELSE IF (INCX.EQ.0) THEN+ INFO = 8+ ELSE IF (INCY.EQ.0) THEN+ INFO = 11+ END IF+ IF (INFO.NE.0) THEN+ CALL XERBLA('SSBMV ',INFO)+ RETURN+ END IF+*+* Quick return if possible.+*+ IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN+*+* Set up the start points in X and Y.+*+ IF (INCX.GT.0) THEN+ KX = 1+ ELSE+ KX = 1 - (N-1)*INCX+ END IF+ IF (INCY.GT.0) THEN+ KY = 1+ ELSE+ KY = 1 - (N-1)*INCY+ END IF+*+* Start the operations. In this version the elements of the array A+* are accessed sequentially with one pass through A.+*+* First form y := beta*y.+*+ IF (BETA.NE.ONE) THEN+ IF (INCY.EQ.1) THEN+ IF (BETA.EQ.ZERO) THEN+ DO 10 I = 1,N+ Y(I) = ZERO+ 10 CONTINUE+ ELSE+ DO 20 I = 1,N+ Y(I) = BETA*Y(I)+ 20 CONTINUE+ END IF+ ELSE+ IY = KY+ IF (BETA.EQ.ZERO) THEN+ DO 30 I = 1,N+ Y(IY) = ZERO+ IY = IY + INCY+ 30 CONTINUE+ ELSE+ DO 40 I = 1,N+ Y(IY) = BETA*Y(IY)+ IY = IY + INCY+ 40 CONTINUE+ END IF+ END IF+ END IF+ IF (ALPHA.EQ.ZERO) RETURN+ IF (LSAME(UPLO,'U')) THEN+*+* Form y when upper triangle of A is stored.+*+ KPLUS1 = K + 1+ IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN+ DO 60 J = 1,N+ TEMP1 = ALPHA*X(J)+ TEMP2 = ZERO+ L = KPLUS1 - J+ DO 50 I = MAX(1,J-K),J - 1+ Y(I) = Y(I) + TEMP1*A(L+I,J)+ TEMP2 = TEMP2 + A(L+I,J)*X(I)+ 50 CONTINUE+ Y(J) = Y(J) + TEMP1*A(KPLUS1,J) + ALPHA*TEMP2+ 60 CONTINUE+ ELSE+ JX = KX+ JY = KY+ DO 80 J = 1,N+ TEMP1 = ALPHA*X(JX)+ TEMP2 = ZERO+ IX = KX+ IY = KY+ L = KPLUS1 - J+ DO 70 I = MAX(1,J-K),J - 1+ Y(IY) = Y(IY) + TEMP1*A(L+I,J)+ TEMP2 = TEMP2 + A(L+I,J)*X(IX)+ IX = IX + INCX+ IY = IY + INCY+ 70 CONTINUE+ Y(JY) = Y(JY) + TEMP1*A(KPLUS1,J) + ALPHA*TEMP2+ JX = JX + INCX+ JY = JY + INCY+ IF (J.GT.K) THEN+ KX = KX + INCX+ KY = KY + INCY+ END IF+ 80 CONTINUE+ END IF+ ELSE+*+* Form y when lower triangle of A is stored.+*+ IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN+ DO 100 J = 1,N+ TEMP1 = ALPHA*X(J)+ TEMP2 = ZERO+ Y(J) = Y(J) + TEMP1*A(1,J)+ L = 1 - J+ DO 90 I = J + 1,MIN(N,J+K)+ Y(I) = Y(I) + TEMP1*A(L+I,J)+ TEMP2 = TEMP2 + A(L+I,J)*X(I)+ 90 CONTINUE+ Y(J) = Y(J) + ALPHA*TEMP2+ 100 CONTINUE+ ELSE+ JX = KX+ JY = KY+ DO 120 J = 1,N+ TEMP1 = ALPHA*X(JX)+ TEMP2 = ZERO+ Y(JY) = Y(JY) + TEMP1*A(1,J)+ L = 1 - J+ IX = JX+ IY = JY+ DO 110 I = J + 1,MIN(N,J+K)+ IX = IX + INCX+ IY = IY + INCY+ Y(IY) = Y(IY) + TEMP1*A(L+I,J)+ TEMP2 = TEMP2 + A(L+I,J)*X(IX)+ 110 CONTINUE+ Y(JY) = Y(JY) + ALPHA*TEMP2+ JX = JX + INCX+ JY = JY + INCY+ 120 CONTINUE+ END IF+ END IF+*+ RETURN+*+* End of SSBMV .+*+ END
+ eigen3/blas/sspmv.f view
@@ -0,0 +1,265 @@+ SUBROUTINE SSPMV(UPLO,N,ALPHA,AP,X,INCX,BETA,Y,INCY)+* .. Scalar Arguments ..+ REAL ALPHA,BETA+ INTEGER INCX,INCY,N+ CHARACTER UPLO+* ..+* .. Array Arguments ..+ REAL AP(*),X(*),Y(*)+* ..+*+* Purpose+* =======+*+* SSPMV performs the matrix-vector operation+*+* y := alpha*A*x + beta*y,+*+* where alpha and beta are scalars, x and y are n element vectors and+* A is an n by n symmetric matrix, supplied in packed form.+*+* Arguments+* ==========+*+* UPLO - CHARACTER*1.+* On entry, UPLO specifies whether the upper or lower+* triangular part of the matrix A is supplied in the packed+* array AP as follows:+*+* UPLO = 'U' or 'u' The upper triangular part of A is+* supplied in AP.+*+* UPLO = 'L' or 'l' The lower triangular part of A is+* supplied in AP.+*+* Unchanged on exit.+*+* N - INTEGER.+* On entry, N specifies the order of the matrix A.+* N must be at least zero.+* Unchanged on exit.+*+* ALPHA - REAL .+* On entry, ALPHA specifies the scalar alpha.+* Unchanged on exit.+*+* AP - REAL array of DIMENSION at least+* ( ( n*( n + 1 ) )/2 ).+* Before entry with UPLO = 'U' or 'u', the array AP must+* contain the upper triangular part of the symmetric matrix+* packed sequentially, column by column, so that AP( 1 )+* contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 )+* and a( 2, 2 ) respectively, and so on.+* Before entry with UPLO = 'L' or 'l', the array AP must+* contain the lower triangular part of the symmetric matrix+* packed sequentially, column by column, so that AP( 1 )+* contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 )+* and a( 3, 1 ) respectively, and so on.+* Unchanged on exit.+*+* X - REAL array of dimension at least+* ( 1 + ( n - 1 )*abs( INCX ) ).+* Before entry, the incremented array X must contain the n+* element vector x.+* Unchanged on exit.+*+* INCX - INTEGER.+* On entry, INCX specifies the increment for the elements of+* X. INCX must not be zero.+* Unchanged on exit.+*+* BETA - REAL .+* On entry, BETA specifies the scalar beta. When BETA is+* supplied as zero then Y need not be set on input.+* Unchanged on exit.+*+* Y - REAL array of dimension at least+* ( 1 + ( n - 1 )*abs( INCY ) ).+* Before entry, the incremented array Y must contain the n+* element vector y. On exit, Y is overwritten by the updated+* vector y.+*+* INCY - INTEGER.+* On entry, INCY specifies the increment for the elements of+* Y. INCY must not be zero.+* Unchanged on exit.+*+* Further Details+* ===============+*+* Level 2 Blas routine.+*+* -- Written on 22-October-1986.+* Jack Dongarra, Argonne National Lab.+* Jeremy Du Croz, Nag Central Office.+* Sven Hammarling, Nag Central Office.+* Richard Hanson, Sandia National Labs.+*+* =====================================================================+*+* .. Parameters ..+ REAL ONE,ZERO+ PARAMETER (ONE=1.0E+0,ZERO=0.0E+0)+* ..+* .. Local Scalars ..+ REAL TEMP1,TEMP2+ INTEGER I,INFO,IX,IY,J,JX,JY,K,KK,KX,KY+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. External Subroutines ..+ EXTERNAL XERBLA+* ..+*+* Test the input parameters.+*+ INFO = 0+ IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN+ INFO = 1+ ELSE IF (N.LT.0) THEN+ INFO = 2+ ELSE IF (INCX.EQ.0) THEN+ INFO = 6+ ELSE IF (INCY.EQ.0) THEN+ INFO = 9+ END IF+ IF (INFO.NE.0) THEN+ CALL XERBLA('SSPMV ',INFO)+ RETURN+ END IF+*+* Quick return if possible.+*+ IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN+*+* Set up the start points in X and Y.+*+ IF (INCX.GT.0) THEN+ KX = 1+ ELSE+ KX = 1 - (N-1)*INCX+ END IF+ IF (INCY.GT.0) THEN+ KY = 1+ ELSE+ KY = 1 - (N-1)*INCY+ END IF+*+* Start the operations. In this version the elements of the array AP+* are accessed sequentially with one pass through AP.+*+* First form y := beta*y.+*+ IF (BETA.NE.ONE) THEN+ IF (INCY.EQ.1) THEN+ IF (BETA.EQ.ZERO) THEN+ DO 10 I = 1,N+ Y(I) = ZERO+ 10 CONTINUE+ ELSE+ DO 20 I = 1,N+ Y(I) = BETA*Y(I)+ 20 CONTINUE+ END IF+ ELSE+ IY = KY+ IF (BETA.EQ.ZERO) THEN+ DO 30 I = 1,N+ Y(IY) = ZERO+ IY = IY + INCY+ 30 CONTINUE+ ELSE+ DO 40 I = 1,N+ Y(IY) = BETA*Y(IY)+ IY = IY + INCY+ 40 CONTINUE+ END IF+ END IF+ END IF+ IF (ALPHA.EQ.ZERO) RETURN+ KK = 1+ IF (LSAME(UPLO,'U')) THEN+*+* Form y when AP contains the upper triangle.+*+ IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN+ DO 60 J = 1,N+ TEMP1 = ALPHA*X(J)+ TEMP2 = ZERO+ K = KK+ DO 50 I = 1,J - 1+ Y(I) = Y(I) + TEMP1*AP(K)+ TEMP2 = TEMP2 + AP(K)*X(I)+ K = K + 1+ 50 CONTINUE+ Y(J) = Y(J) + TEMP1*AP(KK+J-1) + ALPHA*TEMP2+ KK = KK + J+ 60 CONTINUE+ ELSE+ JX = KX+ JY = KY+ DO 80 J = 1,N+ TEMP1 = ALPHA*X(JX)+ TEMP2 = ZERO+ IX = KX+ IY = KY+ DO 70 K = KK,KK + J - 2+ Y(IY) = Y(IY) + TEMP1*AP(K)+ TEMP2 = TEMP2 + AP(K)*X(IX)+ IX = IX + INCX+ IY = IY + INCY+ 70 CONTINUE+ Y(JY) = Y(JY) + TEMP1*AP(KK+J-1) + ALPHA*TEMP2+ JX = JX + INCX+ JY = JY + INCY+ KK = KK + J+ 80 CONTINUE+ END IF+ ELSE+*+* Form y when AP contains the lower triangle.+*+ IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN+ DO 100 J = 1,N+ TEMP1 = ALPHA*X(J)+ TEMP2 = ZERO+ Y(J) = Y(J) + TEMP1*AP(KK)+ K = KK + 1+ DO 90 I = J + 1,N+ Y(I) = Y(I) + TEMP1*AP(K)+ TEMP2 = TEMP2 + AP(K)*X(I)+ K = K + 1+ 90 CONTINUE+ Y(J) = Y(J) + ALPHA*TEMP2+ KK = KK + (N-J+1)+ 100 CONTINUE+ ELSE+ JX = KX+ JY = KY+ DO 120 J = 1,N+ TEMP1 = ALPHA*X(JX)+ TEMP2 = ZERO+ Y(JY) = Y(JY) + TEMP1*AP(KK)+ IX = JX+ IY = JY+ DO 110 K = KK + 1,KK + N - J+ IX = IX + INCX+ IY = IY + INCY+ Y(IY) = Y(IY) + TEMP1*AP(K)+ TEMP2 = TEMP2 + AP(K)*X(IX)+ 110 CONTINUE+ Y(JY) = Y(JY) + ALPHA*TEMP2+ JX = JX + INCX+ JY = JY + INCY+ KK = KK + (N-J+1)+ 120 CONTINUE+ END IF+ END IF+*+ RETURN+*+* End of SSPMV .+*+ END
+ eigen3/blas/stbmv.f view
@@ -0,0 +1,335 @@+ SUBROUTINE STBMV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)+* .. Scalar Arguments ..+ INTEGER INCX,K,LDA,N+ CHARACTER DIAG,TRANS,UPLO+* ..+* .. Array Arguments ..+ REAL A(LDA,*),X(*)+* ..+*+* Purpose+* =======+*+* STBMV performs one of the matrix-vector operations+*+* x := A*x, or x := A'*x,+*+* where x is an n element vector and A is an n by n unit, or non-unit,+* upper or lower triangular band matrix, with ( k + 1 ) diagonals.+*+* Arguments+* ==========+*+* UPLO - CHARACTER*1.+* On entry, UPLO specifies whether the matrix is an upper or+* lower triangular matrix as follows:+*+* UPLO = 'U' or 'u' A is an upper triangular matrix.+*+* UPLO = 'L' or 'l' A is a lower triangular matrix.+*+* Unchanged on exit.+*+* TRANS - CHARACTER*1.+* On entry, TRANS specifies the operation to be performed as+* follows:+*+* TRANS = 'N' or 'n' x := A*x.+*+* TRANS = 'T' or 't' x := A'*x.+*+* TRANS = 'C' or 'c' x := A'*x.+*+* Unchanged on exit.+*+* DIAG - CHARACTER*1.+* On entry, DIAG specifies whether or not A is unit+* triangular as follows:+*+* DIAG = 'U' or 'u' A is assumed to be unit triangular.+*+* DIAG = 'N' or 'n' A is not assumed to be unit+* triangular.+*+* Unchanged on exit.+*+* N - INTEGER.+* On entry, N specifies the order of the matrix A.+* N must be at least zero.+* Unchanged on exit.+*+* K - INTEGER.+* On entry with UPLO = 'U' or 'u', K specifies the number of+* super-diagonals of the matrix A.+* On entry with UPLO = 'L' or 'l', K specifies the number of+* sub-diagonals of the matrix A.+* K must satisfy 0 .le. K.+* Unchanged on exit.+*+* A - REAL array of DIMENSION ( LDA, n ).+* Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )+* by n part of the array A must contain the upper triangular+* band part of the matrix of coefficients, supplied column by+* column, with the leading diagonal of the matrix in row+* ( k + 1 ) of the array, the first super-diagonal starting at+* position 2 in row k, and so on. The top left k by k triangle+* of the array A is not referenced.+* The following program segment will transfer an upper+* triangular band matrix from conventional full matrix storage+* to band storage:+*+* DO 20, J = 1, N+* M = K + 1 - J+* DO 10, I = MAX( 1, J - K ), J+* A( M + I, J ) = matrix( I, J )+* 10 CONTINUE+* 20 CONTINUE+*+* Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )+* by n part of the array A must contain the lower triangular+* band part of the matrix of coefficients, supplied column by+* column, with the leading diagonal of the matrix in row 1 of+* the array, the first sub-diagonal starting at position 1 in+* row 2, and so on. The bottom right k by k triangle of the+* array A is not referenced.+* The following program segment will transfer a lower+* triangular band matrix from conventional full matrix storage+* to band storage:+*+* DO 20, J = 1, N+* M = 1 - J+* DO 10, I = J, MIN( N, J + K )+* A( M + I, J ) = matrix( I, J )+* 10 CONTINUE+* 20 CONTINUE+*+* Note that when DIAG = 'U' or 'u' the elements of the array A+* corresponding to the diagonal elements of the matrix are not+* referenced, but are assumed to be unity.+* Unchanged on exit.+*+* LDA - INTEGER.+* On entry, LDA specifies the first dimension of A as declared+* in the calling (sub) program. LDA must be at least+* ( k + 1 ).+* Unchanged on exit.+*+* X - REAL array of dimension at least+* ( 1 + ( n - 1 )*abs( INCX ) ).+* Before entry, the incremented array X must contain the n+* element vector x. On exit, X is overwritten with the+* tranformed vector x.+*+* INCX - INTEGER.+* On entry, INCX specifies the increment for the elements of+* X. INCX must not be zero.+* Unchanged on exit.+*+* Further Details+* ===============+*+* Level 2 Blas routine.+*+* -- Written on 22-October-1986.+* Jack Dongarra, Argonne National Lab.+* Jeremy Du Croz, Nag Central Office.+* Sven Hammarling, Nag Central Office.+* Richard Hanson, Sandia National Labs.+*+* =====================================================================+*+* .. Parameters ..+ REAL ZERO+ PARAMETER (ZERO=0.0E+0)+* ..+* .. Local Scalars ..+ REAL TEMP+ INTEGER I,INFO,IX,J,JX,KPLUS1,KX,L+ LOGICAL NOUNIT+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. External Subroutines ..+ EXTERNAL XERBLA+* ..+* .. Intrinsic Functions ..+ INTRINSIC MAX,MIN+* ..+*+* Test the input parameters.+*+ INFO = 0+ IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN+ INFO = 1+ ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.+ + .NOT.LSAME(TRANS,'C')) THEN+ INFO = 2+ ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN+ INFO = 3+ ELSE IF (N.LT.0) THEN+ INFO = 4+ ELSE IF (K.LT.0) THEN+ INFO = 5+ ELSE IF (LDA.LT. (K+1)) THEN+ INFO = 7+ ELSE IF (INCX.EQ.0) THEN+ INFO = 9+ END IF+ IF (INFO.NE.0) THEN+ CALL XERBLA('STBMV ',INFO)+ RETURN+ END IF+*+* Quick return if possible.+*+ IF (N.EQ.0) RETURN+*+ NOUNIT = LSAME(DIAG,'N')+*+* Set up the start point in X if the increment is not unity. This+* will be ( N - 1 )*INCX too small for descending loops.+*+ IF (INCX.LE.0) THEN+ KX = 1 - (N-1)*INCX+ ELSE IF (INCX.NE.1) THEN+ KX = 1+ END IF+*+* Start the operations. In this version the elements of A are+* accessed sequentially with one pass through A.+*+ IF (LSAME(TRANS,'N')) THEN+*+* Form x := A*x.+*+ IF (LSAME(UPLO,'U')) THEN+ KPLUS1 = K + 1+ IF (INCX.EQ.1) THEN+ DO 20 J = 1,N+ IF (X(J).NE.ZERO) THEN+ TEMP = X(J)+ L = KPLUS1 - J+ DO 10 I = MAX(1,J-K),J - 1+ X(I) = X(I) + TEMP*A(L+I,J)+ 10 CONTINUE+ IF (NOUNIT) X(J) = X(J)*A(KPLUS1,J)+ END IF+ 20 CONTINUE+ ELSE+ JX = KX+ DO 40 J = 1,N+ IF (X(JX).NE.ZERO) THEN+ TEMP = X(JX)+ IX = KX+ L = KPLUS1 - J+ DO 30 I = MAX(1,J-K),J - 1+ X(IX) = X(IX) + TEMP*A(L+I,J)+ IX = IX + INCX+ 30 CONTINUE+ IF (NOUNIT) X(JX) = X(JX)*A(KPLUS1,J)+ END IF+ JX = JX + INCX+ IF (J.GT.K) KX = KX + INCX+ 40 CONTINUE+ END IF+ ELSE+ IF (INCX.EQ.1) THEN+ DO 60 J = N,1,-1+ IF (X(J).NE.ZERO) THEN+ TEMP = X(J)+ L = 1 - J+ DO 50 I = MIN(N,J+K),J + 1,-1+ X(I) = X(I) + TEMP*A(L+I,J)+ 50 CONTINUE+ IF (NOUNIT) X(J) = X(J)*A(1,J)+ END IF+ 60 CONTINUE+ ELSE+ KX = KX + (N-1)*INCX+ JX = KX+ DO 80 J = N,1,-1+ IF (X(JX).NE.ZERO) THEN+ TEMP = X(JX)+ IX = KX+ L = 1 - J+ DO 70 I = MIN(N,J+K),J + 1,-1+ X(IX) = X(IX) + TEMP*A(L+I,J)+ IX = IX - INCX+ 70 CONTINUE+ IF (NOUNIT) X(JX) = X(JX)*A(1,J)+ END IF+ JX = JX - INCX+ IF ((N-J).GE.K) KX = KX - INCX+ 80 CONTINUE+ END IF+ END IF+ ELSE+*+* Form x := A'*x.+*+ IF (LSAME(UPLO,'U')) THEN+ KPLUS1 = K + 1+ IF (INCX.EQ.1) THEN+ DO 100 J = N,1,-1+ TEMP = X(J)+ L = KPLUS1 - J+ IF (NOUNIT) TEMP = TEMP*A(KPLUS1,J)+ DO 90 I = J - 1,MAX(1,J-K),-1+ TEMP = TEMP + A(L+I,J)*X(I)+ 90 CONTINUE+ X(J) = TEMP+ 100 CONTINUE+ ELSE+ KX = KX + (N-1)*INCX+ JX = KX+ DO 120 J = N,1,-1+ TEMP = X(JX)+ KX = KX - INCX+ IX = KX+ L = KPLUS1 - J+ IF (NOUNIT) TEMP = TEMP*A(KPLUS1,J)+ DO 110 I = J - 1,MAX(1,J-K),-1+ TEMP = TEMP + A(L+I,J)*X(IX)+ IX = IX - INCX+ 110 CONTINUE+ X(JX) = TEMP+ JX = JX - INCX+ 120 CONTINUE+ END IF+ ELSE+ IF (INCX.EQ.1) THEN+ DO 140 J = 1,N+ TEMP = X(J)+ L = 1 - J+ IF (NOUNIT) TEMP = TEMP*A(1,J)+ DO 130 I = J + 1,MIN(N,J+K)+ TEMP = TEMP + A(L+I,J)*X(I)+ 130 CONTINUE+ X(J) = TEMP+ 140 CONTINUE+ ELSE+ JX = KX+ DO 160 J = 1,N+ TEMP = X(JX)+ KX = KX + INCX+ IX = KX+ L = 1 - J+ IF (NOUNIT) TEMP = TEMP*A(1,J)+ DO 150 I = J + 1,MIN(N,J+K)+ TEMP = TEMP + A(L+I,J)*X(IX)+ IX = IX + INCX+ 150 CONTINUE+ X(JX) = TEMP+ JX = JX + INCX+ 160 CONTINUE+ END IF+ END IF+ END IF+*+ RETURN+*+* End of STBMV .+*+ END
+ eigen3/blas/testing/CMakeLists.txt view
@@ -0,0 +1,40 @@++macro(ei_add_blas_test testname)++ set(targetname ${testname})++ set(filename ${testname}.f)+ add_executable(${targetname} ${filename})++ target_link_libraries(${targetname} eigen_blas)++ if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)+ target_link_libraries(${targetname} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})+ endif()++ target_link_libraries(${targetname} ${EXTERNAL_LIBS})++ add_test(${testname} "${Eigen_SOURCE_DIR}/blas/testing/runblastest.sh" "${testname}" "${Eigen_SOURCE_DIR}/blas/testing/${testname}.dat")+ add_dependencies(buildtests ${targetname})+ +endmacro(ei_add_blas_test)++ei_add_blas_test(sblat1)+ei_add_blas_test(sblat2)+ei_add_blas_test(sblat3)++ei_add_blas_test(dblat1)+ei_add_blas_test(dblat2)+ei_add_blas_test(dblat3)++ei_add_blas_test(cblat1)+ei_add_blas_test(cblat2)+ei_add_blas_test(cblat3)++ei_add_blas_test(zblat1)+ei_add_blas_test(zblat2)+ei_add_blas_test(zblat3)++# add_custom_target(level1)+# add_dependencies(level1 sblat1)+
+ eigen3/blas/testing/cblat1.f view
@@ -0,0 +1,681 @@+ PROGRAM CBLAT1+* Test program for the COMPLEX Level 1 BLAS.+* Based upon the original BLAS test routine together with:+* F06GAF Example Program Text+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, MODE, N+ LOGICAL PASS+* .. Local Scalars ..+ REAL SFAC+ INTEGER IC+* .. External Subroutines ..+ EXTERNAL CHECK1, CHECK2, HEADER+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, MODE, PASS+* .. Data statements ..+ DATA SFAC/9.765625E-4/+* .. Executable Statements ..+ WRITE (NOUT,99999)+ DO 20 IC = 1, 10+ ICASE = IC+ CALL HEADER+*+* Initialize PASS, INCX, INCY, and MODE for a new case.+* The value 9999 for INCX, INCY or MODE will appear in the+* detailed output, if any, for cases that do not involve+* these parameters.+*+ PASS = .TRUE.+ INCX = 9999+ INCY = 9999+ MODE = 9999+ IF (ICASE.LE.5) THEN+ CALL CHECK2(SFAC)+ ELSE IF (ICASE.GE.6) THEN+ CALL CHECK1(SFAC)+ END IF+* -- Print+ IF (PASS) WRITE (NOUT,99998)+ 20 CONTINUE+ STOP+*+99999 FORMAT (' Complex BLAS Test Program Results',/1X)+99998 FORMAT (' ----- PASS -----')+ END+ SUBROUTINE HEADER+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, MODE, N+ LOGICAL PASS+* .. Local Arrays ..+ CHARACTER*6 L(10)+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, MODE, PASS+* .. Data statements ..+ DATA L(1)/'CDOTC '/+ DATA L(2)/'CDOTU '/+ DATA L(3)/'CAXPY '/+ DATA L(4)/'CCOPY '/+ DATA L(5)/'CSWAP '/+ DATA L(6)/'SCNRM2'/+ DATA L(7)/'SCASUM'/+ DATA L(8)/'CSCAL '/+ DATA L(9)/'CSSCAL'/+ DATA L(10)/'ICAMAX'/+* .. Executable Statements ..+ WRITE (NOUT,99999) ICASE, L(ICASE)+ RETURN+*+99999 FORMAT (/' Test of subprogram number',I3,12X,A6)+ END+ SUBROUTINE CHECK1(SFAC)+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ REAL SFAC+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, MODE, N+ LOGICAL PASS+* .. Local Scalars ..+ COMPLEX CA+ REAL SA+ INTEGER I, J, LEN, NP1+* .. Local Arrays ..+ COMPLEX CTRUE5(8,5,2), CTRUE6(8,5,2), CV(8,5,2), CX(8),+ + MWPCS(5), MWPCT(5)+ REAL STRUE2(5), STRUE4(5)+ INTEGER ITRUE3(5)+* .. External Functions ..+ REAL SCASUM, SCNRM2+ INTEGER ICAMAX+ EXTERNAL SCASUM, SCNRM2, ICAMAX+* .. External Subroutines ..+ EXTERNAL CSCAL, CSSCAL, CTEST, ITEST1, STEST1+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, MODE, PASS+* .. Data statements ..+ DATA SA, CA/0.3E0, (0.4E0,-0.7E0)/+ DATA ((CV(I,J,1),I=1,8),J=1,5)/(0.1E0,0.1E0),+ + (1.0E0,2.0E0), (1.0E0,2.0E0), (1.0E0,2.0E0),+ + (1.0E0,2.0E0), (1.0E0,2.0E0), (1.0E0,2.0E0),+ + (1.0E0,2.0E0), (0.3E0,-0.4E0), (3.0E0,4.0E0),+ + (3.0E0,4.0E0), (3.0E0,4.0E0), (3.0E0,4.0E0),+ + (3.0E0,4.0E0), (3.0E0,4.0E0), (3.0E0,4.0E0),+ + (0.1E0,-0.3E0), (0.5E0,-0.1E0), (5.0E0,6.0E0),+ + (5.0E0,6.0E0), (5.0E0,6.0E0), (5.0E0,6.0E0),+ + (5.0E0,6.0E0), (5.0E0,6.0E0), (0.1E0,0.1E0),+ + (-0.6E0,0.1E0), (0.1E0,-0.3E0), (7.0E0,8.0E0),+ + (7.0E0,8.0E0), (7.0E0,8.0E0), (7.0E0,8.0E0),+ + (7.0E0,8.0E0), (0.3E0,0.1E0), (0.1E0,0.4E0),+ + (0.4E0,0.1E0), (0.1E0,0.2E0), (2.0E0,3.0E0),+ + (2.0E0,3.0E0), (2.0E0,3.0E0), (2.0E0,3.0E0)/+ DATA ((CV(I,J,2),I=1,8),J=1,5)/(0.1E0,0.1E0),+ + (4.0E0,5.0E0), (4.0E0,5.0E0), (4.0E0,5.0E0),+ + (4.0E0,5.0E0), (4.0E0,5.0E0), (4.0E0,5.0E0),+ + (4.0E0,5.0E0), (0.3E0,-0.4E0), (6.0E0,7.0E0),+ + (6.0E0,7.0E0), (6.0E0,7.0E0), (6.0E0,7.0E0),+ + (6.0E0,7.0E0), (6.0E0,7.0E0), (6.0E0,7.0E0),+ + (0.1E0,-0.3E0), (8.0E0,9.0E0), (0.5E0,-0.1E0),+ + (2.0E0,5.0E0), (2.0E0,5.0E0), (2.0E0,5.0E0),+ + (2.0E0,5.0E0), (2.0E0,5.0E0), (0.1E0,0.1E0),+ + (3.0E0,6.0E0), (-0.6E0,0.1E0), (4.0E0,7.0E0),+ + (0.1E0,-0.3E0), (7.0E0,2.0E0), (7.0E0,2.0E0),+ + (7.0E0,2.0E0), (0.3E0,0.1E0), (5.0E0,8.0E0),+ + (0.1E0,0.4E0), (6.0E0,9.0E0), (0.4E0,0.1E0),+ + (8.0E0,3.0E0), (0.1E0,0.2E0), (9.0E0,4.0E0)/+ DATA STRUE2/0.0E0, 0.5E0, 0.6E0, 0.7E0, 0.7E0/+ DATA STRUE4/0.0E0, 0.7E0, 1.0E0, 1.3E0, 1.7E0/+ DATA ((CTRUE5(I,J,1),I=1,8),J=1,5)/(0.1E0,0.1E0),+ + (1.0E0,2.0E0), (1.0E0,2.0E0), (1.0E0,2.0E0),+ + (1.0E0,2.0E0), (1.0E0,2.0E0), (1.0E0,2.0E0),+ + (1.0E0,2.0E0), (-0.16E0,-0.37E0), (3.0E0,4.0E0),+ + (3.0E0,4.0E0), (3.0E0,4.0E0), (3.0E0,4.0E0),+ + (3.0E0,4.0E0), (3.0E0,4.0E0), (3.0E0,4.0E0),+ + (-0.17E0,-0.19E0), (0.13E0,-0.39E0),+ + (5.0E0,6.0E0), (5.0E0,6.0E0), (5.0E0,6.0E0),+ + (5.0E0,6.0E0), (5.0E0,6.0E0), (5.0E0,6.0E0),+ + (0.11E0,-0.03E0), (-0.17E0,0.46E0),+ + (-0.17E0,-0.19E0), (7.0E0,8.0E0), (7.0E0,8.0E0),+ + (7.0E0,8.0E0), (7.0E0,8.0E0), (7.0E0,8.0E0),+ + (0.19E0,-0.17E0), (0.32E0,0.09E0),+ + (0.23E0,-0.24E0), (0.18E0,0.01E0),+ + (2.0E0,3.0E0), (2.0E0,3.0E0), (2.0E0,3.0E0),+ + (2.0E0,3.0E0)/+ DATA ((CTRUE5(I,J,2),I=1,8),J=1,5)/(0.1E0,0.1E0),+ + (4.0E0,5.0E0), (4.0E0,5.0E0), (4.0E0,5.0E0),+ + (4.0E0,5.0E0), (4.0E0,5.0E0), (4.0E0,5.0E0),+ + (4.0E0,5.0E0), (-0.16E0,-0.37E0), (6.0E0,7.0E0),+ + (6.0E0,7.0E0), (6.0E0,7.0E0), (6.0E0,7.0E0),+ + (6.0E0,7.0E0), (6.0E0,7.0E0), (6.0E0,7.0E0),+ + (-0.17E0,-0.19E0), (8.0E0,9.0E0),+ + (0.13E0,-0.39E0), (2.0E0,5.0E0), (2.0E0,5.0E0),+ + (2.0E0,5.0E0), (2.0E0,5.0E0), (2.0E0,5.0E0),+ + (0.11E0,-0.03E0), (3.0E0,6.0E0),+ + (-0.17E0,0.46E0), (4.0E0,7.0E0),+ + (-0.17E0,-0.19E0), (7.0E0,2.0E0), (7.0E0,2.0E0),+ + (7.0E0,2.0E0), (0.19E0,-0.17E0), (5.0E0,8.0E0),+ + (0.32E0,0.09E0), (6.0E0,9.0E0),+ + (0.23E0,-0.24E0), (8.0E0,3.0E0),+ + (0.18E0,0.01E0), (9.0E0,4.0E0)/+ DATA ((CTRUE6(I,J,1),I=1,8),J=1,5)/(0.1E0,0.1E0),+ + (1.0E0,2.0E0), (1.0E0,2.0E0), (1.0E0,2.0E0),+ + (1.0E0,2.0E0), (1.0E0,2.0E0), (1.0E0,2.0E0),+ + (1.0E0,2.0E0), (0.09E0,-0.12E0), (3.0E0,4.0E0),+ + (3.0E0,4.0E0), (3.0E0,4.0E0), (3.0E0,4.0E0),+ + (3.0E0,4.0E0), (3.0E0,4.0E0), (3.0E0,4.0E0),+ + (0.03E0,-0.09E0), (0.15E0,-0.03E0),+ + (5.0E0,6.0E0), (5.0E0,6.0E0), (5.0E0,6.0E0),+ + (5.0E0,6.0E0), (5.0E0,6.0E0), (5.0E0,6.0E0),+ + (0.03E0,0.03E0), (-0.18E0,0.03E0),+ + (0.03E0,-0.09E0), (7.0E0,8.0E0), (7.0E0,8.0E0),+ + (7.0E0,8.0E0), (7.0E0,8.0E0), (7.0E0,8.0E0),+ + (0.09E0,0.03E0), (0.03E0,0.12E0),+ + (0.12E0,0.03E0), (0.03E0,0.06E0), (2.0E0,3.0E0),+ + (2.0E0,3.0E0), (2.0E0,3.0E0), (2.0E0,3.0E0)/+ DATA ((CTRUE6(I,J,2),I=1,8),J=1,5)/(0.1E0,0.1E0),+ + (4.0E0,5.0E0), (4.0E0,5.0E0), (4.0E0,5.0E0),+ + (4.0E0,5.0E0), (4.0E0,5.0E0), (4.0E0,5.0E0),+ + (4.0E0,5.0E0), (0.09E0,-0.12E0), (6.0E0,7.0E0),+ + (6.0E0,7.0E0), (6.0E0,7.0E0), (6.0E0,7.0E0),+ + (6.0E0,7.0E0), (6.0E0,7.0E0), (6.0E0,7.0E0),+ + (0.03E0,-0.09E0), (8.0E0,9.0E0),+ + (0.15E0,-0.03E0), (2.0E0,5.0E0), (2.0E0,5.0E0),+ + (2.0E0,5.0E0), (2.0E0,5.0E0), (2.0E0,5.0E0),+ + (0.03E0,0.03E0), (3.0E0,6.0E0),+ + (-0.18E0,0.03E0), (4.0E0,7.0E0),+ + (0.03E0,-0.09E0), (7.0E0,2.0E0), (7.0E0,2.0E0),+ + (7.0E0,2.0E0), (0.09E0,0.03E0), (5.0E0,8.0E0),+ + (0.03E0,0.12E0), (6.0E0,9.0E0), (0.12E0,0.03E0),+ + (8.0E0,3.0E0), (0.03E0,0.06E0), (9.0E0,4.0E0)/+ DATA ITRUE3/0, 1, 2, 2, 2/+* .. Executable Statements ..+ DO 60 INCX = 1, 2+ DO 40 NP1 = 1, 5+ N = NP1 - 1+ LEN = 2*MAX(N,1)+* .. Set vector arguments ..+ DO 20 I = 1, LEN+ CX(I) = CV(I,NP1,INCX)+ 20 CONTINUE+ IF (ICASE.EQ.6) THEN+* .. SCNRM2 ..+ CALL STEST1(SCNRM2(N,CX,INCX),STRUE2(NP1),STRUE2(NP1),+ + SFAC)+ ELSE IF (ICASE.EQ.7) THEN+* .. SCASUM ..+ CALL STEST1(SCASUM(N,CX,INCX),STRUE4(NP1),STRUE4(NP1),+ + SFAC)+ ELSE IF (ICASE.EQ.8) THEN+* .. CSCAL ..+ CALL CSCAL(N,CA,CX,INCX)+ CALL CTEST(LEN,CX,CTRUE5(1,NP1,INCX),CTRUE5(1,NP1,INCX),+ + SFAC)+ ELSE IF (ICASE.EQ.9) THEN+* .. CSSCAL ..+ CALL CSSCAL(N,SA,CX,INCX)+ CALL CTEST(LEN,CX,CTRUE6(1,NP1,INCX),CTRUE6(1,NP1,INCX),+ + SFAC)+ ELSE IF (ICASE.EQ.10) THEN+* .. ICAMAX ..+ CALL ITEST1(ICAMAX(N,CX,INCX),ITRUE3(NP1))+ ELSE+ WRITE (NOUT,*) ' Shouldn''t be here in CHECK1'+ STOP+ END IF+*+ 40 CONTINUE+ 60 CONTINUE+*+ INCX = 1+ IF (ICASE.EQ.8) THEN+* CSCAL+* Add a test for alpha equal to zero.+ CA = (0.0E0,0.0E0)+ DO 80 I = 1, 5+ MWPCT(I) = (0.0E0,0.0E0)+ MWPCS(I) = (1.0E0,1.0E0)+ 80 CONTINUE+ CALL CSCAL(5,CA,CX,INCX)+ CALL CTEST(5,CX,MWPCT,MWPCS,SFAC)+ ELSE IF (ICASE.EQ.9) THEN+* CSSCAL+* Add a test for alpha equal to zero.+ SA = 0.0E0+ DO 100 I = 1, 5+ MWPCT(I) = (0.0E0,0.0E0)+ MWPCS(I) = (1.0E0,1.0E0)+ 100 CONTINUE+ CALL CSSCAL(5,SA,CX,INCX)+ CALL CTEST(5,CX,MWPCT,MWPCS,SFAC)+* Add a test for alpha equal to one.+ SA = 1.0E0+ DO 120 I = 1, 5+ MWPCT(I) = CX(I)+ MWPCS(I) = CX(I)+ 120 CONTINUE+ CALL CSSCAL(5,SA,CX,INCX)+ CALL CTEST(5,CX,MWPCT,MWPCS,SFAC)+* Add a test for alpha equal to minus one.+ SA = -1.0E0+ DO 140 I = 1, 5+ MWPCT(I) = -CX(I)+ MWPCS(I) = -CX(I)+ 140 CONTINUE+ CALL CSSCAL(5,SA,CX,INCX)+ CALL CTEST(5,CX,MWPCT,MWPCS,SFAC)+ END IF+ RETURN+ END+ SUBROUTINE CHECK2(SFAC)+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ REAL SFAC+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, MODE, N+ LOGICAL PASS+* .. Local Scalars ..+ COMPLEX CA+ INTEGER I, J, KI, KN, KSIZE, LENX, LENY, MX, MY+* .. Local Arrays ..+ COMPLEX CDOT(1), CSIZE1(4), CSIZE2(7,2), CSIZE3(14),+ + CT10X(7,4,4), CT10Y(7,4,4), CT6(4,4), CT7(4,4),+ + CT8(7,4,4), CX(7), CX1(7), CY(7), CY1(7)+ INTEGER INCXS(4), INCYS(4), LENS(4,2), NS(4)+* .. External Functions ..+ COMPLEX CDOTC, CDOTU+ EXTERNAL CDOTC, CDOTU+* .. External Subroutines ..+ EXTERNAL CAXPY, CCOPY, CSWAP, CTEST+* .. Intrinsic Functions ..+ INTRINSIC ABS, MIN+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, MODE, PASS+* .. Data statements ..+ DATA CA/(0.4E0,-0.7E0)/+ DATA INCXS/1, 2, -2, -1/+ DATA INCYS/1, -2, 1, -2/+ DATA LENS/1, 1, 2, 4, 1, 1, 3, 7/+ DATA NS/0, 1, 2, 4/+ DATA CX1/(0.7E0,-0.8E0), (-0.4E0,-0.7E0),+ + (-0.1E0,-0.9E0), (0.2E0,-0.8E0),+ + (-0.9E0,-0.4E0), (0.1E0,0.4E0), (-0.6E0,0.6E0)/+ DATA CY1/(0.6E0,-0.6E0), (-0.9E0,0.5E0),+ + (0.7E0,-0.6E0), (0.1E0,-0.5E0), (-0.1E0,-0.2E0),+ + (-0.5E0,-0.3E0), (0.8E0,-0.7E0)/+ DATA ((CT8(I,J,1),I=1,7),J=1,4)/(0.6E0,-0.6E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.32E0,-1.41E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.32E0,-1.41E0),+ + (-1.55E0,0.5E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.32E0,-1.41E0), (-1.55E0,0.5E0),+ + (0.03E0,-0.89E0), (-0.38E0,-0.96E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0)/+ DATA ((CT8(I,J,2),I=1,7),J=1,4)/(0.6E0,-0.6E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.32E0,-1.41E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (-0.07E0,-0.89E0),+ + (-0.9E0,0.5E0), (0.42E0,-1.41E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.78E0,0.06E0), (-0.9E0,0.5E0),+ + (0.06E0,-0.13E0), (0.1E0,-0.5E0),+ + (-0.77E0,-0.49E0), (-0.5E0,-0.3E0),+ + (0.52E0,-1.51E0)/+ DATA ((CT8(I,J,3),I=1,7),J=1,4)/(0.6E0,-0.6E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.32E0,-1.41E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (-0.07E0,-0.89E0),+ + (-1.18E0,-0.31E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.78E0,0.06E0), (-1.54E0,0.97E0),+ + (0.03E0,-0.89E0), (-0.18E0,-1.31E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0)/+ DATA ((CT8(I,J,4),I=1,7),J=1,4)/(0.6E0,-0.6E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.32E0,-1.41E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.32E0,-1.41E0), (-0.9E0,0.5E0),+ + (0.05E0,-0.6E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.32E0,-1.41E0),+ + (-0.9E0,0.5E0), (0.05E0,-0.6E0), (0.1E0,-0.5E0),+ + (-0.77E0,-0.49E0), (-0.5E0,-0.3E0),+ + (0.32E0,-1.16E0)/+ DATA CT7/(0.0E0,0.0E0), (-0.06E0,-0.90E0),+ + (0.65E0,-0.47E0), (-0.34E0,-1.22E0),+ + (0.0E0,0.0E0), (-0.06E0,-0.90E0),+ + (-0.59E0,-1.46E0), (-1.04E0,-0.04E0),+ + (0.0E0,0.0E0), (-0.06E0,-0.90E0),+ + (-0.83E0,0.59E0), (0.07E0,-0.37E0),+ + (0.0E0,0.0E0), (-0.06E0,-0.90E0),+ + (-0.76E0,-1.15E0), (-1.33E0,-1.82E0)/+ DATA CT6/(0.0E0,0.0E0), (0.90E0,0.06E0),+ + (0.91E0,-0.77E0), (1.80E0,-0.10E0),+ + (0.0E0,0.0E0), (0.90E0,0.06E0), (1.45E0,0.74E0),+ + (0.20E0,0.90E0), (0.0E0,0.0E0), (0.90E0,0.06E0),+ + (-0.55E0,0.23E0), (0.83E0,-0.39E0),+ + (0.0E0,0.0E0), (0.90E0,0.06E0), (1.04E0,0.79E0),+ + (1.95E0,1.22E0)/+ DATA ((CT10X(I,J,1),I=1,7),J=1,4)/(0.7E0,-0.8E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.6E0,-0.6E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.6E0,-0.6E0), (-0.9E0,0.5E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.6E0,-0.6E0),+ + (-0.9E0,0.5E0), (0.7E0,-0.6E0), (0.1E0,-0.5E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0)/+ DATA ((CT10X(I,J,2),I=1,7),J=1,4)/(0.7E0,-0.8E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.6E0,-0.6E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.7E0,-0.6E0), (-0.4E0,-0.7E0),+ + (0.6E0,-0.6E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.8E0,-0.7E0),+ + (-0.4E0,-0.7E0), (-0.1E0,-0.2E0),+ + (0.2E0,-0.8E0), (0.7E0,-0.6E0), (0.1E0,0.4E0),+ + (0.6E0,-0.6E0)/+ DATA ((CT10X(I,J,3),I=1,7),J=1,4)/(0.7E0,-0.8E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.6E0,-0.6E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (-0.9E0,0.5E0), (-0.4E0,-0.7E0),+ + (0.6E0,-0.6E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.1E0,-0.5E0),+ + (-0.4E0,-0.7E0), (0.7E0,-0.6E0), (0.2E0,-0.8E0),+ + (-0.9E0,0.5E0), (0.1E0,0.4E0), (0.6E0,-0.6E0)/+ DATA ((CT10X(I,J,4),I=1,7),J=1,4)/(0.7E0,-0.8E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.6E0,-0.6E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.6E0,-0.6E0), (0.7E0,-0.6E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.6E0,-0.6E0),+ + (0.7E0,-0.6E0), (-0.1E0,-0.2E0), (0.8E0,-0.7E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0)/+ DATA ((CT10Y(I,J,1),I=1,7),J=1,4)/(0.6E0,-0.6E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.7E0,-0.8E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.7E0,-0.8E0), (-0.4E0,-0.7E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.7E0,-0.8E0),+ + (-0.4E0,-0.7E0), (-0.1E0,-0.9E0),+ + (0.2E0,-0.8E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0)/+ DATA ((CT10Y(I,J,2),I=1,7),J=1,4)/(0.6E0,-0.6E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.7E0,-0.8E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (-0.1E0,-0.9E0), (-0.9E0,0.5E0),+ + (0.7E0,-0.8E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (-0.6E0,0.6E0),+ + (-0.9E0,0.5E0), (-0.9E0,-0.4E0), (0.1E0,-0.5E0),+ + (-0.1E0,-0.9E0), (-0.5E0,-0.3E0),+ + (0.7E0,-0.8E0)/+ DATA ((CT10Y(I,J,3),I=1,7),J=1,4)/(0.6E0,-0.6E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.7E0,-0.8E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (-0.1E0,-0.9E0), (0.7E0,-0.8E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (-0.6E0,0.6E0),+ + (-0.9E0,-0.4E0), (-0.1E0,-0.9E0),+ + (0.7E0,-0.8E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0)/+ DATA ((CT10Y(I,J,4),I=1,7),J=1,4)/(0.6E0,-0.6E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.7E0,-0.8E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.7E0,-0.8E0), (-0.9E0,0.5E0),+ + (-0.4E0,-0.7E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.7E0,-0.8E0),+ + (-0.9E0,0.5E0), (-0.4E0,-0.7E0), (0.1E0,-0.5E0),+ + (-0.1E0,-0.9E0), (-0.5E0,-0.3E0),+ + (0.2E0,-0.8E0)/+ DATA CSIZE1/(0.0E0,0.0E0), (0.9E0,0.9E0),+ + (1.63E0,1.73E0), (2.90E0,2.78E0)/+ DATA CSIZE3/(0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (1.17E0,1.17E0),+ + (1.17E0,1.17E0), (1.17E0,1.17E0),+ + (1.17E0,1.17E0), (1.17E0,1.17E0),+ + (1.17E0,1.17E0), (1.17E0,1.17E0)/+ DATA CSIZE2/(0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (0.0E0,0.0E0),+ + (0.0E0,0.0E0), (0.0E0,0.0E0), (1.54E0,1.54E0),+ + (1.54E0,1.54E0), (1.54E0,1.54E0),+ + (1.54E0,1.54E0), (1.54E0,1.54E0),+ + (1.54E0,1.54E0), (1.54E0,1.54E0)/+* .. Executable Statements ..+ DO 60 KI = 1, 4+ INCX = INCXS(KI)+ INCY = INCYS(KI)+ MX = ABS(INCX)+ MY = ABS(INCY)+*+ DO 40 KN = 1, 4+ N = NS(KN)+ KSIZE = MIN(2,KN)+ LENX = LENS(KN,MX)+ LENY = LENS(KN,MY)+* .. initialize all argument arrays ..+ DO 20 I = 1, 7+ CX(I) = CX1(I)+ CY(I) = CY1(I)+ 20 CONTINUE+ IF (ICASE.EQ.1) THEN+* .. CDOTC ..+ CDOT(1) = CDOTC(N,CX,INCX,CY,INCY)+ CALL CTEST(1,CDOT,CT6(KN,KI),CSIZE1(KN),SFAC)+ ELSE IF (ICASE.EQ.2) THEN+* .. CDOTU ..+ CDOT(1) = CDOTU(N,CX,INCX,CY,INCY)+ CALL CTEST(1,CDOT,CT7(KN,KI),CSIZE1(KN),SFAC)+ ELSE IF (ICASE.EQ.3) THEN+* .. CAXPY ..+ CALL CAXPY(N,CA,CX,INCX,CY,INCY)+ CALL CTEST(LENY,CY,CT8(1,KN,KI),CSIZE2(1,KSIZE),SFAC)+ ELSE IF (ICASE.EQ.4) THEN+* .. CCOPY ..+ CALL CCOPY(N,CX,INCX,CY,INCY)+ CALL CTEST(LENY,CY,CT10Y(1,KN,KI),CSIZE3,1.0E0)+ ELSE IF (ICASE.EQ.5) THEN+* .. CSWAP ..+ CALL CSWAP(N,CX,INCX,CY,INCY)+ CALL CTEST(LENX,CX,CT10X(1,KN,KI),CSIZE3,1.0E0)+ CALL CTEST(LENY,CY,CT10Y(1,KN,KI),CSIZE3,1.0E0)+ ELSE+ WRITE (NOUT,*) ' Shouldn''t be here in CHECK2'+ STOP+ END IF+*+ 40 CONTINUE+ 60 CONTINUE+ RETURN+ END+ SUBROUTINE STEST(LEN,SCOMP,STRUE,SSIZE,SFAC)+* ********************************* STEST **************************+*+* THIS SUBR COMPARES ARRAYS SCOMP() AND STRUE() OF LENGTH LEN TO+* SEE IF THE TERM BY TERM DIFFERENCES, MULTIPLIED BY SFAC, ARE+* NEGLIGIBLE.+*+* C. L. LAWSON, JPL, 1974 DEC 10+*+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ REAL SFAC+ INTEGER LEN+* .. Array Arguments ..+ REAL SCOMP(LEN), SSIZE(LEN), STRUE(LEN)+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, MODE, N+ LOGICAL PASS+* .. Local Scalars ..+ REAL SD+ INTEGER I+* .. External Functions ..+ REAL SDIFF+ EXTERNAL SDIFF+* .. Intrinsic Functions ..+ INTRINSIC ABS+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, MODE, PASS+* .. Executable Statements ..+*+ DO 40 I = 1, LEN+ SD = SCOMP(I) - STRUE(I)+ IF (SDIFF(ABS(SSIZE(I))+ABS(SFAC*SD),ABS(SSIZE(I))).EQ.0.0E0)+ + GO TO 40+*+* HERE SCOMP(I) IS NOT CLOSE TO STRUE(I).+*+ IF ( .NOT. PASS) GO TO 20+* PRINT FAIL MESSAGE AND HEADER.+ PASS = .FALSE.+ WRITE (NOUT,99999)+ WRITE (NOUT,99998)+ 20 WRITE (NOUT,99997) ICASE, N, INCX, INCY, MODE, I, SCOMP(I),+ + STRUE(I), SD, SSIZE(I)+ 40 CONTINUE+ RETURN+*+99999 FORMAT (' FAIL')+99998 FORMAT (/' CASE N INCX INCY MODE I ',+ + ' COMP(I) TRUE(I) DIFFERENCE',+ + ' SIZE(I)',/1X)+99997 FORMAT (1X,I4,I3,3I5,I3,2E36.8,2E12.4)+ END+ SUBROUTINE STEST1(SCOMP1,STRUE1,SSIZE,SFAC)+* ************************* STEST1 *****************************+*+* THIS IS AN INTERFACE SUBROUTINE TO ACCOMODATE THE FORTRAN+* REQUIREMENT THAT WHEN A DUMMY ARGUMENT IS AN ARRAY, THE+* ACTUAL ARGUMENT MUST ALSO BE AN ARRAY OR AN ARRAY ELEMENT.+*+* C.L. LAWSON, JPL, 1978 DEC 6+*+* .. Scalar Arguments ..+ REAL SCOMP1, SFAC, STRUE1+* .. Array Arguments ..+ REAL SSIZE(*)+* .. Local Arrays ..+ REAL SCOMP(1), STRUE(1)+* .. External Subroutines ..+ EXTERNAL STEST+* .. Executable Statements ..+*+ SCOMP(1) = SCOMP1+ STRUE(1) = STRUE1+ CALL STEST(1,SCOMP,STRUE,SSIZE,SFAC)+*+ RETURN+ END+ REAL FUNCTION SDIFF(SA,SB)+* ********************************* SDIFF **************************+* COMPUTES DIFFERENCE OF TWO NUMBERS. C. L. LAWSON, JPL 1974 FEB 15+*+* .. Scalar Arguments ..+ REAL SA, SB+* .. Executable Statements ..+ SDIFF = SA - SB+ RETURN+ END+ SUBROUTINE CTEST(LEN,CCOMP,CTRUE,CSIZE,SFAC)+* **************************** CTEST *****************************+*+* C.L. LAWSON, JPL, 1978 DEC 6+*+* .. Scalar Arguments ..+ REAL SFAC+ INTEGER LEN+* .. Array Arguments ..+ COMPLEX CCOMP(LEN), CSIZE(LEN), CTRUE(LEN)+* .. Local Scalars ..+ INTEGER I+* .. Local Arrays ..+ REAL SCOMP(20), SSIZE(20), STRUE(20)+* .. External Subroutines ..+ EXTERNAL STEST+* .. Intrinsic Functions ..+ INTRINSIC AIMAG, REAL+* .. Executable Statements ..+ DO 20 I = 1, LEN+ SCOMP(2*I-1) = REAL(CCOMP(I))+ SCOMP(2*I) = AIMAG(CCOMP(I))+ STRUE(2*I-1) = REAL(CTRUE(I))+ STRUE(2*I) = AIMAG(CTRUE(I))+ SSIZE(2*I-1) = REAL(CSIZE(I))+ SSIZE(2*I) = AIMAG(CSIZE(I))+ 20 CONTINUE+*+ CALL STEST(2*LEN,SCOMP,STRUE,SSIZE,SFAC)+ RETURN+ END+ SUBROUTINE ITEST1(ICOMP,ITRUE)+* ********************************* ITEST1 *************************+*+* THIS SUBROUTINE COMPARES THE VARIABLES ICOMP AND ITRUE FOR+* EQUALITY.+* C. L. LAWSON, JPL, 1974 DEC 10+*+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ INTEGER ICOMP, ITRUE+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, MODE, N+ LOGICAL PASS+* .. Local Scalars ..+ INTEGER ID+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, MODE, PASS+* .. Executable Statements ..+ IF (ICOMP.EQ.ITRUE) GO TO 40+*+* HERE ICOMP IS NOT EQUAL TO ITRUE.+*+ IF ( .NOT. PASS) GO TO 20+* PRINT FAIL MESSAGE AND HEADER.+ PASS = .FALSE.+ WRITE (NOUT,99999)+ WRITE (NOUT,99998)+ 20 ID = ICOMP - ITRUE+ WRITE (NOUT,99997) ICASE, N, INCX, INCY, MODE, ICOMP, ITRUE, ID+ 40 CONTINUE+ RETURN+*+99999 FORMAT (' FAIL')+99998 FORMAT (/' CASE N INCX INCY MODE ',+ + ' COMP TRUE DIFFERENCE',+ + /1X)+99997 FORMAT (1X,I4,I3,3I5,2I36,I12)+ END
+ eigen3/blas/testing/cblat2.dat view
@@ -0,0 +1,35 @@+'cblat2.summ' NAME OF SUMMARY OUTPUT FILE+6 UNIT NUMBER OF SUMMARY FILE+'cblat2.snap' NAME OF SNAPSHOT OUTPUT FILE+-1 UNIT NUMBER OF SNAPSHOT FILE (NOT USED IF .LT. 0)+F LOGICAL FLAG, T TO REWIND SNAPSHOT FILE AFTER EACH RECORD.+F LOGICAL FLAG, T TO STOP ON FAILURES.+T LOGICAL FLAG, T TO TEST ERROR EXITS.+16.0 THRESHOLD VALUE OF TEST RATIO+6 NUMBER OF VALUES OF N+0 1 2 3 5 9 VALUES OF N+4 NUMBER OF VALUES OF K+0 1 2 4 VALUES OF K+4 NUMBER OF VALUES OF INCX AND INCY+1 2 -1 -2 VALUES OF INCX AND INCY+3 NUMBER OF VALUES OF ALPHA+(0.0,0.0) (1.0,0.0) (0.7,-0.9) VALUES OF ALPHA+3 NUMBER OF VALUES OF BETA+(0.0,0.0) (1.0,0.0) (1.3,-1.1) VALUES OF BETA+CGEMV T PUT F FOR NO TEST. SAME COLUMNS.+CGBMV T PUT F FOR NO TEST. SAME COLUMNS.+CHEMV T PUT F FOR NO TEST. SAME COLUMNS.+CHBMV T PUT F FOR NO TEST. SAME COLUMNS.+CHPMV T PUT F FOR NO TEST. SAME COLUMNS.+CTRMV T PUT F FOR NO TEST. SAME COLUMNS.+CTBMV T PUT F FOR NO TEST. SAME COLUMNS.+CTPMV T PUT F FOR NO TEST. SAME COLUMNS.+CTRSV T PUT F FOR NO TEST. SAME COLUMNS.+CTBSV T PUT F FOR NO TEST. SAME COLUMNS.+CTPSV T PUT F FOR NO TEST. SAME COLUMNS.+CGERC T PUT F FOR NO TEST. SAME COLUMNS.+CGERU T PUT F FOR NO TEST. SAME COLUMNS.+CHER T PUT F FOR NO TEST. SAME COLUMNS.+CHPR T PUT F FOR NO TEST. SAME COLUMNS.+CHER2 T PUT F FOR NO TEST. SAME COLUMNS.+CHPR2 T PUT F FOR NO TEST. SAME COLUMNS.
+ eigen3/blas/testing/cblat2.f view
@@ -0,0 +1,3241 @@+ PROGRAM CBLAT2+*+* Test program for the COMPLEX Level 2 Blas.+*+* The program must be driven by a short data file. The first 18 records+* of the file are read using list-directed input, the last 17 records+* are read using the format ( A6, L2 ). An annotated example of a data+* file can be obtained by deleting the first 3 characters from the+* following 35 lines:+* 'CBLAT2.SUMM' NAME OF SUMMARY OUTPUT FILE+* 6 UNIT NUMBER OF SUMMARY FILE+* 'CBLA2T.SNAP' NAME OF SNAPSHOT OUTPUT FILE+* -1 UNIT NUMBER OF SNAPSHOT FILE (NOT USED IF .LT. 0)+* F LOGICAL FLAG, T TO REWIND SNAPSHOT FILE AFTER EACH RECORD.+* F LOGICAL FLAG, T TO STOP ON FAILURES.+* T LOGICAL FLAG, T TO TEST ERROR EXITS.+* 16.0 THRESHOLD VALUE OF TEST RATIO+* 6 NUMBER OF VALUES OF N+* 0 1 2 3 5 9 VALUES OF N+* 4 NUMBER OF VALUES OF K+* 0 1 2 4 VALUES OF K+* 4 NUMBER OF VALUES OF INCX AND INCY+* 1 2 -1 -2 VALUES OF INCX AND INCY+* 3 NUMBER OF VALUES OF ALPHA+* (0.0,0.0) (1.0,0.0) (0.7,-0.9) VALUES OF ALPHA+* 3 NUMBER OF VALUES OF BETA+* (0.0,0.0) (1.0,0.0) (1.3,-1.1) VALUES OF BETA+* CGEMV T PUT F FOR NO TEST. SAME COLUMNS.+* CGBMV T PUT F FOR NO TEST. SAME COLUMNS.+* CHEMV T PUT F FOR NO TEST. SAME COLUMNS.+* CHBMV T PUT F FOR NO TEST. SAME COLUMNS.+* CHPMV T PUT F FOR NO TEST. SAME COLUMNS.+* CTRMV T PUT F FOR NO TEST. SAME COLUMNS.+* CTBMV T PUT F FOR NO TEST. SAME COLUMNS.+* CTPMV T PUT F FOR NO TEST. SAME COLUMNS.+* CTRSV T PUT F FOR NO TEST. SAME COLUMNS.+* CTBSV T PUT F FOR NO TEST. SAME COLUMNS.+* CTPSV T PUT F FOR NO TEST. SAME COLUMNS.+* CGERC T PUT F FOR NO TEST. SAME COLUMNS.+* CGERU T PUT F FOR NO TEST. SAME COLUMNS.+* CHER T PUT F FOR NO TEST. SAME COLUMNS.+* CHPR T PUT F FOR NO TEST. SAME COLUMNS.+* CHER2 T PUT F FOR NO TEST. SAME COLUMNS.+* CHPR2 T PUT F FOR NO TEST. SAME COLUMNS.+*+* See:+*+* Dongarra J. J., Du Croz J. J., Hammarling S. and Hanson R. J..+* An extended set of Fortran Basic Linear Algebra Subprograms.+*+* Technical Memoranda Nos. 41 (revision 3) and 81, Mathematics+* and Computer Science Division, Argonne National Laboratory,+* 9700 South Cass Avenue, Argonne, Illinois 60439, US.+*+* Or+*+* NAG Technical Reports TR3/87 and TR4/87, Numerical Algorithms+* Group Ltd., NAG Central Office, 256 Banbury Road, Oxford+* OX2 7DE, UK, and Numerical Algorithms Group Inc., 1101 31st+* Street, Suite 100, Downers Grove, Illinois 60515-1263, USA.+*+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ INTEGER NIN+ PARAMETER ( NIN = 5 )+ INTEGER NSUBS+ PARAMETER ( NSUBS = 17 )+ COMPLEX ZERO, ONE+ PARAMETER ( ZERO = ( 0.0, 0.0 ), ONE = ( 1.0, 0.0 ) )+ REAL RZERO, RHALF, RONE+ PARAMETER ( RZERO = 0.0, RHALF = 0.5, RONE = 1.0 )+ INTEGER NMAX, INCMAX+ PARAMETER ( NMAX = 65, INCMAX = 2 )+ INTEGER NINMAX, NIDMAX, NKBMAX, NALMAX, NBEMAX+ PARAMETER ( NINMAX = 7, NIDMAX = 9, NKBMAX = 7,+ $ NALMAX = 7, NBEMAX = 7 )+* .. Local Scalars ..+ REAL EPS, ERR, THRESH+ INTEGER I, ISNUM, J, N, NALF, NBET, NIDIM, NINC, NKB,+ $ NOUT, NTRA+ LOGICAL FATAL, LTESTT, REWI, SAME, SFATAL, TRACE,+ $ TSTERR+ CHARACTER*1 TRANS+ CHARACTER*6 SNAMET+ CHARACTER*32 SNAPS, SUMMRY+* .. Local Arrays ..+ COMPLEX A( NMAX, NMAX ), AA( NMAX*NMAX ),+ $ ALF( NALMAX ), AS( NMAX*NMAX ), BET( NBEMAX ),+ $ X( NMAX ), XS( NMAX*INCMAX ),+ $ XX( NMAX*INCMAX ), Y( NMAX ),+ $ YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX ), Z( 2*NMAX )+ REAL G( NMAX )+ INTEGER IDIM( NIDMAX ), INC( NINMAX ), KB( NKBMAX )+ LOGICAL LTEST( NSUBS )+ CHARACTER*6 SNAMES( NSUBS )+* .. External Functions ..+ REAL SDIFF+ LOGICAL LCE+ EXTERNAL SDIFF, LCE+* .. External Subroutines ..+ EXTERNAL CCHK1, CCHK2, CCHK3, CCHK4, CCHK5, CCHK6,+ $ CCHKE, CMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, MIN+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+ COMMON /SRNAMC/SRNAMT+* .. Data statements ..+ DATA SNAMES/'CGEMV ', 'CGBMV ', 'CHEMV ', 'CHBMV ',+ $ 'CHPMV ', 'CTRMV ', 'CTBMV ', 'CTPMV ',+ $ 'CTRSV ', 'CTBSV ', 'CTPSV ', 'CGERC ',+ $ 'CGERU ', 'CHER ', 'CHPR ', 'CHER2 ',+ $ 'CHPR2 '/+* .. Executable Statements ..+*+* Read name and unit number for summary output file and open file.+*+ READ( NIN, FMT = * )SUMMRY+ READ( NIN, FMT = * )NOUT+ OPEN( NOUT, FILE = SUMMRY, STATUS = 'NEW' )+ NOUTC = NOUT+*+* Read name and unit number for snapshot output file and open file.+*+ READ( NIN, FMT = * )SNAPS+ READ( NIN, FMT = * )NTRA+ TRACE = NTRA.GE.0+ IF( TRACE )THEN+ OPEN( NTRA, FILE = SNAPS, STATUS = 'NEW' )+ END IF+* Read the flag that directs rewinding of the snapshot file.+ READ( NIN, FMT = * )REWI+ REWI = REWI.AND.TRACE+* Read the flag that directs stopping on any failure.+ READ( NIN, FMT = * )SFATAL+* Read the flag that indicates whether error exits are to be tested.+ READ( NIN, FMT = * )TSTERR+* Read the threshold value of the test ratio+ READ( NIN, FMT = * )THRESH+*+* Read and check the parameter values for the tests.+*+* Values of N+ READ( NIN, FMT = * )NIDIM+ IF( NIDIM.LT.1.OR.NIDIM.GT.NIDMAX )THEN+ WRITE( NOUT, FMT = 9997 )'N', NIDMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( IDIM( I ), I = 1, NIDIM )+ DO 10 I = 1, NIDIM+ IF( IDIM( I ).LT.0.OR.IDIM( I ).GT.NMAX )THEN+ WRITE( NOUT, FMT = 9996 )NMAX+ GO TO 230+ END IF+ 10 CONTINUE+* Values of K+ READ( NIN, FMT = * )NKB+ IF( NKB.LT.1.OR.NKB.GT.NKBMAX )THEN+ WRITE( NOUT, FMT = 9997 )'K', NKBMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( KB( I ), I = 1, NKB )+ DO 20 I = 1, NKB+ IF( KB( I ).LT.0 )THEN+ WRITE( NOUT, FMT = 9995 )+ GO TO 230+ END IF+ 20 CONTINUE+* Values of INCX and INCY+ READ( NIN, FMT = * )NINC+ IF( NINC.LT.1.OR.NINC.GT.NINMAX )THEN+ WRITE( NOUT, FMT = 9997 )'INCX AND INCY', NINMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( INC( I ), I = 1, NINC )+ DO 30 I = 1, NINC+ IF( INC( I ).EQ.0.OR.ABS( INC( I ) ).GT.INCMAX )THEN+ WRITE( NOUT, FMT = 9994 )INCMAX+ GO TO 230+ END IF+ 30 CONTINUE+* Values of ALPHA+ READ( NIN, FMT = * )NALF+ IF( NALF.LT.1.OR.NALF.GT.NALMAX )THEN+ WRITE( NOUT, FMT = 9997 )'ALPHA', NALMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( ALF( I ), I = 1, NALF )+* Values of BETA+ READ( NIN, FMT = * )NBET+ IF( NBET.LT.1.OR.NBET.GT.NBEMAX )THEN+ WRITE( NOUT, FMT = 9997 )'BETA', NBEMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( BET( I ), I = 1, NBET )+*+* Report values of parameters.+*+ WRITE( NOUT, FMT = 9993 )+ WRITE( NOUT, FMT = 9992 )( IDIM( I ), I = 1, NIDIM )+ WRITE( NOUT, FMT = 9991 )( KB( I ), I = 1, NKB )+ WRITE( NOUT, FMT = 9990 )( INC( I ), I = 1, NINC )+ WRITE( NOUT, FMT = 9989 )( ALF( I ), I = 1, NALF )+ WRITE( NOUT, FMT = 9988 )( BET( I ), I = 1, NBET )+ IF( .NOT.TSTERR )THEN+ WRITE( NOUT, FMT = * )+ WRITE( NOUT, FMT = 9980 )+ END IF+ WRITE( NOUT, FMT = * )+ WRITE( NOUT, FMT = 9999 )THRESH+ WRITE( NOUT, FMT = * )+*+* Read names of subroutines and flags which indicate+* whether they are to be tested.+*+ DO 40 I = 1, NSUBS+ LTEST( I ) = .FALSE.+ 40 CONTINUE+ 50 READ( NIN, FMT = 9984, END = 80 )SNAMET, LTESTT+ DO 60 I = 1, NSUBS+ IF( SNAMET.EQ.SNAMES( I ) )+ $ GO TO 70+ 60 CONTINUE+ WRITE( NOUT, FMT = 9986 )SNAMET+ STOP+ 70 LTEST( I ) = LTESTT+ GO TO 50+*+ 80 CONTINUE+ CLOSE ( NIN )+*+* Compute EPS (the machine precision).+*+ EPS = RONE+ 90 CONTINUE+ IF( SDIFF( RONE + EPS, RONE ).EQ.RZERO )+ $ GO TO 100+ EPS = RHALF*EPS+ GO TO 90+ 100 CONTINUE+ EPS = EPS + EPS+ WRITE( NOUT, FMT = 9998 )EPS+*+* Check the reliability of CMVCH using exact data.+*+ N = MIN( 32, NMAX )+ DO 120 J = 1, N+ DO 110 I = 1, N+ A( I, J ) = MAX( I - J + 1, 0 )+ 110 CONTINUE+ X( J ) = J+ Y( J ) = ZERO+ 120 CONTINUE+ DO 130 J = 1, N+ YY( J ) = J*( ( J + 1 )*J )/2 - ( ( J + 1 )*J*( J - 1 ) )/3+ 130 CONTINUE+* YY holds the exact result. On exit from CMVCH YT holds+* the result computed by CMVCH.+ TRANS = 'N'+ CALL CMVCH( TRANS, N, N, ONE, A, NMAX, X, 1, ZERO, Y, 1, YT, G,+ $ YY, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LCE( YY, YT, N )+ IF( .NOT.SAME.OR.ERR.NE.RZERO )THEN+ WRITE( NOUT, FMT = 9985 )TRANS, SAME, ERR+ STOP+ END IF+ TRANS = 'T'+ CALL CMVCH( TRANS, N, N, ONE, A, NMAX, X, -1, ZERO, Y, -1, YT, G,+ $ YY, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LCE( YY, YT, N )+ IF( .NOT.SAME.OR.ERR.NE.RZERO )THEN+ WRITE( NOUT, FMT = 9985 )TRANS, SAME, ERR+ STOP+ END IF+*+* Test each subroutine in turn.+*+ DO 210 ISNUM = 1, NSUBS+ WRITE( NOUT, FMT = * )+ IF( .NOT.LTEST( ISNUM ) )THEN+* Subprogram is not to be tested.+ WRITE( NOUT, FMT = 9983 )SNAMES( ISNUM )+ ELSE+ SRNAMT = SNAMES( ISNUM )+* Test error exits.+ IF( TSTERR )THEN+ CALL CCHKE( ISNUM, SNAMES( ISNUM ), NOUT )+ WRITE( NOUT, FMT = * )+ END IF+* Test computations.+ INFOT = 0+ OK = .TRUE.+ FATAL = .FALSE.+ GO TO ( 140, 140, 150, 150, 150, 160, 160,+ $ 160, 160, 160, 160, 170, 170, 180,+ $ 180, 190, 190 )ISNUM+* Test CGEMV, 01, and CGBMV, 02.+ 140 CALL CCHK1( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NKB, KB, NALF, ALF,+ $ NBET, BET, NINC, INC, NMAX, INCMAX, A, AA, AS,+ $ X, XX, XS, Y, YY, YS, YT, G )+ GO TO 200+* Test CHEMV, 03, CHBMV, 04, and CHPMV, 05.+ 150 CALL CCHK2( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NKB, KB, NALF, ALF,+ $ NBET, BET, NINC, INC, NMAX, INCMAX, A, AA, AS,+ $ X, XX, XS, Y, YY, YS, YT, G )+ GO TO 200+* Test CTRMV, 06, CTBMV, 07, CTPMV, 08,+* CTRSV, 09, CTBSV, 10, and CTPSV, 11.+ 160 CALL CCHK3( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NKB, KB, NINC, INC,+ $ NMAX, INCMAX, A, AA, AS, Y, YY, YS, YT, G, Z )+ GO TO 200+* Test CGERC, 12, CGERU, 13.+ 170 CALL CCHK4( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC,+ $ NMAX, INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS,+ $ YT, G, Z )+ GO TO 200+* Test CHER, 14, and CHPR, 15.+ 180 CALL CCHK5( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC,+ $ NMAX, INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS,+ $ YT, G, Z )+ GO TO 200+* Test CHER2, 16, and CHPR2, 17.+ 190 CALL CCHK6( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC,+ $ NMAX, INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS,+ $ YT, G, Z )+*+ 200 IF( FATAL.AND.SFATAL )+ $ GO TO 220+ END IF+ 210 CONTINUE+ WRITE( NOUT, FMT = 9982 )+ GO TO 240+*+ 220 CONTINUE+ WRITE( NOUT, FMT = 9981 )+ GO TO 240+*+ 230 CONTINUE+ WRITE( NOUT, FMT = 9987 )+*+ 240 CONTINUE+ IF( TRACE )+ $ CLOSE ( NTRA )+ CLOSE ( NOUT )+ STOP+*+ 9999 FORMAT( ' ROUTINES PASS COMPUTATIONAL TESTS IF TEST RATIO IS LES',+ $ 'S THAN', F8.2 )+ 9998 FORMAT( ' RELATIVE MACHINE PRECISION IS TAKEN TO BE', 1P, E9.1 )+ 9997 FORMAT( ' NUMBER OF VALUES OF ', A, ' IS LESS THAN 1 OR GREATER ',+ $ 'THAN ', I2 )+ 9996 FORMAT( ' VALUE OF N IS LESS THAN 0 OR GREATER THAN ', I2 )+ 9995 FORMAT( ' VALUE OF K IS LESS THAN 0' )+ 9994 FORMAT( ' ABSOLUTE VALUE OF INCX OR INCY IS 0 OR GREATER THAN ',+ $ I2 )+ 9993 FORMAT( ' TESTS OF THE COMPLEX LEVEL 2 BLAS', //' THE F',+ $ 'OLLOWING PARAMETER VALUES WILL BE USED:' )+ 9992 FORMAT( ' FOR N ', 9I6 )+ 9991 FORMAT( ' FOR K ', 7I6 )+ 9990 FORMAT( ' FOR INCX AND INCY ', 7I6 )+ 9989 FORMAT( ' FOR ALPHA ',+ $ 7( '(', F4.1, ',', F4.1, ') ', : ) )+ 9988 FORMAT( ' FOR BETA ',+ $ 7( '(', F4.1, ',', F4.1, ') ', : ) )+ 9987 FORMAT( ' AMEND DATA FILE OR INCREASE ARRAY SIZES IN PROGRAM',+ $ /' ******* TESTS ABANDONED *******' )+ 9986 FORMAT( ' SUBPROGRAM NAME ', A6, ' NOT RECOGNIZED', /' ******* T',+ $ 'ESTS ABANDONED *******' )+ 9985 FORMAT( ' ERROR IN CMVCH - IN-LINE DOT PRODUCTS ARE BEING EVALU',+ $ 'ATED WRONGLY.', /' CMVCH WAS CALLED WITH TRANS = ', A1,+ $ ' AND RETURNED SAME = ', L1, ' AND ERR = ', F12.3, '.', /+ $ ' THIS MAY BE DUE TO FAULTS IN THE ARITHMETIC OR THE COMPILER.'+ $ , /' ******* TESTS ABANDONED *******' )+ 9984 FORMAT( A6, L2 )+ 9983 FORMAT( 1X, A6, ' WAS NOT TESTED' )+ 9982 FORMAT( /' END OF TESTS' )+ 9981 FORMAT( /' ******* FATAL ERROR - TESTS ABANDONED *******' )+ 9980 FORMAT( ' ERROR-EXITS WILL NOT BE TESTED' )+*+* End of CBLAT2.+*+ END+ SUBROUTINE CCHK1( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NKB, KB, NALF, ALF, NBET,+ $ BET, NINC, INC, NMAX, INCMAX, A, AA, AS, X, XX,+ $ XS, Y, YY, YS, YT, G )+*+* Tests CGEMV and CGBMV.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ COMPLEX ZERO, HALF+ PARAMETER ( ZERO = ( 0.0, 0.0 ), HALF = ( 0.5, 0.0 ) )+ REAL RZERO+ PARAMETER ( RZERO = 0.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER INCMAX, NALF, NBET, NIDIM, NINC, NKB, NMAX,+ $ NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), BET( NBET ), X( NMAX ),+ $ XS( NMAX*INCMAX ), XX( NMAX*INCMAX ),+ $ Y( NMAX ), YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX )+ REAL G( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC ), KB( NKB )+* .. Local Scalars ..+ COMPLEX ALPHA, ALS, BETA, BLS, TRANSL+ REAL ERR, ERRMAX+ INTEGER I, IA, IB, IC, IKU, IM, IN, INCX, INCXS, INCY,+ $ INCYS, IX, IY, KL, KLS, KU, KUS, LAA, LDA,+ $ LDAS, LX, LY, M, ML, MS, N, NARGS, NC, ND, NK,+ $ NL, NS+ LOGICAL BANDED, FULL, NULL, RESET, SAME, TRAN+ CHARACTER*1 TRANS, TRANSS+ CHARACTER*3 ICH+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LCE, LCERES+ EXTERNAL LCE, LCERES+* .. External Subroutines ..+ EXTERNAL CGBMV, CGEMV, CMAKE, CMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, MIN+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'NTC'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'E'+ BANDED = SNAME( 3: 3 ).EQ.'B'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 11+ ELSE IF( BANDED )THEN+ NARGS = 13+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 120 IN = 1, NIDIM+ N = IDIM( IN )+ ND = N/2 + 1+*+ DO 110 IM = 1, 2+ IF( IM.EQ.1 )+ $ M = MAX( N - ND, 0 )+ IF( IM.EQ.2 )+ $ M = MIN( N + ND, NMAX )+*+ IF( BANDED )THEN+ NK = NKB+ ELSE+ NK = 1+ END IF+ DO 100 IKU = 1, NK+ IF( BANDED )THEN+ KU = KB( IKU )+ KL = MAX( KU - 1, 0 )+ ELSE+ KU = N - 1+ KL = M - 1+ END IF+* Set LDA to 1 more than minimum value if room.+ IF( BANDED )THEN+ LDA = KL + KU + 1+ ELSE+ LDA = M+ END IF+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 100+ LAA = LDA*N+ NULL = N.LE.0.OR.M.LE.0+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL CMAKE( SNAME( 2: 3 ), ' ', ' ', M, N, A, NMAX, AA,+ $ LDA, KL, KU, RESET, TRANSL )+*+ DO 90 IC = 1, 3+ TRANS = ICH( IC: IC )+ TRAN = TRANS.EQ.'T'.OR.TRANS.EQ.'C'+*+ IF( TRAN )THEN+ ML = N+ NL = M+ ELSE+ ML = M+ NL = N+ END IF+*+ DO 80 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*NL+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL CMAKE( 'GE', ' ', ' ', 1, NL, X, 1, XX,+ $ ABS( INCX ), 0, NL - 1, RESET, TRANSL )+ IF( NL.GT.1 )THEN+ X( NL/2 ) = ZERO+ XX( 1 + ABS( INCX )*( NL/2 - 1 ) ) = ZERO+ END IF+*+ DO 70 IY = 1, NINC+ INCY = INC( IY )+ LY = ABS( INCY )*ML+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the vector Y.+*+ TRANSL = ZERO+ CALL CMAKE( 'GE', ' ', ' ', 1, ML, Y, 1,+ $ YY, ABS( INCY ), 0, ML - 1,+ $ RESET, TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ TRANSS = TRANS+ MS = M+ NS = N+ KLS = KL+ KUS = KU+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+ BLS = BETA+ DO 30 I = 1, LY+ YS( I ) = YY( I )+ 30 CONTINUE+ INCYS = INCY+*+* Call the subroutine.+*+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME,+ $ TRANS, M, N, ALPHA, LDA, INCX, BETA,+ $ INCY+ IF( REWI )+ $ REWIND NTRA+ CALL CGEMV( TRANS, M, N, ALPHA, AA,+ $ LDA, XX, INCX, BETA, YY,+ $ INCY )+ ELSE IF( BANDED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ TRANS, M, N, KL, KU, ALPHA, LDA,+ $ INCX, BETA, INCY+ IF( REWI )+ $ REWIND NTRA+ CALL CGBMV( TRANS, M, N, KL, KU, ALPHA,+ $ AA, LDA, XX, INCX, BETA,+ $ YY, INCY )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9993 )+ FATAL = .TRUE.+ GO TO 130+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = TRANS.EQ.TRANSS+ ISAME( 2 ) = MS.EQ.M+ ISAME( 3 ) = NS.EQ.N+ IF( FULL )THEN+ ISAME( 4 ) = ALS.EQ.ALPHA+ ISAME( 5 ) = LCE( AS, AA, LAA )+ ISAME( 6 ) = LDAS.EQ.LDA+ ISAME( 7 ) = LCE( XS, XX, LX )+ ISAME( 8 ) = INCXS.EQ.INCX+ ISAME( 9 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 10 ) = LCE( YS, YY, LY )+ ELSE+ ISAME( 10 ) = LCERES( 'GE', ' ', 1,+ $ ML, YS, YY,+ $ ABS( INCY ) )+ END IF+ ISAME( 11 ) = INCYS.EQ.INCY+ ELSE IF( BANDED )THEN+ ISAME( 4 ) = KLS.EQ.KL+ ISAME( 5 ) = KUS.EQ.KU+ ISAME( 6 ) = ALS.EQ.ALPHA+ ISAME( 7 ) = LCE( AS, AA, LAA )+ ISAME( 8 ) = LDAS.EQ.LDA+ ISAME( 9 ) = LCE( XS, XX, LX )+ ISAME( 10 ) = INCXS.EQ.INCX+ ISAME( 11 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 12 ) = LCE( YS, YY, LY )+ ELSE+ ISAME( 12 ) = LCERES( 'GE', ' ', 1,+ $ ML, YS, YY,+ $ ABS( INCY ) )+ END IF+ ISAME( 13 ) = INCYS.EQ.INCY+ END IF+*+* If data was incorrectly changed, report+* and return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 130+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result.+*+ CALL CMVCH( TRANS, M, N, ALPHA, A,+ $ NMAX, X, INCX, BETA, Y,+ $ INCY, YT, G, YY, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 130+ ELSE+* Avoid repeating tests with M.le.0 or+* N.le.0.+ GO TO 110+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 140+*+ 130 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, TRANS, M, N, ALPHA, LDA,+ $ INCX, BETA, INCY+ ELSE IF( BANDED )THEN+ WRITE( NOUT, FMT = 9995 )NC, SNAME, TRANS, M, N, KL, KU,+ $ ALPHA, LDA, INCX, BETA, INCY+ END IF+*+ 140 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', 4( I3, ',' ), '(',+ $ F4.1, ',', F4.1, '), A,', I3, ', X,', I2, ',(', F4.1, ',',+ $ F4.1, '), Y,', I2, ') .' )+ 9994 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', 2( I3, ',' ), '(',+ $ F4.1, ',', F4.1, '), A,', I3, ', X,', I2, ',(', F4.1, ',',+ $ F4.1, '), Y,', I2, ') .' )+ 9993 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of CCHK1.+*+ END+ SUBROUTINE CCHK2( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NKB, KB, NALF, ALF, NBET,+ $ BET, NINC, INC, NMAX, INCMAX, A, AA, AS, X, XX,+ $ XS, Y, YY, YS, YT, G )+*+* Tests CHEMV, CHBMV and CHPMV.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ COMPLEX ZERO, HALF+ PARAMETER ( ZERO = ( 0.0, 0.0 ), HALF = ( 0.5, 0.0 ) )+ REAL RZERO+ PARAMETER ( RZERO = 0.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER INCMAX, NALF, NBET, NIDIM, NINC, NKB, NMAX,+ $ NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), BET( NBET ), X( NMAX ),+ $ XS( NMAX*INCMAX ), XX( NMAX*INCMAX ),+ $ Y( NMAX ), YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX )+ REAL G( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC ), KB( NKB )+* .. Local Scalars ..+ COMPLEX ALPHA, ALS, BETA, BLS, TRANSL+ REAL ERR, ERRMAX+ INTEGER I, IA, IB, IC, IK, IN, INCX, INCXS, INCY,+ $ INCYS, IX, IY, K, KS, LAA, LDA, LDAS, LX, LY,+ $ N, NARGS, NC, NK, NS+ LOGICAL BANDED, FULL, NULL, PACKED, RESET, SAME+ CHARACTER*1 UPLO, UPLOS+ CHARACTER*2 ICH+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LCE, LCERES+ EXTERNAL LCE, LCERES+* .. External Subroutines ..+ EXTERNAL CHBMV, CHEMV, CHPMV, CMAKE, CMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'UL'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'E'+ BANDED = SNAME( 3: 3 ).EQ.'B'+ PACKED = SNAME( 3: 3 ).EQ.'P'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 10+ ELSE IF( BANDED )THEN+ NARGS = 11+ ELSE IF( PACKED )THEN+ NARGS = 9+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 110 IN = 1, NIDIM+ N = IDIM( IN )+*+ IF( BANDED )THEN+ NK = NKB+ ELSE+ NK = 1+ END IF+ DO 100 IK = 1, NK+ IF( BANDED )THEN+ K = KB( IK )+ ELSE+ K = N - 1+ END IF+* Set LDA to 1 more than minimum value if room.+ IF( BANDED )THEN+ LDA = K + 1+ ELSE+ LDA = N+ END IF+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 100+ IF( PACKED )THEN+ LAA = ( N*( N + 1 ) )/2+ ELSE+ LAA = LDA*N+ END IF+ NULL = N.LE.0+*+ DO 90 IC = 1, 2+ UPLO = ICH( IC: IC )+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL CMAKE( SNAME( 2: 3 ), UPLO, ' ', N, N, A, NMAX, AA,+ $ LDA, K, K, RESET, TRANSL )+*+ DO 80 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*N+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL CMAKE( 'GE', ' ', ' ', 1, N, X, 1, XX,+ $ ABS( INCX ), 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ X( N/2 ) = ZERO+ XX( 1 + ABS( INCX )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 70 IY = 1, NINC+ INCY = INC( IY )+ LY = ABS( INCY )*N+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the vector Y.+*+ TRANSL = ZERO+ CALL CMAKE( 'GE', ' ', ' ', 1, N, Y, 1, YY,+ $ ABS( INCY ), 0, N - 1, RESET,+ $ TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ UPLOS = UPLO+ NS = N+ KS = K+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+ BLS = BETA+ DO 30 I = 1, LY+ YS( I ) = YY( I )+ 30 CONTINUE+ INCYS = INCY+*+* Call the subroutine.+*+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME,+ $ UPLO, N, ALPHA, LDA, INCX, BETA, INCY+ IF( REWI )+ $ REWIND NTRA+ CALL CHEMV( UPLO, N, ALPHA, AA, LDA, XX,+ $ INCX, BETA, YY, INCY )+ ELSE IF( BANDED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME,+ $ UPLO, N, K, ALPHA, LDA, INCX, BETA,+ $ INCY+ IF( REWI )+ $ REWIND NTRA+ CALL CHBMV( UPLO, N, K, ALPHA, AA, LDA,+ $ XX, INCX, BETA, YY, INCY )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ UPLO, N, ALPHA, INCX, BETA, INCY+ IF( REWI )+ $ REWIND NTRA+ CALL CHPMV( UPLO, N, ALPHA, AA, XX, INCX,+ $ BETA, YY, INCY )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLO.EQ.UPLOS+ ISAME( 2 ) = NS.EQ.N+ IF( FULL )THEN+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LCE( AS, AA, LAA )+ ISAME( 5 ) = LDAS.EQ.LDA+ ISAME( 6 ) = LCE( XS, XX, LX )+ ISAME( 7 ) = INCXS.EQ.INCX+ ISAME( 8 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 9 ) = LCE( YS, YY, LY )+ ELSE+ ISAME( 9 ) = LCERES( 'GE', ' ', 1, N,+ $ YS, YY, ABS( INCY ) )+ END IF+ ISAME( 10 ) = INCYS.EQ.INCY+ ELSE IF( BANDED )THEN+ ISAME( 3 ) = KS.EQ.K+ ISAME( 4 ) = ALS.EQ.ALPHA+ ISAME( 5 ) = LCE( AS, AA, LAA )+ ISAME( 6 ) = LDAS.EQ.LDA+ ISAME( 7 ) = LCE( XS, XX, LX )+ ISAME( 8 ) = INCXS.EQ.INCX+ ISAME( 9 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 10 ) = LCE( YS, YY, LY )+ ELSE+ ISAME( 10 ) = LCERES( 'GE', ' ', 1, N,+ $ YS, YY, ABS( INCY ) )+ END IF+ ISAME( 11 ) = INCYS.EQ.INCY+ ELSE IF( PACKED )THEN+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LCE( AS, AA, LAA )+ ISAME( 5 ) = LCE( XS, XX, LX )+ ISAME( 6 ) = INCXS.EQ.INCX+ ISAME( 7 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 8 ) = LCE( YS, YY, LY )+ ELSE+ ISAME( 8 ) = LCERES( 'GE', ' ', 1, N,+ $ YS, YY, ABS( INCY ) )+ END IF+ ISAME( 9 ) = INCYS.EQ.INCY+ END IF+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result.+*+ CALL CMVCH( 'N', N, N, ALPHA, A, NMAX, X,+ $ INCX, BETA, Y, INCY, YT, G,+ $ YY, EPS, ERR, FATAL, NOUT,+ $ .TRUE. )+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 120+ ELSE+* Avoid repeating tests with N.le.0+ GO TO 110+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, N, ALPHA, LDA, INCX,+ $ BETA, INCY+ ELSE IF( BANDED )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, N, K, ALPHA, LDA,+ $ INCX, BETA, INCY+ ELSE IF( PACKED )THEN+ WRITE( NOUT, FMT = 9995 )NC, SNAME, UPLO, N, ALPHA, INCX,+ $ BETA, INCY+ END IF+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',(', F4.1, ',',+ $ F4.1, '), AP, X,', I2, ',(', F4.1, ',', F4.1, '), Y,', I2,+ $ ') .' )+ 9994 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', 2( I3, ',' ), '(',+ $ F4.1, ',', F4.1, '), A,', I3, ', X,', I2, ',(', F4.1, ',',+ $ F4.1, '), Y,', I2, ') .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',(', F4.1, ',',+ $ F4.1, '), A,', I3, ', X,', I2, ',(', F4.1, ',', F4.1, '), ',+ $ 'Y,', I2, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of CCHK2.+*+ END+ SUBROUTINE CCHK3( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NKB, KB, NINC, INC, NMAX,+ $ INCMAX, A, AA, AS, X, XX, XS, XT, G, Z )+*+* Tests CTRMV, CTBMV, CTPMV, CTRSV, CTBSV and CTPSV.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ COMPLEX ZERO, HALF, ONE+ PARAMETER ( ZERO = ( 0.0, 0.0 ), HALF = ( 0.5, 0.0 ),+ $ ONE = ( 1.0, 0.0 ) )+ REAL RZERO+ PARAMETER ( RZERO = 0.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER INCMAX, NIDIM, NINC, NKB, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX A( NMAX, NMAX ), AA( NMAX*NMAX ),+ $ AS( NMAX*NMAX ), X( NMAX ), XS( NMAX*INCMAX ),+ $ XT( NMAX ), XX( NMAX*INCMAX ), Z( NMAX )+ REAL G( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC ), KB( NKB )+* .. Local Scalars ..+ COMPLEX TRANSL+ REAL ERR, ERRMAX+ INTEGER I, ICD, ICT, ICU, IK, IN, INCX, INCXS, IX, K,+ $ KS, LAA, LDA, LDAS, LX, N, NARGS, NC, NK, NS+ LOGICAL BANDED, FULL, NULL, PACKED, RESET, SAME+ CHARACTER*1 DIAG, DIAGS, TRANS, TRANSS, UPLO, UPLOS+ CHARACTER*2 ICHD, ICHU+ CHARACTER*3 ICHT+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LCE, LCERES+ EXTERNAL LCE, LCERES+* .. External Subroutines ..+ EXTERNAL CMAKE, CMVCH, CTBMV, CTBSV, CTPMV, CTPSV,+ $ CTRMV, CTRSV+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHU/'UL'/, ICHT/'NTC'/, ICHD/'UN'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'R'+ BANDED = SNAME( 3: 3 ).EQ.'B'+ PACKED = SNAME( 3: 3 ).EQ.'P'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 8+ ELSE IF( BANDED )THEN+ NARGS = 9+ ELSE IF( PACKED )THEN+ NARGS = 7+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+* Set up zero vector for CMVCH.+ DO 10 I = 1, NMAX+ Z( I ) = ZERO+ 10 CONTINUE+*+ DO 110 IN = 1, NIDIM+ N = IDIM( IN )+*+ IF( BANDED )THEN+ NK = NKB+ ELSE+ NK = 1+ END IF+ DO 100 IK = 1, NK+ IF( BANDED )THEN+ K = KB( IK )+ ELSE+ K = N - 1+ END IF+* Set LDA to 1 more than minimum value if room.+ IF( BANDED )THEN+ LDA = K + 1+ ELSE+ LDA = N+ END IF+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 100+ IF( PACKED )THEN+ LAA = ( N*( N + 1 ) )/2+ ELSE+ LAA = LDA*N+ END IF+ NULL = N.LE.0+*+ DO 90 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+*+ DO 80 ICT = 1, 3+ TRANS = ICHT( ICT: ICT )+*+ DO 70 ICD = 1, 2+ DIAG = ICHD( ICD: ICD )+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL CMAKE( SNAME( 2: 3 ), UPLO, DIAG, N, N, A,+ $ NMAX, AA, LDA, K, K, RESET, TRANSL )+*+ DO 60 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*N+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL CMAKE( 'GE', ' ', ' ', 1, N, X, 1, XX,+ $ ABS( INCX ), 0, N - 1, RESET,+ $ TRANSL )+ IF( N.GT.1 )THEN+ X( N/2 ) = ZERO+ XX( 1 + ABS( INCX )*( N/2 - 1 ) ) = ZERO+ END IF+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ TRANSS = TRANS+ DIAGS = DIAG+ NS = N+ KS = K+ DO 20 I = 1, LAA+ AS( I ) = AA( I )+ 20 CONTINUE+ LDAS = LDA+ DO 30 I = 1, LX+ XS( I ) = XX( I )+ 30 CONTINUE+ INCXS = INCX+*+* Call the subroutine.+*+ IF( SNAME( 4: 5 ).EQ.'MV' )THEN+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, LDA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL CTRMV( UPLO, TRANS, DIAG, N, AA, LDA,+ $ XX, INCX )+ ELSE IF( BANDED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, K, LDA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL CTBMV( UPLO, TRANS, DIAG, N, K, AA,+ $ LDA, XX, INCX )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL CTPMV( UPLO, TRANS, DIAG, N, AA, XX,+ $ INCX )+ END IF+ ELSE IF( SNAME( 4: 5 ).EQ.'SV' )THEN+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, LDA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL CTRSV( UPLO, TRANS, DIAG, N, AA, LDA,+ $ XX, INCX )+ ELSE IF( BANDED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, K, LDA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL CTBSV( UPLO, TRANS, DIAG, N, K, AA,+ $ LDA, XX, INCX )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL CTPSV( UPLO, TRANS, DIAG, N, AA, XX,+ $ INCX )+ END IF+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLO.EQ.UPLOS+ ISAME( 2 ) = TRANS.EQ.TRANSS+ ISAME( 3 ) = DIAG.EQ.DIAGS+ ISAME( 4 ) = NS.EQ.N+ IF( FULL )THEN+ ISAME( 5 ) = LCE( AS, AA, LAA )+ ISAME( 6 ) = LDAS.EQ.LDA+ IF( NULL )THEN+ ISAME( 7 ) = LCE( XS, XX, LX )+ ELSE+ ISAME( 7 ) = LCERES( 'GE', ' ', 1, N, XS,+ $ XX, ABS( INCX ) )+ END IF+ ISAME( 8 ) = INCXS.EQ.INCX+ ELSE IF( BANDED )THEN+ ISAME( 5 ) = KS.EQ.K+ ISAME( 6 ) = LCE( AS, AA, LAA )+ ISAME( 7 ) = LDAS.EQ.LDA+ IF( NULL )THEN+ ISAME( 8 ) = LCE( XS, XX, LX )+ ELSE+ ISAME( 8 ) = LCERES( 'GE', ' ', 1, N, XS,+ $ XX, ABS( INCX ) )+ END IF+ ISAME( 9 ) = INCXS.EQ.INCX+ ELSE IF( PACKED )THEN+ ISAME( 5 ) = LCE( AS, AA, LAA )+ IF( NULL )THEN+ ISAME( 6 ) = LCE( XS, XX, LX )+ ELSE+ ISAME( 6 ) = LCERES( 'GE', ' ', 1, N, XS,+ $ XX, ABS( INCX ) )+ END IF+ ISAME( 7 ) = INCXS.EQ.INCX+ END IF+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+ IF( SNAME( 4: 5 ).EQ.'MV' )THEN+*+* Check the result.+*+ CALL CMVCH( TRANS, N, N, ONE, A, NMAX, X,+ $ INCX, ZERO, Z, INCX, XT, G,+ $ XX, EPS, ERR, FATAL, NOUT,+ $ .TRUE. )+ ELSE IF( SNAME( 4: 5 ).EQ.'SV' )THEN+*+* Compute approximation to original vector.+*+ DO 50 I = 1, N+ Z( I ) = XX( 1 + ( I - 1 )*+ $ ABS( INCX ) )+ XX( 1 + ( I - 1 )*ABS( INCX ) )+ $ = X( I )+ 50 CONTINUE+ CALL CMVCH( TRANS, N, N, ONE, A, NMAX, Z,+ $ INCX, ZERO, X, INCX, XT, G,+ $ XX, EPS, ERR, FATAL, NOUT,+ $ .FALSE. )+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and return.+ IF( FATAL )+ $ GO TO 120+ ELSE+* Avoid repeating tests with N.le.0.+ GO TO 110+ END IF+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, TRANS, DIAG, N, LDA,+ $ INCX+ ELSE IF( BANDED )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, TRANS, DIAG, N, K,+ $ LDA, INCX+ ELSE IF( PACKED )THEN+ WRITE( NOUT, FMT = 9995 )NC, SNAME, UPLO, TRANS, DIAG, N, INCX+ END IF+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(', 3( '''', A1, ''',' ), I3, ', AP, ',+ $ 'X,', I2, ') .' )+ 9994 FORMAT( 1X, I6, ': ', A6, '(', 3( '''', A1, ''',' ), 2( I3, ',' ),+ $ ' A,', I3, ', X,', I2, ') .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(', 3( '''', A1, ''',' ), I3, ', A,',+ $ I3, ', X,', I2, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of CCHK3.+*+ END+ SUBROUTINE CCHK4( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC, NMAX,+ $ INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS, YT, G,+ $ Z )+*+* Tests CGERC and CGERU.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ COMPLEX ZERO, HALF, ONE+ PARAMETER ( ZERO = ( 0.0, 0.0 ), HALF = ( 0.5, 0.0 ),+ $ ONE = ( 1.0, 0.0 ) )+ REAL RZERO+ PARAMETER ( RZERO = 0.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER INCMAX, NALF, NIDIM, NINC, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), X( NMAX ), XS( NMAX*INCMAX ),+ $ XX( NMAX*INCMAX ), Y( NMAX ),+ $ YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX ), Z( NMAX )+ REAL G( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC )+* .. Local Scalars ..+ COMPLEX ALPHA, ALS, TRANSL+ REAL ERR, ERRMAX+ INTEGER I, IA, IM, IN, INCX, INCXS, INCY, INCYS, IX,+ $ IY, J, LAA, LDA, LDAS, LX, LY, M, MS, N, NARGS,+ $ NC, ND, NS+ LOGICAL CONJ, NULL, RESET, SAME+* .. Local Arrays ..+ COMPLEX W( 1 )+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LCE, LCERES+ EXTERNAL LCE, LCERES+* .. External Subroutines ..+ EXTERNAL CGERC, CGERU, CMAKE, CMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, CONJG, MAX, MIN+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Executable Statements ..+ CONJ = SNAME( 5: 5 ).EQ.'C'+* Define the number of arguments.+ NARGS = 9+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 120 IN = 1, NIDIM+ N = IDIM( IN )+ ND = N/2 + 1+*+ DO 110 IM = 1, 2+ IF( IM.EQ.1 )+ $ M = MAX( N - ND, 0 )+ IF( IM.EQ.2 )+ $ M = MIN( N + ND, NMAX )+*+* Set LDA to 1 more than minimum value if room.+ LDA = M+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 110+ LAA = LDA*N+ NULL = N.LE.0.OR.M.LE.0+*+ DO 100 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*M+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL CMAKE( 'GE', ' ', ' ', 1, M, X, 1, XX, ABS( INCX ),+ $ 0, M - 1, RESET, TRANSL )+ IF( M.GT.1 )THEN+ X( M/2 ) = ZERO+ XX( 1 + ABS( INCX )*( M/2 - 1 ) ) = ZERO+ END IF+*+ DO 90 IY = 1, NINC+ INCY = INC( IY )+ LY = ABS( INCY )*N+*+* Generate the vector Y.+*+ TRANSL = ZERO+ CALL CMAKE( 'GE', ' ', ' ', 1, N, Y, 1, YY,+ $ ABS( INCY ), 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ Y( N/2 ) = ZERO+ YY( 1 + ABS( INCY )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 80 IA = 1, NALF+ ALPHA = ALF( IA )+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL CMAKE( SNAME( 2: 3 ), ' ', ' ', M, N, A, NMAX,+ $ AA, LDA, M - 1, N - 1, RESET, TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ MS = M+ NS = N+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+ DO 30 I = 1, LY+ YS( I ) = YY( I )+ 30 CONTINUE+ INCYS = INCY+*+* Call the subroutine.+*+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, M, N,+ $ ALPHA, INCX, INCY, LDA+ IF( CONJ )THEN+ IF( REWI )+ $ REWIND NTRA+ CALL CGERC( M, N, ALPHA, XX, INCX, YY, INCY, AA,+ $ LDA )+ ELSE+ IF( REWI )+ $ REWIND NTRA+ CALL CGERU( M, N, ALPHA, XX, INCX, YY, INCY, AA,+ $ LDA )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9993 )+ FATAL = .TRUE.+ GO TO 140+ END IF+*+* See what data changed inside subroutine.+*+ ISAME( 1 ) = MS.EQ.M+ ISAME( 2 ) = NS.EQ.N+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LCE( XS, XX, LX )+ ISAME( 5 ) = INCXS.EQ.INCX+ ISAME( 6 ) = LCE( YS, YY, LY )+ ISAME( 7 ) = INCYS.EQ.INCY+ IF( NULL )THEN+ ISAME( 8 ) = LCE( AS, AA, LAA )+ ELSE+ ISAME( 8 ) = LCERES( 'GE', ' ', M, N, AS, AA,+ $ LDA )+ END IF+ ISAME( 9 ) = LDAS.EQ.LDA+*+* If data was incorrectly changed, report and return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 140+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ IF( INCX.GT.0 )THEN+ DO 50 I = 1, M+ Z( I ) = X( I )+ 50 CONTINUE+ ELSE+ DO 60 I = 1, M+ Z( I ) = X( M - I + 1 )+ 60 CONTINUE+ END IF+ DO 70 J = 1, N+ IF( INCY.GT.0 )THEN+ W( 1 ) = Y( J )+ ELSE+ W( 1 ) = Y( N - J + 1 )+ END IF+ IF( CONJ )+ $ W( 1 ) = CONJG( W( 1 ) )+ CALL CMVCH( 'N', M, 1, ALPHA, Z, NMAX, W, 1,+ $ ONE, A( 1, J ), 1, YT, G,+ $ AA( 1 + ( J - 1 )*LDA ), EPS,+ $ ERR, FATAL, NOUT, .TRUE. )+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and return.+ IF( FATAL )+ $ GO TO 130+ 70 CONTINUE+ ELSE+* Avoid repeating tests with M.le.0 or N.le.0.+ GO TO 110+ END IF+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 150+*+ 130 CONTINUE+ WRITE( NOUT, FMT = 9995 )J+*+ 140 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9994 )NC, SNAME, M, N, ALPHA, INCX, INCY, LDA+*+ 150 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(', 2( I3, ',' ), '(', F4.1, ',', F4.1,+ $ '), X,', I2, ', Y,', I2, ', A,', I3, ') ',+ $ ' .' )+ 9993 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of CCHK4.+*+ END+ SUBROUTINE CCHK5( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC, NMAX,+ $ INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS, YT, G,+ $ Z )+*+* Tests CHER and CHPR.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ COMPLEX ZERO, HALF, ONE+ PARAMETER ( ZERO = ( 0.0, 0.0 ), HALF = ( 0.5, 0.0 ),+ $ ONE = ( 1.0, 0.0 ) )+ REAL RZERO+ PARAMETER ( RZERO = 0.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER INCMAX, NALF, NIDIM, NINC, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), X( NMAX ), XS( NMAX*INCMAX ),+ $ XX( NMAX*INCMAX ), Y( NMAX ),+ $ YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX ), Z( NMAX )+ REAL G( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC )+* .. Local Scalars ..+ COMPLEX ALPHA, TRANSL+ REAL ERR, ERRMAX, RALPHA, RALS+ INTEGER I, IA, IC, IN, INCX, INCXS, IX, J, JA, JJ, LAA,+ $ LDA, LDAS, LJ, LX, N, NARGS, NC, NS+ LOGICAL FULL, NULL, PACKED, RESET, SAME, UPPER+ CHARACTER*1 UPLO, UPLOS+ CHARACTER*2 ICH+* .. Local Arrays ..+ COMPLEX W( 1 )+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LCE, LCERES+ EXTERNAL LCE, LCERES+* .. External Subroutines ..+ EXTERNAL CHER, CHPR, CMAKE, CMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, CMPLX, CONJG, MAX, REAL+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'UL'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'E'+ PACKED = SNAME( 3: 3 ).EQ.'P'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 7+ ELSE IF( PACKED )THEN+ NARGS = 6+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 100 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDA to 1 more than minimum value if room.+ LDA = N+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 100+ IF( PACKED )THEN+ LAA = ( N*( N + 1 ) )/2+ ELSE+ LAA = LDA*N+ END IF+*+ DO 90 IC = 1, 2+ UPLO = ICH( IC: IC )+ UPPER = UPLO.EQ.'U'+*+ DO 80 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*N+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL CMAKE( 'GE', ' ', ' ', 1, N, X, 1, XX, ABS( INCX ),+ $ 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ X( N/2 ) = ZERO+ XX( 1 + ABS( INCX )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 70 IA = 1, NALF+ RALPHA = REAL( ALF( IA ) )+ ALPHA = CMPLX( RALPHA, RZERO )+ NULL = N.LE.0.OR.RALPHA.EQ.RZERO+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL CMAKE( SNAME( 2: 3 ), UPLO, ' ', N, N, A, NMAX,+ $ AA, LDA, N - 1, N - 1, RESET, TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ NS = N+ RALS = RALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+*+* Call the subroutine.+*+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME, UPLO, N,+ $ RALPHA, INCX, LDA+ IF( REWI )+ $ REWIND NTRA+ CALL CHER( UPLO, N, RALPHA, XX, INCX, AA, LDA )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, UPLO, N,+ $ RALPHA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL CHPR( UPLO, N, RALPHA, XX, INCX, AA )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLO.EQ.UPLOS+ ISAME( 2 ) = NS.EQ.N+ ISAME( 3 ) = RALS.EQ.RALPHA+ ISAME( 4 ) = LCE( XS, XX, LX )+ ISAME( 5 ) = INCXS.EQ.INCX+ IF( NULL )THEN+ ISAME( 6 ) = LCE( AS, AA, LAA )+ ELSE+ ISAME( 6 ) = LCERES( SNAME( 2: 3 ), UPLO, N, N, AS,+ $ AA, LDA )+ END IF+ IF( .NOT.PACKED )THEN+ ISAME( 7 ) = LDAS.EQ.LDA+ END IF+*+* If data was incorrectly changed, report and return.+*+ SAME = .TRUE.+ DO 30 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 30 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ IF( INCX.GT.0 )THEN+ DO 40 I = 1, N+ Z( I ) = X( I )+ 40 CONTINUE+ ELSE+ DO 50 I = 1, N+ Z( I ) = X( N - I + 1 )+ 50 CONTINUE+ END IF+ JA = 1+ DO 60 J = 1, N+ W( 1 ) = CONJG( Z( J ) )+ IF( UPPER )THEN+ JJ = 1+ LJ = J+ ELSE+ JJ = J+ LJ = N - J + 1+ END IF+ CALL CMVCH( 'N', LJ, 1, ALPHA, Z( JJ ), LJ, W,+ $ 1, ONE, A( JJ, J ), 1, YT, G,+ $ AA( JA ), EPS, ERR, FATAL, NOUT,+ $ .TRUE. )+ IF( FULL )THEN+ IF( UPPER )THEN+ JA = JA + LDA+ ELSE+ JA = JA + LDA + 1+ END IF+ ELSE+ JA = JA + LJ+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and return.+ IF( FATAL )+ $ GO TO 110+ 60 CONTINUE+ ELSE+* Avoid repeating tests if N.le.0.+ IF( N.LE.0 )+ $ GO TO 100+ END IF+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 110 CONTINUE+ WRITE( NOUT, FMT = 9995 )J+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, N, RALPHA, INCX, LDA+ ELSE IF( PACKED )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, N, RALPHA, INCX+ END IF+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',', F4.1, ', X,',+ $ I2, ', AP) .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',', F4.1, ', X,',+ $ I2, ', A,', I3, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of CCHK5.+*+ END+ SUBROUTINE CCHK6( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC, NMAX,+ $ INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS, YT, G,+ $ Z )+*+* Tests CHER2 and CHPR2.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ COMPLEX ZERO, HALF, ONE+ PARAMETER ( ZERO = ( 0.0, 0.0 ), HALF = ( 0.5, 0.0 ),+ $ ONE = ( 1.0, 0.0 ) )+ REAL RZERO+ PARAMETER ( RZERO = 0.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER INCMAX, NALF, NIDIM, NINC, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), X( NMAX ), XS( NMAX*INCMAX ),+ $ XX( NMAX*INCMAX ), Y( NMAX ),+ $ YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX ), Z( NMAX, 2 )+ REAL G( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC )+* .. Local Scalars ..+ COMPLEX ALPHA, ALS, TRANSL+ REAL ERR, ERRMAX+ INTEGER I, IA, IC, IN, INCX, INCXS, INCY, INCYS, IX,+ $ IY, J, JA, JJ, LAA, LDA, LDAS, LJ, LX, LY, N,+ $ NARGS, NC, NS+ LOGICAL FULL, NULL, PACKED, RESET, SAME, UPPER+ CHARACTER*1 UPLO, UPLOS+ CHARACTER*2 ICH+* .. Local Arrays ..+ COMPLEX W( 2 )+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LCE, LCERES+ EXTERNAL LCE, LCERES+* .. External Subroutines ..+ EXTERNAL CHER2, CHPR2, CMAKE, CMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, CONJG, MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'UL'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'E'+ PACKED = SNAME( 3: 3 ).EQ.'P'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 9+ ELSE IF( PACKED )THEN+ NARGS = 8+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 140 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDA to 1 more than minimum value if room.+ LDA = N+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 140+ IF( PACKED )THEN+ LAA = ( N*( N + 1 ) )/2+ ELSE+ LAA = LDA*N+ END IF+*+ DO 130 IC = 1, 2+ UPLO = ICH( IC: IC )+ UPPER = UPLO.EQ.'U'+*+ DO 120 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*N+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL CMAKE( 'GE', ' ', ' ', 1, N, X, 1, XX, ABS( INCX ),+ $ 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ X( N/2 ) = ZERO+ XX( 1 + ABS( INCX )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 110 IY = 1, NINC+ INCY = INC( IY )+ LY = ABS( INCY )*N+*+* Generate the vector Y.+*+ TRANSL = ZERO+ CALL CMAKE( 'GE', ' ', ' ', 1, N, Y, 1, YY,+ $ ABS( INCY ), 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ Y( N/2 ) = ZERO+ YY( 1 + ABS( INCY )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 100 IA = 1, NALF+ ALPHA = ALF( IA )+ NULL = N.LE.0.OR.ALPHA.EQ.ZERO+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL CMAKE( SNAME( 2: 3 ), UPLO, ' ', N, N, A,+ $ NMAX, AA, LDA, N - 1, N - 1, RESET,+ $ TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ NS = N+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+ DO 30 I = 1, LY+ YS( I ) = YY( I )+ 30 CONTINUE+ INCYS = INCY+*+* Call the subroutine.+*+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME, UPLO, N,+ $ ALPHA, INCX, INCY, LDA+ IF( REWI )+ $ REWIND NTRA+ CALL CHER2( UPLO, N, ALPHA, XX, INCX, YY, INCY,+ $ AA, LDA )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, UPLO, N,+ $ ALPHA, INCX, INCY+ IF( REWI )+ $ REWIND NTRA+ CALL CHPR2( UPLO, N, ALPHA, XX, INCX, YY, INCY,+ $ AA )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 160+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLO.EQ.UPLOS+ ISAME( 2 ) = NS.EQ.N+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LCE( XS, XX, LX )+ ISAME( 5 ) = INCXS.EQ.INCX+ ISAME( 6 ) = LCE( YS, YY, LY )+ ISAME( 7 ) = INCYS.EQ.INCY+ IF( NULL )THEN+ ISAME( 8 ) = LCE( AS, AA, LAA )+ ELSE+ ISAME( 8 ) = LCERES( SNAME( 2: 3 ), UPLO, N, N,+ $ AS, AA, LDA )+ END IF+ IF( .NOT.PACKED )THEN+ ISAME( 9 ) = LDAS.EQ.LDA+ END IF+*+* If data was incorrectly changed, report and return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 160+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ IF( INCX.GT.0 )THEN+ DO 50 I = 1, N+ Z( I, 1 ) = X( I )+ 50 CONTINUE+ ELSE+ DO 60 I = 1, N+ Z( I, 1 ) = X( N - I + 1 )+ 60 CONTINUE+ END IF+ IF( INCY.GT.0 )THEN+ DO 70 I = 1, N+ Z( I, 2 ) = Y( I )+ 70 CONTINUE+ ELSE+ DO 80 I = 1, N+ Z( I, 2 ) = Y( N - I + 1 )+ 80 CONTINUE+ END IF+ JA = 1+ DO 90 J = 1, N+ W( 1 ) = ALPHA*CONJG( Z( J, 2 ) )+ W( 2 ) = CONJG( ALPHA )*CONJG( Z( J, 1 ) )+ IF( UPPER )THEN+ JJ = 1+ LJ = J+ ELSE+ JJ = J+ LJ = N - J + 1+ END IF+ CALL CMVCH( 'N', LJ, 2, ONE, Z( JJ, 1 ),+ $ NMAX, W, 1, ONE, A( JJ, J ), 1,+ $ YT, G, AA( JA ), EPS, ERR, FATAL,+ $ NOUT, .TRUE. )+ IF( FULL )THEN+ IF( UPPER )THEN+ JA = JA + LDA+ ELSE+ JA = JA + LDA + 1+ END IF+ ELSE+ JA = JA + LJ+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and return.+ IF( FATAL )+ $ GO TO 150+ 90 CONTINUE+ ELSE+* Avoid repeating tests with N.le.0.+ IF( N.LE.0 )+ $ GO TO 140+ END IF+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+ 130 CONTINUE+*+ 140 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 170+*+ 150 CONTINUE+ WRITE( NOUT, FMT = 9995 )J+*+ 160 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, N, ALPHA, INCX,+ $ INCY, LDA+ ELSE IF( PACKED )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, N, ALPHA, INCX, INCY+ END IF+*+ 170 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',(', F4.1, ',',+ $ F4.1, '), X,', I2, ', Y,', I2, ', AP) ',+ $ ' .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',(', F4.1, ',',+ $ F4.1, '), X,', I2, ', Y,', I2, ', A,', I3, ') ',+ $ ' .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of CCHK6.+*+ END+ SUBROUTINE CCHKE( ISNUM, SRNAMT, NOUT )+*+* Tests the error exits from the Level 2 Blas.+* Requires a special version of the error-handling routine XERBLA.+* ALPHA, RALPHA, BETA, A, X and Y should not need to be defined.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER ISNUM, NOUT+ CHARACTER*6 SRNAMT+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Local Scalars ..+ COMPLEX ALPHA, BETA+ REAL RALPHA+* .. Local Arrays ..+ COMPLEX A( 1, 1 ), X( 1 ), Y( 1 )+* .. External Subroutines ..+ EXTERNAL CGBMV, CGEMV, CGERC, CGERU, CHBMV, CHEMV, CHER,+ $ CHER2, CHKXER, CHPMV, CHPR, CHPR2, CTBMV,+ $ CTBSV, CTPMV, CTPSV, CTRMV, CTRSV+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Executable Statements ..+* OK is set to .FALSE. by the special version of XERBLA or by CHKXER+* if anything is wrong.+ OK = .TRUE.+* LERR is set to .TRUE. by the special version of XERBLA each time+* it is called, and is then tested and re-set by CHKXER.+ LERR = .FALSE.+ GO TO ( 10, 20, 30, 40, 50, 60, 70, 80,+ $ 90, 100, 110, 120, 130, 140, 150, 160,+ $ 170 )ISNUM+ 10 INFOT = 1+ CALL CGEMV( '/', 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CGEMV( 'N', -1, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CGEMV( 'N', 0, -1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CGEMV( 'N', 2, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL CGEMV( 'N', 0, 0, ALPHA, A, 1, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CGEMV( 'N', 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 20 INFOT = 1+ CALL CGBMV( '/', 0, 0, 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CGBMV( 'N', -1, 0, 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CGBMV( 'N', 0, -1, 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CGBMV( 'N', 0, 0, -1, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CGBMV( 'N', 2, 0, 0, -1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL CGBMV( 'N', 0, 0, 1, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CGBMV( 'N', 0, 0, 0, 0, ALPHA, A, 1, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL CGBMV( 'N', 0, 0, 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 30 INFOT = 1+ CALL CHEMV( '/', 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CHEMV( 'U', -1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CHEMV( 'U', 2, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CHEMV( 'U', 0, ALPHA, A, 1, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CHEMV( 'U', 0, ALPHA, A, 1, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 40 INFOT = 1+ CALL CHBMV( '/', 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CHBMV( 'U', -1, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CHBMV( 'U', 0, -1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CHBMV( 'U', 0, 1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL CHBMV( 'U', 0, 0, ALPHA, A, 1, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CHBMV( 'U', 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 50 INFOT = 1+ CALL CHPMV( '/', 0, ALPHA, A, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CHPMV( 'U', -1, ALPHA, A, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CHPMV( 'U', 0, ALPHA, A, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CHPMV( 'U', 0, ALPHA, A, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 60 INFOT = 1+ CALL CTRMV( '/', 'N', 'N', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CTRMV( 'U', '/', 'N', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CTRMV( 'U', 'N', '/', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CTRMV( 'U', 'N', 'N', -1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRMV( 'U', 'N', 'N', 2, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL CTRMV( 'U', 'N', 'N', 0, A, 1, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 70 INFOT = 1+ CALL CTBMV( '/', 'N', 'N', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CTBMV( 'U', '/', 'N', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CTBMV( 'U', 'N', '/', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CTBMV( 'U', 'N', 'N', -1, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTBMV( 'U', 'N', 'N', 0, -1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CTBMV( 'U', 'N', 'N', 0, 1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTBMV( 'U', 'N', 'N', 0, 0, A, 1, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 80 INFOT = 1+ CALL CTPMV( '/', 'N', 'N', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CTPMV( 'U', '/', 'N', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CTPMV( 'U', 'N', '/', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CTPMV( 'U', 'N', 'N', -1, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CTPMV( 'U', 'N', 'N', 0, A, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 90 INFOT = 1+ CALL CTRSV( '/', 'N', 'N', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CTRSV( 'U', '/', 'N', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CTRSV( 'U', 'N', '/', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CTRSV( 'U', 'N', 'N', -1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRSV( 'U', 'N', 'N', 2, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL CTRSV( 'U', 'N', 'N', 0, A, 1, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 100 INFOT = 1+ CALL CTBSV( '/', 'N', 'N', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CTBSV( 'U', '/', 'N', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CTBSV( 'U', 'N', '/', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CTBSV( 'U', 'N', 'N', -1, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTBSV( 'U', 'N', 'N', 0, -1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CTBSV( 'U', 'N', 'N', 0, 1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTBSV( 'U', 'N', 'N', 0, 0, A, 1, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 110 INFOT = 1+ CALL CTPSV( '/', 'N', 'N', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CTPSV( 'U', '/', 'N', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CTPSV( 'U', 'N', '/', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CTPSV( 'U', 'N', 'N', -1, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CTPSV( 'U', 'N', 'N', 0, A, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 120 INFOT = 1+ CALL CGERC( -1, 0, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CGERC( 0, -1, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CGERC( 0, 0, ALPHA, X, 0, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CGERC( 0, 0, ALPHA, X, 1, Y, 0, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CGERC( 2, 0, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 130 INFOT = 1+ CALL CGERU( -1, 0, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CGERU( 0, -1, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CGERU( 0, 0, ALPHA, X, 0, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CGERU( 0, 0, ALPHA, X, 1, Y, 0, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CGERU( 2, 0, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 140 INFOT = 1+ CALL CHER( '/', 0, RALPHA, X, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CHER( 'U', -1, RALPHA, X, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CHER( 'U', 0, RALPHA, X, 0, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CHER( 'U', 2, RALPHA, X, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 150 INFOT = 1+ CALL CHPR( '/', 0, RALPHA, X, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CHPR( 'U', -1, RALPHA, X, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CHPR( 'U', 0, RALPHA, X, 0, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 160 INFOT = 1+ CALL CHER2( '/', 0, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CHER2( 'U', -1, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CHER2( 'U', 0, ALPHA, X, 0, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CHER2( 'U', 0, ALPHA, X, 1, Y, 0, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CHER2( 'U', 2, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 170 INFOT = 1+ CALL CHPR2( '/', 0, ALPHA, X, 1, Y, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CHPR2( 'U', -1, ALPHA, X, 1, Y, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CHPR2( 'U', 0, ALPHA, X, 0, Y, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CHPR2( 'U', 0, ALPHA, X, 1, Y, 0, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+*+ 180 IF( OK )THEN+ WRITE( NOUT, FMT = 9999 )SRNAMT+ ELSE+ WRITE( NOUT, FMT = 9998 )SRNAMT+ END IF+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE TESTS OF ERROR-EXITS' )+ 9998 FORMAT( ' ******* ', A6, ' FAILED THE TESTS OF ERROR-EXITS *****',+ $ '**' )+*+* End of CCHKE.+*+ END+ SUBROUTINE CMAKE( TYPE, UPLO, DIAG, M, N, A, NMAX, AA, LDA, KL,+ $ KU, RESET, TRANSL )+*+* Generates values for an M by N matrix A within the bandwidth+* defined by KL and KU.+* Stores the values in the array AA in the data structure required+* by the routine, with unwanted elements set to rogue value.+*+* TYPE is 'GE', 'GB', 'HE', 'HB', 'HP', 'TR', 'TB' OR 'TP'.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ COMPLEX ZERO, ONE+ PARAMETER ( ZERO = ( 0.0, 0.0 ), ONE = ( 1.0, 0.0 ) )+ COMPLEX ROGUE+ PARAMETER ( ROGUE = ( -1.0E10, 1.0E10 ) )+ REAL RZERO+ PARAMETER ( RZERO = 0.0 )+ REAL RROGUE+ PARAMETER ( RROGUE = -1.0E10 )+* .. Scalar Arguments ..+ COMPLEX TRANSL+ INTEGER KL, KU, LDA, M, N, NMAX+ LOGICAL RESET+ CHARACTER*1 DIAG, UPLO+ CHARACTER*2 TYPE+* .. Array Arguments ..+ COMPLEX A( NMAX, * ), AA( * )+* .. Local Scalars ..+ INTEGER I, I1, I2, I3, IBEG, IEND, IOFF, J, JJ, KK+ LOGICAL GEN, LOWER, SYM, TRI, UNIT, UPPER+* .. External Functions ..+ COMPLEX CBEG+ EXTERNAL CBEG+* .. Intrinsic Functions ..+ INTRINSIC CMPLX, CONJG, MAX, MIN, REAL+* .. Executable Statements ..+ GEN = TYPE( 1: 1 ).EQ.'G'+ SYM = TYPE( 1: 1 ).EQ.'H'+ TRI = TYPE( 1: 1 ).EQ.'T'+ UPPER = ( SYM.OR.TRI ).AND.UPLO.EQ.'U'+ LOWER = ( SYM.OR.TRI ).AND.UPLO.EQ.'L'+ UNIT = TRI.AND.DIAG.EQ.'U'+*+* Generate data in array A.+*+ DO 20 J = 1, N+ DO 10 I = 1, M+ IF( GEN.OR.( UPPER.AND.I.LE.J ).OR.( LOWER.AND.I.GE.J ) )+ $ THEN+ IF( ( I.LE.J.AND.J - I.LE.KU ).OR.+ $ ( I.GE.J.AND.I - J.LE.KL ) )THEN+ A( I, J ) = CBEG( RESET ) + TRANSL+ ELSE+ A( I, J ) = ZERO+ END IF+ IF( I.NE.J )THEN+ IF( SYM )THEN+ A( J, I ) = CONJG( A( I, J ) )+ ELSE IF( TRI )THEN+ A( J, I ) = ZERO+ END IF+ END IF+ END IF+ 10 CONTINUE+ IF( SYM )+ $ A( J, J ) = CMPLX( REAL( A( J, J ) ), RZERO )+ IF( TRI )+ $ A( J, J ) = A( J, J ) + ONE+ IF( UNIT )+ $ A( J, J ) = ONE+ 20 CONTINUE+*+* Store elements in array AS in data structure required by routine.+*+ IF( TYPE.EQ.'GE' )THEN+ DO 50 J = 1, N+ DO 30 I = 1, M+ AA( I + ( J - 1 )*LDA ) = A( I, J )+ 30 CONTINUE+ DO 40 I = M + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 40 CONTINUE+ 50 CONTINUE+ ELSE IF( TYPE.EQ.'GB' )THEN+ DO 90 J = 1, N+ DO 60 I1 = 1, KU + 1 - J+ AA( I1 + ( J - 1 )*LDA ) = ROGUE+ 60 CONTINUE+ DO 70 I2 = I1, MIN( KL + KU + 1, KU + 1 + M - J )+ AA( I2 + ( J - 1 )*LDA ) = A( I2 + J - KU - 1, J )+ 70 CONTINUE+ DO 80 I3 = I2, LDA+ AA( I3 + ( J - 1 )*LDA ) = ROGUE+ 80 CONTINUE+ 90 CONTINUE+ ELSE IF( TYPE.EQ.'HE'.OR.TYPE.EQ.'TR' )THEN+ DO 130 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IF( UNIT )THEN+ IEND = J - 1+ ELSE+ IEND = J+ END IF+ ELSE+ IF( UNIT )THEN+ IBEG = J + 1+ ELSE+ IBEG = J+ END IF+ IEND = N+ END IF+ DO 100 I = 1, IBEG - 1+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 100 CONTINUE+ DO 110 I = IBEG, IEND+ AA( I + ( J - 1 )*LDA ) = A( I, J )+ 110 CONTINUE+ DO 120 I = IEND + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 120 CONTINUE+ IF( SYM )THEN+ JJ = J + ( J - 1 )*LDA+ AA( JJ ) = CMPLX( REAL( AA( JJ ) ), RROGUE )+ END IF+ 130 CONTINUE+ ELSE IF( TYPE.EQ.'HB'.OR.TYPE.EQ.'TB' )THEN+ DO 170 J = 1, N+ IF( UPPER )THEN+ KK = KL + 1+ IBEG = MAX( 1, KL + 2 - J )+ IF( UNIT )THEN+ IEND = KL+ ELSE+ IEND = KL + 1+ END IF+ ELSE+ KK = 1+ IF( UNIT )THEN+ IBEG = 2+ ELSE+ IBEG = 1+ END IF+ IEND = MIN( KL + 1, 1 + M - J )+ END IF+ DO 140 I = 1, IBEG - 1+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 140 CONTINUE+ DO 150 I = IBEG, IEND+ AA( I + ( J - 1 )*LDA ) = A( I + J - KK, J )+ 150 CONTINUE+ DO 160 I = IEND + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 160 CONTINUE+ IF( SYM )THEN+ JJ = KK + ( J - 1 )*LDA+ AA( JJ ) = CMPLX( REAL( AA( JJ ) ), RROGUE )+ END IF+ 170 CONTINUE+ ELSE IF( TYPE.EQ.'HP'.OR.TYPE.EQ.'TP' )THEN+ IOFF = 0+ DO 190 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IEND = J+ ELSE+ IBEG = J+ IEND = N+ END IF+ DO 180 I = IBEG, IEND+ IOFF = IOFF + 1+ AA( IOFF ) = A( I, J )+ IF( I.EQ.J )THEN+ IF( UNIT )+ $ AA( IOFF ) = ROGUE+ IF( SYM )+ $ AA( IOFF ) = CMPLX( REAL( AA( IOFF ) ), RROGUE )+ END IF+ 180 CONTINUE+ 190 CONTINUE+ END IF+ RETURN+*+* End of CMAKE.+*+ END+ SUBROUTINE CMVCH( TRANS, M, N, ALPHA, A, NMAX, X, INCX, BETA, Y,+ $ INCY, YT, G, YY, EPS, ERR, FATAL, NOUT, MV )+*+* Checks the results of the computational tests.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ COMPLEX ZERO+ PARAMETER ( ZERO = ( 0.0, 0.0 ) )+ REAL RZERO, RONE+ PARAMETER ( RZERO = 0.0, RONE = 1.0 )+* .. Scalar Arguments ..+ COMPLEX ALPHA, BETA+ REAL EPS, ERR+ INTEGER INCX, INCY, M, N, NMAX, NOUT+ LOGICAL FATAL, MV+ CHARACTER*1 TRANS+* .. Array Arguments ..+ COMPLEX A( NMAX, * ), X( * ), Y( * ), YT( * ), YY( * )+ REAL G( * )+* .. Local Scalars ..+ COMPLEX C+ REAL ERRI+ INTEGER I, INCXL, INCYL, IY, J, JX, KX, KY, ML, NL+ LOGICAL CTRAN, TRAN+* .. Intrinsic Functions ..+ INTRINSIC ABS, AIMAG, CONJG, MAX, REAL, SQRT+* .. Statement Functions ..+ REAL ABS1+* .. Statement Function definitions ..+ ABS1( C ) = ABS( REAL( C ) ) + ABS( AIMAG( C ) )+* .. Executable Statements ..+ TRAN = TRANS.EQ.'T'+ CTRAN = TRANS.EQ.'C'+ IF( TRAN.OR.CTRAN )THEN+ ML = N+ NL = M+ ELSE+ ML = M+ NL = N+ END IF+ IF( INCX.LT.0 )THEN+ KX = NL+ INCXL = -1+ ELSE+ KX = 1+ INCXL = 1+ END IF+ IF( INCY.LT.0 )THEN+ KY = ML+ INCYL = -1+ ELSE+ KY = 1+ INCYL = 1+ END IF+*+* Compute expected result in YT using data in A, X and Y.+* Compute gauges in G.+*+ IY = KY+ DO 40 I = 1, ML+ YT( IY ) = ZERO+ G( IY ) = RZERO+ JX = KX+ IF( TRAN )THEN+ DO 10 J = 1, NL+ YT( IY ) = YT( IY ) + A( J, I )*X( JX )+ G( IY ) = G( IY ) + ABS1( A( J, I ) )*ABS1( X( JX ) )+ JX = JX + INCXL+ 10 CONTINUE+ ELSE IF( CTRAN )THEN+ DO 20 J = 1, NL+ YT( IY ) = YT( IY ) + CONJG( A( J, I ) )*X( JX )+ G( IY ) = G( IY ) + ABS1( A( J, I ) )*ABS1( X( JX ) )+ JX = JX + INCXL+ 20 CONTINUE+ ELSE+ DO 30 J = 1, NL+ YT( IY ) = YT( IY ) + A( I, J )*X( JX )+ G( IY ) = G( IY ) + ABS1( A( I, J ) )*ABS1( X( JX ) )+ JX = JX + INCXL+ 30 CONTINUE+ END IF+ YT( IY ) = ALPHA*YT( IY ) + BETA*Y( IY )+ G( IY ) = ABS1( ALPHA )*G( IY ) + ABS1( BETA )*ABS1( Y( IY ) )+ IY = IY + INCYL+ 40 CONTINUE+*+* Compute the error ratio for this result.+*+ ERR = ZERO+ DO 50 I = 1, ML+ ERRI = ABS( YT( I ) - YY( 1 + ( I - 1 )*ABS( INCY ) ) )/EPS+ IF( G( I ).NE.RZERO )+ $ ERRI = ERRI/G( I )+ ERR = MAX( ERR, ERRI )+ IF( ERR*SQRT( EPS ).GE.RONE )+ $ GO TO 60+ 50 CONTINUE+* If the loop completes, all results are at least half accurate.+ GO TO 80+*+* Report fatal error.+*+ 60 FATAL = .TRUE.+ WRITE( NOUT, FMT = 9999 )+ DO 70 I = 1, ML+ IF( MV )THEN+ WRITE( NOUT, FMT = 9998 )I, YT( I ),+ $ YY( 1 + ( I - 1 )*ABS( INCY ) )+ ELSE+ WRITE( NOUT, FMT = 9998 )I,+ $ YY( 1 + ( I - 1 )*ABS( INCY ) ), YT( I )+ END IF+ 70 CONTINUE+*+ 80 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ******* FATAL ERROR - COMPUTED RESULT IS LESS THAN HAL',+ $ 'F ACCURATE *******', /' EXPECTED RE',+ $ 'SULT COMPUTED RESULT' )+ 9998 FORMAT( 1X, I7, 2( ' (', G15.6, ',', G15.6, ')' ) )+*+* End of CMVCH.+*+ END+ LOGICAL FUNCTION LCE( RI, RJ, LR )+*+* Tests if two arrays are identical.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER LR+* .. Array Arguments ..+ COMPLEX RI( * ), RJ( * )+* .. Local Scalars ..+ INTEGER I+* .. Executable Statements ..+ DO 10 I = 1, LR+ IF( RI( I ).NE.RJ( I ) )+ $ GO TO 20+ 10 CONTINUE+ LCE = .TRUE.+ GO TO 30+ 20 CONTINUE+ LCE = .FALSE.+ 30 RETURN+*+* End of LCE.+*+ END+ LOGICAL FUNCTION LCERES( TYPE, UPLO, M, N, AA, AS, LDA )+*+* Tests if selected elements in two arrays are equal.+*+* TYPE is 'GE', 'HE' or 'HP'.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER LDA, M, N+ CHARACTER*1 UPLO+ CHARACTER*2 TYPE+* .. Array Arguments ..+ COMPLEX AA( LDA, * ), AS( LDA, * )+* .. Local Scalars ..+ INTEGER I, IBEG, IEND, J+ LOGICAL UPPER+* .. Executable Statements ..+ UPPER = UPLO.EQ.'U'+ IF( TYPE.EQ.'GE' )THEN+ DO 20 J = 1, N+ DO 10 I = M + 1, LDA+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 10 CONTINUE+ 20 CONTINUE+ ELSE IF( TYPE.EQ.'HE' )THEN+ DO 50 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IEND = J+ ELSE+ IBEG = J+ IEND = N+ END IF+ DO 30 I = 1, IBEG - 1+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 30 CONTINUE+ DO 40 I = IEND + 1, LDA+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 40 CONTINUE+ 50 CONTINUE+ END IF+*+ 60 CONTINUE+ LCERES = .TRUE.+ GO TO 80+ 70 CONTINUE+ LCERES = .FALSE.+ 80 RETURN+*+* End of LCERES.+*+ END+ COMPLEX FUNCTION CBEG( RESET )+*+* Generates complex numbers as pairs of random numbers uniformly+* distributed between -0.5 and 0.5.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ LOGICAL RESET+* .. Local Scalars ..+ INTEGER I, IC, J, MI, MJ+* .. Save statement ..+ SAVE I, IC, J, MI, MJ+* .. Intrinsic Functions ..+ INTRINSIC CMPLX+* .. Executable Statements ..+ IF( RESET )THEN+* Initialize local variables.+ MI = 891+ MJ = 457+ I = 7+ J = 7+ IC = 0+ RESET = .FALSE.+ END IF+*+* The sequence of values of I or J is bounded between 1 and 999.+* If initial I or J = 1,2,3,6,7 or 9, the period will be 50.+* If initial I or J = 4 or 8, the period will be 25.+* If initial I or J = 5, the period will be 10.+* IC is used to break up the period by skipping 1 value of I or J+* in 6.+*+ IC = IC + 1+ 10 I = I*MI+ J = J*MJ+ I = I - 1000*( I/1000 )+ J = J - 1000*( J/1000 )+ IF( IC.GE.5 )THEN+ IC = 0+ GO TO 10+ END IF+ CBEG = CMPLX( ( I - 500 )/1001.0, ( J - 500 )/1001.0 )+ RETURN+*+* End of CBEG.+*+ END+ REAL FUNCTION SDIFF( X, Y )+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+*+* .. Scalar Arguments ..+ REAL X, Y+* .. Executable Statements ..+ SDIFF = X - Y+ RETURN+*+* End of SDIFF.+*+ END+ SUBROUTINE CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+*+* Tests whether XERBLA has detected an error when it should.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER INFOT, NOUT+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Executable Statements ..+ IF( .NOT.LERR )THEN+ WRITE( NOUT, FMT = 9999 )INFOT, SRNAMT+ OK = .FALSE.+ END IF+ LERR = .FALSE.+ RETURN+*+ 9999 FORMAT( ' ***** ILLEGAL VALUE OF PARAMETER NUMBER ', I2, ' NOT D',+ $ 'ETECTED BY ', A6, ' *****' )+*+* End of CHKXER.+*+ END+ SUBROUTINE XERBLA( SRNAME, INFO )+*+* This is a special version of XERBLA to be used only as part of+* the test program for testing error exits from the Level 2 BLAS+* routines.+*+* XERBLA is an error handler for the Level 2 BLAS routines.+*+* It is called by the Level 2 BLAS routines if an input parameter is+* invalid.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER INFO+ CHARACTER*6 SRNAME+* .. Scalars in Common ..+ INTEGER INFOT, NOUT+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUT, OK, LERR+ COMMON /SRNAMC/SRNAMT+* .. Executable Statements ..+ LERR = .TRUE.+ IF( INFO.NE.INFOT )THEN+ IF( INFOT.NE.0 )THEN+ WRITE( NOUT, FMT = 9999 )INFO, INFOT+ ELSE+ WRITE( NOUT, FMT = 9997 )INFO+ END IF+ OK = .FALSE.+ END IF+ IF( SRNAME.NE.SRNAMT )THEN+ WRITE( NOUT, FMT = 9998 )SRNAME, SRNAMT+ OK = .FALSE.+ END IF+ RETURN+*+ 9999 FORMAT( ' ******* XERBLA WAS CALLED WITH INFO = ', I6, ' INSTEAD',+ $ ' OF ', I2, ' *******' )+ 9998 FORMAT( ' ******* XERBLA WAS CALLED WITH SRNAME = ', A6, ' INSTE',+ $ 'AD OF ', A6, ' *******' )+ 9997 FORMAT( ' ******* XERBLA WAS CALLED WITH INFO = ', I6,+ $ ' *******' )+*+* End of XERBLA+*+ END+
+ eigen3/blas/testing/cblat3.dat view
@@ -0,0 +1,23 @@+'cblat3.summ' NAME OF SUMMARY OUTPUT FILE+6 UNIT NUMBER OF SUMMARY FILE+'cblat3.snap' NAME OF SNAPSHOT OUTPUT FILE+-1 UNIT NUMBER OF SNAPSHOT FILE (NOT USED IF .LT. 0)+F LOGICAL FLAG, T TO REWIND SNAPSHOT FILE AFTER EACH RECORD.+F LOGICAL FLAG, T TO STOP ON FAILURES.+F LOGICAL FLAG, T TO TEST ERROR EXITS.+16.0 THRESHOLD VALUE OF TEST RATIO+6 NUMBER OF VALUES OF N+0 1 2 3 5 9 VALUES OF N+3 NUMBER OF VALUES OF ALPHA+(0.0,0.0) (1.0,0.0) (0.7,-0.9) VALUES OF ALPHA+3 NUMBER OF VALUES OF BETA+(0.0,0.0) (1.0,0.0) (1.3,-1.1) VALUES OF BETA+CGEMM T PUT F FOR NO TEST. SAME COLUMNS.+CHEMM T PUT F FOR NO TEST. SAME COLUMNS.+CSYMM T PUT F FOR NO TEST. SAME COLUMNS.+CTRMM T PUT F FOR NO TEST. SAME COLUMNS.+CTRSM T PUT F FOR NO TEST. SAME COLUMNS.+CHERK T PUT F FOR NO TEST. SAME COLUMNS.+CSYRK T PUT F FOR NO TEST. SAME COLUMNS.+CHER2K T PUT F FOR NO TEST. SAME COLUMNS.+CSYR2K T PUT F FOR NO TEST. SAME COLUMNS.
+ eigen3/blas/testing/cblat3.f view
@@ -0,0 +1,3439 @@+ PROGRAM CBLAT3+*+* Test program for the COMPLEX Level 3 Blas.+*+* The program must be driven by a short data file. The first 14 records+* of the file are read using list-directed input, the last 9 records+* are read using the format ( A6, L2 ). An annotated example of a data+* file can be obtained by deleting the first 3 characters from the+* following 23 lines:+* 'CBLAT3.SUMM' NAME OF SUMMARY OUTPUT FILE+* 6 UNIT NUMBER OF SUMMARY FILE+* 'CBLAT3.SNAP' NAME OF SNAPSHOT OUTPUT FILE+* -1 UNIT NUMBER OF SNAPSHOT FILE (NOT USED IF .LT. 0)+* F LOGICAL FLAG, T TO REWIND SNAPSHOT FILE AFTER EACH RECORD.+* F LOGICAL FLAG, T TO STOP ON FAILURES.+* T LOGICAL FLAG, T TO TEST ERROR EXITS.+* 16.0 THRESHOLD VALUE OF TEST RATIO+* 6 NUMBER OF VALUES OF N+* 0 1 2 3 5 9 VALUES OF N+* 3 NUMBER OF VALUES OF ALPHA+* (0.0,0.0) (1.0,0.0) (0.7,-0.9) VALUES OF ALPHA+* 3 NUMBER OF VALUES OF BETA+* (0.0,0.0) (1.0,0.0) (1.3,-1.1) VALUES OF BETA+* CGEMM T PUT F FOR NO TEST. SAME COLUMNS.+* CHEMM T PUT F FOR NO TEST. SAME COLUMNS.+* CSYMM T PUT F FOR NO TEST. SAME COLUMNS.+* CTRMM T PUT F FOR NO TEST. SAME COLUMNS.+* CTRSM T PUT F FOR NO TEST. SAME COLUMNS.+* CHERK T PUT F FOR NO TEST. SAME COLUMNS.+* CSYRK T PUT F FOR NO TEST. SAME COLUMNS.+* CHER2K T PUT F FOR NO TEST. SAME COLUMNS.+* CSYR2K T PUT F FOR NO TEST. SAME COLUMNS.+*+* See:+*+* Dongarra J. J., Du Croz J. J., Duff I. S. and Hammarling S.+* A Set of Level 3 Basic Linear Algebra Subprograms.+*+* Technical Memorandum No.88 (Revision 1), Mathematics and+* Computer Science Division, Argonne National Laboratory, 9700+* South Cass Avenue, Argonne, Illinois 60439, US.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ INTEGER NIN+ PARAMETER ( NIN = 5 )+ INTEGER NSUBS+ PARAMETER ( NSUBS = 9 )+ COMPLEX ZERO, ONE+ PARAMETER ( ZERO = ( 0.0, 0.0 ), ONE = ( 1.0, 0.0 ) )+ REAL RZERO, RHALF, RONE+ PARAMETER ( RZERO = 0.0, RHALF = 0.5, RONE = 1.0 )+ INTEGER NMAX+ PARAMETER ( NMAX = 65 )+ INTEGER NIDMAX, NALMAX, NBEMAX+ PARAMETER ( NIDMAX = 9, NALMAX = 7, NBEMAX = 7 )+* .. Local Scalars ..+ REAL EPS, ERR, THRESH+ INTEGER I, ISNUM, J, N, NALF, NBET, NIDIM, NOUT, NTRA+ LOGICAL FATAL, LTESTT, REWI, SAME, SFATAL, TRACE,+ $ TSTERR+ CHARACTER*1 TRANSA, TRANSB+ CHARACTER*6 SNAMET+ CHARACTER*32 SNAPS, SUMMRY+* .. Local Arrays ..+ COMPLEX AA( NMAX*NMAX ), AB( NMAX, 2*NMAX ),+ $ ALF( NALMAX ), AS( NMAX*NMAX ),+ $ BB( NMAX*NMAX ), BET( NBEMAX ),+ $ BS( NMAX*NMAX ), C( NMAX, NMAX ),+ $ CC( NMAX*NMAX ), CS( NMAX*NMAX ), CT( NMAX ),+ $ W( 2*NMAX )+ REAL G( NMAX )+ INTEGER IDIM( NIDMAX )+ LOGICAL LTEST( NSUBS )+ CHARACTER*6 SNAMES( NSUBS )+* .. External Functions ..+ REAL SDIFF+ LOGICAL LCE+ EXTERNAL SDIFF, LCE+* .. External Subroutines ..+ EXTERNAL CCHK1, CCHK2, CCHK3, CCHK4, CCHK5, CCHKE, CMMCH+* .. Intrinsic Functions ..+ INTRINSIC MAX, MIN+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+ COMMON /SRNAMC/SRNAMT+* .. Data statements ..+ DATA SNAMES/'CGEMM ', 'CHEMM ', 'CSYMM ', 'CTRMM ',+ $ 'CTRSM ', 'CHERK ', 'CSYRK ', 'CHER2K',+ $ 'CSYR2K'/+* .. Executable Statements ..+*+* Read name and unit number for summary output file and open file.+*+ READ( NIN, FMT = * )SUMMRY+ READ( NIN, FMT = * )NOUT+ OPEN( NOUT, FILE = SUMMRY, STATUS = 'NEW' )+ NOUTC = NOUT+*+* Read name and unit number for snapshot output file and open file.+*+ READ( NIN, FMT = * )SNAPS+ READ( NIN, FMT = * )NTRA+ TRACE = NTRA.GE.0+ IF( TRACE )THEN+ OPEN( NTRA, FILE = SNAPS, STATUS = 'NEW' )+ END IF+* Read the flag that directs rewinding of the snapshot file.+ READ( NIN, FMT = * )REWI+ REWI = REWI.AND.TRACE+* Read the flag that directs stopping on any failure.+ READ( NIN, FMT = * )SFATAL+* Read the flag that indicates whether error exits are to be tested.+ READ( NIN, FMT = * )TSTERR+* Read the threshold value of the test ratio+ READ( NIN, FMT = * )THRESH+*+* Read and check the parameter values for the tests.+*+* Values of N+ READ( NIN, FMT = * )NIDIM+ IF( NIDIM.LT.1.OR.NIDIM.GT.NIDMAX )THEN+ WRITE( NOUT, FMT = 9997 )'N', NIDMAX+ GO TO 220+ END IF+ READ( NIN, FMT = * )( IDIM( I ), I = 1, NIDIM )+ DO 10 I = 1, NIDIM+ IF( IDIM( I ).LT.0.OR.IDIM( I ).GT.NMAX )THEN+ WRITE( NOUT, FMT = 9996 )NMAX+ GO TO 220+ END IF+ 10 CONTINUE+* Values of ALPHA+ READ( NIN, FMT = * )NALF+ IF( NALF.LT.1.OR.NALF.GT.NALMAX )THEN+ WRITE( NOUT, FMT = 9997 )'ALPHA', NALMAX+ GO TO 220+ END IF+ READ( NIN, FMT = * )( ALF( I ), I = 1, NALF )+* Values of BETA+ READ( NIN, FMT = * )NBET+ IF( NBET.LT.1.OR.NBET.GT.NBEMAX )THEN+ WRITE( NOUT, FMT = 9997 )'BETA', NBEMAX+ GO TO 220+ END IF+ READ( NIN, FMT = * )( BET( I ), I = 1, NBET )+*+* Report values of parameters.+*+ WRITE( NOUT, FMT = 9995 )+ WRITE( NOUT, FMT = 9994 )( IDIM( I ), I = 1, NIDIM )+ WRITE( NOUT, FMT = 9993 )( ALF( I ), I = 1, NALF )+ WRITE( NOUT, FMT = 9992 )( BET( I ), I = 1, NBET )+ IF( .NOT.TSTERR )THEN+ WRITE( NOUT, FMT = * )+ WRITE( NOUT, FMT = 9984 )+ END IF+ WRITE( NOUT, FMT = * )+ WRITE( NOUT, FMT = 9999 )THRESH+ WRITE( NOUT, FMT = * )+*+* Read names of subroutines and flags which indicate+* whether they are to be tested.+*+ DO 20 I = 1, NSUBS+ LTEST( I ) = .FALSE.+ 20 CONTINUE+ 30 READ( NIN, FMT = 9988, END = 60 )SNAMET, LTESTT+ DO 40 I = 1, NSUBS+ IF( SNAMET.EQ.SNAMES( I ) )+ $ GO TO 50+ 40 CONTINUE+ WRITE( NOUT, FMT = 9990 )SNAMET+ STOP+ 50 LTEST( I ) = LTESTT+ GO TO 30+*+ 60 CONTINUE+ CLOSE ( NIN )+*+* Compute EPS (the machine precision).+*+ EPS = RONE+ 70 CONTINUE+ IF( SDIFF( RONE + EPS, RONE ).EQ.RZERO )+ $ GO TO 80+ EPS = RHALF*EPS+ GO TO 70+ 80 CONTINUE+ EPS = EPS + EPS+ WRITE( NOUT, FMT = 9998 )EPS+*+* Check the reliability of CMMCH using exact data.+*+ N = MIN( 32, NMAX )+ DO 100 J = 1, N+ DO 90 I = 1, N+ AB( I, J ) = MAX( I - J + 1, 0 )+ 90 CONTINUE+ AB( J, NMAX + 1 ) = J+ AB( 1, NMAX + J ) = J+ C( J, 1 ) = ZERO+ 100 CONTINUE+ DO 110 J = 1, N+ CC( J ) = J*( ( J + 1 )*J )/2 - ( ( J + 1 )*J*( J - 1 ) )/3+ 110 CONTINUE+* CC holds the exact result. On exit from CMMCH CT holds+* the result computed by CMMCH.+ TRANSA = 'N'+ TRANSB = 'N'+ CALL CMMCH( TRANSA, TRANSB, N, 1, N, ONE, AB, NMAX,+ $ AB( 1, NMAX + 1 ), NMAX, ZERO, C, NMAX, CT, G, CC,+ $ NMAX, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LCE( CC, CT, N )+ IF( .NOT.SAME.OR.ERR.NE.RZERO )THEN+ WRITE( NOUT, FMT = 9989 )TRANSA, TRANSB, SAME, ERR+ STOP+ END IF+ TRANSB = 'C'+ CALL CMMCH( TRANSA, TRANSB, N, 1, N, ONE, AB, NMAX,+ $ AB( 1, NMAX + 1 ), NMAX, ZERO, C, NMAX, CT, G, CC,+ $ NMAX, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LCE( CC, CT, N )+ IF( .NOT.SAME.OR.ERR.NE.RZERO )THEN+ WRITE( NOUT, FMT = 9989 )TRANSA, TRANSB, SAME, ERR+ STOP+ END IF+ DO 120 J = 1, N+ AB( J, NMAX + 1 ) = N - J + 1+ AB( 1, NMAX + J ) = N - J + 1+ 120 CONTINUE+ DO 130 J = 1, N+ CC( N - J + 1 ) = J*( ( J + 1 )*J )/2 -+ $ ( ( J + 1 )*J*( J - 1 ) )/3+ 130 CONTINUE+ TRANSA = 'C'+ TRANSB = 'N'+ CALL CMMCH( TRANSA, TRANSB, N, 1, N, ONE, AB, NMAX,+ $ AB( 1, NMAX + 1 ), NMAX, ZERO, C, NMAX, CT, G, CC,+ $ NMAX, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LCE( CC, CT, N )+ IF( .NOT.SAME.OR.ERR.NE.RZERO )THEN+ WRITE( NOUT, FMT = 9989 )TRANSA, TRANSB, SAME, ERR+ STOP+ END IF+ TRANSB = 'C'+ CALL CMMCH( TRANSA, TRANSB, N, 1, N, ONE, AB, NMAX,+ $ AB( 1, NMAX + 1 ), NMAX, ZERO, C, NMAX, CT, G, CC,+ $ NMAX, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LCE( CC, CT, N )+ IF( .NOT.SAME.OR.ERR.NE.RZERO )THEN+ WRITE( NOUT, FMT = 9989 )TRANSA, TRANSB, SAME, ERR+ STOP+ END IF+*+* Test each subroutine in turn.+*+ DO 200 ISNUM = 1, NSUBS+ WRITE( NOUT, FMT = * )+ IF( .NOT.LTEST( ISNUM ) )THEN+* Subprogram is not to be tested.+ WRITE( NOUT, FMT = 9987 )SNAMES( ISNUM )+ ELSE+ SRNAMT = SNAMES( ISNUM )+* Test error exits.+ IF( TSTERR )THEN+ CALL CCHKE( ISNUM, SNAMES( ISNUM ), NOUT )+ WRITE( NOUT, FMT = * )+ END IF+* Test computations.+ INFOT = 0+ OK = .TRUE.+ FATAL = .FALSE.+ GO TO ( 140, 150, 150, 160, 160, 170, 170,+ $ 180, 180 )ISNUM+* Test CGEMM, 01.+ 140 CALL CCHK1( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET,+ $ NMAX, AB, AA, AS, AB( 1, NMAX + 1 ), BB, BS, C,+ $ CC, CS, CT, G )+ GO TO 190+* Test CHEMM, 02, CSYMM, 03.+ 150 CALL CCHK2( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET,+ $ NMAX, AB, AA, AS, AB( 1, NMAX + 1 ), BB, BS, C,+ $ CC, CS, CT, G )+ GO TO 190+* Test CTRMM, 04, CTRSM, 05.+ 160 CALL CCHK3( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NMAX, AB,+ $ AA, AS, AB( 1, NMAX + 1 ), BB, BS, CT, G, C )+ GO TO 190+* Test CHERK, 06, CSYRK, 07.+ 170 CALL CCHK4( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET,+ $ NMAX, AB, AA, AS, AB( 1, NMAX + 1 ), BB, BS, C,+ $ CC, CS, CT, G )+ GO TO 190+* Test CHER2K, 08, CSYR2K, 09.+ 180 CALL CCHK5( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET,+ $ NMAX, AB, AA, AS, BB, BS, C, CC, CS, CT, G, W )+ GO TO 190+*+ 190 IF( FATAL.AND.SFATAL )+ $ GO TO 210+ END IF+ 200 CONTINUE+ WRITE( NOUT, FMT = 9986 )+ GO TO 230+*+ 210 CONTINUE+ WRITE( NOUT, FMT = 9985 )+ GO TO 230+*+ 220 CONTINUE+ WRITE( NOUT, FMT = 9991 )+*+ 230 CONTINUE+ IF( TRACE )+ $ CLOSE ( NTRA )+ CLOSE ( NOUT )+ STOP+*+ 9999 FORMAT( ' ROUTINES PASS COMPUTATIONAL TESTS IF TEST RATIO IS LES',+ $ 'S THAN', F8.2 )+ 9998 FORMAT( ' RELATIVE MACHINE PRECISION IS TAKEN TO BE', 1P, E9.1 )+ 9997 FORMAT( ' NUMBER OF VALUES OF ', A, ' IS LESS THAN 1 OR GREATER ',+ $ 'THAN ', I2 )+ 9996 FORMAT( ' VALUE OF N IS LESS THAN 0 OR GREATER THAN ', I2 )+ 9995 FORMAT( ' TESTS OF THE COMPLEX LEVEL 3 BLAS', //' THE F',+ $ 'OLLOWING PARAMETER VALUES WILL BE USED:' )+ 9994 FORMAT( ' FOR N ', 9I6 )+ 9993 FORMAT( ' FOR ALPHA ',+ $ 7( '(', F4.1, ',', F4.1, ') ', : ) )+ 9992 FORMAT( ' FOR BETA ',+ $ 7( '(', F4.1, ',', F4.1, ') ', : ) )+ 9991 FORMAT( ' AMEND DATA FILE OR INCREASE ARRAY SIZES IN PROGRAM',+ $ /' ******* TESTS ABANDONED *******' )+ 9990 FORMAT( ' SUBPROGRAM NAME ', A6, ' NOT RECOGNIZED', /' ******* T',+ $ 'ESTS ABANDONED *******' )+ 9989 FORMAT( ' ERROR IN CMMCH - IN-LINE DOT PRODUCTS ARE BEING EVALU',+ $ 'ATED WRONGLY.', /' CMMCH WAS CALLED WITH TRANSA = ', A1,+ $ ' AND TRANSB = ', A1, /' AND RETURNED SAME = ', L1, ' AND ',+ $ 'ERR = ', F12.3, '.', /' THIS MAY BE DUE TO FAULTS IN THE ',+ $ 'ARITHMETIC OR THE COMPILER.', /' ******* TESTS ABANDONED ',+ $ '*******' )+ 9988 FORMAT( A6, L2 )+ 9987 FORMAT( 1X, A6, ' WAS NOT TESTED' )+ 9986 FORMAT( /' END OF TESTS' )+ 9985 FORMAT( /' ******* FATAL ERROR - TESTS ABANDONED *******' )+ 9984 FORMAT( ' ERROR-EXITS WILL NOT BE TESTED' )+*+* End of CBLAT3.+*+ END+ SUBROUTINE CCHK1( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET, NMAX,+ $ A, AA, AS, B, BB, BS, C, CC, CS, CT, G )+*+* Tests CGEMM.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ COMPLEX ZERO+ PARAMETER ( ZERO = ( 0.0, 0.0 ) )+ REAL RZERO+ PARAMETER ( RZERO = 0.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER NALF, NBET, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), B( NMAX, NMAX ),+ $ BB( NMAX*NMAX ), BET( NBET ), BS( NMAX*NMAX ),+ $ C( NMAX, NMAX ), CC( NMAX*NMAX ),+ $ CS( NMAX*NMAX ), CT( NMAX )+ REAL G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ COMPLEX ALPHA, ALS, BETA, BLS+ REAL ERR, ERRMAX+ INTEGER I, IA, IB, ICA, ICB, IK, IM, IN, K, KS, LAA,+ $ LBB, LCC, LDA, LDAS, LDB, LDBS, LDC, LDCS, M,+ $ MA, MB, MS, N, NA, NARGS, NB, NC, NS+ LOGICAL NULL, RESET, SAME, TRANA, TRANB+ CHARACTER*1 TRANAS, TRANBS, TRANSA, TRANSB+ CHARACTER*3 ICH+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LCE, LCERES+ EXTERNAL LCE, LCERES+* .. External Subroutines ..+ EXTERNAL CGEMM, CMAKE, CMMCH+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'NTC'/+* .. Executable Statements ..+*+ NARGS = 13+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 110 IM = 1, NIDIM+ M = IDIM( IM )+*+ DO 100 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDC to 1 more than minimum value if room.+ LDC = M+ IF( LDC.LT.NMAX )+ $ LDC = LDC + 1+* Skip tests if not enough room.+ IF( LDC.GT.NMAX )+ $ GO TO 100+ LCC = LDC*N+ NULL = N.LE.0.OR.M.LE.0+*+ DO 90 IK = 1, NIDIM+ K = IDIM( IK )+*+ DO 80 ICA = 1, 3+ TRANSA = ICH( ICA: ICA )+ TRANA = TRANSA.EQ.'T'.OR.TRANSA.EQ.'C'+*+ IF( TRANA )THEN+ MA = K+ NA = M+ ELSE+ MA = M+ NA = K+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = MA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 80+ LAA = LDA*NA+*+* Generate the matrix A.+*+ CALL CMAKE( 'GE', ' ', ' ', MA, NA, A, NMAX, AA, LDA,+ $ RESET, ZERO )+*+ DO 70 ICB = 1, 3+ TRANSB = ICH( ICB: ICB )+ TRANB = TRANSB.EQ.'T'.OR.TRANSB.EQ.'C'+*+ IF( TRANB )THEN+ MB = N+ NB = K+ ELSE+ MB = K+ NB = N+ END IF+* Set LDB to 1 more than minimum value if room.+ LDB = MB+ IF( LDB.LT.NMAX )+ $ LDB = LDB + 1+* Skip tests if not enough room.+ IF( LDB.GT.NMAX )+ $ GO TO 70+ LBB = LDB*NB+*+* Generate the matrix B.+*+ CALL CMAKE( 'GE', ' ', ' ', MB, NB, B, NMAX, BB,+ $ LDB, RESET, ZERO )+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the matrix C.+*+ CALL CMAKE( 'GE', ' ', ' ', M, N, C, NMAX,+ $ CC, LDC, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ TRANAS = TRANSA+ TRANBS = TRANSB+ MS = M+ NS = N+ KS = K+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LBB+ BS( I ) = BB( I )+ 20 CONTINUE+ LDBS = LDB+ BLS = BETA+ DO 30 I = 1, LCC+ CS( I ) = CC( I )+ 30 CONTINUE+ LDCS = LDC+*+* Call the subroutine.+*+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ TRANSA, TRANSB, M, N, K, ALPHA, LDA, LDB,+ $ BETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL CGEMM( TRANSA, TRANSB, M, N, K, ALPHA,+ $ AA, LDA, BB, LDB, BETA, CC, LDC )+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9994 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = TRANSA.EQ.TRANAS+ ISAME( 2 ) = TRANSB.EQ.TRANBS+ ISAME( 3 ) = MS.EQ.M+ ISAME( 4 ) = NS.EQ.N+ ISAME( 5 ) = KS.EQ.K+ ISAME( 6 ) = ALS.EQ.ALPHA+ ISAME( 7 ) = LCE( AS, AA, LAA )+ ISAME( 8 ) = LDAS.EQ.LDA+ ISAME( 9 ) = LCE( BS, BB, LBB )+ ISAME( 10 ) = LDBS.EQ.LDB+ ISAME( 11 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 12 ) = LCE( CS, CC, LCC )+ ELSE+ ISAME( 12 ) = LCERES( 'GE', ' ', M, N, CS,+ $ CC, LDC )+ END IF+ ISAME( 13 ) = LDCS.EQ.LDC+*+* If data was incorrectly changed, report+* and return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result.+*+ CALL CMMCH( TRANSA, TRANSB, M, N, K,+ $ ALPHA, A, NMAX, B, NMAX, BETA,+ $ C, NMAX, CT, G, CC, LDC, EPS,+ $ ERR, FATAL, NOUT, .TRUE. )+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 120+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9995 )NC, SNAME, TRANSA, TRANSB, M, N, K,+ $ ALPHA, LDA, LDB, BETA, LDC+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',''', A1, ''',',+ $ 3( I3, ',' ), '(', F4.1, ',', F4.1, '), A,', I3, ', B,', I3,+ $ ',(', F4.1, ',', F4.1, '), C,', I3, ').' )+ 9994 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of CCHK1.+*+ END+ SUBROUTINE CCHK2( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET, NMAX,+ $ A, AA, AS, B, BB, BS, C, CC, CS, CT, G )+*+* Tests CHEMM and CSYMM.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ COMPLEX ZERO+ PARAMETER ( ZERO = ( 0.0, 0.0 ) )+ REAL RZERO+ PARAMETER ( RZERO = 0.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER NALF, NBET, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), B( NMAX, NMAX ),+ $ BB( NMAX*NMAX ), BET( NBET ), BS( NMAX*NMAX ),+ $ C( NMAX, NMAX ), CC( NMAX*NMAX ),+ $ CS( NMAX*NMAX ), CT( NMAX )+ REAL G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ COMPLEX ALPHA, ALS, BETA, BLS+ REAL ERR, ERRMAX+ INTEGER I, IA, IB, ICS, ICU, IM, IN, LAA, LBB, LCC,+ $ LDA, LDAS, LDB, LDBS, LDC, LDCS, M, MS, N, NA,+ $ NARGS, NC, NS+ LOGICAL CONJ, LEFT, NULL, RESET, SAME+ CHARACTER*1 SIDE, SIDES, UPLO, UPLOS+ CHARACTER*2 ICHS, ICHU+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LCE, LCERES+ EXTERNAL LCE, LCERES+* .. External Subroutines ..+ EXTERNAL CHEMM, CMAKE, CMMCH, CSYMM+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHS/'LR'/, ICHU/'UL'/+* .. Executable Statements ..+ CONJ = SNAME( 2: 3 ).EQ.'HE'+*+ NARGS = 12+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 100 IM = 1, NIDIM+ M = IDIM( IM )+*+ DO 90 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDC to 1 more than minimum value if room.+ LDC = M+ IF( LDC.LT.NMAX )+ $ LDC = LDC + 1+* Skip tests if not enough room.+ IF( LDC.GT.NMAX )+ $ GO TO 90+ LCC = LDC*N+ NULL = N.LE.0.OR.M.LE.0+* Set LDB to 1 more than minimum value if room.+ LDB = M+ IF( LDB.LT.NMAX )+ $ LDB = LDB + 1+* Skip tests if not enough room.+ IF( LDB.GT.NMAX )+ $ GO TO 90+ LBB = LDB*N+*+* Generate the matrix B.+*+ CALL CMAKE( 'GE', ' ', ' ', M, N, B, NMAX, BB, LDB, RESET,+ $ ZERO )+*+ DO 80 ICS = 1, 2+ SIDE = ICHS( ICS: ICS )+ LEFT = SIDE.EQ.'L'+*+ IF( LEFT )THEN+ NA = M+ ELSE+ NA = N+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = NA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 80+ LAA = LDA*NA+*+ DO 70 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+*+* Generate the hermitian or symmetric matrix A.+*+ CALL CMAKE( SNAME( 2: 3 ), UPLO, ' ', NA, NA, A, NMAX,+ $ AA, LDA, RESET, ZERO )+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the matrix C.+*+ CALL CMAKE( 'GE', ' ', ' ', M, N, C, NMAX, CC,+ $ LDC, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ SIDES = SIDE+ UPLOS = UPLO+ MS = M+ NS = N+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LBB+ BS( I ) = BB( I )+ 20 CONTINUE+ LDBS = LDB+ BLS = BETA+ DO 30 I = 1, LCC+ CS( I ) = CC( I )+ 30 CONTINUE+ LDCS = LDC+*+* Call the subroutine.+*+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME, SIDE,+ $ UPLO, M, N, ALPHA, LDA, LDB, BETA, LDC+ IF( REWI )+ $ REWIND NTRA+ IF( CONJ )THEN+ CALL CHEMM( SIDE, UPLO, M, N, ALPHA, AA, LDA,+ $ BB, LDB, BETA, CC, LDC )+ ELSE+ CALL CSYMM( SIDE, UPLO, M, N, ALPHA, AA, LDA,+ $ BB, LDB, BETA, CC, LDC )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9994 )+ FATAL = .TRUE.+ GO TO 110+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = SIDES.EQ.SIDE+ ISAME( 2 ) = UPLOS.EQ.UPLO+ ISAME( 3 ) = MS.EQ.M+ ISAME( 4 ) = NS.EQ.N+ ISAME( 5 ) = ALS.EQ.ALPHA+ ISAME( 6 ) = LCE( AS, AA, LAA )+ ISAME( 7 ) = LDAS.EQ.LDA+ ISAME( 8 ) = LCE( BS, BB, LBB )+ ISAME( 9 ) = LDBS.EQ.LDB+ ISAME( 10 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 11 ) = LCE( CS, CC, LCC )+ ELSE+ ISAME( 11 ) = LCERES( 'GE', ' ', M, N, CS,+ $ CC, LDC )+ END IF+ ISAME( 12 ) = LDCS.EQ.LDC+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 110+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result.+*+ IF( LEFT )THEN+ CALL CMMCH( 'N', 'N', M, N, M, ALPHA, A,+ $ NMAX, B, NMAX, BETA, C, NMAX,+ $ CT, G, CC, LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ELSE+ CALL CMMCH( 'N', 'N', M, N, N, ALPHA, B,+ $ NMAX, A, NMAX, BETA, C, NMAX,+ $ CT, G, CC, LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 110+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 120+*+ 110 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9995 )NC, SNAME, SIDE, UPLO, M, N, ALPHA, LDA,+ $ LDB, BETA, LDC+*+ 120 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(', 2( '''', A1, ''',' ), 2( I3, ',' ),+ $ '(', F4.1, ',', F4.1, '), A,', I3, ', B,', I3, ',(', F4.1,+ $ ',', F4.1, '), C,', I3, ') .' )+ 9994 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of CCHK2.+*+ END+ SUBROUTINE CCHK3( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NMAX, A, AA, AS,+ $ B, BB, BS, CT, G, C )+*+* Tests CTRMM and CTRSM.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ COMPLEX ZERO, ONE+ PARAMETER ( ZERO = ( 0.0, 0.0 ), ONE = ( 1.0, 0.0 ) )+ REAL RZERO+ PARAMETER ( RZERO = 0.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER NALF, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), B( NMAX, NMAX ),+ $ BB( NMAX*NMAX ), BS( NMAX*NMAX ),+ $ C( NMAX, NMAX ), CT( NMAX )+ REAL G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ COMPLEX ALPHA, ALS+ REAL ERR, ERRMAX+ INTEGER I, IA, ICD, ICS, ICT, ICU, IM, IN, J, LAA, LBB,+ $ LDA, LDAS, LDB, LDBS, M, MS, N, NA, NARGS, NC,+ $ NS+ LOGICAL LEFT, NULL, RESET, SAME+ CHARACTER*1 DIAG, DIAGS, SIDE, SIDES, TRANAS, TRANSA, UPLO,+ $ UPLOS+ CHARACTER*2 ICHD, ICHS, ICHU+ CHARACTER*3 ICHT+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LCE, LCERES+ EXTERNAL LCE, LCERES+* .. External Subroutines ..+ EXTERNAL CMAKE, CMMCH, CTRMM, CTRSM+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHU/'UL'/, ICHT/'NTC'/, ICHD/'UN'/, ICHS/'LR'/+* .. Executable Statements ..+*+ NARGS = 11+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+* Set up zero matrix for CMMCH.+ DO 20 J = 1, NMAX+ DO 10 I = 1, NMAX+ C( I, J ) = ZERO+ 10 CONTINUE+ 20 CONTINUE+*+ DO 140 IM = 1, NIDIM+ M = IDIM( IM )+*+ DO 130 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDB to 1 more than minimum value if room.+ LDB = M+ IF( LDB.LT.NMAX )+ $ LDB = LDB + 1+* Skip tests if not enough room.+ IF( LDB.GT.NMAX )+ $ GO TO 130+ LBB = LDB*N+ NULL = M.LE.0.OR.N.LE.0+*+ DO 120 ICS = 1, 2+ SIDE = ICHS( ICS: ICS )+ LEFT = SIDE.EQ.'L'+ IF( LEFT )THEN+ NA = M+ ELSE+ NA = N+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = NA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 130+ LAA = LDA*NA+*+ DO 110 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+*+ DO 100 ICT = 1, 3+ TRANSA = ICHT( ICT: ICT )+*+ DO 90 ICD = 1, 2+ DIAG = ICHD( ICD: ICD )+*+ DO 80 IA = 1, NALF+ ALPHA = ALF( IA )+*+* Generate the matrix A.+*+ CALL CMAKE( 'TR', UPLO, DIAG, NA, NA, A,+ $ NMAX, AA, LDA, RESET, ZERO )+*+* Generate the matrix B.+*+ CALL CMAKE( 'GE', ' ', ' ', M, N, B, NMAX,+ $ BB, LDB, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ SIDES = SIDE+ UPLOS = UPLO+ TRANAS = TRANSA+ DIAGS = DIAG+ MS = M+ NS = N+ ALS = ALPHA+ DO 30 I = 1, LAA+ AS( I ) = AA( I )+ 30 CONTINUE+ LDAS = LDA+ DO 40 I = 1, LBB+ BS( I ) = BB( I )+ 40 CONTINUE+ LDBS = LDB+*+* Call the subroutine.+*+ IF( SNAME( 4: 5 ).EQ.'MM' )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA,+ $ LDA, LDB+ IF( REWI )+ $ REWIND NTRA+ CALL CTRMM( SIDE, UPLO, TRANSA, DIAG, M,+ $ N, ALPHA, AA, LDA, BB, LDB )+ ELSE IF( SNAME( 4: 5 ).EQ.'SM' )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA,+ $ LDA, LDB+ IF( REWI )+ $ REWIND NTRA+ CALL CTRSM( SIDE, UPLO, TRANSA, DIAG, M,+ $ N, ALPHA, AA, LDA, BB, LDB )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9994 )+ FATAL = .TRUE.+ GO TO 150+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = SIDES.EQ.SIDE+ ISAME( 2 ) = UPLOS.EQ.UPLO+ ISAME( 3 ) = TRANAS.EQ.TRANSA+ ISAME( 4 ) = DIAGS.EQ.DIAG+ ISAME( 5 ) = MS.EQ.M+ ISAME( 6 ) = NS.EQ.N+ ISAME( 7 ) = ALS.EQ.ALPHA+ ISAME( 8 ) = LCE( AS, AA, LAA )+ ISAME( 9 ) = LDAS.EQ.LDA+ IF( NULL )THEN+ ISAME( 10 ) = LCE( BS, BB, LBB )+ ELSE+ ISAME( 10 ) = LCERES( 'GE', ' ', M, N, BS,+ $ BB, LDB )+ END IF+ ISAME( 11 ) = LDBS.EQ.LDB+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 50 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 50 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 150+ END IF+*+ IF( .NOT.NULL )THEN+ IF( SNAME( 4: 5 ).EQ.'MM' )THEN+*+* Check the result.+*+ IF( LEFT )THEN+ CALL CMMCH( TRANSA, 'N', M, N, M,+ $ ALPHA, A, NMAX, B, NMAX,+ $ ZERO, C, NMAX, CT, G,+ $ BB, LDB, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ELSE+ CALL CMMCH( 'N', TRANSA, M, N, N,+ $ ALPHA, B, NMAX, A, NMAX,+ $ ZERO, C, NMAX, CT, G,+ $ BB, LDB, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ END IF+ ELSE IF( SNAME( 4: 5 ).EQ.'SM' )THEN+*+* Compute approximation to original+* matrix.+*+ DO 70 J = 1, N+ DO 60 I = 1, M+ C( I, J ) = BB( I + ( J - 1 )*+ $ LDB )+ BB( I + ( J - 1 )*LDB ) = ALPHA*+ $ B( I, J )+ 60 CONTINUE+ 70 CONTINUE+*+ IF( LEFT )THEN+ CALL CMMCH( TRANSA, 'N', M, N, M,+ $ ONE, A, NMAX, C, NMAX,+ $ ZERO, B, NMAX, CT, G,+ $ BB, LDB, EPS, ERR,+ $ FATAL, NOUT, .FALSE. )+ ELSE+ CALL CMMCH( 'N', TRANSA, M, N, N,+ $ ONE, C, NMAX, A, NMAX,+ $ ZERO, B, NMAX, CT, G,+ $ BB, LDB, EPS, ERR,+ $ FATAL, NOUT, .FALSE. )+ END IF+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 150+ END IF+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+ 130 CONTINUE+*+ 140 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 160+*+ 150 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9995 )NC, SNAME, SIDE, UPLO, TRANSA, DIAG, M,+ $ N, ALPHA, LDA, LDB+*+ 160 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(', 4( '''', A1, ''',' ), 2( I3, ',' ),+ $ '(', F4.1, ',', F4.1, '), A,', I3, ', B,', I3, ') ',+ $ ' .' )+ 9994 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of CCHK3.+*+ END+ SUBROUTINE CCHK4( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET, NMAX,+ $ A, AA, AS, B, BB, BS, C, CC, CS, CT, G )+*+* Tests CHERK and CSYRK.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ COMPLEX ZERO+ PARAMETER ( ZERO = ( 0.0, 0.0 ) )+ REAL RONE, RZERO+ PARAMETER ( RONE = 1.0, RZERO = 0.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER NALF, NBET, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), B( NMAX, NMAX ),+ $ BB( NMAX*NMAX ), BET( NBET ), BS( NMAX*NMAX ),+ $ C( NMAX, NMAX ), CC( NMAX*NMAX ),+ $ CS( NMAX*NMAX ), CT( NMAX )+ REAL G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ COMPLEX ALPHA, ALS, BETA, BETS+ REAL ERR, ERRMAX, RALPHA, RALS, RBETA, RBETS+ INTEGER I, IA, IB, ICT, ICU, IK, IN, J, JC, JJ, K, KS,+ $ LAA, LCC, LDA, LDAS, LDC, LDCS, LJ, MA, N, NA,+ $ NARGS, NC, NS+ LOGICAL CONJ, NULL, RESET, SAME, TRAN, UPPER+ CHARACTER*1 TRANS, TRANSS, TRANST, UPLO, UPLOS+ CHARACTER*2 ICHT, ICHU+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LCE, LCERES+ EXTERNAL LCE, LCERES+* .. External Subroutines ..+ EXTERNAL CHERK, CMAKE, CMMCH, CSYRK+* .. Intrinsic Functions ..+ INTRINSIC CMPLX, MAX, REAL+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHT/'NC'/, ICHU/'UL'/+* .. Executable Statements ..+ CONJ = SNAME( 2: 3 ).EQ.'HE'+*+ NARGS = 10+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 100 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDC to 1 more than minimum value if room.+ LDC = N+ IF( LDC.LT.NMAX )+ $ LDC = LDC + 1+* Skip tests if not enough room.+ IF( LDC.GT.NMAX )+ $ GO TO 100+ LCC = LDC*N+*+ DO 90 IK = 1, NIDIM+ K = IDIM( IK )+*+ DO 80 ICT = 1, 2+ TRANS = ICHT( ICT: ICT )+ TRAN = TRANS.EQ.'C'+ IF( TRAN.AND..NOT.CONJ )+ $ TRANS = 'T'+ IF( TRAN )THEN+ MA = K+ NA = N+ ELSE+ MA = N+ NA = K+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = MA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 80+ LAA = LDA*NA+*+* Generate the matrix A.+*+ CALL CMAKE( 'GE', ' ', ' ', MA, NA, A, NMAX, AA, LDA,+ $ RESET, ZERO )+*+ DO 70 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+ UPPER = UPLO.EQ.'U'+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+ IF( CONJ )THEN+ RALPHA = REAL( ALPHA )+ ALPHA = CMPLX( RALPHA, RZERO )+ END IF+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+ IF( CONJ )THEN+ RBETA = REAL( BETA )+ BETA = CMPLX( RBETA, RZERO )+ END IF+ NULL = N.LE.0+ IF( CONJ )+ $ NULL = NULL.OR.( ( K.LE.0.OR.RALPHA.EQ.+ $ RZERO ).AND.RBETA.EQ.RONE )+*+* Generate the matrix C.+*+ CALL CMAKE( SNAME( 2: 3 ), UPLO, ' ', N, N, C,+ $ NMAX, CC, LDC, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ TRANSS = TRANS+ NS = N+ KS = K+ IF( CONJ )THEN+ RALS = RALPHA+ ELSE+ ALS = ALPHA+ END IF+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ IF( CONJ )THEN+ RBETS = RBETA+ ELSE+ BETS = BETA+ END IF+ DO 20 I = 1, LCC+ CS( I ) = CC( I )+ 20 CONTINUE+ LDCS = LDC+*+* Call the subroutine.+*+ IF( CONJ )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, UPLO,+ $ TRANS, N, K, RALPHA, LDA, RBETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL CHERK( UPLO, TRANS, N, K, RALPHA, AA,+ $ LDA, RBETA, CC, LDC )+ ELSE+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME, UPLO,+ $ TRANS, N, K, ALPHA, LDA, BETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL CSYRK( UPLO, TRANS, N, K, ALPHA, AA,+ $ LDA, BETA, CC, LDC )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLOS.EQ.UPLO+ ISAME( 2 ) = TRANSS.EQ.TRANS+ ISAME( 3 ) = NS.EQ.N+ ISAME( 4 ) = KS.EQ.K+ IF( CONJ )THEN+ ISAME( 5 ) = RALS.EQ.RALPHA+ ELSE+ ISAME( 5 ) = ALS.EQ.ALPHA+ END IF+ ISAME( 6 ) = LCE( AS, AA, LAA )+ ISAME( 7 ) = LDAS.EQ.LDA+ IF( CONJ )THEN+ ISAME( 8 ) = RBETS.EQ.RBETA+ ELSE+ ISAME( 8 ) = BETS.EQ.BETA+ END IF+ IF( NULL )THEN+ ISAME( 9 ) = LCE( CS, CC, LCC )+ ELSE+ ISAME( 9 ) = LCERES( SNAME( 2: 3 ), UPLO, N,+ $ N, CS, CC, LDC )+ END IF+ ISAME( 10 ) = LDCS.EQ.LDC+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 30 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 30 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ IF( CONJ )THEN+ TRANST = 'C'+ ELSE+ TRANST = 'T'+ END IF+ JC = 1+ DO 40 J = 1, N+ IF( UPPER )THEN+ JJ = 1+ LJ = J+ ELSE+ JJ = J+ LJ = N - J + 1+ END IF+ IF( TRAN )THEN+ CALL CMMCH( TRANST, 'N', LJ, 1, K,+ $ ALPHA, A( 1, JJ ), NMAX,+ $ A( 1, J ), NMAX, BETA,+ $ C( JJ, J ), NMAX, CT, G,+ $ CC( JC ), LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ELSE+ CALL CMMCH( 'N', TRANST, LJ, 1, K,+ $ ALPHA, A( JJ, 1 ), NMAX,+ $ A( J, 1 ), NMAX, BETA,+ $ C( JJ, J ), NMAX, CT, G,+ $ CC( JC ), LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ END IF+ IF( UPPER )THEN+ JC = JC + LDC+ ELSE+ JC = JC + LDC + 1+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 110+ 40 CONTINUE+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 110 CONTINUE+ IF( N.GT.1 )+ $ WRITE( NOUT, FMT = 9995 )J+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( CONJ )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, TRANS, N, K, RALPHA,+ $ LDA, RBETA, LDC+ ELSE+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, TRANS, N, K, ALPHA,+ $ LDA, BETA, LDC+ END IF+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(', 2( '''', A1, ''',' ), 2( I3, ',' ),+ $ F4.1, ', A,', I3, ',', F4.1, ', C,', I3, ') ',+ $ ' .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(', 2( '''', A1, ''',' ), 2( I3, ',' ),+ $ '(', F4.1, ',', F4.1, ') , A,', I3, ',(', F4.1, ',', F4.1,+ $ '), C,', I3, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of CCHK4.+*+ END+ SUBROUTINE CCHK5( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET, NMAX,+ $ AB, AA, AS, BB, BS, C, CC, CS, CT, G, W )+*+* Tests CHER2K and CSYR2K.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ COMPLEX ZERO, ONE+ PARAMETER ( ZERO = ( 0.0, 0.0 ), ONE = ( 1.0, 0.0 ) )+ REAL RONE, RZERO+ PARAMETER ( RONE = 1.0, RZERO = 0.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER NALF, NBET, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX AA( NMAX*NMAX ), AB( 2*NMAX*NMAX ),+ $ ALF( NALF ), AS( NMAX*NMAX ), BB( NMAX*NMAX ),+ $ BET( NBET ), BS( NMAX*NMAX ), C( NMAX, NMAX ),+ $ CC( NMAX*NMAX ), CS( NMAX*NMAX ), CT( NMAX ),+ $ W( 2*NMAX )+ REAL G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ COMPLEX ALPHA, ALS, BETA, BETS+ REAL ERR, ERRMAX, RBETA, RBETS+ INTEGER I, IA, IB, ICT, ICU, IK, IN, J, JC, JJ, JJAB,+ $ K, KS, LAA, LBB, LCC, LDA, LDAS, LDB, LDBS,+ $ LDC, LDCS, LJ, MA, N, NA, NARGS, NC, NS+ LOGICAL CONJ, NULL, RESET, SAME, TRAN, UPPER+ CHARACTER*1 TRANS, TRANSS, TRANST, UPLO, UPLOS+ CHARACTER*2 ICHT, ICHU+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LCE, LCERES+ EXTERNAL LCE, LCERES+* .. External Subroutines ..+ EXTERNAL CHER2K, CMAKE, CMMCH, CSYR2K+* .. Intrinsic Functions ..+ INTRINSIC CMPLX, CONJG, MAX, REAL+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHT/'NC'/, ICHU/'UL'/+* .. Executable Statements ..+ CONJ = SNAME( 2: 3 ).EQ.'HE'+*+ NARGS = 12+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 130 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDC to 1 more than minimum value if room.+ LDC = N+ IF( LDC.LT.NMAX )+ $ LDC = LDC + 1+* Skip tests if not enough room.+ IF( LDC.GT.NMAX )+ $ GO TO 130+ LCC = LDC*N+*+ DO 120 IK = 1, NIDIM+ K = IDIM( IK )+*+ DO 110 ICT = 1, 2+ TRANS = ICHT( ICT: ICT )+ TRAN = TRANS.EQ.'C'+ IF( TRAN.AND..NOT.CONJ )+ $ TRANS = 'T'+ IF( TRAN )THEN+ MA = K+ NA = N+ ELSE+ MA = N+ NA = K+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = MA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 110+ LAA = LDA*NA+*+* Generate the matrix A.+*+ IF( TRAN )THEN+ CALL CMAKE( 'GE', ' ', ' ', MA, NA, AB, 2*NMAX, AA,+ $ LDA, RESET, ZERO )+ ELSE+ CALL CMAKE( 'GE', ' ', ' ', MA, NA, AB, NMAX, AA, LDA,+ $ RESET, ZERO )+ END IF+*+* Generate the matrix B.+*+ LDB = LDA+ LBB = LAA+ IF( TRAN )THEN+ CALL CMAKE( 'GE', ' ', ' ', MA, NA, AB( K + 1 ),+ $ 2*NMAX, BB, LDB, RESET, ZERO )+ ELSE+ CALL CMAKE( 'GE', ' ', ' ', MA, NA, AB( K*NMAX + 1 ),+ $ NMAX, BB, LDB, RESET, ZERO )+ END IF+*+ DO 100 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+ UPPER = UPLO.EQ.'U'+*+ DO 90 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 80 IB = 1, NBET+ BETA = BET( IB )+ IF( CONJ )THEN+ RBETA = REAL( BETA )+ BETA = CMPLX( RBETA, RZERO )+ END IF+ NULL = N.LE.0+ IF( CONJ )+ $ NULL = NULL.OR.( ( K.LE.0.OR.ALPHA.EQ.+ $ ZERO ).AND.RBETA.EQ.RONE )+*+* Generate the matrix C.+*+ CALL CMAKE( SNAME( 2: 3 ), UPLO, ' ', N, N, C,+ $ NMAX, CC, LDC, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ TRANSS = TRANS+ NS = N+ KS = K+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LBB+ BS( I ) = BB( I )+ 20 CONTINUE+ LDBS = LDB+ IF( CONJ )THEN+ RBETS = RBETA+ ELSE+ BETS = BETA+ END IF+ DO 30 I = 1, LCC+ CS( I ) = CC( I )+ 30 CONTINUE+ LDCS = LDC+*+* Call the subroutine.+*+ IF( CONJ )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, UPLO,+ $ TRANS, N, K, ALPHA, LDA, LDB, RBETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL CHER2K( UPLO, TRANS, N, K, ALPHA, AA,+ $ LDA, BB, LDB, RBETA, CC, LDC )+ ELSE+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME, UPLO,+ $ TRANS, N, K, ALPHA, LDA, LDB, BETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL CSYR2K( UPLO, TRANS, N, K, ALPHA, AA,+ $ LDA, BB, LDB, BETA, CC, LDC )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 150+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLOS.EQ.UPLO+ ISAME( 2 ) = TRANSS.EQ.TRANS+ ISAME( 3 ) = NS.EQ.N+ ISAME( 4 ) = KS.EQ.K+ ISAME( 5 ) = ALS.EQ.ALPHA+ ISAME( 6 ) = LCE( AS, AA, LAA )+ ISAME( 7 ) = LDAS.EQ.LDA+ ISAME( 8 ) = LCE( BS, BB, LBB )+ ISAME( 9 ) = LDBS.EQ.LDB+ IF( CONJ )THEN+ ISAME( 10 ) = RBETS.EQ.RBETA+ ELSE+ ISAME( 10 ) = BETS.EQ.BETA+ END IF+ IF( NULL )THEN+ ISAME( 11 ) = LCE( CS, CC, LCC )+ ELSE+ ISAME( 11 ) = LCERES( 'HE', UPLO, N, N, CS,+ $ CC, LDC )+ END IF+ ISAME( 12 ) = LDCS.EQ.LDC+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 150+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ IF( CONJ )THEN+ TRANST = 'C'+ ELSE+ TRANST = 'T'+ END IF+ JJAB = 1+ JC = 1+ DO 70 J = 1, N+ IF( UPPER )THEN+ JJ = 1+ LJ = J+ ELSE+ JJ = J+ LJ = N - J + 1+ END IF+ IF( TRAN )THEN+ DO 50 I = 1, K+ W( I ) = ALPHA*AB( ( J - 1 )*2*+ $ NMAX + K + I )+ IF( CONJ )THEN+ W( K + I ) = CONJG( ALPHA )*+ $ AB( ( J - 1 )*2*+ $ NMAX + I )+ ELSE+ W( K + I ) = ALPHA*+ $ AB( ( J - 1 )*2*+ $ NMAX + I )+ END IF+ 50 CONTINUE+ CALL CMMCH( TRANST, 'N', LJ, 1, 2*K,+ $ ONE, AB( JJAB ), 2*NMAX, W,+ $ 2*NMAX, BETA, C( JJ, J ),+ $ NMAX, CT, G, CC( JC ), LDC,+ $ EPS, ERR, FATAL, NOUT,+ $ .TRUE. )+ ELSE+ DO 60 I = 1, K+ IF( CONJ )THEN+ W( I ) = ALPHA*CONJG( AB( ( K ++ $ I - 1 )*NMAX + J ) )+ W( K + I ) = CONJG( ALPHA*+ $ AB( ( I - 1 )*NMAX ++ $ J ) )+ ELSE+ W( I ) = ALPHA*AB( ( K + I - 1 )*+ $ NMAX + J )+ W( K + I ) = ALPHA*+ $ AB( ( I - 1 )*NMAX ++ $ J )+ END IF+ 60 CONTINUE+ CALL CMMCH( 'N', 'N', LJ, 1, 2*K, ONE,+ $ AB( JJ ), NMAX, W, 2*NMAX,+ $ BETA, C( JJ, J ), NMAX, CT,+ $ G, CC( JC ), LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ END IF+ IF( UPPER )THEN+ JC = JC + LDC+ ELSE+ JC = JC + LDC + 1+ IF( TRAN )+ $ JJAB = JJAB + 2*NMAX+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 140+ 70 CONTINUE+ END IF+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+ 130 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 160+*+ 140 CONTINUE+ IF( N.GT.1 )+ $ WRITE( NOUT, FMT = 9995 )J+*+ 150 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( CONJ )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, TRANS, N, K, ALPHA,+ $ LDA, LDB, RBETA, LDC+ ELSE+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, TRANS, N, K, ALPHA,+ $ LDA, LDB, BETA, LDC+ END IF+*+ 160 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(', 2( '''', A1, ''',' ), 2( I3, ',' ),+ $ '(', F4.1, ',', F4.1, '), A,', I3, ', B,', I3, ',', F4.1,+ $ ', C,', I3, ') .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(', 2( '''', A1, ''',' ), 2( I3, ',' ),+ $ '(', F4.1, ',', F4.1, '), A,', I3, ', B,', I3, ',(', F4.1,+ $ ',', F4.1, '), C,', I3, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of CCHK5.+*+ END+ SUBROUTINE CCHKE( ISNUM, SRNAMT, NOUT )+*+* Tests the error exits from the Level 3 Blas.+* Requires a special version of the error-handling routine XERBLA.+* ALPHA, RALPHA, BETA, RBETA, A, B and C should not need to be defined.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER ISNUM, NOUT+ CHARACTER*6 SRNAMT+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Local Scalars ..+ COMPLEX ALPHA, BETA+ REAL RALPHA, RBETA+* .. Local Arrays ..+ COMPLEX A( 2, 1 ), B( 2, 1 ), C( 2, 1 )+* .. External Subroutines ..+ EXTERNAL CGEMM, CHEMM, CHER2K, CHERK, CHKXER, CSYMM,+ $ CSYR2K, CSYRK, CTRMM, CTRSM+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Executable Statements ..+* OK is set to .FALSE. by the special version of XERBLA or by CHKXER+* if anything is wrong.+ OK = .TRUE.+* LERR is set to .TRUE. by the special version of XERBLA each time+* it is called, and is then tested and re-set by CHKXER.+ LERR = .FALSE.+ GO TO ( 10, 20, 30, 40, 50, 60, 70, 80,+ $ 90 )ISNUM+ 10 INFOT = 1+ CALL CGEMM( '/', 'N', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 1+ CALL CGEMM( '/', 'C', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 1+ CALL CGEMM( '/', 'T', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CGEMM( 'N', '/', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CGEMM( 'C', '/', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CGEMM( 'T', '/', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CGEMM( 'N', 'N', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CGEMM( 'N', 'C', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CGEMM( 'N', 'T', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CGEMM( 'C', 'N', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CGEMM( 'C', 'C', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CGEMM( 'C', 'T', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CGEMM( 'T', 'N', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CGEMM( 'T', 'C', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CGEMM( 'T', 'T', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CGEMM( 'N', 'N', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CGEMM( 'N', 'C', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CGEMM( 'N', 'T', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CGEMM( 'C', 'N', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CGEMM( 'C', 'C', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CGEMM( 'C', 'T', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CGEMM( 'T', 'N', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CGEMM( 'T', 'C', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CGEMM( 'T', 'T', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CGEMM( 'N', 'N', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CGEMM( 'N', 'C', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CGEMM( 'N', 'T', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CGEMM( 'C', 'N', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CGEMM( 'C', 'C', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CGEMM( 'C', 'T', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CGEMM( 'T', 'N', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CGEMM( 'T', 'C', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CGEMM( 'T', 'T', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL CGEMM( 'N', 'N', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL CGEMM( 'N', 'C', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL CGEMM( 'N', 'T', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL CGEMM( 'C', 'N', 0, 0, 2, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL CGEMM( 'C', 'C', 0, 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL CGEMM( 'C', 'T', 0, 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL CGEMM( 'T', 'N', 0, 0, 2, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL CGEMM( 'T', 'C', 0, 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL CGEMM( 'T', 'T', 0, 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CGEMM( 'N', 'N', 0, 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CGEMM( 'C', 'N', 0, 0, 2, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CGEMM( 'T', 'N', 0, 0, 2, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CGEMM( 'N', 'C', 0, 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CGEMM( 'C', 'C', 0, 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CGEMM( 'T', 'C', 0, 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CGEMM( 'N', 'T', 0, 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CGEMM( 'C', 'T', 0, 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CGEMM( 'T', 'T', 0, 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL CGEMM( 'N', 'N', 2, 0, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL CGEMM( 'N', 'C', 2, 0, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL CGEMM( 'N', 'T', 2, 0, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL CGEMM( 'C', 'N', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL CGEMM( 'C', 'C', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL CGEMM( 'C', 'T', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL CGEMM( 'T', 'N', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL CGEMM( 'T', 'C', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL CGEMM( 'T', 'T', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 100+ 20 INFOT = 1+ CALL CHEMM( '/', 'U', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CHEMM( 'L', '/', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CHEMM( 'L', 'U', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CHEMM( 'R', 'U', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CHEMM( 'L', 'L', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CHEMM( 'R', 'L', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CHEMM( 'L', 'U', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CHEMM( 'R', 'U', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CHEMM( 'L', 'L', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CHEMM( 'R', 'L', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CHEMM( 'L', 'U', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CHEMM( 'R', 'U', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CHEMM( 'L', 'L', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CHEMM( 'R', 'L', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CHEMM( 'L', 'U', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CHEMM( 'R', 'U', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CHEMM( 'L', 'L', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CHEMM( 'R', 'L', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL CHEMM( 'L', 'U', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL CHEMM( 'R', 'U', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL CHEMM( 'L', 'L', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL CHEMM( 'R', 'L', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 100+ 30 INFOT = 1+ CALL CSYMM( '/', 'U', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CSYMM( 'L', '/', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CSYMM( 'L', 'U', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CSYMM( 'R', 'U', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CSYMM( 'L', 'L', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CSYMM( 'R', 'L', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CSYMM( 'L', 'U', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CSYMM( 'R', 'U', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CSYMM( 'L', 'L', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CSYMM( 'R', 'L', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CSYMM( 'L', 'U', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CSYMM( 'R', 'U', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CSYMM( 'L', 'L', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CSYMM( 'R', 'L', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CSYMM( 'L', 'U', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CSYMM( 'R', 'U', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CSYMM( 'L', 'L', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CSYMM( 'R', 'L', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL CSYMM( 'L', 'U', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL CSYMM( 'R', 'U', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL CSYMM( 'L', 'L', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL CSYMM( 'R', 'L', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 100+ 40 INFOT = 1+ CALL CTRMM( '/', 'U', 'N', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CTRMM( 'L', '/', 'N', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CTRMM( 'L', 'U', '/', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CTRMM( 'L', 'U', 'N', '/', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRMM( 'L', 'U', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRMM( 'L', 'U', 'C', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRMM( 'L', 'U', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRMM( 'R', 'U', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRMM( 'R', 'U', 'C', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRMM( 'R', 'U', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRMM( 'L', 'L', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRMM( 'L', 'L', 'C', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRMM( 'L', 'L', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRMM( 'R', 'L', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRMM( 'R', 'L', 'C', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRMM( 'R', 'L', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRMM( 'L', 'U', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRMM( 'L', 'U', 'C', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRMM( 'L', 'U', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRMM( 'R', 'U', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRMM( 'R', 'U', 'C', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRMM( 'R', 'U', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRMM( 'L', 'L', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRMM( 'L', 'L', 'C', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRMM( 'L', 'L', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRMM( 'R', 'L', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRMM( 'R', 'L', 'C', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRMM( 'R', 'L', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRMM( 'L', 'U', 'N', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRMM( 'L', 'U', 'C', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRMM( 'L', 'U', 'T', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRMM( 'R', 'U', 'N', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRMM( 'R', 'U', 'C', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRMM( 'R', 'U', 'T', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRMM( 'L', 'L', 'N', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRMM( 'L', 'L', 'C', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRMM( 'L', 'L', 'T', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRMM( 'R', 'L', 'N', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRMM( 'R', 'L', 'C', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRMM( 'R', 'L', 'T', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRMM( 'L', 'U', 'N', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRMM( 'L', 'U', 'C', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRMM( 'L', 'U', 'T', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRMM( 'R', 'U', 'N', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRMM( 'R', 'U', 'C', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRMM( 'R', 'U', 'T', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRMM( 'L', 'L', 'N', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRMM( 'L', 'L', 'C', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRMM( 'L', 'L', 'T', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRMM( 'R', 'L', 'N', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRMM( 'R', 'L', 'C', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRMM( 'R', 'L', 'T', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 100+ 50 INFOT = 1+ CALL CTRSM( '/', 'U', 'N', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CTRSM( 'L', '/', 'N', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CTRSM( 'L', 'U', '/', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CTRSM( 'L', 'U', 'N', '/', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRSM( 'L', 'U', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRSM( 'L', 'U', 'C', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRSM( 'L', 'U', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRSM( 'R', 'U', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRSM( 'R', 'U', 'C', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRSM( 'R', 'U', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRSM( 'L', 'L', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRSM( 'L', 'L', 'C', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRSM( 'L', 'L', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRSM( 'R', 'L', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRSM( 'R', 'L', 'C', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL CTRSM( 'R', 'L', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRSM( 'L', 'U', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRSM( 'L', 'U', 'C', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRSM( 'L', 'U', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRSM( 'R', 'U', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRSM( 'R', 'U', 'C', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRSM( 'R', 'U', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRSM( 'L', 'L', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRSM( 'L', 'L', 'C', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRSM( 'L', 'L', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRSM( 'R', 'L', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRSM( 'R', 'L', 'C', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL CTRSM( 'R', 'L', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRSM( 'L', 'U', 'N', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRSM( 'L', 'U', 'C', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRSM( 'L', 'U', 'T', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRSM( 'R', 'U', 'N', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRSM( 'R', 'U', 'C', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRSM( 'R', 'U', 'T', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRSM( 'L', 'L', 'N', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRSM( 'L', 'L', 'C', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRSM( 'L', 'L', 'T', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRSM( 'R', 'L', 'N', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRSM( 'R', 'L', 'C', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CTRSM( 'R', 'L', 'T', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRSM( 'L', 'U', 'N', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRSM( 'L', 'U', 'C', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRSM( 'L', 'U', 'T', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRSM( 'R', 'U', 'N', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRSM( 'R', 'U', 'C', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRSM( 'R', 'U', 'T', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRSM( 'L', 'L', 'N', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRSM( 'L', 'L', 'C', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRSM( 'L', 'L', 'T', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRSM( 'R', 'L', 'N', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRSM( 'R', 'L', 'C', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL CTRSM( 'R', 'L', 'T', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 100+ 60 INFOT = 1+ CALL CHERK( '/', 'N', 0, 0, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CHERK( 'U', 'T', 0, 0, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CHERK( 'U', 'N', -1, 0, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CHERK( 'U', 'C', -1, 0, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CHERK( 'L', 'N', -1, 0, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CHERK( 'L', 'C', -1, 0, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CHERK( 'U', 'N', 0, -1, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CHERK( 'U', 'C', 0, -1, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CHERK( 'L', 'N', 0, -1, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CHERK( 'L', 'C', 0, -1, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CHERK( 'U', 'N', 2, 0, RALPHA, A, 1, RBETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CHERK( 'U', 'C', 0, 2, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CHERK( 'L', 'N', 2, 0, RALPHA, A, 1, RBETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CHERK( 'L', 'C', 0, 2, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CHERK( 'U', 'N', 2, 0, RALPHA, A, 2, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CHERK( 'U', 'C', 2, 0, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CHERK( 'L', 'N', 2, 0, RALPHA, A, 2, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CHERK( 'L', 'C', 2, 0, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 100+ 70 INFOT = 1+ CALL CSYRK( '/', 'N', 0, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CSYRK( 'U', 'C', 0, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CSYRK( 'U', 'N', -1, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CSYRK( 'U', 'T', -1, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CSYRK( 'L', 'N', -1, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CSYRK( 'L', 'T', -1, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CSYRK( 'U', 'N', 0, -1, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CSYRK( 'U', 'T', 0, -1, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CSYRK( 'L', 'N', 0, -1, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CSYRK( 'L', 'T', 0, -1, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CSYRK( 'U', 'N', 2, 0, ALPHA, A, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CSYRK( 'U', 'T', 0, 2, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CSYRK( 'L', 'N', 2, 0, ALPHA, A, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CSYRK( 'L', 'T', 0, 2, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CSYRK( 'U', 'N', 2, 0, ALPHA, A, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CSYRK( 'U', 'T', 2, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CSYRK( 'L', 'N', 2, 0, ALPHA, A, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL CSYRK( 'L', 'T', 2, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 100+ 80 INFOT = 1+ CALL CHER2K( '/', 'N', 0, 0, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CHER2K( 'U', 'T', 0, 0, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CHER2K( 'U', 'N', -1, 0, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CHER2K( 'U', 'C', -1, 0, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CHER2K( 'L', 'N', -1, 0, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CHER2K( 'L', 'C', -1, 0, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CHER2K( 'U', 'N', 0, -1, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CHER2K( 'U', 'C', 0, -1, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CHER2K( 'L', 'N', 0, -1, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CHER2K( 'L', 'C', 0, -1, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CHER2K( 'U', 'N', 2, 0, ALPHA, A, 1, B, 1, RBETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CHER2K( 'U', 'C', 0, 2, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CHER2K( 'L', 'N', 2, 0, ALPHA, A, 1, B, 1, RBETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CHER2K( 'L', 'C', 0, 2, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CHER2K( 'U', 'N', 2, 0, ALPHA, A, 2, B, 1, RBETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CHER2K( 'U', 'C', 0, 2, ALPHA, A, 2, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CHER2K( 'L', 'N', 2, 0, ALPHA, A, 2, B, 1, RBETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CHER2K( 'L', 'C', 0, 2, ALPHA, A, 2, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL CHER2K( 'U', 'N', 2, 0, ALPHA, A, 2, B, 2, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL CHER2K( 'U', 'C', 2, 0, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL CHER2K( 'L', 'N', 2, 0, ALPHA, A, 2, B, 2, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL CHER2K( 'L', 'C', 2, 0, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 100+ 90 INFOT = 1+ CALL CSYR2K( '/', 'N', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL CSYR2K( 'U', 'C', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CSYR2K( 'U', 'N', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CSYR2K( 'U', 'T', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CSYR2K( 'L', 'N', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL CSYR2K( 'L', 'T', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CSYR2K( 'U', 'N', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CSYR2K( 'U', 'T', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CSYR2K( 'L', 'N', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL CSYR2K( 'L', 'T', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CSYR2K( 'U', 'N', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CSYR2K( 'U', 'T', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CSYR2K( 'L', 'N', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL CSYR2K( 'L', 'T', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CSYR2K( 'U', 'N', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CSYR2K( 'U', 'T', 0, 2, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CSYR2K( 'L', 'N', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL CSYR2K( 'L', 'T', 0, 2, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL CSYR2K( 'U', 'N', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL CSYR2K( 'U', 'T', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL CSYR2K( 'L', 'N', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL CSYR2K( 'L', 'T', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+*+ 100 IF( OK )THEN+ WRITE( NOUT, FMT = 9999 )SRNAMT+ ELSE+ WRITE( NOUT, FMT = 9998 )SRNAMT+ END IF+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE TESTS OF ERROR-EXITS' )+ 9998 FORMAT( ' ******* ', A6, ' FAILED THE TESTS OF ERROR-EXITS *****',+ $ '**' )+*+* End of CCHKE.+*+ END+ SUBROUTINE CMAKE( TYPE, UPLO, DIAG, M, N, A, NMAX, AA, LDA, RESET,+ $ TRANSL )+*+* Generates values for an M by N matrix A.+* Stores the values in the array AA in the data structure required+* by the routine, with unwanted elements set to rogue value.+*+* TYPE is 'GE', 'HE', 'SY' or 'TR'.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ COMPLEX ZERO, ONE+ PARAMETER ( ZERO = ( 0.0, 0.0 ), ONE = ( 1.0, 0.0 ) )+ COMPLEX ROGUE+ PARAMETER ( ROGUE = ( -1.0E10, 1.0E10 ) )+ REAL RZERO+ PARAMETER ( RZERO = 0.0 )+ REAL RROGUE+ PARAMETER ( RROGUE = -1.0E10 )+* .. Scalar Arguments ..+ COMPLEX TRANSL+ INTEGER LDA, M, N, NMAX+ LOGICAL RESET+ CHARACTER*1 DIAG, UPLO+ CHARACTER*2 TYPE+* .. Array Arguments ..+ COMPLEX A( NMAX, * ), AA( * )+* .. Local Scalars ..+ INTEGER I, IBEG, IEND, J, JJ+ LOGICAL GEN, HER, LOWER, SYM, TRI, UNIT, UPPER+* .. External Functions ..+ COMPLEX CBEG+ EXTERNAL CBEG+* .. Intrinsic Functions ..+ INTRINSIC CMPLX, CONJG, REAL+* .. Executable Statements ..+ GEN = TYPE.EQ.'GE'+ HER = TYPE.EQ.'HE'+ SYM = TYPE.EQ.'SY'+ TRI = TYPE.EQ.'TR'+ UPPER = ( HER.OR.SYM.OR.TRI ).AND.UPLO.EQ.'U'+ LOWER = ( HER.OR.SYM.OR.TRI ).AND.UPLO.EQ.'L'+ UNIT = TRI.AND.DIAG.EQ.'U'+*+* Generate data in array A.+*+ DO 20 J = 1, N+ DO 10 I = 1, M+ IF( GEN.OR.( UPPER.AND.I.LE.J ).OR.( LOWER.AND.I.GE.J ) )+ $ THEN+ A( I, J ) = CBEG( RESET ) + TRANSL+ IF( I.NE.J )THEN+* Set some elements to zero+ IF( N.GT.3.AND.J.EQ.N/2 )+ $ A( I, J ) = ZERO+ IF( HER )THEN+ A( J, I ) = CONJG( A( I, J ) )+ ELSE IF( SYM )THEN+ A( J, I ) = A( I, J )+ ELSE IF( TRI )THEN+ A( J, I ) = ZERO+ END IF+ END IF+ END IF+ 10 CONTINUE+ IF( HER )+ $ A( J, J ) = CMPLX( REAL( A( J, J ) ), RZERO )+ IF( TRI )+ $ A( J, J ) = A( J, J ) + ONE+ IF( UNIT )+ $ A( J, J ) = ONE+ 20 CONTINUE+*+* Store elements in array AS in data structure required by routine.+*+ IF( TYPE.EQ.'GE' )THEN+ DO 50 J = 1, N+ DO 30 I = 1, M+ AA( I + ( J - 1 )*LDA ) = A( I, J )+ 30 CONTINUE+ DO 40 I = M + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 40 CONTINUE+ 50 CONTINUE+ ELSE IF( TYPE.EQ.'HE'.OR.TYPE.EQ.'SY'.OR.TYPE.EQ.'TR' )THEN+ DO 90 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IF( UNIT )THEN+ IEND = J - 1+ ELSE+ IEND = J+ END IF+ ELSE+ IF( UNIT )THEN+ IBEG = J + 1+ ELSE+ IBEG = J+ END IF+ IEND = N+ END IF+ DO 60 I = 1, IBEG - 1+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 60 CONTINUE+ DO 70 I = IBEG, IEND+ AA( I + ( J - 1 )*LDA ) = A( I, J )+ 70 CONTINUE+ DO 80 I = IEND + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 80 CONTINUE+ IF( HER )THEN+ JJ = J + ( J - 1 )*LDA+ AA( JJ ) = CMPLX( REAL( AA( JJ ) ), RROGUE )+ END IF+ 90 CONTINUE+ END IF+ RETURN+*+* End of CMAKE.+*+ END+ SUBROUTINE CMMCH( TRANSA, TRANSB, M, N, KK, ALPHA, A, LDA, B, LDB,+ $ BETA, C, LDC, CT, G, CC, LDCC, EPS, ERR, FATAL,+ $ NOUT, MV )+*+* Checks the results of the computational tests.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ COMPLEX ZERO+ PARAMETER ( ZERO = ( 0.0, 0.0 ) )+ REAL RZERO, RONE+ PARAMETER ( RZERO = 0.0, RONE = 1.0 )+* .. Scalar Arguments ..+ COMPLEX ALPHA, BETA+ REAL EPS, ERR+ INTEGER KK, LDA, LDB, LDC, LDCC, M, N, NOUT+ LOGICAL FATAL, MV+ CHARACTER*1 TRANSA, TRANSB+* .. Array Arguments ..+ COMPLEX A( LDA, * ), B( LDB, * ), C( LDC, * ),+ $ CC( LDCC, * ), CT( * )+ REAL G( * )+* .. Local Scalars ..+ COMPLEX CL+ REAL ERRI+ INTEGER I, J, K+ LOGICAL CTRANA, CTRANB, TRANA, TRANB+* .. Intrinsic Functions ..+ INTRINSIC ABS, AIMAG, CONJG, MAX, REAL, SQRT+* .. Statement Functions ..+ REAL ABS1+* .. Statement Function definitions ..+ ABS1( CL ) = ABS( REAL( CL ) ) + ABS( AIMAG( CL ) )+* .. Executable Statements ..+ TRANA = TRANSA.EQ.'T'.OR.TRANSA.EQ.'C'+ TRANB = TRANSB.EQ.'T'.OR.TRANSB.EQ.'C'+ CTRANA = TRANSA.EQ.'C'+ CTRANB = TRANSB.EQ.'C'+*+* Compute expected result, one column at a time, in CT using data+* in A, B and C.+* Compute gauges in G.+*+ DO 220 J = 1, N+*+ DO 10 I = 1, M+ CT( I ) = ZERO+ G( I ) = RZERO+ 10 CONTINUE+ IF( .NOT.TRANA.AND..NOT.TRANB )THEN+ DO 30 K = 1, KK+ DO 20 I = 1, M+ CT( I ) = CT( I ) + A( I, K )*B( K, J )+ G( I ) = G( I ) + ABS1( A( I, K ) )*ABS1( B( K, J ) )+ 20 CONTINUE+ 30 CONTINUE+ ELSE IF( TRANA.AND..NOT.TRANB )THEN+ IF( CTRANA )THEN+ DO 50 K = 1, KK+ DO 40 I = 1, M+ CT( I ) = CT( I ) + CONJG( A( K, I ) )*B( K, J )+ G( I ) = G( I ) + ABS1( A( K, I ) )*+ $ ABS1( B( K, J ) )+ 40 CONTINUE+ 50 CONTINUE+ ELSE+ DO 70 K = 1, KK+ DO 60 I = 1, M+ CT( I ) = CT( I ) + A( K, I )*B( K, J )+ G( I ) = G( I ) + ABS1( A( K, I ) )*+ $ ABS1( B( K, J ) )+ 60 CONTINUE+ 70 CONTINUE+ END IF+ ELSE IF( .NOT.TRANA.AND.TRANB )THEN+ IF( CTRANB )THEN+ DO 90 K = 1, KK+ DO 80 I = 1, M+ CT( I ) = CT( I ) + A( I, K )*CONJG( B( J, K ) )+ G( I ) = G( I ) + ABS1( A( I, K ) )*+ $ ABS1( B( J, K ) )+ 80 CONTINUE+ 90 CONTINUE+ ELSE+ DO 110 K = 1, KK+ DO 100 I = 1, M+ CT( I ) = CT( I ) + A( I, K )*B( J, K )+ G( I ) = G( I ) + ABS1( A( I, K ) )*+ $ ABS1( B( J, K ) )+ 100 CONTINUE+ 110 CONTINUE+ END IF+ ELSE IF( TRANA.AND.TRANB )THEN+ IF( CTRANA )THEN+ IF( CTRANB )THEN+ DO 130 K = 1, KK+ DO 120 I = 1, M+ CT( I ) = CT( I ) + CONJG( A( K, I ) )*+ $ CONJG( B( J, K ) )+ G( I ) = G( I ) + ABS1( A( K, I ) )*+ $ ABS1( B( J, K ) )+ 120 CONTINUE+ 130 CONTINUE+ ELSE+ DO 150 K = 1, KK+ DO 140 I = 1, M+ CT( I ) = CT( I ) + CONJG( A( K, I ) )*B( J, K )+ G( I ) = G( I ) + ABS1( A( K, I ) )*+ $ ABS1( B( J, K ) )+ 140 CONTINUE+ 150 CONTINUE+ END IF+ ELSE+ IF( CTRANB )THEN+ DO 170 K = 1, KK+ DO 160 I = 1, M+ CT( I ) = CT( I ) + A( K, I )*CONJG( B( J, K ) )+ G( I ) = G( I ) + ABS1( A( K, I ) )*+ $ ABS1( B( J, K ) )+ 160 CONTINUE+ 170 CONTINUE+ ELSE+ DO 190 K = 1, KK+ DO 180 I = 1, M+ CT( I ) = CT( I ) + A( K, I )*B( J, K )+ G( I ) = G( I ) + ABS1( A( K, I ) )*+ $ ABS1( B( J, K ) )+ 180 CONTINUE+ 190 CONTINUE+ END IF+ END IF+ END IF+ DO 200 I = 1, M+ CT( I ) = ALPHA*CT( I ) + BETA*C( I, J )+ G( I ) = ABS1( ALPHA )*G( I ) ++ $ ABS1( BETA )*ABS1( C( I, J ) )+ 200 CONTINUE+*+* Compute the error ratio for this result.+*+ ERR = ZERO+ DO 210 I = 1, M+ ERRI = ABS1( CT( I ) - CC( I, J ) )/EPS+ IF( G( I ).NE.RZERO )+ $ ERRI = ERRI/G( I )+ ERR = MAX( ERR, ERRI )+ IF( ERR*SQRT( EPS ).GE.RONE )+ $ GO TO 230+ 210 CONTINUE+*+ 220 CONTINUE+*+* If the loop completes, all results are at least half accurate.+ GO TO 250+*+* Report fatal error.+*+ 230 FATAL = .TRUE.+ WRITE( NOUT, FMT = 9999 )+ DO 240 I = 1, M+ IF( MV )THEN+ WRITE( NOUT, FMT = 9998 )I, CT( I ), CC( I, J )+ ELSE+ WRITE( NOUT, FMT = 9998 )I, CC( I, J ), CT( I )+ END IF+ 240 CONTINUE+ IF( N.GT.1 )+ $ WRITE( NOUT, FMT = 9997 )J+*+ 250 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ******* FATAL ERROR - COMPUTED RESULT IS LESS THAN HAL',+ $ 'F ACCURATE *******', /' EXPECTED RE',+ $ 'SULT COMPUTED RESULT' )+ 9998 FORMAT( 1X, I7, 2( ' (', G15.6, ',', G15.6, ')' ) )+ 9997 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+*+* End of CMMCH.+*+ END+ LOGICAL FUNCTION LCE( RI, RJ, LR )+*+* Tests if two arrays are identical.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER LR+* .. Array Arguments ..+ COMPLEX RI( * ), RJ( * )+* .. Local Scalars ..+ INTEGER I+* .. Executable Statements ..+ DO 10 I = 1, LR+ IF( RI( I ).NE.RJ( I ) )+ $ GO TO 20+ 10 CONTINUE+ LCE = .TRUE.+ GO TO 30+ 20 CONTINUE+ LCE = .FALSE.+ 30 RETURN+*+* End of LCE.+*+ END+ LOGICAL FUNCTION LCERES( TYPE, UPLO, M, N, AA, AS, LDA )+*+* Tests if selected elements in two arrays are equal.+*+* TYPE is 'GE' or 'HE' or 'SY'.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER LDA, M, N+ CHARACTER*1 UPLO+ CHARACTER*2 TYPE+* .. Array Arguments ..+ COMPLEX AA( LDA, * ), AS( LDA, * )+* .. Local Scalars ..+ INTEGER I, IBEG, IEND, J+ LOGICAL UPPER+* .. Executable Statements ..+ UPPER = UPLO.EQ.'U'+ IF( TYPE.EQ.'GE' )THEN+ DO 20 J = 1, N+ DO 10 I = M + 1, LDA+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 10 CONTINUE+ 20 CONTINUE+ ELSE IF( TYPE.EQ.'HE'.OR.TYPE.EQ.'SY' )THEN+ DO 50 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IEND = J+ ELSE+ IBEG = J+ IEND = N+ END IF+ DO 30 I = 1, IBEG - 1+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 30 CONTINUE+ DO 40 I = IEND + 1, LDA+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 40 CONTINUE+ 50 CONTINUE+ END IF+*+ 60 CONTINUE+ LCERES = .TRUE.+ GO TO 80+ 70 CONTINUE+ LCERES = .FALSE.+ 80 RETURN+*+* End of LCERES.+*+ END+ COMPLEX FUNCTION CBEG( RESET )+*+* Generates complex numbers as pairs of random numbers uniformly+* distributed between -0.5 and 0.5.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ LOGICAL RESET+* .. Local Scalars ..+ INTEGER I, IC, J, MI, MJ+* .. Save statement ..+ SAVE I, IC, J, MI, MJ+* .. Intrinsic Functions ..+ INTRINSIC CMPLX+* .. Executable Statements ..+ IF( RESET )THEN+* Initialize local variables.+ MI = 891+ MJ = 457+ I = 7+ J = 7+ IC = 0+ RESET = .FALSE.+ END IF+*+* The sequence of values of I or J is bounded between 1 and 999.+* If initial I or J = 1,2,3,6,7 or 9, the period will be 50.+* If initial I or J = 4 or 8, the period will be 25.+* If initial I or J = 5, the period will be 10.+* IC is used to break up the period by skipping 1 value of I or J+* in 6.+*+ IC = IC + 1+ 10 I = I*MI+ J = J*MJ+ I = I - 1000*( I/1000 )+ J = J - 1000*( J/1000 )+ IF( IC.GE.5 )THEN+ IC = 0+ GO TO 10+ END IF+ CBEG = CMPLX( ( I - 500 )/1001.0, ( J - 500 )/1001.0 )+ RETURN+*+* End of CBEG.+*+ END+ REAL FUNCTION SDIFF( X, Y )+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ REAL X, Y+* .. Executable Statements ..+ SDIFF = X - Y+ RETURN+*+* End of SDIFF.+*+ END+ SUBROUTINE CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+*+* Tests whether XERBLA has detected an error when it should.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER INFOT, NOUT+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Executable Statements ..+ IF( .NOT.LERR )THEN+ WRITE( NOUT, FMT = 9999 )INFOT, SRNAMT+ OK = .FALSE.+ END IF+ LERR = .FALSE.+ RETURN+*+ 9999 FORMAT( ' ***** ILLEGAL VALUE OF PARAMETER NUMBER ', I2, ' NOT D',+ $ 'ETECTED BY ', A6, ' *****' )+*+* End of CHKXER.+*+ END+ SUBROUTINE XERBLA( SRNAME, INFO )+*+* This is a special version of XERBLA to be used only as part of+* the test program for testing error exits from the Level 3 BLAS+* routines.+*+* XERBLA is an error handler for the Level 3 BLAS routines.+*+* It is called by the Level 3 BLAS routines if an input parameter is+* invalid.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER INFO+ CHARACTER*6 SRNAME+* .. Scalars in Common ..+ INTEGER INFOT, NOUT+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUT, OK, LERR+ COMMON /SRNAMC/SRNAMT+* .. Executable Statements ..+ LERR = .TRUE.+ IF( INFO.NE.INFOT )THEN+ IF( INFOT.NE.0 )THEN+ WRITE( NOUT, FMT = 9999 )INFO, INFOT+ ELSE+ WRITE( NOUT, FMT = 9997 )INFO+ END IF+ OK = .FALSE.+ END IF+ IF( SRNAME.NE.SRNAMT )THEN+ WRITE( NOUT, FMT = 9998 )SRNAME, SRNAMT+ OK = .FALSE.+ END IF+ RETURN+*+ 9999 FORMAT( ' ******* XERBLA WAS CALLED WITH INFO = ', I6, ' INSTEAD',+ $ ' OF ', I2, ' *******' )+ 9998 FORMAT( ' ******* XERBLA WAS CALLED WITH SRNAME = ', A6, ' INSTE',+ $ 'AD OF ', A6, ' *******' )+ 9997 FORMAT( ' ******* XERBLA WAS CALLED WITH INFO = ', I6,+ $ ' *******' )+*+* End of XERBLA+*+ END+
+ eigen3/blas/testing/dblat1.f view
@@ -0,0 +1,1065 @@+*> \brief \b DBLAT1+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+* Definition:+* ===========+*+* PROGRAM DBLAT1+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> Test program for the DOUBLE PRECISION Level 1 BLAS.+*>+*> Based upon the original BLAS test routine together with:+*> F06EAF Example Program Text+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date April 2012+*+*> \ingroup double_blas_testing+*+* =====================================================================+ PROGRAM DBLAT1+*+* -- Reference BLAS test routine (version 3.4.1) --+* -- Reference BLAS is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* April 2012+*+* =====================================================================+*+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, N+ LOGICAL PASS+* .. Local Scalars ..+ DOUBLE PRECISION SFAC+ INTEGER IC+* .. External Subroutines ..+ EXTERNAL CHECK0, CHECK1, CHECK2, CHECK3, HEADER+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, PASS+* .. Data statements ..+ DATA SFAC/9.765625D-4/+* .. Executable Statements ..+ WRITE (NOUT,99999)+ DO 20 IC = 1, 13+ ICASE = IC+ CALL HEADER+*+* .. Initialize PASS, INCX, and INCY for a new case. ..+* .. the value 9999 for INCX or INCY will appear in the ..+* .. detailed output, if any, for cases that do not involve ..+* .. these parameters ..+*+ PASS = .TRUE.+ INCX = 9999+ INCY = 9999+ IF (ICASE.EQ.3 .OR. ICASE.EQ.11) THEN+ CALL CHECK0(SFAC)+ ELSE IF (ICASE.EQ.7 .OR. ICASE.EQ.8 .OR. ICASE.EQ.9 .OR.+ + ICASE.EQ.10) THEN+ CALL CHECK1(SFAC)+ ELSE IF (ICASE.EQ.1 .OR. ICASE.EQ.2 .OR. ICASE.EQ.5 .OR.+ + ICASE.EQ.6 .OR. ICASE.EQ.12 .OR. ICASE.EQ.13) THEN+ CALL CHECK2(SFAC)+ ELSE IF (ICASE.EQ.4) THEN+ CALL CHECK3(SFAC)+ END IF+* -- Print+ IF (PASS) WRITE (NOUT,99998)+ 20 CONTINUE+ STOP+*+99999 FORMAT (' Real BLAS Test Program Results',/1X)+99998 FORMAT (' ----- PASS -----')+ END+ SUBROUTINE HEADER+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, N+ LOGICAL PASS+* .. Local Arrays ..+ CHARACTER*6 L(13)+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, PASS+* .. Data statements ..+ DATA L(1)/' DDOT '/+ DATA L(2)/'DAXPY '/+ DATA L(3)/'DROTG '/+ DATA L(4)/' DROT '/+ DATA L(5)/'DCOPY '/+ DATA L(6)/'DSWAP '/+ DATA L(7)/'DNRM2 '/+ DATA L(8)/'DASUM '/+ DATA L(9)/'DSCAL '/+ DATA L(10)/'IDAMAX'/+ DATA L(11)/'DROTMG'/+ DATA L(12)/'DROTM '/+ DATA L(13)/'DSDOT '/+* .. Executable Statements ..+ WRITE (NOUT,99999) ICASE, L(ICASE)+ RETURN+*+99999 FORMAT (/' Test of subprogram number',I3,12X,A6)+ END+ SUBROUTINE CHECK0(SFAC)+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ DOUBLE PRECISION SFAC+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, N+ LOGICAL PASS+* .. Local Scalars ..+ DOUBLE PRECISION SA, SB, SC, SS, D12+ INTEGER I, K+* .. Local Arrays ..+ DOUBLE PRECISION DA1(8), DATRUE(8), DB1(8), DBTRUE(8), DC1(8),+ $ DS1(8), DAB(4,9), DTEMP(9), DTRUE(9,9)+* .. External Subroutines ..+ EXTERNAL DROTG, DROTMG, STEST1+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, PASS+* .. Data statements ..+ DATA DA1/0.3D0, 0.4D0, -0.3D0, -0.4D0, -0.3D0, 0.0D0,+ + 0.0D0, 1.0D0/+ DATA DB1/0.4D0, 0.3D0, 0.4D0, 0.3D0, -0.4D0, 0.0D0,+ + 1.0D0, 0.0D0/+ DATA DC1/0.6D0, 0.8D0, -0.6D0, 0.8D0, 0.6D0, 1.0D0,+ + 0.0D0, 1.0D0/+ DATA DS1/0.8D0, 0.6D0, 0.8D0, -0.6D0, 0.8D0, 0.0D0,+ + 1.0D0, 0.0D0/+ DATA DATRUE/0.5D0, 0.5D0, 0.5D0, -0.5D0, -0.5D0,+ + 0.0D0, 1.0D0, 1.0D0/+ DATA DBTRUE/0.0D0, 0.6D0, 0.0D0, -0.6D0, 0.0D0,+ + 0.0D0, 1.0D0, 0.0D0/+* INPUT FOR MODIFIED GIVENS+ DATA DAB/ .1D0,.3D0,1.2D0,.2D0,+ A .7D0, .2D0, .6D0, 4.2D0,+ B 0.D0,0.D0,0.D0,0.D0,+ C 4.D0, -1.D0, 2.D0, 4.D0,+ D 6.D-10, 2.D-2, 1.D5, 10.D0,+ E 4.D10, 2.D-2, 1.D-5, 10.D0,+ F 2.D-10, 4.D-2, 1.D5, 10.D0,+ G 2.D10, 4.D-2, 1.D-5, 10.D0,+ H 4.D0, -2.D0, 8.D0, 4.D0 /+* TRUE RESULTS FOR MODIFIED GIVENS+ DATA DTRUE/0.D0,0.D0, 1.3D0, .2D0, 0.D0,0.D0,0.D0, .5D0, 0.D0,+ A 0.D0,0.D0, 4.5D0, 4.2D0, 1.D0, .5D0, 0.D0,0.D0,0.D0,+ B 0.D0,0.D0,0.D0,0.D0, -2.D0, 0.D0,0.D0,0.D0,0.D0,+ C 0.D0,0.D0,0.D0, 4.D0, -1.D0, 0.D0,0.D0,0.D0,0.D0,+ D 0.D0, 15.D-3, 0.D0, 10.D0, -1.D0, 0.D0, -1.D-4,+ E 0.D0, 1.D0,+ F 0.D0,0.D0, 6144.D-5, 10.D0, -1.D0, 4096.D0, -1.D6,+ G 0.D0, 1.D0,+ H 0.D0,0.D0,15.D0,10.D0,-1.D0, 5.D-5, 0.D0,1.D0,0.D0,+ I 0.D0,0.D0, 15.D0, 10.D0, -1. D0, 5.D5, -4096.D0,+ J 1.D0, 4096.D-6,+ K 0.D0,0.D0, 7.D0, 4.D0, 0.D0,0.D0, -.5D0, -.25D0, 0.D0/+* 4096 = 2 ** 12+ DATA D12 /4096.D0/+ DTRUE(1,1) = 12.D0 / 130.D0+ DTRUE(2,1) = 36.D0 / 130.D0+ DTRUE(7,1) = -1.D0 / 6.D0+ DTRUE(1,2) = 14.D0 / 75.D0+ DTRUE(2,2) = 49.D0 / 75.D0+ DTRUE(9,2) = 1.D0 / 7.D0+ DTRUE(1,5) = 45.D-11 * (D12 * D12)+ DTRUE(3,5) = 4.D5 / (3.D0 * D12)+ DTRUE(6,5) = 1.D0 / D12+ DTRUE(8,5) = 1.D4 / (3.D0 * D12)+ DTRUE(1,6) = 4.D10 / (1.5D0 * D12 * D12)+ DTRUE(2,6) = 2.D-2 / 1.5D0+ DTRUE(8,6) = 5.D-7 * D12+ DTRUE(1,7) = 4.D0 / 150.D0+ DTRUE(2,7) = (2.D-10 / 1.5D0) * (D12 * D12)+ DTRUE(7,7) = -DTRUE(6,5)+ DTRUE(9,7) = 1.D4 / D12+ DTRUE(1,8) = DTRUE(1,7)+ DTRUE(2,8) = 2.D10 / (1.5D0 * D12 * D12)+ DTRUE(1,9) = 32.D0 / 7.D0+ DTRUE(2,9) = -16.D0 / 7.D0+* .. Executable Statements ..+*+* Compute true values which cannot be prestored+* in decimal notation+*+ DBTRUE(1) = 1.0D0/0.6D0+ DBTRUE(3) = -1.0D0/0.6D0+ DBTRUE(5) = 1.0D0/0.6D0+*+ DO 20 K = 1, 8+* .. Set N=K for identification in output if any ..+ N = K+ IF (ICASE.EQ.3) THEN+* .. DROTG ..+ IF (K.GT.8) GO TO 40+ SA = DA1(K)+ SB = DB1(K)+ CALL DROTG(SA,SB,SC,SS)+ CALL STEST1(SA,DATRUE(K),DATRUE(K),SFAC)+ CALL STEST1(SB,DBTRUE(K),DBTRUE(K),SFAC)+ CALL STEST1(SC,DC1(K),DC1(K),SFAC)+ CALL STEST1(SS,DS1(K),DS1(K),SFAC)+ ELSEIF (ICASE.EQ.11) THEN+* .. DROTMG ..+ DO I=1,4+ DTEMP(I)= DAB(I,K)+ DTEMP(I+4) = 0.0+ END DO+ DTEMP(9) = 0.0+ CALL DROTMG(DTEMP(1),DTEMP(2),DTEMP(3),DTEMP(4),DTEMP(5))+ CALL STEST(9,DTEMP,DTRUE(1,K),DTRUE(1,K),SFAC)+ ELSE+ WRITE (NOUT,*) ' Shouldn''t be here in CHECK0'+ STOP+ END IF+ 20 CONTINUE+ 40 RETURN+ END+ SUBROUTINE CHECK1(SFAC)+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ DOUBLE PRECISION SFAC+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, N+ LOGICAL PASS+* .. Local Scalars ..+ INTEGER I, LEN, NP1+* .. Local Arrays ..+ DOUBLE PRECISION DTRUE1(5), DTRUE3(5), DTRUE5(8,5,2), DV(8,5,2),+ + SA(10), STEMP(1), STRUE(8), SX(8)+ INTEGER ITRUE2(5)+* .. External Functions ..+ DOUBLE PRECISION DASUM, DNRM2+ INTEGER IDAMAX+ EXTERNAL DASUM, DNRM2, IDAMAX+* .. External Subroutines ..+ EXTERNAL ITEST1, DSCAL, STEST, STEST1+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, PASS+* .. Data statements ..+ DATA SA/0.3D0, -1.0D0, 0.0D0, 1.0D0, 0.3D0, 0.3D0,+ + 0.3D0, 0.3D0, 0.3D0, 0.3D0/+ DATA DV/0.1D0, 2.0D0, 2.0D0, 2.0D0, 2.0D0, 2.0D0,+ + 2.0D0, 2.0D0, 0.3D0, 3.0D0, 3.0D0, 3.0D0, 3.0D0,+ + 3.0D0, 3.0D0, 3.0D0, 0.3D0, -0.4D0, 4.0D0,+ + 4.0D0, 4.0D0, 4.0D0, 4.0D0, 4.0D0, 0.2D0,+ + -0.6D0, 0.3D0, 5.0D0, 5.0D0, 5.0D0, 5.0D0,+ + 5.0D0, 0.1D0, -0.3D0, 0.5D0, -0.1D0, 6.0D0,+ + 6.0D0, 6.0D0, 6.0D0, 0.1D0, 8.0D0, 8.0D0, 8.0D0,+ + 8.0D0, 8.0D0, 8.0D0, 8.0D0, 0.3D0, 9.0D0, 9.0D0,+ + 9.0D0, 9.0D0, 9.0D0, 9.0D0, 9.0D0, 0.3D0, 2.0D0,+ + -0.4D0, 2.0D0, 2.0D0, 2.0D0, 2.0D0, 2.0D0,+ + 0.2D0, 3.0D0, -0.6D0, 5.0D0, 0.3D0, 2.0D0,+ + 2.0D0, 2.0D0, 0.1D0, 4.0D0, -0.3D0, 6.0D0,+ + -0.5D0, 7.0D0, -0.1D0, 3.0D0/+ DATA DTRUE1/0.0D0, 0.3D0, 0.5D0, 0.7D0, 0.6D0/+ DATA DTRUE3/0.0D0, 0.3D0, 0.7D0, 1.1D0, 1.0D0/+ DATA DTRUE5/0.10D0, 2.0D0, 2.0D0, 2.0D0, 2.0D0,+ + 2.0D0, 2.0D0, 2.0D0, -0.3D0, 3.0D0, 3.0D0,+ + 3.0D0, 3.0D0, 3.0D0, 3.0D0, 3.0D0, 0.0D0, 0.0D0,+ + 4.0D0, 4.0D0, 4.0D0, 4.0D0, 4.0D0, 4.0D0,+ + 0.20D0, -0.60D0, 0.30D0, 5.0D0, 5.0D0, 5.0D0,+ + 5.0D0, 5.0D0, 0.03D0, -0.09D0, 0.15D0, -0.03D0,+ + 6.0D0, 6.0D0, 6.0D0, 6.0D0, 0.10D0, 8.0D0,+ + 8.0D0, 8.0D0, 8.0D0, 8.0D0, 8.0D0, 8.0D0,+ + 0.09D0, 9.0D0, 9.0D0, 9.0D0, 9.0D0, 9.0D0,+ + 9.0D0, 9.0D0, 0.09D0, 2.0D0, -0.12D0, 2.0D0,+ + 2.0D0, 2.0D0, 2.0D0, 2.0D0, 0.06D0, 3.0D0,+ + -0.18D0, 5.0D0, 0.09D0, 2.0D0, 2.0D0, 2.0D0,+ + 0.03D0, 4.0D0, -0.09D0, 6.0D0, -0.15D0, 7.0D0,+ + -0.03D0, 3.0D0/+ DATA ITRUE2/0, 1, 2, 2, 3/+* .. Executable Statements ..+ DO 80 INCX = 1, 2+ DO 60 NP1 = 1, 5+ N = NP1 - 1+ LEN = 2*MAX(N,1)+* .. Set vector arguments ..+ DO 20 I = 1, LEN+ SX(I) = DV(I,NP1,INCX)+ 20 CONTINUE+*+ IF (ICASE.EQ.7) THEN+* .. DNRM2 ..+ STEMP(1) = DTRUE1(NP1)+ CALL STEST1(DNRM2(N,SX,INCX),STEMP(1),STEMP,SFAC)+ ELSE IF (ICASE.EQ.8) THEN+* .. DASUM ..+ STEMP(1) = DTRUE3(NP1)+ CALL STEST1(DASUM(N,SX,INCX),STEMP(1),STEMP,SFAC)+ ELSE IF (ICASE.EQ.9) THEN+* .. DSCAL ..+ CALL DSCAL(N,SA((INCX-1)*5+NP1),SX,INCX)+ DO 40 I = 1, LEN+ STRUE(I) = DTRUE5(I,NP1,INCX)+ 40 CONTINUE+ CALL STEST(LEN,SX,STRUE,STRUE,SFAC)+ ELSE IF (ICASE.EQ.10) THEN+* .. IDAMAX ..+ CALL ITEST1(IDAMAX(N,SX,INCX),ITRUE2(NP1))+ ELSE+ WRITE (NOUT,*) ' Shouldn''t be here in CHECK1'+ STOP+ END IF+ 60 CONTINUE+ 80 CONTINUE+ RETURN+ END+ SUBROUTINE CHECK2(SFAC)+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ DOUBLE PRECISION SFAC+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, N+ LOGICAL PASS+* .. Local Scalars ..+ DOUBLE PRECISION SA+ INTEGER I, J, KI, KN, KNI, KPAR, KSIZE, LENX, LENY,+ $ MX, MY +* .. Local Arrays ..+ DOUBLE PRECISION DT10X(7,4,4), DT10Y(7,4,4), DT7(4,4),+ $ DT8(7,4,4), DX1(7),+ $ DY1(7), SSIZE1(4), SSIZE2(14,2), SSIZE(7),+ $ STX(7), STY(7), SX(7), SY(7),+ $ DPAR(5,4), DT19X(7,4,16),DT19XA(7,4,4),+ $ DT19XB(7,4,4), DT19XC(7,4,4),DT19XD(7,4,4),+ $ DT19Y(7,4,16), DT19YA(7,4,4),DT19YB(7,4,4),+ $ DT19YC(7,4,4), DT19YD(7,4,4), DTEMP(5)+ INTEGER INCXS(4), INCYS(4), LENS(4,2), NS(4)+* .. External Functions ..+ DOUBLE PRECISION DDOT, DSDOT+ EXTERNAL DDOT, DSDOT+* .. External Subroutines ..+ EXTERNAL DAXPY, DCOPY, DROTM, DSWAP, STEST, STEST1+* .. Intrinsic Functions ..+ INTRINSIC ABS, MIN+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, PASS+* .. Data statements ..+ EQUIVALENCE (DT19X(1,1,1),DT19XA(1,1,1)),(DT19X(1,1,5),+ A DT19XB(1,1,1)),(DT19X(1,1,9),DT19XC(1,1,1)),+ B (DT19X(1,1,13),DT19XD(1,1,1))+ EQUIVALENCE (DT19Y(1,1,1),DT19YA(1,1,1)),(DT19Y(1,1,5),+ A DT19YB(1,1,1)),(DT19Y(1,1,9),DT19YC(1,1,1)),+ B (DT19Y(1,1,13),DT19YD(1,1,1))++ DATA SA/0.3D0/+ DATA INCXS/1, 2, -2, -1/+ DATA INCYS/1, -2, 1, -2/+ DATA LENS/1, 1, 2, 4, 1, 1, 3, 7/+ DATA NS/0, 1, 2, 4/+ DATA DX1/0.6D0, 0.1D0, -0.5D0, 0.8D0, 0.9D0, -0.3D0,+ + -0.4D0/+ DATA DY1/0.5D0, -0.9D0, 0.3D0, 0.7D0, -0.6D0, 0.2D0,+ + 0.8D0/+ DATA DT7/0.0D0, 0.30D0, 0.21D0, 0.62D0, 0.0D0,+ + 0.30D0, -0.07D0, 0.85D0, 0.0D0, 0.30D0, -0.79D0,+ + -0.74D0, 0.0D0, 0.30D0, 0.33D0, 1.27D0/+ DATA DT8/0.5D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.68D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.68D0, -0.87D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.68D0, -0.87D0, 0.15D0,+ + 0.94D0, 0.0D0, 0.0D0, 0.0D0, 0.5D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.68D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.35D0, -0.9D0, 0.48D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.38D0, -0.9D0, 0.57D0, 0.7D0, -0.75D0,+ + 0.2D0, 0.98D0, 0.5D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.68D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.35D0, -0.72D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.38D0,+ + -0.63D0, 0.15D0, 0.88D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.5D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.68D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.68D0, -0.9D0, 0.33D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.68D0, -0.9D0, 0.33D0, 0.7D0,+ + -0.75D0, 0.2D0, 1.04D0/+ DATA DT10X/0.6D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.5D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.5D0, -0.9D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.5D0, -0.9D0, 0.3D0, 0.7D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.6D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.5D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.3D0, 0.1D0, 0.5D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.8D0, 0.1D0, -0.6D0,+ + 0.8D0, 0.3D0, -0.3D0, 0.5D0, 0.6D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.5D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, -0.9D0,+ + 0.1D0, 0.5D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.7D0,+ + 0.1D0, 0.3D0, 0.8D0, -0.9D0, -0.3D0, 0.5D0,+ + 0.6D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.5D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.5D0, 0.3D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.5D0, 0.3D0, -0.6D0, 0.8D0, 0.0D0, 0.0D0,+ + 0.0D0/+ DATA DT10Y/0.5D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.6D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.6D0, 0.1D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.6D0, 0.1D0, -0.5D0, 0.8D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.5D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.6D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, -0.5D0, -0.9D0, 0.6D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, -0.4D0, -0.9D0, 0.9D0,+ + 0.7D0, -0.5D0, 0.2D0, 0.6D0, 0.5D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.6D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, -0.5D0,+ + 0.6D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + -0.4D0, 0.9D0, -0.5D0, 0.6D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.5D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.6D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.6D0, -0.9D0, 0.1D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.6D0, -0.9D0, 0.1D0, 0.7D0,+ + -0.5D0, 0.2D0, 0.8D0/+ DATA SSIZE1/0.0D0, 0.3D0, 1.6D0, 3.2D0/+ DATA SSIZE2/0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 1.17D0, 1.17D0, 1.17D0, 1.17D0, 1.17D0,+ + 1.17D0, 1.17D0, 1.17D0, 1.17D0, 1.17D0, 1.17D0,+ + 1.17D0, 1.17D0, 1.17D0/+*+* FOR DROTM+*+ DATA DPAR/-2.D0, 0.D0,0.D0,0.D0,0.D0,+ A -1.D0, 2.D0, -3.D0, -4.D0, 5.D0,+ B 0.D0, 0.D0, 2.D0, -3.D0, 0.D0,+ C 1.D0, 5.D0, 2.D0, 0.D0, -4.D0/+* TRUE X RESULTS F0R ROTATIONS DROTM+ DATA DT19XA/.6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ A .6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ B .6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ C .6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ D .6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ E -.8D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ F -.9D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ G 3.5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ H .6D0, .1D0, 0.D0,0.D0,0.D0,0.D0,0.D0,+ I -.8D0, 3.8D0, 0.D0,0.D0,0.D0,0.D0,0.D0,+ J -.9D0, 2.8D0, 0.D0,0.D0,0.D0,0.D0,0.D0,+ K 3.5D0, -.4D0, 0.D0,0.D0,0.D0,0.D0,0.D0,+ L .6D0, .1D0, -.5D0, .8D0, 0.D0,0.D0,0.D0,+ M -.8D0, 3.8D0, -2.2D0, -1.2D0, 0.D0,0.D0,0.D0,+ N -.9D0, 2.8D0, -1.4D0, -1.3D0, 0.D0,0.D0,0.D0,+ O 3.5D0, -.4D0, -2.2D0, 4.7D0, 0.D0,0.D0,0.D0/+*+ DATA DT19XB/.6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ A .6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ B .6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ C .6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ D .6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ E -.8D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ F -.9D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ G 3.5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ H .6D0, .1D0, -.5D0, 0.D0,0.D0,0.D0,0.D0,+ I 0.D0, .1D0, -3.0D0, 0.D0,0.D0,0.D0,0.D0,+ J -.3D0, .1D0, -2.0D0, 0.D0,0.D0,0.D0,0.D0,+ K 3.3D0, .1D0, -2.0D0, 0.D0,0.D0,0.D0,0.D0,+ L .6D0, .1D0, -.5D0, .8D0, .9D0, -.3D0, -.4D0,+ M -2.0D0, .1D0, 1.4D0, .8D0, .6D0, -.3D0, -2.8D0,+ N -1.8D0, .1D0, 1.3D0, .8D0, 0.D0, -.3D0, -1.9D0,+ O 3.8D0, .1D0, -3.1D0, .8D0, 4.8D0, -.3D0, -1.5D0 /+*+ DATA DT19XC/.6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ A .6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ B .6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ C .6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ D .6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ E -.8D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ F -.9D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ G 3.5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ H .6D0, .1D0, -.5D0, 0.D0,0.D0,0.D0,0.D0,+ I 4.8D0, .1D0, -3.0D0, 0.D0,0.D0,0.D0,0.D0,+ J 3.3D0, .1D0, -2.0D0, 0.D0,0.D0,0.D0,0.D0,+ K 2.1D0, .1D0, -2.0D0, 0.D0,0.D0,0.D0,0.D0,+ L .6D0, .1D0, -.5D0, .8D0, .9D0, -.3D0, -.4D0,+ M -1.6D0, .1D0, -2.2D0, .8D0, 5.4D0, -.3D0, -2.8D0,+ N -1.5D0, .1D0, -1.4D0, .8D0, 3.6D0, -.3D0, -1.9D0,+ O 3.7D0, .1D0, -2.2D0, .8D0, 3.6D0, -.3D0, -1.5D0 /+*+ DATA DT19XD/.6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ A .6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ B .6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ C .6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ D .6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ E -.8D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ F -.9D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ G 3.5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ H .6D0, .1D0, 0.D0,0.D0,0.D0,0.D0,0.D0,+ I -.8D0, -1.0D0, 0.D0,0.D0,0.D0,0.D0,0.D0,+ J -.9D0, -.8D0, 0.D0,0.D0,0.D0,0.D0,0.D0,+ K 3.5D0, .8D0, 0.D0,0.D0,0.D0,0.D0,0.D0,+ L .6D0, .1D0, -.5D0, .8D0, 0.D0,0.D0,0.D0,+ M -.8D0, -1.0D0, 1.4D0, -1.6D0, 0.D0,0.D0,0.D0,+ N -.9D0, -.8D0, 1.3D0, -1.6D0, 0.D0,0.D0,0.D0,+ O 3.5D0, .8D0, -3.1D0, 4.8D0, 0.D0,0.D0,0.D0/+* TRUE Y RESULTS FOR ROTATIONS DROTM+ DATA DT19YA/.5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ A .5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ B .5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ C .5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ D .5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ E .7D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ F 1.7D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ G -2.6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ H .5D0, -.9D0, 0.D0,0.D0,0.D0,0.D0,0.D0,+ I .7D0, -4.8D0, 0.D0,0.D0,0.D0,0.D0,0.D0,+ J 1.7D0, -.7D0, 0.D0,0.D0,0.D0,0.D0,0.D0,+ K -2.6D0, 3.5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,+ L .5D0, -.9D0, .3D0, .7D0, 0.D0,0.D0,0.D0,+ M .7D0, -4.8D0, 3.0D0, 1.1D0, 0.D0,0.D0,0.D0,+ N 1.7D0, -.7D0, -.7D0, 2.3D0, 0.D0,0.D0,0.D0,+ O -2.6D0, 3.5D0, -.7D0, -3.6D0, 0.D0,0.D0,0.D0/+*+ DATA DT19YB/.5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ A .5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ B .5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ C .5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ D .5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ E .7D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ F 1.7D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ G -2.6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ H .5D0, -.9D0, .3D0, 0.D0,0.D0,0.D0,0.D0,+ I 4.0D0, -.9D0, -.3D0, 0.D0,0.D0,0.D0,0.D0,+ J -.5D0, -.9D0, 1.5D0, 0.D0,0.D0,0.D0,0.D0,+ K -1.5D0, -.9D0, -1.8D0, 0.D0,0.D0,0.D0,0.D0,+ L .5D0, -.9D0, .3D0, .7D0, -.6D0, .2D0, .8D0,+ M 3.7D0, -.9D0, -1.2D0, .7D0, -1.5D0, .2D0, 2.2D0,+ N -.3D0, -.9D0, 2.1D0, .7D0, -1.6D0, .2D0, 2.0D0,+ O -1.6D0, -.9D0, -2.1D0, .7D0, 2.9D0, .2D0, -3.8D0 /+*+ DATA DT19YC/.5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ A .5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ B .5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ C .5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ D .5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ E .7D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ F 1.7D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ G -2.6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ H .5D0, -.9D0, 0.D0,0.D0,0.D0,0.D0,0.D0,+ I 4.0D0, -6.3D0, 0.D0,0.D0,0.D0,0.D0,0.D0,+ J -.5D0, .3D0, 0.D0,0.D0,0.D0,0.D0,0.D0,+ K -1.5D0, 3.0D0, 0.D0,0.D0,0.D0,0.D0,0.D0,+ L .5D0, -.9D0, .3D0, .7D0, 0.D0,0.D0,0.D0,+ M 3.7D0, -7.2D0, 3.0D0, 1.7D0, 0.D0,0.D0,0.D0,+ N -.3D0, .9D0, -.7D0, 1.9D0, 0.D0,0.D0,0.D0,+ O -1.6D0, 2.7D0, -.7D0, -3.4D0, 0.D0,0.D0,0.D0/+*+ DATA DT19YD/.5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ A .5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ B .5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ C .5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ D .5D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ E .7D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ F 1.7D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ G -2.6D0, 0.D0,0.D0,0.D0,0.D0,0.D0,0.D0,+ H .5D0, -.9D0, .3D0, 0.D0,0.D0,0.D0,0.D0,+ I .7D0, -.9D0, 1.2D0, 0.D0,0.D0,0.D0,0.D0,+ J 1.7D0, -.9D0, .5D0, 0.D0,0.D0,0.D0,0.D0,+ K -2.6D0, -.9D0, -1.3D0, 0.D0,0.D0,0.D0,0.D0,+ L .5D0, -.9D0, .3D0, .7D0, -.6D0, .2D0, .8D0,+ M .7D0, -.9D0, 1.2D0, .7D0, -1.5D0, .2D0, 1.6D0,+ N 1.7D0, -.9D0, .5D0, .7D0, -1.6D0, .2D0, 2.4D0,+ O -2.6D0, -.9D0, -1.3D0, .7D0, 2.9D0, .2D0, -4.0D0 /+* +* .. Executable Statements ..+*+ DO 120 KI = 1, 4+ INCX = INCXS(KI)+ INCY = INCYS(KI)+ MX = ABS(INCX)+ MY = ABS(INCY)+*+ DO 100 KN = 1, 4+ N = NS(KN)+ KSIZE = MIN(2,KN)+ LENX = LENS(KN,MX)+ LENY = LENS(KN,MY)+* .. Initialize all argument arrays ..+ DO 20 I = 1, 7+ SX(I) = DX1(I)+ SY(I) = DY1(I)+ 20 CONTINUE+*+ IF (ICASE.EQ.1) THEN+* .. DDOT ..+ CALL STEST1(DDOT(N,SX,INCX,SY,INCY),DT7(KN,KI),SSIZE1(KN)+ + ,SFAC)+ ELSE IF (ICASE.EQ.2) THEN+* .. DAXPY ..+ CALL DAXPY(N,SA,SX,INCX,SY,INCY)+ DO 40 J = 1, LENY+ STY(J) = DT8(J,KN,KI)+ 40 CONTINUE+ CALL STEST(LENY,SY,STY,SSIZE2(1,KSIZE),SFAC)+ ELSE IF (ICASE.EQ.5) THEN+* .. DCOPY ..+ DO 60 I = 1, 7+ STY(I) = DT10Y(I,KN,KI)+ 60 CONTINUE+ CALL DCOPY(N,SX,INCX,SY,INCY)+ CALL STEST(LENY,SY,STY,SSIZE2(1,1),1.0D0)+ ELSE IF (ICASE.EQ.6) THEN+* .. DSWAP ..+ CALL DSWAP(N,SX,INCX,SY,INCY)+ DO 80 I = 1, 7+ STX(I) = DT10X(I,KN,KI)+ STY(I) = DT10Y(I,KN,KI)+ 80 CONTINUE+ CALL STEST(LENX,SX,STX,SSIZE2(1,1),1.0D0)+ CALL STEST(LENY,SY,STY,SSIZE2(1,1),1.0D0)+ ELSE IF (ICASE.EQ.12) THEN+* .. DROTM ..+ KNI=KN+4*(KI-1)+ DO KPAR=1,4+ DO I=1,7+ SX(I) = DX1(I)+ SY(I) = DY1(I)+ STX(I)= DT19X(I,KPAR,KNI)+ STY(I)= DT19Y(I,KPAR,KNI)+ END DO+*+ DO I=1,5+ DTEMP(I) = DPAR(I,KPAR)+ END DO+*+ DO I=1,LENX+ SSIZE(I)=STX(I)+ END DO+* SEE REMARK ABOVE ABOUT DT11X(1,2,7)+* AND DT11X(5,3,8).+ IF ((KPAR .EQ. 2) .AND. (KNI .EQ. 7))+ $ SSIZE(1) = 2.4D0+ IF ((KPAR .EQ. 3) .AND. (KNI .EQ. 8))+ $ SSIZE(5) = 1.8D0+*+ CALL DROTM(N,SX,INCX,SY,INCY,DTEMP)+ CALL STEST(LENX,SX,STX,SSIZE,SFAC)+ CALL STEST(LENY,SY,STY,STY,SFAC)+ END DO+ ELSE IF (ICASE.EQ.13) THEN+* .. DSDOT ..+ CALL TESTDSDOT(REAL(DSDOT(N,REAL(SX),INCX,REAL(SY),INCY)),+ $ REAL(DT7(KN,KI)),REAL(SSIZE1(KN)), .3125E-1)+ ELSE+ WRITE (NOUT,*) ' Shouldn''t be here in CHECK2'+ STOP+ END IF+ 100 CONTINUE+ 120 CONTINUE+ RETURN+ END+ SUBROUTINE CHECK3(SFAC)+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ DOUBLE PRECISION SFAC+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, N+ LOGICAL PASS+* .. Local Scalars ..+ DOUBLE PRECISION SC, SS+ INTEGER I, K, KI, KN, KSIZE, LENX, LENY, MX, MY+* .. Local Arrays ..+ DOUBLE PRECISION COPYX(5), COPYY(5), DT9X(7,4,4), DT9Y(7,4,4),+ + DX1(7), DY1(7), MWPC(11), MWPS(11), MWPSTX(5),+ + MWPSTY(5), MWPTX(11,5), MWPTY(11,5), MWPX(5),+ + MWPY(5), SSIZE2(14,2), STX(7), STY(7), SX(7),+ + SY(7)+ INTEGER INCXS(4), INCYS(4), LENS(4,2), MWPINX(11),+ + MWPINY(11), MWPN(11), NS(4)+* .. External Subroutines ..+ EXTERNAL DROT, STEST+* .. Intrinsic Functions ..+ INTRINSIC ABS, MIN+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, PASS+* .. Data statements ..+ DATA INCXS/1, 2, -2, -1/+ DATA INCYS/1, -2, 1, -2/+ DATA LENS/1, 1, 2, 4, 1, 1, 3, 7/+ DATA NS/0, 1, 2, 4/+ DATA DX1/0.6D0, 0.1D0, -0.5D0, 0.8D0, 0.9D0, -0.3D0,+ + -0.4D0/+ DATA DY1/0.5D0, -0.9D0, 0.3D0, 0.7D0, -0.6D0, 0.2D0,+ + 0.8D0/+ DATA SC, SS/0.8D0, 0.6D0/+ DATA DT9X/0.6D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.78D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.78D0, -0.46D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.78D0, -0.46D0, -0.22D0,+ + 1.06D0, 0.0D0, 0.0D0, 0.0D0, 0.6D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.78D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.66D0, 0.1D0, -0.1D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.96D0, 0.1D0, -0.76D0, 0.8D0, 0.90D0,+ + -0.3D0, -0.02D0, 0.6D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.78D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.0D0, -0.06D0, 0.1D0,+ + -0.1D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.90D0,+ + 0.1D0, -0.22D0, 0.8D0, 0.18D0, -0.3D0, -0.02D0,+ + 0.6D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.78D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.78D0, 0.26D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.78D0, 0.26D0, -0.76D0, 1.12D0,+ + 0.0D0, 0.0D0, 0.0D0/+ DATA DT9Y/0.5D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.04D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.04D0, -0.78D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.04D0, -0.78D0, 0.54D0,+ + 0.08D0, 0.0D0, 0.0D0, 0.0D0, 0.5D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.04D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.7D0,+ + -0.9D0, -0.12D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.64D0, -0.9D0, -0.30D0, 0.7D0, -0.18D0, 0.2D0,+ + 0.28D0, 0.5D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.04D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.7D0, -1.08D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.64D0, -1.26D0,+ + 0.54D0, 0.20D0, 0.0D0, 0.0D0, 0.0D0, 0.5D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.04D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.04D0, -0.9D0, 0.18D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.04D0, -0.9D0, 0.18D0, 0.7D0,+ + -0.18D0, 0.2D0, 0.16D0/+ DATA SSIZE2/0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0, 0.0D0,+ + 0.0D0, 1.17D0, 1.17D0, 1.17D0, 1.17D0, 1.17D0,+ + 1.17D0, 1.17D0, 1.17D0, 1.17D0, 1.17D0, 1.17D0,+ + 1.17D0, 1.17D0, 1.17D0/+* .. Executable Statements ..+*+ DO 60 KI = 1, 4+ INCX = INCXS(KI)+ INCY = INCYS(KI)+ MX = ABS(INCX)+ MY = ABS(INCY)+*+ DO 40 KN = 1, 4+ N = NS(KN)+ KSIZE = MIN(2,KN)+ LENX = LENS(KN,MX)+ LENY = LENS(KN,MY)+*+ IF (ICASE.EQ.4) THEN+* .. DROT ..+ DO 20 I = 1, 7+ SX(I) = DX1(I)+ SY(I) = DY1(I)+ STX(I) = DT9X(I,KN,KI)+ STY(I) = DT9Y(I,KN,KI)+ 20 CONTINUE+ CALL DROT(N,SX,INCX,SY,INCY,SC,SS)+ CALL STEST(LENX,SX,STX,SSIZE2(1,KSIZE),SFAC)+ CALL STEST(LENY,SY,STY,SSIZE2(1,KSIZE),SFAC)+ ELSE+ WRITE (NOUT,*) ' Shouldn''t be here in CHECK3'+ STOP+ END IF+ 40 CONTINUE+ 60 CONTINUE+*+ MWPC(1) = 1+ DO 80 I = 2, 11+ MWPC(I) = 0+ 80 CONTINUE+ MWPS(1) = 0+ DO 100 I = 2, 6+ MWPS(I) = 1+ 100 CONTINUE+ DO 120 I = 7, 11+ MWPS(I) = -1+ 120 CONTINUE+ MWPINX(1) = 1+ MWPINX(2) = 1+ MWPINX(3) = 1+ MWPINX(4) = -1+ MWPINX(5) = 1+ MWPINX(6) = -1+ MWPINX(7) = 1+ MWPINX(8) = 1+ MWPINX(9) = -1+ MWPINX(10) = 1+ MWPINX(11) = -1+ MWPINY(1) = 1+ MWPINY(2) = 1+ MWPINY(3) = -1+ MWPINY(4) = -1+ MWPINY(5) = 2+ MWPINY(6) = 1+ MWPINY(7) = 1+ MWPINY(8) = -1+ MWPINY(9) = -1+ MWPINY(10) = 2+ MWPINY(11) = 1+ DO 140 I = 1, 11+ MWPN(I) = 5+ 140 CONTINUE+ MWPN(5) = 3+ MWPN(10) = 3+ DO 160 I = 1, 5+ MWPX(I) = I+ MWPY(I) = I+ MWPTX(1,I) = I+ MWPTY(1,I) = I+ MWPTX(2,I) = I+ MWPTY(2,I) = -I+ MWPTX(3,I) = 6 - I+ MWPTY(3,I) = I - 6+ MWPTX(4,I) = I+ MWPTY(4,I) = -I+ MWPTX(6,I) = 6 - I+ MWPTY(6,I) = I - 6+ MWPTX(7,I) = -I+ MWPTY(7,I) = I+ MWPTX(8,I) = I - 6+ MWPTY(8,I) = 6 - I+ MWPTX(9,I) = -I+ MWPTY(9,I) = I+ MWPTX(11,I) = I - 6+ MWPTY(11,I) = 6 - I+ 160 CONTINUE+ MWPTX(5,1) = 1+ MWPTX(5,2) = 3+ MWPTX(5,3) = 5+ MWPTX(5,4) = 4+ MWPTX(5,5) = 5+ MWPTY(5,1) = -1+ MWPTY(5,2) = 2+ MWPTY(5,3) = -2+ MWPTY(5,4) = 4+ MWPTY(5,5) = -3+ MWPTX(10,1) = -1+ MWPTX(10,2) = -3+ MWPTX(10,3) = -5+ MWPTX(10,4) = 4+ MWPTX(10,5) = 5+ MWPTY(10,1) = 1+ MWPTY(10,2) = 2+ MWPTY(10,3) = 2+ MWPTY(10,4) = 4+ MWPTY(10,5) = 3+ DO 200 I = 1, 11+ INCX = MWPINX(I)+ INCY = MWPINY(I)+ DO 180 K = 1, 5+ COPYX(K) = MWPX(K)+ COPYY(K) = MWPY(K)+ MWPSTX(K) = MWPTX(I,K)+ MWPSTY(K) = MWPTY(I,K)+ 180 CONTINUE+ CALL DROT(MWPN(I),COPYX,INCX,COPYY,INCY,MWPC(I),MWPS(I))+ CALL STEST(5,COPYX,MWPSTX,MWPSTX,SFAC)+ CALL STEST(5,COPYY,MWPSTY,MWPSTY,SFAC)+ 200 CONTINUE+ RETURN+ END+ SUBROUTINE STEST(LEN,SCOMP,STRUE,SSIZE,SFAC)+* ********************************* STEST **************************+*+* THIS SUBR COMPARES ARRAYS SCOMP() AND STRUE() OF LENGTH LEN TO+* SEE IF THE TERM BY TERM DIFFERENCES, MULTIPLIED BY SFAC, ARE+* NEGLIGIBLE.+*+* C. L. LAWSON, JPL, 1974 DEC 10+*+* .. Parameters ..+ INTEGER NOUT+ DOUBLE PRECISION ZERO+ PARAMETER (NOUT=6, ZERO=0.0D0)+* .. Scalar Arguments ..+ DOUBLE PRECISION SFAC+ INTEGER LEN+* .. Array Arguments ..+ DOUBLE PRECISION SCOMP(LEN), SSIZE(LEN), STRUE(LEN)+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, N+ LOGICAL PASS+* .. Local Scalars ..+ DOUBLE PRECISION SD+ INTEGER I+* .. External Functions ..+ DOUBLE PRECISION SDIFF+ EXTERNAL SDIFF+* .. Intrinsic Functions ..+ INTRINSIC ABS+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, PASS+* .. Executable Statements ..+*+ DO 40 I = 1, LEN+ SD = SCOMP(I) - STRUE(I)+ IF (ABS(SFAC*SD) .LE. ABS(SSIZE(I))*EPSILON(ZERO))+ + GO TO 40+*+* HERE SCOMP(I) IS NOT CLOSE TO STRUE(I).+*+ IF ( .NOT. PASS) GO TO 20+* PRINT FAIL MESSAGE AND HEADER.+ PASS = .FALSE.+ WRITE (NOUT,99999)+ WRITE (NOUT,99998)+ 20 WRITE (NOUT,99997) ICASE, N, INCX, INCY, I, SCOMP(I),+ + STRUE(I), SD, SSIZE(I)+ 40 CONTINUE+ RETURN+*+99999 FORMAT (' FAIL')+99998 FORMAT (/' CASE N INCX INCY I ',+ + ' COMP(I) TRUE(I) DIFFERENCE',+ + ' SIZE(I)',/1X)+99997 FORMAT (1X,I4,I3,2I5,I3,2D36.8,2D12.4)+ END+ SUBROUTINE TESTDSDOT(SCOMP,STRUE,SSIZE,SFAC)+* ********************************* STEST **************************+*+* THIS SUBR COMPARES ARRAYS SCOMP() AND STRUE() OF LENGTH LEN TO+* SEE IF THE TERM BY TERM DIFFERENCES, MULTIPLIED BY SFAC, ARE+* NEGLIGIBLE.+*+* C. L. LAWSON, JPL, 1974 DEC 10+*+* .. Parameters ..+ INTEGER NOUT+ REAL ZERO+ PARAMETER (NOUT=6, ZERO=0.0E0)+* .. Scalar Arguments ..+ REAL SFAC, SCOMP, SSIZE, STRUE+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, N+ LOGICAL PASS+* .. Local Scalars ..+ REAL SD+* .. Intrinsic Functions ..+ INTRINSIC ABS+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, PASS+* .. Executable Statements ..+*+ SD = SCOMP - STRUE+ IF (ABS(SFAC*SD) .LE. ABS(SSIZE) * EPSILON(ZERO))+ + GO TO 40+*+* HERE SCOMP(I) IS NOT CLOSE TO STRUE(I).+*+ IF ( .NOT. PASS) GO TO 20+* PRINT FAIL MESSAGE AND HEADER.+ PASS = .FALSE.+ WRITE (NOUT,99999)+ WRITE (NOUT,99998)+ 20 WRITE (NOUT,99997) ICASE, N, INCX, INCY, SCOMP,+ + STRUE, SD, SSIZE+ 40 CONTINUE+ RETURN+*+99999 FORMAT (' FAIL')+99998 FORMAT (/' CASE N INCX INCY ',+ + ' COMP(I) TRUE(I) DIFFERENCE',+ + ' SIZE(I)',/1X)+99997 FORMAT (1X,I4,I3,1I5,I3,2E36.8,2E12.4)+ END+ SUBROUTINE STEST1(SCOMP1,STRUE1,SSIZE,SFAC)+* ************************* STEST1 *****************************+*+* THIS IS AN INTERFACE SUBROUTINE TO ACCOMODATE THE FORTRAN+* REQUIREMENT THAT WHEN A DUMMY ARGUMENT IS AN ARRAY, THE+* ACTUAL ARGUMENT MUST ALSO BE AN ARRAY OR AN ARRAY ELEMENT.+*+* C.L. LAWSON, JPL, 1978 DEC 6+*+* .. Scalar Arguments ..+ DOUBLE PRECISION SCOMP1, SFAC, STRUE1+* .. Array Arguments ..+ DOUBLE PRECISION SSIZE(*)+* .. Local Arrays ..+ DOUBLE PRECISION SCOMP(1), STRUE(1)+* .. External Subroutines ..+ EXTERNAL STEST+* .. Executable Statements ..+*+ SCOMP(1) = SCOMP1+ STRUE(1) = STRUE1+ CALL STEST(1,SCOMP,STRUE,SSIZE,SFAC)+*+ RETURN+ END+ DOUBLE PRECISION FUNCTION SDIFF(SA,SB)+* ********************************* SDIFF **************************+* COMPUTES DIFFERENCE OF TWO NUMBERS. C. L. LAWSON, JPL 1974 FEB 15+*+* .. Scalar Arguments ..+ DOUBLE PRECISION SA, SB+* .. Executable Statements ..+ SDIFF = SA - SB+ RETURN+ END+ SUBROUTINE ITEST1(ICOMP,ITRUE)+* ********************************* ITEST1 *************************+*+* THIS SUBROUTINE COMPARES THE VARIABLES ICOMP AND ITRUE FOR+* EQUALITY.+* C. L. LAWSON, JPL, 1974 DEC 10+*+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ INTEGER ICOMP, ITRUE+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, N+ LOGICAL PASS+* .. Local Scalars ..+ INTEGER ID+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, PASS+* .. Executable Statements ..+*+ IF (ICOMP.EQ.ITRUE) GO TO 40+*+* HERE ICOMP IS NOT EQUAL TO ITRUE.+*+ IF ( .NOT. PASS) GO TO 20+* PRINT FAIL MESSAGE AND HEADER.+ PASS = .FALSE.+ WRITE (NOUT,99999)+ WRITE (NOUT,99998)+ 20 ID = ICOMP - ITRUE+ WRITE (NOUT,99997) ICASE, N, INCX, INCY, ICOMP, ITRUE, ID+ 40 CONTINUE+ RETURN+*+99999 FORMAT (' FAIL')+99998 FORMAT (/' CASE N INCX INCY ',+ + ' COMP TRUE DIFFERENCE',+ + /1X)+99997 FORMAT (1X,I4,I3,2I5,2I36,I12)+ END
+ eigen3/blas/testing/dblat2.dat view
@@ -0,0 +1,34 @@+'dblat2.summ' NAME OF SUMMARY OUTPUT FILE+6 UNIT NUMBER OF SUMMARY FILE+'dblat2.snap' NAME OF SNAPSHOT OUTPUT FILE+-1 UNIT NUMBER OF SNAPSHOT FILE (NOT USED IF .LT. 0)+F LOGICAL FLAG, T TO REWIND SNAPSHOT FILE AFTER EACH RECORD.+F LOGICAL FLAG, T TO STOP ON FAILURES.+T LOGICAL FLAG, T TO TEST ERROR EXITS.+16.0 THRESHOLD VALUE OF TEST RATIO+6 NUMBER OF VALUES OF N+0 1 2 3 5 9 VALUES OF N+4 NUMBER OF VALUES OF K+0 1 2 4 VALUES OF K+4 NUMBER OF VALUES OF INCX AND INCY+1 2 -1 -2 VALUES OF INCX AND INCY+3 NUMBER OF VALUES OF ALPHA+0.0 1.0 0.7 VALUES OF ALPHA+3 NUMBER OF VALUES OF BETA+0.0 1.0 0.9 VALUES OF BETA+DGEMV T PUT F FOR NO TEST. SAME COLUMNS.+DGBMV T PUT F FOR NO TEST. SAME COLUMNS.+DSYMV T PUT F FOR NO TEST. SAME COLUMNS.+DSBMV T PUT F FOR NO TEST. SAME COLUMNS.+DSPMV T PUT F FOR NO TEST. SAME COLUMNS.+DTRMV T PUT F FOR NO TEST. SAME COLUMNS.+DTBMV T PUT F FOR NO TEST. SAME COLUMNS.+DTPMV T PUT F FOR NO TEST. SAME COLUMNS.+DTRSV T PUT F FOR NO TEST. SAME COLUMNS.+DTBSV T PUT F FOR NO TEST. SAME COLUMNS.+DTPSV T PUT F FOR NO TEST. SAME COLUMNS.+DGER T PUT F FOR NO TEST. SAME COLUMNS.+DSYR T PUT F FOR NO TEST. SAME COLUMNS.+DSPR T PUT F FOR NO TEST. SAME COLUMNS.+DSYR2 T PUT F FOR NO TEST. SAME COLUMNS.+DSPR2 T PUT F FOR NO TEST. SAME COLUMNS.
+ eigen3/blas/testing/dblat2.f view
@@ -0,0 +1,3138 @@+ PROGRAM DBLAT2+*+* Test program for the DOUBLE PRECISION Level 2 Blas.+*+* The program must be driven by a short data file. The first 18 records+* of the file are read using list-directed input, the last 16 records+* are read using the format ( A6, L2 ). An annotated example of a data+* file can be obtained by deleting the first 3 characters from the+* following 34 lines:+* 'DBLAT2.SUMM' NAME OF SUMMARY OUTPUT FILE+* 6 UNIT NUMBER OF SUMMARY FILE+* 'DBLAT2.SNAP' NAME OF SNAPSHOT OUTPUT FILE+* -1 UNIT NUMBER OF SNAPSHOT FILE (NOT USED IF .LT. 0)+* F LOGICAL FLAG, T TO REWIND SNAPSHOT FILE AFTER EACH RECORD.+* F LOGICAL FLAG, T TO STOP ON FAILURES.+* T LOGICAL FLAG, T TO TEST ERROR EXITS.+* 16.0 THRESHOLD VALUE OF TEST RATIO+* 6 NUMBER OF VALUES OF N+* 0 1 2 3 5 9 VALUES OF N+* 4 NUMBER OF VALUES OF K+* 0 1 2 4 VALUES OF K+* 4 NUMBER OF VALUES OF INCX AND INCY+* 1 2 -1 -2 VALUES OF INCX AND INCY+* 3 NUMBER OF VALUES OF ALPHA+* 0.0 1.0 0.7 VALUES OF ALPHA+* 3 NUMBER OF VALUES OF BETA+* 0.0 1.0 0.9 VALUES OF BETA+* DGEMV T PUT F FOR NO TEST. SAME COLUMNS.+* DGBMV T PUT F FOR NO TEST. SAME COLUMNS.+* DSYMV T PUT F FOR NO TEST. SAME COLUMNS.+* DSBMV T PUT F FOR NO TEST. SAME COLUMNS.+* DSPMV T PUT F FOR NO TEST. SAME COLUMNS.+* DTRMV T PUT F FOR NO TEST. SAME COLUMNS.+* DTBMV T PUT F FOR NO TEST. SAME COLUMNS.+* DTPMV T PUT F FOR NO TEST. SAME COLUMNS.+* DTRSV T PUT F FOR NO TEST. SAME COLUMNS.+* DTBSV T PUT F FOR NO TEST. SAME COLUMNS.+* DTPSV T PUT F FOR NO TEST. SAME COLUMNS.+* DGER T PUT F FOR NO TEST. SAME COLUMNS.+* DSYR T PUT F FOR NO TEST. SAME COLUMNS.+* DSPR T PUT F FOR NO TEST. SAME COLUMNS.+* DSYR2 T PUT F FOR NO TEST. SAME COLUMNS.+* DSPR2 T PUT F FOR NO TEST. SAME COLUMNS.+*+* See:+*+* Dongarra J. J., Du Croz J. J., Hammarling S. and Hanson R. J..+* An extended set of Fortran Basic Linear Algebra Subprograms.+*+* Technical Memoranda Nos. 41 (revision 3) and 81, Mathematics+* and Computer Science Division, Argonne National Laboratory,+* 9700 South Cass Avenue, Argonne, Illinois 60439, US.+*+* Or+*+* NAG Technical Reports TR3/87 and TR4/87, Numerical Algorithms+* Group Ltd., NAG Central Office, 256 Banbury Road, Oxford+* OX2 7DE, UK, and Numerical Algorithms Group Inc., 1101 31st+* Street, Suite 100, Downers Grove, Illinois 60515-1263, USA.+*+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ INTEGER NIN+ PARAMETER ( NIN = 5 )+ INTEGER NSUBS+ PARAMETER ( NSUBS = 16 )+ DOUBLE PRECISION ZERO, HALF, ONE+ PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0 )+ INTEGER NMAX, INCMAX+ PARAMETER ( NMAX = 65, INCMAX = 2 )+ INTEGER NINMAX, NIDMAX, NKBMAX, NALMAX, NBEMAX+ PARAMETER ( NINMAX = 7, NIDMAX = 9, NKBMAX = 7,+ $ NALMAX = 7, NBEMAX = 7 )+* .. Local Scalars ..+ DOUBLE PRECISION EPS, ERR, THRESH+ INTEGER I, ISNUM, J, N, NALF, NBET, NIDIM, NINC, NKB,+ $ NOUT, NTRA+ LOGICAL FATAL, LTESTT, REWI, SAME, SFATAL, TRACE,+ $ TSTERR+ CHARACTER*1 TRANS+ CHARACTER*6 SNAMET+ CHARACTER*32 SNAPS, SUMMRY+* .. Local Arrays ..+ DOUBLE PRECISION A( NMAX, NMAX ), AA( NMAX*NMAX ),+ $ ALF( NALMAX ), AS( NMAX*NMAX ), BET( NBEMAX ),+ $ G( NMAX ), X( NMAX ), XS( NMAX*INCMAX ),+ $ XX( NMAX*INCMAX ), Y( NMAX ),+ $ YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX ), Z( 2*NMAX )+ INTEGER IDIM( NIDMAX ), INC( NINMAX ), KB( NKBMAX )+ LOGICAL LTEST( NSUBS )+ CHARACTER*6 SNAMES( NSUBS )+* .. External Functions ..+ DOUBLE PRECISION DDIFF+ LOGICAL LDE+ EXTERNAL DDIFF, LDE+* .. External Subroutines ..+ EXTERNAL DCHK1, DCHK2, DCHK3, DCHK4, DCHK5, DCHK6,+ $ DCHKE, DMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, MIN+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+ COMMON /SRNAMC/SRNAMT+* .. Data statements ..+ DATA SNAMES/'DGEMV ', 'DGBMV ', 'DSYMV ', 'DSBMV ',+ $ 'DSPMV ', 'DTRMV ', 'DTBMV ', 'DTPMV ',+ $ 'DTRSV ', 'DTBSV ', 'DTPSV ', 'DGER ',+ $ 'DSYR ', 'DSPR ', 'DSYR2 ', 'DSPR2 '/+* .. Executable Statements ..+*+* Read name and unit number for summary output file and open file.+*+ READ( NIN, FMT = * )SUMMRY+ READ( NIN, FMT = * )NOUT+ OPEN( NOUT, FILE = SUMMRY, STATUS = 'NEW' )+ NOUTC = NOUT+*+* Read name and unit number for snapshot output file and open file.+*+ READ( NIN, FMT = * )SNAPS+ READ( NIN, FMT = * )NTRA+ TRACE = NTRA.GE.0+ IF( TRACE )THEN+ OPEN( NTRA, FILE = SNAPS, STATUS = 'NEW' )+ END IF+* Read the flag that directs rewinding of the snapshot file.+ READ( NIN, FMT = * )REWI+ REWI = REWI.AND.TRACE+* Read the flag that directs stopping on any failure.+ READ( NIN, FMT = * )SFATAL+* Read the flag that indicates whether error exits are to be tested.+ READ( NIN, FMT = * )TSTERR+* Read the threshold value of the test ratio+ READ( NIN, FMT = * )THRESH+*+* Read and check the parameter values for the tests.+*+* Values of N+ READ( NIN, FMT = * )NIDIM+ IF( NIDIM.LT.1.OR.NIDIM.GT.NIDMAX )THEN+ WRITE( NOUT, FMT = 9997 )'N', NIDMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( IDIM( I ), I = 1, NIDIM )+ DO 10 I = 1, NIDIM+ IF( IDIM( I ).LT.0.OR.IDIM( I ).GT.NMAX )THEN+ WRITE( NOUT, FMT = 9996 )NMAX+ GO TO 230+ END IF+ 10 CONTINUE+* Values of K+ READ( NIN, FMT = * )NKB+ IF( NKB.LT.1.OR.NKB.GT.NKBMAX )THEN+ WRITE( NOUT, FMT = 9997 )'K', NKBMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( KB( I ), I = 1, NKB )+ DO 20 I = 1, NKB+ IF( KB( I ).LT.0 )THEN+ WRITE( NOUT, FMT = 9995 )+ GO TO 230+ END IF+ 20 CONTINUE+* Values of INCX and INCY+ READ( NIN, FMT = * )NINC+ IF( NINC.LT.1.OR.NINC.GT.NINMAX )THEN+ WRITE( NOUT, FMT = 9997 )'INCX AND INCY', NINMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( INC( I ), I = 1, NINC )+ DO 30 I = 1, NINC+ IF( INC( I ).EQ.0.OR.ABS( INC( I ) ).GT.INCMAX )THEN+ WRITE( NOUT, FMT = 9994 )INCMAX+ GO TO 230+ END IF+ 30 CONTINUE+* Values of ALPHA+ READ( NIN, FMT = * )NALF+ IF( NALF.LT.1.OR.NALF.GT.NALMAX )THEN+ WRITE( NOUT, FMT = 9997 )'ALPHA', NALMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( ALF( I ), I = 1, NALF )+* Values of BETA+ READ( NIN, FMT = * )NBET+ IF( NBET.LT.1.OR.NBET.GT.NBEMAX )THEN+ WRITE( NOUT, FMT = 9997 )'BETA', NBEMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( BET( I ), I = 1, NBET )+*+* Report values of parameters.+*+ WRITE( NOUT, FMT = 9993 )+ WRITE( NOUT, FMT = 9992 )( IDIM( I ), I = 1, NIDIM )+ WRITE( NOUT, FMT = 9991 )( KB( I ), I = 1, NKB )+ WRITE( NOUT, FMT = 9990 )( INC( I ), I = 1, NINC )+ WRITE( NOUT, FMT = 9989 )( ALF( I ), I = 1, NALF )+ WRITE( NOUT, FMT = 9988 )( BET( I ), I = 1, NBET )+ IF( .NOT.TSTERR )THEN+ WRITE( NOUT, FMT = * )+ WRITE( NOUT, FMT = 9980 )+ END IF+ WRITE( NOUT, FMT = * )+ WRITE( NOUT, FMT = 9999 )THRESH+ WRITE( NOUT, FMT = * )+*+* Read names of subroutines and flags which indicate+* whether they are to be tested.+*+ DO 40 I = 1, NSUBS+ LTEST( I ) = .FALSE.+ 40 CONTINUE+ 50 READ( NIN, FMT = 9984, END = 80 )SNAMET, LTESTT+ DO 60 I = 1, NSUBS+ IF( SNAMET.EQ.SNAMES( I ) )+ $ GO TO 70+ 60 CONTINUE+ WRITE( NOUT, FMT = 9986 )SNAMET+ STOP+ 70 LTEST( I ) = LTESTT+ GO TO 50+*+ 80 CONTINUE+ CLOSE ( NIN )+*+* Compute EPS (the machine precision).+*+ EPS = ONE+ 90 CONTINUE+ IF( DDIFF( ONE + EPS, ONE ).EQ.ZERO )+ $ GO TO 100+ EPS = HALF*EPS+ GO TO 90+ 100 CONTINUE+ EPS = EPS + EPS+ WRITE( NOUT, FMT = 9998 )EPS+*+* Check the reliability of DMVCH using exact data.+*+ N = MIN( 32, NMAX )+ DO 120 J = 1, N+ DO 110 I = 1, N+ A( I, J ) = MAX( I - J + 1, 0 )+ 110 CONTINUE+ X( J ) = J+ Y( J ) = ZERO+ 120 CONTINUE+ DO 130 J = 1, N+ YY( J ) = J*( ( J + 1 )*J )/2 - ( ( J + 1 )*J*( J - 1 ) )/3+ 130 CONTINUE+* YY holds the exact result. On exit from DMVCH YT holds+* the result computed by DMVCH.+ TRANS = 'N'+ CALL DMVCH( TRANS, N, N, ONE, A, NMAX, X, 1, ZERO, Y, 1, YT, G,+ $ YY, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LDE( YY, YT, N )+ IF( .NOT.SAME.OR.ERR.NE.ZERO )THEN+ WRITE( NOUT, FMT = 9985 )TRANS, SAME, ERR+ STOP+ END IF+ TRANS = 'T'+ CALL DMVCH( TRANS, N, N, ONE, A, NMAX, X, -1, ZERO, Y, -1, YT, G,+ $ YY, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LDE( YY, YT, N )+ IF( .NOT.SAME.OR.ERR.NE.ZERO )THEN+ WRITE( NOUT, FMT = 9985 )TRANS, SAME, ERR+ STOP+ END IF+*+* Test each subroutine in turn.+*+ DO 210 ISNUM = 1, NSUBS+ WRITE( NOUT, FMT = * )+ IF( .NOT.LTEST( ISNUM ) )THEN+* Subprogram is not to be tested.+ WRITE( NOUT, FMT = 9983 )SNAMES( ISNUM )+ ELSE+ SRNAMT = SNAMES( ISNUM )+* Test error exits.+ IF( TSTERR )THEN+ CALL DCHKE( ISNUM, SNAMES( ISNUM ), NOUT )+ WRITE( NOUT, FMT = * )+ END IF+* Test computations.+ INFOT = 0+ OK = .TRUE.+ FATAL = .FALSE.+ GO TO ( 140, 140, 150, 150, 150, 160, 160,+ $ 160, 160, 160, 160, 170, 180, 180,+ $ 190, 190 )ISNUM+* Test DGEMV, 01, and DGBMV, 02.+ 140 CALL DCHK1( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NKB, KB, NALF, ALF,+ $ NBET, BET, NINC, INC, NMAX, INCMAX, A, AA, AS,+ $ X, XX, XS, Y, YY, YS, YT, G )+ GO TO 200+* Test DSYMV, 03, DSBMV, 04, and DSPMV, 05.+ 150 CALL DCHK2( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NKB, KB, NALF, ALF,+ $ NBET, BET, NINC, INC, NMAX, INCMAX, A, AA, AS,+ $ X, XX, XS, Y, YY, YS, YT, G )+ GO TO 200+* Test DTRMV, 06, DTBMV, 07, DTPMV, 08,+* DTRSV, 09, DTBSV, 10, and DTPSV, 11.+ 160 CALL DCHK3( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NKB, KB, NINC, INC,+ $ NMAX, INCMAX, A, AA, AS, Y, YY, YS, YT, G, Z )+ GO TO 200+* Test DGER, 12.+ 170 CALL DCHK4( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC,+ $ NMAX, INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS,+ $ YT, G, Z )+ GO TO 200+* Test DSYR, 13, and DSPR, 14.+ 180 CALL DCHK5( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC,+ $ NMAX, INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS,+ $ YT, G, Z )+ GO TO 200+* Test DSYR2, 15, and DSPR2, 16.+ 190 CALL DCHK6( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC,+ $ NMAX, INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS,+ $ YT, G, Z )+*+ 200 IF( FATAL.AND.SFATAL )+ $ GO TO 220+ END IF+ 210 CONTINUE+ WRITE( NOUT, FMT = 9982 )+ GO TO 240+*+ 220 CONTINUE+ WRITE( NOUT, FMT = 9981 )+ GO TO 240+*+ 230 CONTINUE+ WRITE( NOUT, FMT = 9987 )+*+ 240 CONTINUE+ IF( TRACE )+ $ CLOSE ( NTRA )+ CLOSE ( NOUT )+ STOP+*+ 9999 FORMAT( ' ROUTINES PASS COMPUTATIONAL TESTS IF TEST RATIO IS LES',+ $ 'S THAN', F8.2 )+ 9998 FORMAT( ' RELATIVE MACHINE PRECISION IS TAKEN TO BE', 1P, D9.1 )+ 9997 FORMAT( ' NUMBER OF VALUES OF ', A, ' IS LESS THAN 1 OR GREATER ',+ $ 'THAN ', I2 )+ 9996 FORMAT( ' VALUE OF N IS LESS THAN 0 OR GREATER THAN ', I2 )+ 9995 FORMAT( ' VALUE OF K IS LESS THAN 0' )+ 9994 FORMAT( ' ABSOLUTE VALUE OF INCX OR INCY IS 0 OR GREATER THAN ',+ $ I2 )+ 9993 FORMAT( ' TESTS OF THE DOUBLE PRECISION LEVEL 2 BLAS', //' THE F',+ $ 'OLLOWING PARAMETER VALUES WILL BE USED:' )+ 9992 FORMAT( ' FOR N ', 9I6 )+ 9991 FORMAT( ' FOR K ', 7I6 )+ 9990 FORMAT( ' FOR INCX AND INCY ', 7I6 )+ 9989 FORMAT( ' FOR ALPHA ', 7F6.1 )+ 9988 FORMAT( ' FOR BETA ', 7F6.1 )+ 9987 FORMAT( ' AMEND DATA FILE OR INCREASE ARRAY SIZES IN PROGRAM',+ $ /' ******* TESTS ABANDONED *******' )+ 9986 FORMAT( ' SUBPROGRAM NAME ', A6, ' NOT RECOGNIZED', /' ******* T',+ $ 'ESTS ABANDONED *******' )+ 9985 FORMAT( ' ERROR IN DMVCH - IN-LINE DOT PRODUCTS ARE BEING EVALU',+ $ 'ATED WRONGLY.', /' DMVCH WAS CALLED WITH TRANS = ', A1,+ $ ' AND RETURNED SAME = ', L1, ' AND ERR = ', F12.3, '.', /+ $ ' THIS MAY BE DUE TO FAULTS IN THE ARITHMETIC OR THE COMPILER.'+ $ , /' ******* TESTS ABANDONED *******' )+ 9984 FORMAT( A6, L2 )+ 9983 FORMAT( 1X, A6, ' WAS NOT TESTED' )+ 9982 FORMAT( /' END OF TESTS' )+ 9981 FORMAT( /' ******* FATAL ERROR - TESTS ABANDONED *******' )+ 9980 FORMAT( ' ERROR-EXITS WILL NOT BE TESTED' )+*+* End of DBLAT2.+*+ END+ SUBROUTINE DCHK1( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NKB, KB, NALF, ALF, NBET,+ $ BET, NINC, INC, NMAX, INCMAX, A, AA, AS, X, XX,+ $ XS, Y, YY, YS, YT, G )+*+* Tests DGEMV and DGBMV.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ DOUBLE PRECISION ZERO, HALF+ PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER INCMAX, NALF, NBET, NIDIM, NINC, NKB, NMAX,+ $ NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ DOUBLE PRECISION A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), BET( NBET ), G( NMAX ),+ $ X( NMAX ), XS( NMAX*INCMAX ),+ $ XX( NMAX*INCMAX ), Y( NMAX ),+ $ YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX )+ INTEGER IDIM( NIDIM ), INC( NINC ), KB( NKB )+* .. Local Scalars ..+ DOUBLE PRECISION ALPHA, ALS, BETA, BLS, ERR, ERRMAX, TRANSL+ INTEGER I, IA, IB, IC, IKU, IM, IN, INCX, INCXS, INCY,+ $ INCYS, IX, IY, KL, KLS, KU, KUS, LAA, LDA,+ $ LDAS, LX, LY, M, ML, MS, N, NARGS, NC, ND, NK,+ $ NL, NS+ LOGICAL BANDED, FULL, NULL, RESET, SAME, TRAN+ CHARACTER*1 TRANS, TRANSS+ CHARACTER*3 ICH+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LDE, LDERES+ EXTERNAL LDE, LDERES+* .. External Subroutines ..+ EXTERNAL DGBMV, DGEMV, DMAKE, DMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, MIN+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'NTC'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'E'+ BANDED = SNAME( 3: 3 ).EQ.'B'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 11+ ELSE IF( BANDED )THEN+ NARGS = 13+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 120 IN = 1, NIDIM+ N = IDIM( IN )+ ND = N/2 + 1+*+ DO 110 IM = 1, 2+ IF( IM.EQ.1 )+ $ M = MAX( N - ND, 0 )+ IF( IM.EQ.2 )+ $ M = MIN( N + ND, NMAX )+*+ IF( BANDED )THEN+ NK = NKB+ ELSE+ NK = 1+ END IF+ DO 100 IKU = 1, NK+ IF( BANDED )THEN+ KU = KB( IKU )+ KL = MAX( KU - 1, 0 )+ ELSE+ KU = N - 1+ KL = M - 1+ END IF+* Set LDA to 1 more than minimum value if room.+ IF( BANDED )THEN+ LDA = KL + KU + 1+ ELSE+ LDA = M+ END IF+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 100+ LAA = LDA*N+ NULL = N.LE.0.OR.M.LE.0+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL DMAKE( SNAME( 2: 3 ), ' ', ' ', M, N, A, NMAX, AA,+ $ LDA, KL, KU, RESET, TRANSL )+*+ DO 90 IC = 1, 3+ TRANS = ICH( IC: IC )+ TRAN = TRANS.EQ.'T'.OR.TRANS.EQ.'C'+*+ IF( TRAN )THEN+ ML = N+ NL = M+ ELSE+ ML = M+ NL = N+ END IF+*+ DO 80 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*NL+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL DMAKE( 'GE', ' ', ' ', 1, NL, X, 1, XX,+ $ ABS( INCX ), 0, NL - 1, RESET, TRANSL )+ IF( NL.GT.1 )THEN+ X( NL/2 ) = ZERO+ XX( 1 + ABS( INCX )*( NL/2 - 1 ) ) = ZERO+ END IF+*+ DO 70 IY = 1, NINC+ INCY = INC( IY )+ LY = ABS( INCY )*ML+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the vector Y.+*+ TRANSL = ZERO+ CALL DMAKE( 'GE', ' ', ' ', 1, ML, Y, 1,+ $ YY, ABS( INCY ), 0, ML - 1,+ $ RESET, TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ TRANSS = TRANS+ MS = M+ NS = N+ KLS = KL+ KUS = KU+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+ BLS = BETA+ DO 30 I = 1, LY+ YS( I ) = YY( I )+ 30 CONTINUE+ INCYS = INCY+*+* Call the subroutine.+*+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME,+ $ TRANS, M, N, ALPHA, LDA, INCX, BETA,+ $ INCY+ IF( REWI )+ $ REWIND NTRA+ CALL DGEMV( TRANS, M, N, ALPHA, AA,+ $ LDA, XX, INCX, BETA, YY,+ $ INCY )+ ELSE IF( BANDED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ TRANS, M, N, KL, KU, ALPHA, LDA,+ $ INCX, BETA, INCY+ IF( REWI )+ $ REWIND NTRA+ CALL DGBMV( TRANS, M, N, KL, KU, ALPHA,+ $ AA, LDA, XX, INCX, BETA,+ $ YY, INCY )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9993 )+ FATAL = .TRUE.+ GO TO 130+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = TRANS.EQ.TRANSS+ ISAME( 2 ) = MS.EQ.M+ ISAME( 3 ) = NS.EQ.N+ IF( FULL )THEN+ ISAME( 4 ) = ALS.EQ.ALPHA+ ISAME( 5 ) = LDE( AS, AA, LAA )+ ISAME( 6 ) = LDAS.EQ.LDA+ ISAME( 7 ) = LDE( XS, XX, LX )+ ISAME( 8 ) = INCXS.EQ.INCX+ ISAME( 9 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 10 ) = LDE( YS, YY, LY )+ ELSE+ ISAME( 10 ) = LDERES( 'GE', ' ', 1,+ $ ML, YS, YY,+ $ ABS( INCY ) )+ END IF+ ISAME( 11 ) = INCYS.EQ.INCY+ ELSE IF( BANDED )THEN+ ISAME( 4 ) = KLS.EQ.KL+ ISAME( 5 ) = KUS.EQ.KU+ ISAME( 6 ) = ALS.EQ.ALPHA+ ISAME( 7 ) = LDE( AS, AA, LAA )+ ISAME( 8 ) = LDAS.EQ.LDA+ ISAME( 9 ) = LDE( XS, XX, LX )+ ISAME( 10 ) = INCXS.EQ.INCX+ ISAME( 11 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 12 ) = LDE( YS, YY, LY )+ ELSE+ ISAME( 12 ) = LDERES( 'GE', ' ', 1,+ $ ML, YS, YY,+ $ ABS( INCY ) )+ END IF+ ISAME( 13 ) = INCYS.EQ.INCY+ END IF+*+* If data was incorrectly changed, report+* and return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 130+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result.+*+ CALL DMVCH( TRANS, M, N, ALPHA, A,+ $ NMAX, X, INCX, BETA, Y,+ $ INCY, YT, G, YY, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 130+ ELSE+* Avoid repeating tests with M.le.0 or+* N.le.0.+ GO TO 110+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 140+*+ 130 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, TRANS, M, N, ALPHA, LDA,+ $ INCX, BETA, INCY+ ELSE IF( BANDED )THEN+ WRITE( NOUT, FMT = 9995 )NC, SNAME, TRANS, M, N, KL, KU,+ $ ALPHA, LDA, INCX, BETA, INCY+ END IF+*+ 140 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', 4( I3, ',' ), F4.1,+ $ ', A,', I3, ', X,', I2, ',', F4.1, ', Y,', I2, ') .' )+ 9994 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', 2( I3, ',' ), F4.1,+ $ ', A,', I3, ', X,', I2, ',', F4.1, ', Y,', I2,+ $ ') .' )+ 9993 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of DCHK1.+*+ END+ SUBROUTINE DCHK2( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NKB, KB, NALF, ALF, NBET,+ $ BET, NINC, INC, NMAX, INCMAX, A, AA, AS, X, XX,+ $ XS, Y, YY, YS, YT, G )+*+* Tests DSYMV, DSBMV and DSPMV.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ DOUBLE PRECISION ZERO, HALF+ PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER INCMAX, NALF, NBET, NIDIM, NINC, NKB, NMAX,+ $ NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ DOUBLE PRECISION A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), BET( NBET ), G( NMAX ),+ $ X( NMAX ), XS( NMAX*INCMAX ),+ $ XX( NMAX*INCMAX ), Y( NMAX ),+ $ YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX )+ INTEGER IDIM( NIDIM ), INC( NINC ), KB( NKB )+* .. Local Scalars ..+ DOUBLE PRECISION ALPHA, ALS, BETA, BLS, ERR, ERRMAX, TRANSL+ INTEGER I, IA, IB, IC, IK, IN, INCX, INCXS, INCY,+ $ INCYS, IX, IY, K, KS, LAA, LDA, LDAS, LX, LY,+ $ N, NARGS, NC, NK, NS+ LOGICAL BANDED, FULL, NULL, PACKED, RESET, SAME+ CHARACTER*1 UPLO, UPLOS+ CHARACTER*2 ICH+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LDE, LDERES+ EXTERNAL LDE, LDERES+* .. External Subroutines ..+ EXTERNAL DMAKE, DMVCH, DSBMV, DSPMV, DSYMV+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'UL'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'Y'+ BANDED = SNAME( 3: 3 ).EQ.'B'+ PACKED = SNAME( 3: 3 ).EQ.'P'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 10+ ELSE IF( BANDED )THEN+ NARGS = 11+ ELSE IF( PACKED )THEN+ NARGS = 9+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 110 IN = 1, NIDIM+ N = IDIM( IN )+*+ IF( BANDED )THEN+ NK = NKB+ ELSE+ NK = 1+ END IF+ DO 100 IK = 1, NK+ IF( BANDED )THEN+ K = KB( IK )+ ELSE+ K = N - 1+ END IF+* Set LDA to 1 more than minimum value if room.+ IF( BANDED )THEN+ LDA = K + 1+ ELSE+ LDA = N+ END IF+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 100+ IF( PACKED )THEN+ LAA = ( N*( N + 1 ) )/2+ ELSE+ LAA = LDA*N+ END IF+ NULL = N.LE.0+*+ DO 90 IC = 1, 2+ UPLO = ICH( IC: IC )+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL DMAKE( SNAME( 2: 3 ), UPLO, ' ', N, N, A, NMAX, AA,+ $ LDA, K, K, RESET, TRANSL )+*+ DO 80 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*N+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL DMAKE( 'GE', ' ', ' ', 1, N, X, 1, XX,+ $ ABS( INCX ), 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ X( N/2 ) = ZERO+ XX( 1 + ABS( INCX )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 70 IY = 1, NINC+ INCY = INC( IY )+ LY = ABS( INCY )*N+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the vector Y.+*+ TRANSL = ZERO+ CALL DMAKE( 'GE', ' ', ' ', 1, N, Y, 1, YY,+ $ ABS( INCY ), 0, N - 1, RESET,+ $ TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ UPLOS = UPLO+ NS = N+ KS = K+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+ BLS = BETA+ DO 30 I = 1, LY+ YS( I ) = YY( I )+ 30 CONTINUE+ INCYS = INCY+*+* Call the subroutine.+*+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME,+ $ UPLO, N, ALPHA, LDA, INCX, BETA, INCY+ IF( REWI )+ $ REWIND NTRA+ CALL DSYMV( UPLO, N, ALPHA, AA, LDA, XX,+ $ INCX, BETA, YY, INCY )+ ELSE IF( BANDED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME,+ $ UPLO, N, K, ALPHA, LDA, INCX, BETA,+ $ INCY+ IF( REWI )+ $ REWIND NTRA+ CALL DSBMV( UPLO, N, K, ALPHA, AA, LDA,+ $ XX, INCX, BETA, YY, INCY )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ UPLO, N, ALPHA, INCX, BETA, INCY+ IF( REWI )+ $ REWIND NTRA+ CALL DSPMV( UPLO, N, ALPHA, AA, XX, INCX,+ $ BETA, YY, INCY )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLO.EQ.UPLOS+ ISAME( 2 ) = NS.EQ.N+ IF( FULL )THEN+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LDE( AS, AA, LAA )+ ISAME( 5 ) = LDAS.EQ.LDA+ ISAME( 6 ) = LDE( XS, XX, LX )+ ISAME( 7 ) = INCXS.EQ.INCX+ ISAME( 8 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 9 ) = LDE( YS, YY, LY )+ ELSE+ ISAME( 9 ) = LDERES( 'GE', ' ', 1, N,+ $ YS, YY, ABS( INCY ) )+ END IF+ ISAME( 10 ) = INCYS.EQ.INCY+ ELSE IF( BANDED )THEN+ ISAME( 3 ) = KS.EQ.K+ ISAME( 4 ) = ALS.EQ.ALPHA+ ISAME( 5 ) = LDE( AS, AA, LAA )+ ISAME( 6 ) = LDAS.EQ.LDA+ ISAME( 7 ) = LDE( XS, XX, LX )+ ISAME( 8 ) = INCXS.EQ.INCX+ ISAME( 9 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 10 ) = LDE( YS, YY, LY )+ ELSE+ ISAME( 10 ) = LDERES( 'GE', ' ', 1, N,+ $ YS, YY, ABS( INCY ) )+ END IF+ ISAME( 11 ) = INCYS.EQ.INCY+ ELSE IF( PACKED )THEN+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LDE( AS, AA, LAA )+ ISAME( 5 ) = LDE( XS, XX, LX )+ ISAME( 6 ) = INCXS.EQ.INCX+ ISAME( 7 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 8 ) = LDE( YS, YY, LY )+ ELSE+ ISAME( 8 ) = LDERES( 'GE', ' ', 1, N,+ $ YS, YY, ABS( INCY ) )+ END IF+ ISAME( 9 ) = INCYS.EQ.INCY+ END IF+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result.+*+ CALL DMVCH( 'N', N, N, ALPHA, A, NMAX, X,+ $ INCX, BETA, Y, INCY, YT, G,+ $ YY, EPS, ERR, FATAL, NOUT,+ $ .TRUE. )+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 120+ ELSE+* Avoid repeating tests with N.le.0+ GO TO 110+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, N, ALPHA, LDA, INCX,+ $ BETA, INCY+ ELSE IF( BANDED )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, N, K, ALPHA, LDA,+ $ INCX, BETA, INCY+ ELSE IF( PACKED )THEN+ WRITE( NOUT, FMT = 9995 )NC, SNAME, UPLO, N, ALPHA, INCX,+ $ BETA, INCY+ END IF+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',', F4.1, ', AP',+ $ ', X,', I2, ',', F4.1, ', Y,', I2, ') .' )+ 9994 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', 2( I3, ',' ), F4.1,+ $ ', A,', I3, ', X,', I2, ',', F4.1, ', Y,', I2,+ $ ') .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',', F4.1, ', A,',+ $ I3, ', X,', I2, ',', F4.1, ', Y,', I2, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of DCHK2.+*+ END+ SUBROUTINE DCHK3( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NKB, KB, NINC, INC, NMAX,+ $ INCMAX, A, AA, AS, X, XX, XS, XT, G, Z )+*+* Tests DTRMV, DTBMV, DTPMV, DTRSV, DTBSV and DTPSV.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ DOUBLE PRECISION ZERO, HALF, ONE+ PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER INCMAX, NIDIM, NINC, NKB, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ DOUBLE PRECISION A( NMAX, NMAX ), AA( NMAX*NMAX ),+ $ AS( NMAX*NMAX ), G( NMAX ), X( NMAX ),+ $ XS( NMAX*INCMAX ), XT( NMAX ),+ $ XX( NMAX*INCMAX ), Z( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC ), KB( NKB )+* .. Local Scalars ..+ DOUBLE PRECISION ERR, ERRMAX, TRANSL+ INTEGER I, ICD, ICT, ICU, IK, IN, INCX, INCXS, IX, K,+ $ KS, LAA, LDA, LDAS, LX, N, NARGS, NC, NK, NS+ LOGICAL BANDED, FULL, NULL, PACKED, RESET, SAME+ CHARACTER*1 DIAG, DIAGS, TRANS, TRANSS, UPLO, UPLOS+ CHARACTER*2 ICHD, ICHU+ CHARACTER*3 ICHT+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LDE, LDERES+ EXTERNAL LDE, LDERES+* .. External Subroutines ..+ EXTERNAL DMAKE, DMVCH, DTBMV, DTBSV, DTPMV, DTPSV,+ $ DTRMV, DTRSV+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHU/'UL'/, ICHT/'NTC'/, ICHD/'UN'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'R'+ BANDED = SNAME( 3: 3 ).EQ.'B'+ PACKED = SNAME( 3: 3 ).EQ.'P'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 8+ ELSE IF( BANDED )THEN+ NARGS = 9+ ELSE IF( PACKED )THEN+ NARGS = 7+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+* Set up zero vector for DMVCH.+ DO 10 I = 1, NMAX+ Z( I ) = ZERO+ 10 CONTINUE+*+ DO 110 IN = 1, NIDIM+ N = IDIM( IN )+*+ IF( BANDED )THEN+ NK = NKB+ ELSE+ NK = 1+ END IF+ DO 100 IK = 1, NK+ IF( BANDED )THEN+ K = KB( IK )+ ELSE+ K = N - 1+ END IF+* Set LDA to 1 more than minimum value if room.+ IF( BANDED )THEN+ LDA = K + 1+ ELSE+ LDA = N+ END IF+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 100+ IF( PACKED )THEN+ LAA = ( N*( N + 1 ) )/2+ ELSE+ LAA = LDA*N+ END IF+ NULL = N.LE.0+*+ DO 90 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+*+ DO 80 ICT = 1, 3+ TRANS = ICHT( ICT: ICT )+*+ DO 70 ICD = 1, 2+ DIAG = ICHD( ICD: ICD )+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL DMAKE( SNAME( 2: 3 ), UPLO, DIAG, N, N, A,+ $ NMAX, AA, LDA, K, K, RESET, TRANSL )+*+ DO 60 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*N+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL DMAKE( 'GE', ' ', ' ', 1, N, X, 1, XX,+ $ ABS( INCX ), 0, N - 1, RESET,+ $ TRANSL )+ IF( N.GT.1 )THEN+ X( N/2 ) = ZERO+ XX( 1 + ABS( INCX )*( N/2 - 1 ) ) = ZERO+ END IF+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ TRANSS = TRANS+ DIAGS = DIAG+ NS = N+ KS = K+ DO 20 I = 1, LAA+ AS( I ) = AA( I )+ 20 CONTINUE+ LDAS = LDA+ DO 30 I = 1, LX+ XS( I ) = XX( I )+ 30 CONTINUE+ INCXS = INCX+*+* Call the subroutine.+*+ IF( SNAME( 4: 5 ).EQ.'MV' )THEN+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, LDA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL DTRMV( UPLO, TRANS, DIAG, N, AA, LDA,+ $ XX, INCX )+ ELSE IF( BANDED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, K, LDA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL DTBMV( UPLO, TRANS, DIAG, N, K, AA,+ $ LDA, XX, INCX )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL DTPMV( UPLO, TRANS, DIAG, N, AA, XX,+ $ INCX )+ END IF+ ELSE IF( SNAME( 4: 5 ).EQ.'SV' )THEN+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, LDA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL DTRSV( UPLO, TRANS, DIAG, N, AA, LDA,+ $ XX, INCX )+ ELSE IF( BANDED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, K, LDA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL DTBSV( UPLO, TRANS, DIAG, N, K, AA,+ $ LDA, XX, INCX )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL DTPSV( UPLO, TRANS, DIAG, N, AA, XX,+ $ INCX )+ END IF+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLO.EQ.UPLOS+ ISAME( 2 ) = TRANS.EQ.TRANSS+ ISAME( 3 ) = DIAG.EQ.DIAGS+ ISAME( 4 ) = NS.EQ.N+ IF( FULL )THEN+ ISAME( 5 ) = LDE( AS, AA, LAA )+ ISAME( 6 ) = LDAS.EQ.LDA+ IF( NULL )THEN+ ISAME( 7 ) = LDE( XS, XX, LX )+ ELSE+ ISAME( 7 ) = LDERES( 'GE', ' ', 1, N, XS,+ $ XX, ABS( INCX ) )+ END IF+ ISAME( 8 ) = INCXS.EQ.INCX+ ELSE IF( BANDED )THEN+ ISAME( 5 ) = KS.EQ.K+ ISAME( 6 ) = LDE( AS, AA, LAA )+ ISAME( 7 ) = LDAS.EQ.LDA+ IF( NULL )THEN+ ISAME( 8 ) = LDE( XS, XX, LX )+ ELSE+ ISAME( 8 ) = LDERES( 'GE', ' ', 1, N, XS,+ $ XX, ABS( INCX ) )+ END IF+ ISAME( 9 ) = INCXS.EQ.INCX+ ELSE IF( PACKED )THEN+ ISAME( 5 ) = LDE( AS, AA, LAA )+ IF( NULL )THEN+ ISAME( 6 ) = LDE( XS, XX, LX )+ ELSE+ ISAME( 6 ) = LDERES( 'GE', ' ', 1, N, XS,+ $ XX, ABS( INCX ) )+ END IF+ ISAME( 7 ) = INCXS.EQ.INCX+ END IF+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+ IF( SNAME( 4: 5 ).EQ.'MV' )THEN+*+* Check the result.+*+ CALL DMVCH( TRANS, N, N, ONE, A, NMAX, X,+ $ INCX, ZERO, Z, INCX, XT, G,+ $ XX, EPS, ERR, FATAL, NOUT,+ $ .TRUE. )+ ELSE IF( SNAME( 4: 5 ).EQ.'SV' )THEN+*+* Compute approximation to original vector.+*+ DO 50 I = 1, N+ Z( I ) = XX( 1 + ( I - 1 )*+ $ ABS( INCX ) )+ XX( 1 + ( I - 1 )*ABS( INCX ) )+ $ = X( I )+ 50 CONTINUE+ CALL DMVCH( TRANS, N, N, ONE, A, NMAX, Z,+ $ INCX, ZERO, X, INCX, XT, G,+ $ XX, EPS, ERR, FATAL, NOUT,+ $ .FALSE. )+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and return.+ IF( FATAL )+ $ GO TO 120+ ELSE+* Avoid repeating tests with N.le.0.+ GO TO 110+ END IF+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, TRANS, DIAG, N, LDA,+ $ INCX+ ELSE IF( BANDED )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, TRANS, DIAG, N, K,+ $ LDA, INCX+ ELSE IF( PACKED )THEN+ WRITE( NOUT, FMT = 9995 )NC, SNAME, UPLO, TRANS, DIAG, N, INCX+ END IF+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(', 3( '''', A1, ''',' ), I3, ', AP, ',+ $ 'X,', I2, ') .' )+ 9994 FORMAT( 1X, I6, ': ', A6, '(', 3( '''', A1, ''',' ), 2( I3, ',' ),+ $ ' A,', I3, ', X,', I2, ') .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(', 3( '''', A1, ''',' ), I3, ', A,',+ $ I3, ', X,', I2, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of DCHK3.+*+ END+ SUBROUTINE DCHK4( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC, NMAX,+ $ INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS, YT, G,+ $ Z )+*+* Tests DGER.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ DOUBLE PRECISION ZERO, HALF, ONE+ PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER INCMAX, NALF, NIDIM, NINC, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ DOUBLE PRECISION A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), G( NMAX ), X( NMAX ),+ $ XS( NMAX*INCMAX ), XX( NMAX*INCMAX ),+ $ Y( NMAX ), YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX ), Z( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC )+* .. Local Scalars ..+ DOUBLE PRECISION ALPHA, ALS, ERR, ERRMAX, TRANSL+ INTEGER I, IA, IM, IN, INCX, INCXS, INCY, INCYS, IX,+ $ IY, J, LAA, LDA, LDAS, LX, LY, M, MS, N, NARGS,+ $ NC, ND, NS+ LOGICAL NULL, RESET, SAME+* .. Local Arrays ..+ DOUBLE PRECISION W( 1 )+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LDE, LDERES+ EXTERNAL LDE, LDERES+* .. External Subroutines ..+ EXTERNAL DGER, DMAKE, DMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, MIN+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Executable Statements ..+* Define the number of arguments.+ NARGS = 9+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 120 IN = 1, NIDIM+ N = IDIM( IN )+ ND = N/2 + 1+*+ DO 110 IM = 1, 2+ IF( IM.EQ.1 )+ $ M = MAX( N - ND, 0 )+ IF( IM.EQ.2 )+ $ M = MIN( N + ND, NMAX )+*+* Set LDA to 1 more than minimum value if room.+ LDA = M+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 110+ LAA = LDA*N+ NULL = N.LE.0.OR.M.LE.0+*+ DO 100 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*M+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL DMAKE( 'GE', ' ', ' ', 1, M, X, 1, XX, ABS( INCX ),+ $ 0, M - 1, RESET, TRANSL )+ IF( M.GT.1 )THEN+ X( M/2 ) = ZERO+ XX( 1 + ABS( INCX )*( M/2 - 1 ) ) = ZERO+ END IF+*+ DO 90 IY = 1, NINC+ INCY = INC( IY )+ LY = ABS( INCY )*N+*+* Generate the vector Y.+*+ TRANSL = ZERO+ CALL DMAKE( 'GE', ' ', ' ', 1, N, Y, 1, YY,+ $ ABS( INCY ), 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ Y( N/2 ) = ZERO+ YY( 1 + ABS( INCY )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 80 IA = 1, NALF+ ALPHA = ALF( IA )+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL DMAKE( SNAME( 2: 3 ), ' ', ' ', M, N, A, NMAX,+ $ AA, LDA, M - 1, N - 1, RESET, TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ MS = M+ NS = N+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+ DO 30 I = 1, LY+ YS( I ) = YY( I )+ 30 CONTINUE+ INCYS = INCY+*+* Call the subroutine.+*+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, M, N,+ $ ALPHA, INCX, INCY, LDA+ IF( REWI )+ $ REWIND NTRA+ CALL DGER( M, N, ALPHA, XX, INCX, YY, INCY, AA,+ $ LDA )+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9993 )+ FATAL = .TRUE.+ GO TO 140+ END IF+*+* See what data changed inside subroutine.+*+ ISAME( 1 ) = MS.EQ.M+ ISAME( 2 ) = NS.EQ.N+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LDE( XS, XX, LX )+ ISAME( 5 ) = INCXS.EQ.INCX+ ISAME( 6 ) = LDE( YS, YY, LY )+ ISAME( 7 ) = INCYS.EQ.INCY+ IF( NULL )THEN+ ISAME( 8 ) = LDE( AS, AA, LAA )+ ELSE+ ISAME( 8 ) = LDERES( 'GE', ' ', M, N, AS, AA,+ $ LDA )+ END IF+ ISAME( 9 ) = LDAS.EQ.LDA+*+* If data was incorrectly changed, report and return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 140+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ IF( INCX.GT.0 )THEN+ DO 50 I = 1, M+ Z( I ) = X( I )+ 50 CONTINUE+ ELSE+ DO 60 I = 1, M+ Z( I ) = X( M - I + 1 )+ 60 CONTINUE+ END IF+ DO 70 J = 1, N+ IF( INCY.GT.0 )THEN+ W( 1 ) = Y( J )+ ELSE+ W( 1 ) = Y( N - J + 1 )+ END IF+ CALL DMVCH( 'N', M, 1, ALPHA, Z, NMAX, W, 1,+ $ ONE, A( 1, J ), 1, YT, G,+ $ AA( 1 + ( J - 1 )*LDA ), EPS,+ $ ERR, FATAL, NOUT, .TRUE. )+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and return.+ IF( FATAL )+ $ GO TO 130+ 70 CONTINUE+ ELSE+* Avoid repeating tests with M.le.0 or N.le.0.+ GO TO 110+ END IF+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 150+*+ 130 CONTINUE+ WRITE( NOUT, FMT = 9995 )J+*+ 140 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9994 )NC, SNAME, M, N, ALPHA, INCX, INCY, LDA+*+ 150 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(', 2( I3, ',' ), F4.1, ', X,', I2,+ $ ', Y,', I2, ', A,', I3, ') .' )+ 9993 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of DCHK4.+*+ END+ SUBROUTINE DCHK5( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC, NMAX,+ $ INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS, YT, G,+ $ Z )+*+* Tests DSYR and DSPR.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ DOUBLE PRECISION ZERO, HALF, ONE+ PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER INCMAX, NALF, NIDIM, NINC, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ DOUBLE PRECISION A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), G( NMAX ), X( NMAX ),+ $ XS( NMAX*INCMAX ), XX( NMAX*INCMAX ),+ $ Y( NMAX ), YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX ), Z( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC )+* .. Local Scalars ..+ DOUBLE PRECISION ALPHA, ALS, ERR, ERRMAX, TRANSL+ INTEGER I, IA, IC, IN, INCX, INCXS, IX, J, JA, JJ, LAA,+ $ LDA, LDAS, LJ, LX, N, NARGS, NC, NS+ LOGICAL FULL, NULL, PACKED, RESET, SAME, UPPER+ CHARACTER*1 UPLO, UPLOS+ CHARACTER*2 ICH+* .. Local Arrays ..+ DOUBLE PRECISION W( 1 )+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LDE, LDERES+ EXTERNAL LDE, LDERES+* .. External Subroutines ..+ EXTERNAL DMAKE, DMVCH, DSPR, DSYR+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'UL'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'Y'+ PACKED = SNAME( 3: 3 ).EQ.'P'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 7+ ELSE IF( PACKED )THEN+ NARGS = 6+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 100 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDA to 1 more than minimum value if room.+ LDA = N+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 100+ IF( PACKED )THEN+ LAA = ( N*( N + 1 ) )/2+ ELSE+ LAA = LDA*N+ END IF+*+ DO 90 IC = 1, 2+ UPLO = ICH( IC: IC )+ UPPER = UPLO.EQ.'U'+*+ DO 80 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*N+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL DMAKE( 'GE', ' ', ' ', 1, N, X, 1, XX, ABS( INCX ),+ $ 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ X( N/2 ) = ZERO+ XX( 1 + ABS( INCX )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 70 IA = 1, NALF+ ALPHA = ALF( IA )+ NULL = N.LE.0.OR.ALPHA.EQ.ZERO+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL DMAKE( SNAME( 2: 3 ), UPLO, ' ', N, N, A, NMAX,+ $ AA, LDA, N - 1, N - 1, RESET, TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ NS = N+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+*+* Call the subroutine.+*+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME, UPLO, N,+ $ ALPHA, INCX, LDA+ IF( REWI )+ $ REWIND NTRA+ CALL DSYR( UPLO, N, ALPHA, XX, INCX, AA, LDA )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, UPLO, N,+ $ ALPHA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL DSPR( UPLO, N, ALPHA, XX, INCX, AA )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLO.EQ.UPLOS+ ISAME( 2 ) = NS.EQ.N+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LDE( XS, XX, LX )+ ISAME( 5 ) = INCXS.EQ.INCX+ IF( NULL )THEN+ ISAME( 6 ) = LDE( AS, AA, LAA )+ ELSE+ ISAME( 6 ) = LDERES( SNAME( 2: 3 ), UPLO, N, N, AS,+ $ AA, LDA )+ END IF+ IF( .NOT.PACKED )THEN+ ISAME( 7 ) = LDAS.EQ.LDA+ END IF+*+* If data was incorrectly changed, report and return.+*+ SAME = .TRUE.+ DO 30 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 30 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ IF( INCX.GT.0 )THEN+ DO 40 I = 1, N+ Z( I ) = X( I )+ 40 CONTINUE+ ELSE+ DO 50 I = 1, N+ Z( I ) = X( N - I + 1 )+ 50 CONTINUE+ END IF+ JA = 1+ DO 60 J = 1, N+ W( 1 ) = Z( J )+ IF( UPPER )THEN+ JJ = 1+ LJ = J+ ELSE+ JJ = J+ LJ = N - J + 1+ END IF+ CALL DMVCH( 'N', LJ, 1, ALPHA, Z( JJ ), LJ, W,+ $ 1, ONE, A( JJ, J ), 1, YT, G,+ $ AA( JA ), EPS, ERR, FATAL, NOUT,+ $ .TRUE. )+ IF( FULL )THEN+ IF( UPPER )THEN+ JA = JA + LDA+ ELSE+ JA = JA + LDA + 1+ END IF+ ELSE+ JA = JA + LJ+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and return.+ IF( FATAL )+ $ GO TO 110+ 60 CONTINUE+ ELSE+* Avoid repeating tests if N.le.0.+ IF( N.LE.0 )+ $ GO TO 100+ END IF+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 110 CONTINUE+ WRITE( NOUT, FMT = 9995 )J+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, N, ALPHA, INCX, LDA+ ELSE IF( PACKED )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, N, ALPHA, INCX+ END IF+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',', F4.1, ', X,',+ $ I2, ', AP) .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',', F4.1, ', X,',+ $ I2, ', A,', I3, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of DCHK5.+*+ END+ SUBROUTINE DCHK6( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC, NMAX,+ $ INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS, YT, G,+ $ Z )+*+* Tests DSYR2 and DSPR2.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ DOUBLE PRECISION ZERO, HALF, ONE+ PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER INCMAX, NALF, NIDIM, NINC, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ DOUBLE PRECISION A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), G( NMAX ), X( NMAX ),+ $ XS( NMAX*INCMAX ), XX( NMAX*INCMAX ),+ $ Y( NMAX ), YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX ), Z( NMAX, 2 )+ INTEGER IDIM( NIDIM ), INC( NINC )+* .. Local Scalars ..+ DOUBLE PRECISION ALPHA, ALS, ERR, ERRMAX, TRANSL+ INTEGER I, IA, IC, IN, INCX, INCXS, INCY, INCYS, IX,+ $ IY, J, JA, JJ, LAA, LDA, LDAS, LJ, LX, LY, N,+ $ NARGS, NC, NS+ LOGICAL FULL, NULL, PACKED, RESET, SAME, UPPER+ CHARACTER*1 UPLO, UPLOS+ CHARACTER*2 ICH+* .. Local Arrays ..+ DOUBLE PRECISION W( 2 )+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LDE, LDERES+ EXTERNAL LDE, LDERES+* .. External Subroutines ..+ EXTERNAL DMAKE, DMVCH, DSPR2, DSYR2+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'UL'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'Y'+ PACKED = SNAME( 3: 3 ).EQ.'P'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 9+ ELSE IF( PACKED )THEN+ NARGS = 8+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 140 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDA to 1 more than minimum value if room.+ LDA = N+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 140+ IF( PACKED )THEN+ LAA = ( N*( N + 1 ) )/2+ ELSE+ LAA = LDA*N+ END IF+*+ DO 130 IC = 1, 2+ UPLO = ICH( IC: IC )+ UPPER = UPLO.EQ.'U'+*+ DO 120 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*N+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL DMAKE( 'GE', ' ', ' ', 1, N, X, 1, XX, ABS( INCX ),+ $ 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ X( N/2 ) = ZERO+ XX( 1 + ABS( INCX )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 110 IY = 1, NINC+ INCY = INC( IY )+ LY = ABS( INCY )*N+*+* Generate the vector Y.+*+ TRANSL = ZERO+ CALL DMAKE( 'GE', ' ', ' ', 1, N, Y, 1, YY,+ $ ABS( INCY ), 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ Y( N/2 ) = ZERO+ YY( 1 + ABS( INCY )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 100 IA = 1, NALF+ ALPHA = ALF( IA )+ NULL = N.LE.0.OR.ALPHA.EQ.ZERO+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL DMAKE( SNAME( 2: 3 ), UPLO, ' ', N, N, A,+ $ NMAX, AA, LDA, N - 1, N - 1, RESET,+ $ TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ NS = N+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+ DO 30 I = 1, LY+ YS( I ) = YY( I )+ 30 CONTINUE+ INCYS = INCY+*+* Call the subroutine.+*+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME, UPLO, N,+ $ ALPHA, INCX, INCY, LDA+ IF( REWI )+ $ REWIND NTRA+ CALL DSYR2( UPLO, N, ALPHA, XX, INCX, YY, INCY,+ $ AA, LDA )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, UPLO, N,+ $ ALPHA, INCX, INCY+ IF( REWI )+ $ REWIND NTRA+ CALL DSPR2( UPLO, N, ALPHA, XX, INCX, YY, INCY,+ $ AA )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 160+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLO.EQ.UPLOS+ ISAME( 2 ) = NS.EQ.N+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LDE( XS, XX, LX )+ ISAME( 5 ) = INCXS.EQ.INCX+ ISAME( 6 ) = LDE( YS, YY, LY )+ ISAME( 7 ) = INCYS.EQ.INCY+ IF( NULL )THEN+ ISAME( 8 ) = LDE( AS, AA, LAA )+ ELSE+ ISAME( 8 ) = LDERES( SNAME( 2: 3 ), UPLO, N, N,+ $ AS, AA, LDA )+ END IF+ IF( .NOT.PACKED )THEN+ ISAME( 9 ) = LDAS.EQ.LDA+ END IF+*+* If data was incorrectly changed, report and return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 160+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ IF( INCX.GT.0 )THEN+ DO 50 I = 1, N+ Z( I, 1 ) = X( I )+ 50 CONTINUE+ ELSE+ DO 60 I = 1, N+ Z( I, 1 ) = X( N - I + 1 )+ 60 CONTINUE+ END IF+ IF( INCY.GT.0 )THEN+ DO 70 I = 1, N+ Z( I, 2 ) = Y( I )+ 70 CONTINUE+ ELSE+ DO 80 I = 1, N+ Z( I, 2 ) = Y( N - I + 1 )+ 80 CONTINUE+ END IF+ JA = 1+ DO 90 J = 1, N+ W( 1 ) = Z( J, 2 )+ W( 2 ) = Z( J, 1 )+ IF( UPPER )THEN+ JJ = 1+ LJ = J+ ELSE+ JJ = J+ LJ = N - J + 1+ END IF+ CALL DMVCH( 'N', LJ, 2, ALPHA, Z( JJ, 1 ),+ $ NMAX, W, 1, ONE, A( JJ, J ), 1,+ $ YT, G, AA( JA ), EPS, ERR, FATAL,+ $ NOUT, .TRUE. )+ IF( FULL )THEN+ IF( UPPER )THEN+ JA = JA + LDA+ ELSE+ JA = JA + LDA + 1+ END IF+ ELSE+ JA = JA + LJ+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and return.+ IF( FATAL )+ $ GO TO 150+ 90 CONTINUE+ ELSE+* Avoid repeating tests with N.le.0.+ IF( N.LE.0 )+ $ GO TO 140+ END IF+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+ 130 CONTINUE+*+ 140 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 170+*+ 150 CONTINUE+ WRITE( NOUT, FMT = 9995 )J+*+ 160 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, N, ALPHA, INCX,+ $ INCY, LDA+ ELSE IF( PACKED )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, N, ALPHA, INCX, INCY+ END IF+*+ 170 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',', F4.1, ', X,',+ $ I2, ', Y,', I2, ', AP) .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',', F4.1, ', X,',+ $ I2, ', Y,', I2, ', A,', I3, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of DCHK6.+*+ END+ SUBROUTINE DCHKE( ISNUM, SRNAMT, NOUT )+*+* Tests the error exits from the Level 2 Blas.+* Requires a special version of the error-handling routine XERBLA.+* ALPHA, BETA, A, X and Y should not need to be defined.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER ISNUM, NOUT+ CHARACTER*6 SRNAMT+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Local Scalars ..+ DOUBLE PRECISION ALPHA, BETA+* .. Local Arrays ..+ DOUBLE PRECISION A( 1, 1 ), X( 1 ), Y( 1 )+* .. External Subroutines ..+ EXTERNAL CHKXER, DGBMV, DGEMV, DGER, DSBMV, DSPMV, DSPR,+ $ DSPR2, DSYMV, DSYR, DSYR2, DTBMV, DTBSV, DTPMV,+ $ DTPSV, DTRMV, DTRSV+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Executable Statements ..+* OK is set to .FALSE. by the special version of XERBLA or by CHKXER+* if anything is wrong.+ OK = .TRUE.+* LERR is set to .TRUE. by the special version of XERBLA each time+* it is called, and is then tested and re-set by CHKXER.+ LERR = .FALSE.+ GO TO ( 10, 20, 30, 40, 50, 60, 70, 80,+ $ 90, 100, 110, 120, 130, 140, 150,+ $ 160 )ISNUM+ 10 INFOT = 1+ CALL DGEMV( '/', 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DGEMV( 'N', -1, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DGEMV( 'N', 0, -1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DGEMV( 'N', 2, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL DGEMV( 'N', 0, 0, ALPHA, A, 1, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DGEMV( 'N', 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 20 INFOT = 1+ CALL DGBMV( '/', 0, 0, 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DGBMV( 'N', -1, 0, 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DGBMV( 'N', 0, -1, 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DGBMV( 'N', 0, 0, -1, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DGBMV( 'N', 2, 0, 0, -1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL DGBMV( 'N', 0, 0, 1, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL DGBMV( 'N', 0, 0, 0, 0, ALPHA, A, 1, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL DGBMV( 'N', 0, 0, 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 30 INFOT = 1+ CALL DSYMV( '/', 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DSYMV( 'U', -1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DSYMV( 'U', 2, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DSYMV( 'U', 0, ALPHA, A, 1, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL DSYMV( 'U', 0, ALPHA, A, 1, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 40 INFOT = 1+ CALL DSBMV( '/', 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DSBMV( 'U', -1, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DSBMV( 'U', 0, -1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DSBMV( 'U', 0, 1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL DSBMV( 'U', 0, 0, ALPHA, A, 1, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DSBMV( 'U', 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 50 INFOT = 1+ CALL DSPMV( '/', 0, ALPHA, A, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DSPMV( 'U', -1, ALPHA, A, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DSPMV( 'U', 0, ALPHA, A, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DSPMV( 'U', 0, ALPHA, A, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 60 INFOT = 1+ CALL DTRMV( '/', 'N', 'N', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DTRMV( 'U', '/', 'N', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DTRMV( 'U', 'N', '/', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DTRMV( 'U', 'N', 'N', -1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRMV( 'U', 'N', 'N', 2, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL DTRMV( 'U', 'N', 'N', 0, A, 1, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 70 INFOT = 1+ CALL DTBMV( '/', 'N', 'N', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DTBMV( 'U', '/', 'N', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DTBMV( 'U', 'N', '/', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DTBMV( 'U', 'N', 'N', -1, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTBMV( 'U', 'N', 'N', 0, -1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DTBMV( 'U', 'N', 'N', 0, 1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTBMV( 'U', 'N', 'N', 0, 0, A, 1, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 80 INFOT = 1+ CALL DTPMV( '/', 'N', 'N', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DTPMV( 'U', '/', 'N', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DTPMV( 'U', 'N', '/', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DTPMV( 'U', 'N', 'N', -1, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DTPMV( 'U', 'N', 'N', 0, A, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 90 INFOT = 1+ CALL DTRSV( '/', 'N', 'N', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DTRSV( 'U', '/', 'N', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DTRSV( 'U', 'N', '/', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DTRSV( 'U', 'N', 'N', -1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRSV( 'U', 'N', 'N', 2, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL DTRSV( 'U', 'N', 'N', 0, A, 1, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 100 INFOT = 1+ CALL DTBSV( '/', 'N', 'N', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DTBSV( 'U', '/', 'N', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DTBSV( 'U', 'N', '/', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DTBSV( 'U', 'N', 'N', -1, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTBSV( 'U', 'N', 'N', 0, -1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DTBSV( 'U', 'N', 'N', 0, 1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTBSV( 'U', 'N', 'N', 0, 0, A, 1, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 110 INFOT = 1+ CALL DTPSV( '/', 'N', 'N', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DTPSV( 'U', '/', 'N', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DTPSV( 'U', 'N', '/', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DTPSV( 'U', 'N', 'N', -1, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DTPSV( 'U', 'N', 'N', 0, A, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 120 INFOT = 1+ CALL DGER( -1, 0, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DGER( 0, -1, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DGER( 0, 0, ALPHA, X, 0, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DGER( 0, 0, ALPHA, X, 1, Y, 0, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DGER( 2, 0, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 130 INFOT = 1+ CALL DSYR( '/', 0, ALPHA, X, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DSYR( 'U', -1, ALPHA, X, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DSYR( 'U', 0, ALPHA, X, 0, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DSYR( 'U', 2, ALPHA, X, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 140 INFOT = 1+ CALL DSPR( '/', 0, ALPHA, X, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DSPR( 'U', -1, ALPHA, X, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DSPR( 'U', 0, ALPHA, X, 0, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 150 INFOT = 1+ CALL DSYR2( '/', 0, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DSYR2( 'U', -1, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DSYR2( 'U', 0, ALPHA, X, 0, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DSYR2( 'U', 0, ALPHA, X, 1, Y, 0, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DSYR2( 'U', 2, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 160 INFOT = 1+ CALL DSPR2( '/', 0, ALPHA, X, 1, Y, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DSPR2( 'U', -1, ALPHA, X, 1, Y, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DSPR2( 'U', 0, ALPHA, X, 0, Y, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DSPR2( 'U', 0, ALPHA, X, 1, Y, 0, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+*+ 170 IF( OK )THEN+ WRITE( NOUT, FMT = 9999 )SRNAMT+ ELSE+ WRITE( NOUT, FMT = 9998 )SRNAMT+ END IF+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE TESTS OF ERROR-EXITS' )+ 9998 FORMAT( ' ******* ', A6, ' FAILED THE TESTS OF ERROR-EXITS *****',+ $ '**' )+*+* End of DCHKE.+*+ END+ SUBROUTINE DMAKE( TYPE, UPLO, DIAG, M, N, A, NMAX, AA, LDA, KL,+ $ KU, RESET, TRANSL )+*+* Generates values for an M by N matrix A within the bandwidth+* defined by KL and KU.+* Stores the values in the array AA in the data structure required+* by the routine, with unwanted elements set to rogue value.+*+* TYPE is 'GE', 'GB', 'SY', 'SB', 'SP', 'TR', 'TB' OR 'TP'.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ DOUBLE PRECISION ZERO, ONE+ PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )+ DOUBLE PRECISION ROGUE+ PARAMETER ( ROGUE = -1.0D10 )+* .. Scalar Arguments ..+ DOUBLE PRECISION TRANSL+ INTEGER KL, KU, LDA, M, N, NMAX+ LOGICAL RESET+ CHARACTER*1 DIAG, UPLO+ CHARACTER*2 TYPE+* .. Array Arguments ..+ DOUBLE PRECISION A( NMAX, * ), AA( * )+* .. Local Scalars ..+ INTEGER I, I1, I2, I3, IBEG, IEND, IOFF, J, KK+ LOGICAL GEN, LOWER, SYM, TRI, UNIT, UPPER+* .. External Functions ..+ DOUBLE PRECISION DBEG+ EXTERNAL DBEG+* .. Intrinsic Functions ..+ INTRINSIC MAX, MIN+* .. Executable Statements ..+ GEN = TYPE( 1: 1 ).EQ.'G'+ SYM = TYPE( 1: 1 ).EQ.'S'+ TRI = TYPE( 1: 1 ).EQ.'T'+ UPPER = ( SYM.OR.TRI ).AND.UPLO.EQ.'U'+ LOWER = ( SYM.OR.TRI ).AND.UPLO.EQ.'L'+ UNIT = TRI.AND.DIAG.EQ.'U'+*+* Generate data in array A.+*+ DO 20 J = 1, N+ DO 10 I = 1, M+ IF( GEN.OR.( UPPER.AND.I.LE.J ).OR.( LOWER.AND.I.GE.J ) )+ $ THEN+ IF( ( I.LE.J.AND.J - I.LE.KU ).OR.+ $ ( I.GE.J.AND.I - J.LE.KL ) )THEN+ A( I, J ) = DBEG( RESET ) + TRANSL+ ELSE+ A( I, J ) = ZERO+ END IF+ IF( I.NE.J )THEN+ IF( SYM )THEN+ A( J, I ) = A( I, J )+ ELSE IF( TRI )THEN+ A( J, I ) = ZERO+ END IF+ END IF+ END IF+ 10 CONTINUE+ IF( TRI )+ $ A( J, J ) = A( J, J ) + ONE+ IF( UNIT )+ $ A( J, J ) = ONE+ 20 CONTINUE+*+* Store elements in array AS in data structure required by routine.+*+ IF( TYPE.EQ.'GE' )THEN+ DO 50 J = 1, N+ DO 30 I = 1, M+ AA( I + ( J - 1 )*LDA ) = A( I, J )+ 30 CONTINUE+ DO 40 I = M + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 40 CONTINUE+ 50 CONTINUE+ ELSE IF( TYPE.EQ.'GB' )THEN+ DO 90 J = 1, N+ DO 60 I1 = 1, KU + 1 - J+ AA( I1 + ( J - 1 )*LDA ) = ROGUE+ 60 CONTINUE+ DO 70 I2 = I1, MIN( KL + KU + 1, KU + 1 + M - J )+ AA( I2 + ( J - 1 )*LDA ) = A( I2 + J - KU - 1, J )+ 70 CONTINUE+ DO 80 I3 = I2, LDA+ AA( I3 + ( J - 1 )*LDA ) = ROGUE+ 80 CONTINUE+ 90 CONTINUE+ ELSE IF( TYPE.EQ.'SY'.OR.TYPE.EQ.'TR' )THEN+ DO 130 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IF( UNIT )THEN+ IEND = J - 1+ ELSE+ IEND = J+ END IF+ ELSE+ IF( UNIT )THEN+ IBEG = J + 1+ ELSE+ IBEG = J+ END IF+ IEND = N+ END IF+ DO 100 I = 1, IBEG - 1+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 100 CONTINUE+ DO 110 I = IBEG, IEND+ AA( I + ( J - 1 )*LDA ) = A( I, J )+ 110 CONTINUE+ DO 120 I = IEND + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 120 CONTINUE+ 130 CONTINUE+ ELSE IF( TYPE.EQ.'SB'.OR.TYPE.EQ.'TB' )THEN+ DO 170 J = 1, N+ IF( UPPER )THEN+ KK = KL + 1+ IBEG = MAX( 1, KL + 2 - J )+ IF( UNIT )THEN+ IEND = KL+ ELSE+ IEND = KL + 1+ END IF+ ELSE+ KK = 1+ IF( UNIT )THEN+ IBEG = 2+ ELSE+ IBEG = 1+ END IF+ IEND = MIN( KL + 1, 1 + M - J )+ END IF+ DO 140 I = 1, IBEG - 1+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 140 CONTINUE+ DO 150 I = IBEG, IEND+ AA( I + ( J - 1 )*LDA ) = A( I + J - KK, J )+ 150 CONTINUE+ DO 160 I = IEND + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 160 CONTINUE+ 170 CONTINUE+ ELSE IF( TYPE.EQ.'SP'.OR.TYPE.EQ.'TP' )THEN+ IOFF = 0+ DO 190 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IEND = J+ ELSE+ IBEG = J+ IEND = N+ END IF+ DO 180 I = IBEG, IEND+ IOFF = IOFF + 1+ AA( IOFF ) = A( I, J )+ IF( I.EQ.J )THEN+ IF( UNIT )+ $ AA( IOFF ) = ROGUE+ END IF+ 180 CONTINUE+ 190 CONTINUE+ END IF+ RETURN+*+* End of DMAKE.+*+ END+ SUBROUTINE DMVCH( TRANS, M, N, ALPHA, A, NMAX, X, INCX, BETA, Y,+ $ INCY, YT, G, YY, EPS, ERR, FATAL, NOUT, MV )+*+* Checks the results of the computational tests.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ DOUBLE PRECISION ZERO, ONE+ PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION ALPHA, BETA, EPS, ERR+ INTEGER INCX, INCY, M, N, NMAX, NOUT+ LOGICAL FATAL, MV+ CHARACTER*1 TRANS+* .. Array Arguments ..+ DOUBLE PRECISION A( NMAX, * ), G( * ), X( * ), Y( * ), YT( * ),+ $ YY( * )+* .. Local Scalars ..+ DOUBLE PRECISION ERRI+ INTEGER I, INCXL, INCYL, IY, J, JX, KX, KY, ML, NL+ LOGICAL TRAN+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, SQRT+* .. Executable Statements ..+ TRAN = TRANS.EQ.'T'.OR.TRANS.EQ.'C'+ IF( TRAN )THEN+ ML = N+ NL = M+ ELSE+ ML = M+ NL = N+ END IF+ IF( INCX.LT.0 )THEN+ KX = NL+ INCXL = -1+ ELSE+ KX = 1+ INCXL = 1+ END IF+ IF( INCY.LT.0 )THEN+ KY = ML+ INCYL = -1+ ELSE+ KY = 1+ INCYL = 1+ END IF+*+* Compute expected result in YT using data in A, X and Y.+* Compute gauges in G.+*+ IY = KY+ DO 30 I = 1, ML+ YT( IY ) = ZERO+ G( IY ) = ZERO+ JX = KX+ IF( TRAN )THEN+ DO 10 J = 1, NL+ YT( IY ) = YT( IY ) + A( J, I )*X( JX )+ G( IY ) = G( IY ) + ABS( A( J, I )*X( JX ) )+ JX = JX + INCXL+ 10 CONTINUE+ ELSE+ DO 20 J = 1, NL+ YT( IY ) = YT( IY ) + A( I, J )*X( JX )+ G( IY ) = G( IY ) + ABS( A( I, J )*X( JX ) )+ JX = JX + INCXL+ 20 CONTINUE+ END IF+ YT( IY ) = ALPHA*YT( IY ) + BETA*Y( IY )+ G( IY ) = ABS( ALPHA )*G( IY ) + ABS( BETA*Y( IY ) )+ IY = IY + INCYL+ 30 CONTINUE+*+* Compute the error ratio for this result.+*+ ERR = ZERO+ DO 40 I = 1, ML+ ERRI = ABS( YT( I ) - YY( 1 + ( I - 1 )*ABS( INCY ) ) )/EPS+ IF( G( I ).NE.ZERO )+ $ ERRI = ERRI/G( I )+ ERR = MAX( ERR, ERRI )+ IF( ERR*SQRT( EPS ).GE.ONE )+ $ GO TO 50+ 40 CONTINUE+* If the loop completes, all results are at least half accurate.+ GO TO 70+*+* Report fatal error.+*+ 50 FATAL = .TRUE.+ WRITE( NOUT, FMT = 9999 )+ DO 60 I = 1, ML+ IF( MV )THEN+ WRITE( NOUT, FMT = 9998 )I, YT( I ),+ $ YY( 1 + ( I - 1 )*ABS( INCY ) )+ ELSE+ WRITE( NOUT, FMT = 9998 )I,+ $ YY( 1 + ( I - 1 )*ABS( INCY ) ), YT( I )+ END IF+ 60 CONTINUE+*+ 70 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ******* FATAL ERROR - COMPUTED RESULT IS LESS THAN HAL',+ $ 'F ACCURATE *******', /' EXPECTED RESULT COMPU',+ $ 'TED RESULT' )+ 9998 FORMAT( 1X, I7, 2G18.6 )+*+* End of DMVCH.+*+ END+ LOGICAL FUNCTION LDE( RI, RJ, LR )+*+* Tests if two arrays are identical.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER LR+* .. Array Arguments ..+ DOUBLE PRECISION RI( * ), RJ( * )+* .. Local Scalars ..+ INTEGER I+* .. Executable Statements ..+ DO 10 I = 1, LR+ IF( RI( I ).NE.RJ( I ) )+ $ GO TO 20+ 10 CONTINUE+ LDE = .TRUE.+ GO TO 30+ 20 CONTINUE+ LDE = .FALSE.+ 30 RETURN+*+* End of LDE.+*+ END+ LOGICAL FUNCTION LDERES( TYPE, UPLO, M, N, AA, AS, LDA )+*+* Tests if selected elements in two arrays are equal.+*+* TYPE is 'GE', 'SY' or 'SP'.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER LDA, M, N+ CHARACTER*1 UPLO+ CHARACTER*2 TYPE+* .. Array Arguments ..+ DOUBLE PRECISION AA( LDA, * ), AS( LDA, * )+* .. Local Scalars ..+ INTEGER I, IBEG, IEND, J+ LOGICAL UPPER+* .. Executable Statements ..+ UPPER = UPLO.EQ.'U'+ IF( TYPE.EQ.'GE' )THEN+ DO 20 J = 1, N+ DO 10 I = M + 1, LDA+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 10 CONTINUE+ 20 CONTINUE+ ELSE IF( TYPE.EQ.'SY' )THEN+ DO 50 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IEND = J+ ELSE+ IBEG = J+ IEND = N+ END IF+ DO 30 I = 1, IBEG - 1+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 30 CONTINUE+ DO 40 I = IEND + 1, LDA+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 40 CONTINUE+ 50 CONTINUE+ END IF+*+ 60 CONTINUE+ LDERES = .TRUE.+ GO TO 80+ 70 CONTINUE+ LDERES = .FALSE.+ 80 RETURN+*+* End of LDERES.+*+ END+ DOUBLE PRECISION FUNCTION DBEG( RESET )+*+* Generates random numbers uniformly distributed between -0.5 and 0.5.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ LOGICAL RESET+* .. Local Scalars ..+ INTEGER I, IC, MI+* .. Save statement ..+ SAVE I, IC, MI+* .. Intrinsic Functions ..+ INTRINSIC DBLE+* .. Executable Statements ..+ IF( RESET )THEN+* Initialize local variables.+ MI = 891+ I = 7+ IC = 0+ RESET = .FALSE.+ END IF+*+* The sequence of values of I is bounded between 1 and 999.+* If initial I = 1,2,3,6,7 or 9, the period will be 50.+* If initial I = 4 or 8, the period will be 25.+* If initial I = 5, the period will be 10.+* IC is used to break up the period by skipping 1 value of I in 6.+*+ IC = IC + 1+ 10 I = I*MI+ I = I - 1000*( I/1000 )+ IF( IC.GE.5 )THEN+ IC = 0+ GO TO 10+ END IF+ DBEG = DBLE( I - 500 )/1001.0D0+ RETURN+*+* End of DBEG.+*+ END+ DOUBLE PRECISION FUNCTION DDIFF( X, Y )+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+*+* .. Scalar Arguments ..+ DOUBLE PRECISION X, Y+* .. Executable Statements ..+ DDIFF = X - Y+ RETURN+*+* End of DDIFF.+*+ END+ SUBROUTINE CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+*+* Tests whether XERBLA has detected an error when it should.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER INFOT, NOUT+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Executable Statements ..+ IF( .NOT.LERR )THEN+ WRITE( NOUT, FMT = 9999 )INFOT, SRNAMT+ OK = .FALSE.+ END IF+ LERR = .FALSE.+ RETURN+*+ 9999 FORMAT( ' ***** ILLEGAL VALUE OF PARAMETER NUMBER ', I2, ' NOT D',+ $ 'ETECTED BY ', A6, ' *****' )+*+* End of CHKXER.+*+ END+ SUBROUTINE XERBLA( SRNAME, INFO )+*+* This is a special version of XERBLA to be used only as part of+* the test program for testing error exits from the Level 2 BLAS+* routines.+*+* XERBLA is an error handler for the Level 2 BLAS routines.+*+* It is called by the Level 2 BLAS routines if an input parameter is+* invalid.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER INFO+ CHARACTER*6 SRNAME+* .. Scalars in Common ..+ INTEGER INFOT, NOUT+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUT, OK, LERR+ COMMON /SRNAMC/SRNAMT+* .. Executable Statements ..+ LERR = .TRUE.+ IF( INFO.NE.INFOT )THEN+ IF( INFOT.NE.0 )THEN+ WRITE( NOUT, FMT = 9999 )INFO, INFOT+ ELSE+ WRITE( NOUT, FMT = 9997 )INFO+ END IF+ OK = .FALSE.+ END IF+ IF( SRNAME.NE.SRNAMT )THEN+ WRITE( NOUT, FMT = 9998 )SRNAME, SRNAMT+ OK = .FALSE.+ END IF+ RETURN+*+ 9999 FORMAT( ' ******* XERBLA WAS CALLED WITH INFO = ', I6, ' INSTEAD',+ $ ' OF ', I2, ' *******' )+ 9998 FORMAT( ' ******* XERBLA WAS CALLED WITH SRNAME = ', A6, ' INSTE',+ $ 'AD OF ', A6, ' *******' )+ 9997 FORMAT( ' ******* XERBLA WAS CALLED WITH INFO = ', I6,+ $ ' *******' )+*+* End of XERBLA+*+ END+
+ eigen3/blas/testing/dblat3.dat view
@@ -0,0 +1,20 @@+'dblat3.summ' NAME OF SUMMARY OUTPUT FILE+6 UNIT NUMBER OF SUMMARY FILE+'dblat3.snap' NAME OF SNAPSHOT OUTPUT FILE+-1 UNIT NUMBER OF SNAPSHOT FILE (NOT USED IF .LT. 0)+F LOGICAL FLAG, T TO REWIND SNAPSHOT FILE AFTER EACH RECORD.+F LOGICAL FLAG, T TO STOP ON FAILURES.+T LOGICAL FLAG, T TO TEST ERROR EXITS.+16.0 THRESHOLD VALUE OF TEST RATIO+6 NUMBER OF VALUES OF N+0 1 2 3 5 9 VALUES OF N+3 NUMBER OF VALUES OF ALPHA+0.0 1.0 0.7 VALUES OF ALPHA+3 NUMBER OF VALUES OF BETA+0.0 1.0 1.3 VALUES OF BETA+DGEMM T PUT F FOR NO TEST. SAME COLUMNS.+DSYMM T PUT F FOR NO TEST. SAME COLUMNS.+DTRMM T PUT F FOR NO TEST. SAME COLUMNS.+DTRSM T PUT F FOR NO TEST. SAME COLUMNS.+DSYRK T PUT F FOR NO TEST. SAME COLUMNS.+DSYR2K T PUT F FOR NO TEST. SAME COLUMNS.
+ eigen3/blas/testing/dblat3.f view
@@ -0,0 +1,2823 @@+ PROGRAM DBLAT3+*+* Test program for the DOUBLE PRECISION Level 3 Blas.+*+* The program must be driven by a short data file. The first 14 records+* of the file are read using list-directed input, the last 6 records+* are read using the format ( A6, L2 ). An annotated example of a data+* file can be obtained by deleting the first 3 characters from the+* following 20 lines:+* 'DBLAT3.SUMM' NAME OF SUMMARY OUTPUT FILE+* 6 UNIT NUMBER OF SUMMARY FILE+* 'DBLAT3.SNAP' NAME OF SNAPSHOT OUTPUT FILE+* -1 UNIT NUMBER OF SNAPSHOT FILE (NOT USED IF .LT. 0)+* F LOGICAL FLAG, T TO REWIND SNAPSHOT FILE AFTER EACH RECORD.+* F LOGICAL FLAG, T TO STOP ON FAILURES.+* T LOGICAL FLAG, T TO TEST ERROR EXITS.+* 16.0 THRESHOLD VALUE OF TEST RATIO+* 6 NUMBER OF VALUES OF N+* 0 1 2 3 5 9 VALUES OF N+* 3 NUMBER OF VALUES OF ALPHA+* 0.0 1.0 0.7 VALUES OF ALPHA+* 3 NUMBER OF VALUES OF BETA+* 0.0 1.0 1.3 VALUES OF BETA+* DGEMM T PUT F FOR NO TEST. SAME COLUMNS.+* DSYMM T PUT F FOR NO TEST. SAME COLUMNS.+* DTRMM T PUT F FOR NO TEST. SAME COLUMNS.+* DTRSM T PUT F FOR NO TEST. SAME COLUMNS.+* DSYRK T PUT F FOR NO TEST. SAME COLUMNS.+* DSYR2K T PUT F FOR NO TEST. SAME COLUMNS.+*+* See:+*+* Dongarra J. J., Du Croz J. J., Duff I. S. and Hammarling S.+* A Set of Level 3 Basic Linear Algebra Subprograms.+*+* Technical Memorandum No.88 (Revision 1), Mathematics and+* Computer Science Division, Argonne National Laboratory, 9700+* South Cass Avenue, Argonne, Illinois 60439, US.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ INTEGER NIN+ PARAMETER ( NIN = 5 )+ INTEGER NSUBS+ PARAMETER ( NSUBS = 6 )+ DOUBLE PRECISION ZERO, HALF, ONE+ PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0 )+ INTEGER NMAX+ PARAMETER ( NMAX = 65 )+ INTEGER NIDMAX, NALMAX, NBEMAX+ PARAMETER ( NIDMAX = 9, NALMAX = 7, NBEMAX = 7 )+* .. Local Scalars ..+ DOUBLE PRECISION EPS, ERR, THRESH+ INTEGER I, ISNUM, J, N, NALF, NBET, NIDIM, NOUT, NTRA+ LOGICAL FATAL, LTESTT, REWI, SAME, SFATAL, TRACE,+ $ TSTERR+ CHARACTER*1 TRANSA, TRANSB+ CHARACTER*6 SNAMET+ CHARACTER*32 SNAPS, SUMMRY+* .. Local Arrays ..+ DOUBLE PRECISION AA( NMAX*NMAX ), AB( NMAX, 2*NMAX ),+ $ ALF( NALMAX ), AS( NMAX*NMAX ),+ $ BB( NMAX*NMAX ), BET( NBEMAX ),+ $ BS( NMAX*NMAX ), C( NMAX, NMAX ),+ $ CC( NMAX*NMAX ), CS( NMAX*NMAX ), CT( NMAX ),+ $ G( NMAX ), W( 2*NMAX )+ INTEGER IDIM( NIDMAX )+ LOGICAL LTEST( NSUBS )+ CHARACTER*6 SNAMES( NSUBS )+* .. External Functions ..+ DOUBLE PRECISION DDIFF+ LOGICAL LDE+ EXTERNAL DDIFF, LDE+* .. External Subroutines ..+ EXTERNAL DCHK1, DCHK2, DCHK3, DCHK4, DCHK5, DCHKE, DMMCH+* .. Intrinsic Functions ..+ INTRINSIC MAX, MIN+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+ COMMON /SRNAMC/SRNAMT+* .. Data statements ..+ DATA SNAMES/'DGEMM ', 'DSYMM ', 'DTRMM ', 'DTRSM ',+ $ 'DSYRK ', 'DSYR2K'/+* .. Executable Statements ..+*+* Read name and unit number for summary output file and open file.+*+ READ( NIN, FMT = * )SUMMRY+ READ( NIN, FMT = * )NOUT+ OPEN( NOUT, FILE = SUMMRY, STATUS = 'NEW' )+ NOUTC = NOUT+*+* Read name and unit number for snapshot output file and open file.+*+ READ( NIN, FMT = * )SNAPS+ READ( NIN, FMT = * )NTRA+ TRACE = NTRA.GE.0+ IF( TRACE )THEN+ OPEN( NTRA, FILE = SNAPS, STATUS = 'NEW' )+ END IF+* Read the flag that directs rewinding of the snapshot file.+ READ( NIN, FMT = * )REWI+ REWI = REWI.AND.TRACE+* Read the flag that directs stopping on any failure.+ READ( NIN, FMT = * )SFATAL+* Read the flag that indicates whether error exits are to be tested.+ READ( NIN, FMT = * )TSTERR+* Read the threshold value of the test ratio+ READ( NIN, FMT = * )THRESH+*+* Read and check the parameter values for the tests.+*+* Values of N+ READ( NIN, FMT = * )NIDIM+ IF( NIDIM.LT.1.OR.NIDIM.GT.NIDMAX )THEN+ WRITE( NOUT, FMT = 9997 )'N', NIDMAX+ GO TO 220+ END IF+ READ( NIN, FMT = * )( IDIM( I ), I = 1, NIDIM )+ DO 10 I = 1, NIDIM+ IF( IDIM( I ).LT.0.OR.IDIM( I ).GT.NMAX )THEN+ WRITE( NOUT, FMT = 9996 )NMAX+ GO TO 220+ END IF+ 10 CONTINUE+* Values of ALPHA+ READ( NIN, FMT = * )NALF+ IF( NALF.LT.1.OR.NALF.GT.NALMAX )THEN+ WRITE( NOUT, FMT = 9997 )'ALPHA', NALMAX+ GO TO 220+ END IF+ READ( NIN, FMT = * )( ALF( I ), I = 1, NALF )+* Values of BETA+ READ( NIN, FMT = * )NBET+ IF( NBET.LT.1.OR.NBET.GT.NBEMAX )THEN+ WRITE( NOUT, FMT = 9997 )'BETA', NBEMAX+ GO TO 220+ END IF+ READ( NIN, FMT = * )( BET( I ), I = 1, NBET )+*+* Report values of parameters.+*+ WRITE( NOUT, FMT = 9995 )+ WRITE( NOUT, FMT = 9994 )( IDIM( I ), I = 1, NIDIM )+ WRITE( NOUT, FMT = 9993 )( ALF( I ), I = 1, NALF )+ WRITE( NOUT, FMT = 9992 )( BET( I ), I = 1, NBET )+ IF( .NOT.TSTERR )THEN+ WRITE( NOUT, FMT = * )+ WRITE( NOUT, FMT = 9984 )+ END IF+ WRITE( NOUT, FMT = * )+ WRITE( NOUT, FMT = 9999 )THRESH+ WRITE( NOUT, FMT = * )+*+* Read names of subroutines and flags which indicate+* whether they are to be tested.+*+ DO 20 I = 1, NSUBS+ LTEST( I ) = .FALSE.+ 20 CONTINUE+ 30 READ( NIN, FMT = 9988, END = 60 )SNAMET, LTESTT+ DO 40 I = 1, NSUBS+ IF( SNAMET.EQ.SNAMES( I ) )+ $ GO TO 50+ 40 CONTINUE+ WRITE( NOUT, FMT = 9990 )SNAMET+ STOP+ 50 LTEST( I ) = LTESTT+ GO TO 30+*+ 60 CONTINUE+ CLOSE ( NIN )+*+* Compute EPS (the machine precision).+*+ EPS = ONE+ 70 CONTINUE+ IF( DDIFF( ONE + EPS, ONE ).EQ.ZERO )+ $ GO TO 80+ EPS = HALF*EPS+ GO TO 70+ 80 CONTINUE+ EPS = EPS + EPS+ WRITE( NOUT, FMT = 9998 )EPS+*+* Check the reliability of DMMCH using exact data.+*+ N = MIN( 32, NMAX )+ DO 100 J = 1, N+ DO 90 I = 1, N+ AB( I, J ) = MAX( I - J + 1, 0 )+ 90 CONTINUE+ AB( J, NMAX + 1 ) = J+ AB( 1, NMAX + J ) = J+ C( J, 1 ) = ZERO+ 100 CONTINUE+ DO 110 J = 1, N+ CC( J ) = J*( ( J + 1 )*J )/2 - ( ( J + 1 )*J*( J - 1 ) )/3+ 110 CONTINUE+* CC holds the exact result. On exit from DMMCH CT holds+* the result computed by DMMCH.+ TRANSA = 'N'+ TRANSB = 'N'+ CALL DMMCH( TRANSA, TRANSB, N, 1, N, ONE, AB, NMAX,+ $ AB( 1, NMAX + 1 ), NMAX, ZERO, C, NMAX, CT, G, CC,+ $ NMAX, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LDE( CC, CT, N )+ IF( .NOT.SAME.OR.ERR.NE.ZERO )THEN+ WRITE( NOUT, FMT = 9989 )TRANSA, TRANSB, SAME, ERR+ STOP+ END IF+ TRANSB = 'T'+ CALL DMMCH( TRANSA, TRANSB, N, 1, N, ONE, AB, NMAX,+ $ AB( 1, NMAX + 1 ), NMAX, ZERO, C, NMAX, CT, G, CC,+ $ NMAX, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LDE( CC, CT, N )+ IF( .NOT.SAME.OR.ERR.NE.ZERO )THEN+ WRITE( NOUT, FMT = 9989 )TRANSA, TRANSB, SAME, ERR+ STOP+ END IF+ DO 120 J = 1, N+ AB( J, NMAX + 1 ) = N - J + 1+ AB( 1, NMAX + J ) = N - J + 1+ 120 CONTINUE+ DO 130 J = 1, N+ CC( N - J + 1 ) = J*( ( J + 1 )*J )/2 -+ $ ( ( J + 1 )*J*( J - 1 ) )/3+ 130 CONTINUE+ TRANSA = 'T'+ TRANSB = 'N'+ CALL DMMCH( TRANSA, TRANSB, N, 1, N, ONE, AB, NMAX,+ $ AB( 1, NMAX + 1 ), NMAX, ZERO, C, NMAX, CT, G, CC,+ $ NMAX, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LDE( CC, CT, N )+ IF( .NOT.SAME.OR.ERR.NE.ZERO )THEN+ WRITE( NOUT, FMT = 9989 )TRANSA, TRANSB, SAME, ERR+ STOP+ END IF+ TRANSB = 'T'+ CALL DMMCH( TRANSA, TRANSB, N, 1, N, ONE, AB, NMAX,+ $ AB( 1, NMAX + 1 ), NMAX, ZERO, C, NMAX, CT, G, CC,+ $ NMAX, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LDE( CC, CT, N )+ IF( .NOT.SAME.OR.ERR.NE.ZERO )THEN+ WRITE( NOUT, FMT = 9989 )TRANSA, TRANSB, SAME, ERR+ STOP+ END IF+*+* Test each subroutine in turn.+*+ DO 200 ISNUM = 1, NSUBS+ WRITE( NOUT, FMT = * )+ IF( .NOT.LTEST( ISNUM ) )THEN+* Subprogram is not to be tested.+ WRITE( NOUT, FMT = 9987 )SNAMES( ISNUM )+ ELSE+ SRNAMT = SNAMES( ISNUM )+* Test error exits.+ IF( TSTERR )THEN+ CALL DCHKE( ISNUM, SNAMES( ISNUM ), NOUT )+ WRITE( NOUT, FMT = * )+ END IF+* Test computations.+ INFOT = 0+ OK = .TRUE.+ FATAL = .FALSE.+ GO TO ( 140, 150, 160, 160, 170, 180 )ISNUM+* Test DGEMM, 01.+ 140 CALL DCHK1( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET,+ $ NMAX, AB, AA, AS, AB( 1, NMAX + 1 ), BB, BS, C,+ $ CC, CS, CT, G )+ GO TO 190+* Test DSYMM, 02.+ 150 CALL DCHK2( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET,+ $ NMAX, AB, AA, AS, AB( 1, NMAX + 1 ), BB, BS, C,+ $ CC, CS, CT, G )+ GO TO 190+* Test DTRMM, 03, DTRSM, 04.+ 160 CALL DCHK3( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NMAX, AB,+ $ AA, AS, AB( 1, NMAX + 1 ), BB, BS, CT, G, C )+ GO TO 190+* Test DSYRK, 05.+ 170 CALL DCHK4( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET,+ $ NMAX, AB, AA, AS, AB( 1, NMAX + 1 ), BB, BS, C,+ $ CC, CS, CT, G )+ GO TO 190+* Test DSYR2K, 06.+ 180 CALL DCHK5( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET,+ $ NMAX, AB, AA, AS, BB, BS, C, CC, CS, CT, G, W )+ GO TO 190+*+ 190 IF( FATAL.AND.SFATAL )+ $ GO TO 210+ END IF+ 200 CONTINUE+ WRITE( NOUT, FMT = 9986 )+ GO TO 230+*+ 210 CONTINUE+ WRITE( NOUT, FMT = 9985 )+ GO TO 230+*+ 220 CONTINUE+ WRITE( NOUT, FMT = 9991 )+*+ 230 CONTINUE+ IF( TRACE )+ $ CLOSE ( NTRA )+ CLOSE ( NOUT )+ STOP+*+ 9999 FORMAT( ' ROUTINES PASS COMPUTATIONAL TESTS IF TEST RATIO IS LES',+ $ 'S THAN', F8.2 )+ 9998 FORMAT( ' RELATIVE MACHINE PRECISION IS TAKEN TO BE', 1P, D9.1 )+ 9997 FORMAT( ' NUMBER OF VALUES OF ', A, ' IS LESS THAN 1 OR GREATER ',+ $ 'THAN ', I2 )+ 9996 FORMAT( ' VALUE OF N IS LESS THAN 0 OR GREATER THAN ', I2 )+ 9995 FORMAT( ' TESTS OF THE DOUBLE PRECISION LEVEL 3 BLAS', //' THE F',+ $ 'OLLOWING PARAMETER VALUES WILL BE USED:' )+ 9994 FORMAT( ' FOR N ', 9I6 )+ 9993 FORMAT( ' FOR ALPHA ', 7F6.1 )+ 9992 FORMAT( ' FOR BETA ', 7F6.1 )+ 9991 FORMAT( ' AMEND DATA FILE OR INCREASE ARRAY SIZES IN PROGRAM',+ $ /' ******* TESTS ABANDONED *******' )+ 9990 FORMAT( ' SUBPROGRAM NAME ', A6, ' NOT RECOGNIZED', /' ******* T',+ $ 'ESTS ABANDONED *******' )+ 9989 FORMAT( ' ERROR IN DMMCH - IN-LINE DOT PRODUCTS ARE BEING EVALU',+ $ 'ATED WRONGLY.', /' DMMCH WAS CALLED WITH TRANSA = ', A1,+ $ ' AND TRANSB = ', A1, /' AND RETURNED SAME = ', L1, ' AND ',+ $ 'ERR = ', F12.3, '.', /' THIS MAY BE DUE TO FAULTS IN THE ',+ $ 'ARITHMETIC OR THE COMPILER.', /' ******* TESTS ABANDONED ',+ $ '*******' )+ 9988 FORMAT( A6, L2 )+ 9987 FORMAT( 1X, A6, ' WAS NOT TESTED' )+ 9986 FORMAT( /' END OF TESTS' )+ 9985 FORMAT( /' ******* FATAL ERROR - TESTS ABANDONED *******' )+ 9984 FORMAT( ' ERROR-EXITS WILL NOT BE TESTED' )+*+* End of DBLAT3.+*+ END+ SUBROUTINE DCHK1( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET, NMAX,+ $ A, AA, AS, B, BB, BS, C, CC, CS, CT, G )+*+* Tests DGEMM.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ DOUBLE PRECISION ZERO+ PARAMETER ( ZERO = 0.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER NALF, NBET, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ DOUBLE PRECISION A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), B( NMAX, NMAX ),+ $ BB( NMAX*NMAX ), BET( NBET ), BS( NMAX*NMAX ),+ $ C( NMAX, NMAX ), CC( NMAX*NMAX ),+ $ CS( NMAX*NMAX ), CT( NMAX ), G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ DOUBLE PRECISION ALPHA, ALS, BETA, BLS, ERR, ERRMAX+ INTEGER I, IA, IB, ICA, ICB, IK, IM, IN, K, KS, LAA,+ $ LBB, LCC, LDA, LDAS, LDB, LDBS, LDC, LDCS, M,+ $ MA, MB, MS, N, NA, NARGS, NB, NC, NS+ LOGICAL NULL, RESET, SAME, TRANA, TRANB+ CHARACTER*1 TRANAS, TRANBS, TRANSA, TRANSB+ CHARACTER*3 ICH+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LDE, LDERES+ EXTERNAL LDE, LDERES+* .. External Subroutines ..+ EXTERNAL DGEMM, DMAKE, DMMCH+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'NTC'/+* .. Executable Statements ..+*+ NARGS = 13+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 110 IM = 1, NIDIM+ M = IDIM( IM )+*+ DO 100 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDC to 1 more than minimum value if room.+ LDC = M+ IF( LDC.LT.NMAX )+ $ LDC = LDC + 1+* Skip tests if not enough room.+ IF( LDC.GT.NMAX )+ $ GO TO 100+ LCC = LDC*N+ NULL = N.LE.0.OR.M.LE.0+*+ DO 90 IK = 1, NIDIM+ K = IDIM( IK )+*+ DO 80 ICA = 1, 3+ TRANSA = ICH( ICA: ICA )+ TRANA = TRANSA.EQ.'T'.OR.TRANSA.EQ.'C'+*+ IF( TRANA )THEN+ MA = K+ NA = M+ ELSE+ MA = M+ NA = K+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = MA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 80+ LAA = LDA*NA+*+* Generate the matrix A.+*+ CALL DMAKE( 'GE', ' ', ' ', MA, NA, A, NMAX, AA, LDA,+ $ RESET, ZERO )+*+ DO 70 ICB = 1, 3+ TRANSB = ICH( ICB: ICB )+ TRANB = TRANSB.EQ.'T'.OR.TRANSB.EQ.'C'+*+ IF( TRANB )THEN+ MB = N+ NB = K+ ELSE+ MB = K+ NB = N+ END IF+* Set LDB to 1 more than minimum value if room.+ LDB = MB+ IF( LDB.LT.NMAX )+ $ LDB = LDB + 1+* Skip tests if not enough room.+ IF( LDB.GT.NMAX )+ $ GO TO 70+ LBB = LDB*NB+*+* Generate the matrix B.+*+ CALL DMAKE( 'GE', ' ', ' ', MB, NB, B, NMAX, BB,+ $ LDB, RESET, ZERO )+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the matrix C.+*+ CALL DMAKE( 'GE', ' ', ' ', M, N, C, NMAX,+ $ CC, LDC, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ TRANAS = TRANSA+ TRANBS = TRANSB+ MS = M+ NS = N+ KS = K+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LBB+ BS( I ) = BB( I )+ 20 CONTINUE+ LDBS = LDB+ BLS = BETA+ DO 30 I = 1, LCC+ CS( I ) = CC( I )+ 30 CONTINUE+ LDCS = LDC+*+* Call the subroutine.+*+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ TRANSA, TRANSB, M, N, K, ALPHA, LDA, LDB,+ $ BETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL DGEMM( TRANSA, TRANSB, M, N, K, ALPHA,+ $ AA, LDA, BB, LDB, BETA, CC, LDC )+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9994 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = TRANSA.EQ.TRANAS+ ISAME( 2 ) = TRANSB.EQ.TRANBS+ ISAME( 3 ) = MS.EQ.M+ ISAME( 4 ) = NS.EQ.N+ ISAME( 5 ) = KS.EQ.K+ ISAME( 6 ) = ALS.EQ.ALPHA+ ISAME( 7 ) = LDE( AS, AA, LAA )+ ISAME( 8 ) = LDAS.EQ.LDA+ ISAME( 9 ) = LDE( BS, BB, LBB )+ ISAME( 10 ) = LDBS.EQ.LDB+ ISAME( 11 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 12 ) = LDE( CS, CC, LCC )+ ELSE+ ISAME( 12 ) = LDERES( 'GE', ' ', M, N, CS,+ $ CC, LDC )+ END IF+ ISAME( 13 ) = LDCS.EQ.LDC+*+* If data was incorrectly changed, report+* and return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result.+*+ CALL DMMCH( TRANSA, TRANSB, M, N, K,+ $ ALPHA, A, NMAX, B, NMAX, BETA,+ $ C, NMAX, CT, G, CC, LDC, EPS,+ $ ERR, FATAL, NOUT, .TRUE. )+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 120+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9995 )NC, SNAME, TRANSA, TRANSB, M, N, K,+ $ ALPHA, LDA, LDB, BETA, LDC+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',''', A1, ''',',+ $ 3( I3, ',' ), F4.1, ', A,', I3, ', B,', I3, ',', F4.1, ', ',+ $ 'C,', I3, ').' )+ 9994 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of DCHK1.+*+ END+ SUBROUTINE DCHK2( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET, NMAX,+ $ A, AA, AS, B, BB, BS, C, CC, CS, CT, G )+*+* Tests DSYMM.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ DOUBLE PRECISION ZERO+ PARAMETER ( ZERO = 0.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER NALF, NBET, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ DOUBLE PRECISION A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), B( NMAX, NMAX ),+ $ BB( NMAX*NMAX ), BET( NBET ), BS( NMAX*NMAX ),+ $ C( NMAX, NMAX ), CC( NMAX*NMAX ),+ $ CS( NMAX*NMAX ), CT( NMAX ), G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ DOUBLE PRECISION ALPHA, ALS, BETA, BLS, ERR, ERRMAX+ INTEGER I, IA, IB, ICS, ICU, IM, IN, LAA, LBB, LCC,+ $ LDA, LDAS, LDB, LDBS, LDC, LDCS, M, MS, N, NA,+ $ NARGS, NC, NS+ LOGICAL LEFT, NULL, RESET, SAME+ CHARACTER*1 SIDE, SIDES, UPLO, UPLOS+ CHARACTER*2 ICHS, ICHU+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LDE, LDERES+ EXTERNAL LDE, LDERES+* .. External Subroutines ..+ EXTERNAL DMAKE, DMMCH, DSYMM+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHS/'LR'/, ICHU/'UL'/+* .. Executable Statements ..+*+ NARGS = 12+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 100 IM = 1, NIDIM+ M = IDIM( IM )+*+ DO 90 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDC to 1 more than minimum value if room.+ LDC = M+ IF( LDC.LT.NMAX )+ $ LDC = LDC + 1+* Skip tests if not enough room.+ IF( LDC.GT.NMAX )+ $ GO TO 90+ LCC = LDC*N+ NULL = N.LE.0.OR.M.LE.0+*+* Set LDB to 1 more than minimum value if room.+ LDB = M+ IF( LDB.LT.NMAX )+ $ LDB = LDB + 1+* Skip tests if not enough room.+ IF( LDB.GT.NMAX )+ $ GO TO 90+ LBB = LDB*N+*+* Generate the matrix B.+*+ CALL DMAKE( 'GE', ' ', ' ', M, N, B, NMAX, BB, LDB, RESET,+ $ ZERO )+*+ DO 80 ICS = 1, 2+ SIDE = ICHS( ICS: ICS )+ LEFT = SIDE.EQ.'L'+*+ IF( LEFT )THEN+ NA = M+ ELSE+ NA = N+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = NA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 80+ LAA = LDA*NA+*+ DO 70 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+*+* Generate the symmetric matrix A.+*+ CALL DMAKE( 'SY', UPLO, ' ', NA, NA, A, NMAX, AA, LDA,+ $ RESET, ZERO )+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the matrix C.+*+ CALL DMAKE( 'GE', ' ', ' ', M, N, C, NMAX, CC,+ $ LDC, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ SIDES = SIDE+ UPLOS = UPLO+ MS = M+ NS = N+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LBB+ BS( I ) = BB( I )+ 20 CONTINUE+ LDBS = LDB+ BLS = BETA+ DO 30 I = 1, LCC+ CS( I ) = CC( I )+ 30 CONTINUE+ LDCS = LDC+*+* Call the subroutine.+*+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME, SIDE,+ $ UPLO, M, N, ALPHA, LDA, LDB, BETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL DSYMM( SIDE, UPLO, M, N, ALPHA, AA, LDA,+ $ BB, LDB, BETA, CC, LDC )+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9994 )+ FATAL = .TRUE.+ GO TO 110+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = SIDES.EQ.SIDE+ ISAME( 2 ) = UPLOS.EQ.UPLO+ ISAME( 3 ) = MS.EQ.M+ ISAME( 4 ) = NS.EQ.N+ ISAME( 5 ) = ALS.EQ.ALPHA+ ISAME( 6 ) = LDE( AS, AA, LAA )+ ISAME( 7 ) = LDAS.EQ.LDA+ ISAME( 8 ) = LDE( BS, BB, LBB )+ ISAME( 9 ) = LDBS.EQ.LDB+ ISAME( 10 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 11 ) = LDE( CS, CC, LCC )+ ELSE+ ISAME( 11 ) = LDERES( 'GE', ' ', M, N, CS,+ $ CC, LDC )+ END IF+ ISAME( 12 ) = LDCS.EQ.LDC+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 110+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result.+*+ IF( LEFT )THEN+ CALL DMMCH( 'N', 'N', M, N, M, ALPHA, A,+ $ NMAX, B, NMAX, BETA, C, NMAX,+ $ CT, G, CC, LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ELSE+ CALL DMMCH( 'N', 'N', M, N, N, ALPHA, B,+ $ NMAX, A, NMAX, BETA, C, NMAX,+ $ CT, G, CC, LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 110+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 120+*+ 110 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9995 )NC, SNAME, SIDE, UPLO, M, N, ALPHA, LDA,+ $ LDB, BETA, LDC+*+ 120 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(', 2( '''', A1, ''',' ), 2( I3, ',' ),+ $ F4.1, ', A,', I3, ', B,', I3, ',', F4.1, ', C,', I3, ') ',+ $ ' .' )+ 9994 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of DCHK2.+*+ END+ SUBROUTINE DCHK3( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NMAX, A, AA, AS,+ $ B, BB, BS, CT, G, C )+*+* Tests DTRMM and DTRSM.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ DOUBLE PRECISION ZERO, ONE+ PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER NALF, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ DOUBLE PRECISION A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), B( NMAX, NMAX ),+ $ BB( NMAX*NMAX ), BS( NMAX*NMAX ),+ $ C( NMAX, NMAX ), CT( NMAX ), G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ DOUBLE PRECISION ALPHA, ALS, ERR, ERRMAX+ INTEGER I, IA, ICD, ICS, ICT, ICU, IM, IN, J, LAA, LBB,+ $ LDA, LDAS, LDB, LDBS, M, MS, N, NA, NARGS, NC,+ $ NS+ LOGICAL LEFT, NULL, RESET, SAME+ CHARACTER*1 DIAG, DIAGS, SIDE, SIDES, TRANAS, TRANSA, UPLO,+ $ UPLOS+ CHARACTER*2 ICHD, ICHS, ICHU+ CHARACTER*3 ICHT+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LDE, LDERES+ EXTERNAL LDE, LDERES+* .. External Subroutines ..+ EXTERNAL DMAKE, DMMCH, DTRMM, DTRSM+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHU/'UL'/, ICHT/'NTC'/, ICHD/'UN'/, ICHS/'LR'/+* .. Executable Statements ..+*+ NARGS = 11+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+* Set up zero matrix for DMMCH.+ DO 20 J = 1, NMAX+ DO 10 I = 1, NMAX+ C( I, J ) = ZERO+ 10 CONTINUE+ 20 CONTINUE+*+ DO 140 IM = 1, NIDIM+ M = IDIM( IM )+*+ DO 130 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDB to 1 more than minimum value if room.+ LDB = M+ IF( LDB.LT.NMAX )+ $ LDB = LDB + 1+* Skip tests if not enough room.+ IF( LDB.GT.NMAX )+ $ GO TO 130+ LBB = LDB*N+ NULL = M.LE.0.OR.N.LE.0+*+ DO 120 ICS = 1, 2+ SIDE = ICHS( ICS: ICS )+ LEFT = SIDE.EQ.'L'+ IF( LEFT )THEN+ NA = M+ ELSE+ NA = N+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = NA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 130+ LAA = LDA*NA+*+ DO 110 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+*+ DO 100 ICT = 1, 3+ TRANSA = ICHT( ICT: ICT )+*+ DO 90 ICD = 1, 2+ DIAG = ICHD( ICD: ICD )+*+ DO 80 IA = 1, NALF+ ALPHA = ALF( IA )+*+* Generate the matrix A.+*+ CALL DMAKE( 'TR', UPLO, DIAG, NA, NA, A,+ $ NMAX, AA, LDA, RESET, ZERO )+*+* Generate the matrix B.+*+ CALL DMAKE( 'GE', ' ', ' ', M, N, B, NMAX,+ $ BB, LDB, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ SIDES = SIDE+ UPLOS = UPLO+ TRANAS = TRANSA+ DIAGS = DIAG+ MS = M+ NS = N+ ALS = ALPHA+ DO 30 I = 1, LAA+ AS( I ) = AA( I )+ 30 CONTINUE+ LDAS = LDA+ DO 40 I = 1, LBB+ BS( I ) = BB( I )+ 40 CONTINUE+ LDBS = LDB+*+* Call the subroutine.+*+ IF( SNAME( 4: 5 ).EQ.'MM' )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA,+ $ LDA, LDB+ IF( REWI )+ $ REWIND NTRA+ CALL DTRMM( SIDE, UPLO, TRANSA, DIAG, M,+ $ N, ALPHA, AA, LDA, BB, LDB )+ ELSE IF( SNAME( 4: 5 ).EQ.'SM' )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA,+ $ LDA, LDB+ IF( REWI )+ $ REWIND NTRA+ CALL DTRSM( SIDE, UPLO, TRANSA, DIAG, M,+ $ N, ALPHA, AA, LDA, BB, LDB )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9994 )+ FATAL = .TRUE.+ GO TO 150+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = SIDES.EQ.SIDE+ ISAME( 2 ) = UPLOS.EQ.UPLO+ ISAME( 3 ) = TRANAS.EQ.TRANSA+ ISAME( 4 ) = DIAGS.EQ.DIAG+ ISAME( 5 ) = MS.EQ.M+ ISAME( 6 ) = NS.EQ.N+ ISAME( 7 ) = ALS.EQ.ALPHA+ ISAME( 8 ) = LDE( AS, AA, LAA )+ ISAME( 9 ) = LDAS.EQ.LDA+ IF( NULL )THEN+ ISAME( 10 ) = LDE( BS, BB, LBB )+ ELSE+ ISAME( 10 ) = LDERES( 'GE', ' ', M, N, BS,+ $ BB, LDB )+ END IF+ ISAME( 11 ) = LDBS.EQ.LDB+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 50 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 50 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 150+ END IF+*+ IF( .NOT.NULL )THEN+ IF( SNAME( 4: 5 ).EQ.'MM' )THEN+*+* Check the result.+*+ IF( LEFT )THEN+ CALL DMMCH( TRANSA, 'N', M, N, M,+ $ ALPHA, A, NMAX, B, NMAX,+ $ ZERO, C, NMAX, CT, G,+ $ BB, LDB, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ELSE+ CALL DMMCH( 'N', TRANSA, M, N, N,+ $ ALPHA, B, NMAX, A, NMAX,+ $ ZERO, C, NMAX, CT, G,+ $ BB, LDB, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ END IF+ ELSE IF( SNAME( 4: 5 ).EQ.'SM' )THEN+*+* Compute approximation to original+* matrix.+*+ DO 70 J = 1, N+ DO 60 I = 1, M+ C( I, J ) = BB( I + ( J - 1 )*+ $ LDB )+ BB( I + ( J - 1 )*LDB ) = ALPHA*+ $ B( I, J )+ 60 CONTINUE+ 70 CONTINUE+*+ IF( LEFT )THEN+ CALL DMMCH( TRANSA, 'N', M, N, M,+ $ ONE, A, NMAX, C, NMAX,+ $ ZERO, B, NMAX, CT, G,+ $ BB, LDB, EPS, ERR,+ $ FATAL, NOUT, .FALSE. )+ ELSE+ CALL DMMCH( 'N', TRANSA, M, N, N,+ $ ONE, C, NMAX, A, NMAX,+ $ ZERO, B, NMAX, CT, G,+ $ BB, LDB, EPS, ERR,+ $ FATAL, NOUT, .FALSE. )+ END IF+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 150+ END IF+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+ 130 CONTINUE+*+ 140 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 160+*+ 150 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9995 )NC, SNAME, SIDE, UPLO, TRANSA, DIAG, M,+ $ N, ALPHA, LDA, LDB+*+ 160 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(', 4( '''', A1, ''',' ), 2( I3, ',' ),+ $ F4.1, ', A,', I3, ', B,', I3, ') .' )+ 9994 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of DCHK3.+*+ END+ SUBROUTINE DCHK4( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET, NMAX,+ $ A, AA, AS, B, BB, BS, C, CC, CS, CT, G )+*+* Tests DSYRK.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ DOUBLE PRECISION ZERO+ PARAMETER ( ZERO = 0.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER NALF, NBET, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ DOUBLE PRECISION A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), B( NMAX, NMAX ),+ $ BB( NMAX*NMAX ), BET( NBET ), BS( NMAX*NMAX ),+ $ C( NMAX, NMAX ), CC( NMAX*NMAX ),+ $ CS( NMAX*NMAX ), CT( NMAX ), G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ DOUBLE PRECISION ALPHA, ALS, BETA, BETS, ERR, ERRMAX+ INTEGER I, IA, IB, ICT, ICU, IK, IN, J, JC, JJ, K, KS,+ $ LAA, LCC, LDA, LDAS, LDC, LDCS, LJ, MA, N, NA,+ $ NARGS, NC, NS+ LOGICAL NULL, RESET, SAME, TRAN, UPPER+ CHARACTER*1 TRANS, TRANSS, UPLO, UPLOS+ CHARACTER*2 ICHU+ CHARACTER*3 ICHT+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LDE, LDERES+ EXTERNAL LDE, LDERES+* .. External Subroutines ..+ EXTERNAL DMAKE, DMMCH, DSYRK+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHT/'NTC'/, ICHU/'UL'/+* .. Executable Statements ..+*+ NARGS = 10+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 100 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDC to 1 more than minimum value if room.+ LDC = N+ IF( LDC.LT.NMAX )+ $ LDC = LDC + 1+* Skip tests if not enough room.+ IF( LDC.GT.NMAX )+ $ GO TO 100+ LCC = LDC*N+ NULL = N.LE.0+*+ DO 90 IK = 1, NIDIM+ K = IDIM( IK )+*+ DO 80 ICT = 1, 3+ TRANS = ICHT( ICT: ICT )+ TRAN = TRANS.EQ.'T'.OR.TRANS.EQ.'C'+ IF( TRAN )THEN+ MA = K+ NA = N+ ELSE+ MA = N+ NA = K+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = MA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 80+ LAA = LDA*NA+*+* Generate the matrix A.+*+ CALL DMAKE( 'GE', ' ', ' ', MA, NA, A, NMAX, AA, LDA,+ $ RESET, ZERO )+*+ DO 70 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+ UPPER = UPLO.EQ.'U'+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the matrix C.+*+ CALL DMAKE( 'SY', UPLO, ' ', N, N, C, NMAX, CC,+ $ LDC, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ TRANSS = TRANS+ NS = N+ KS = K+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ BETS = BETA+ DO 20 I = 1, LCC+ CS( I ) = CC( I )+ 20 CONTINUE+ LDCS = LDC+*+* Call the subroutine.+*+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, UPLO,+ $ TRANS, N, K, ALPHA, LDA, BETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL DSYRK( UPLO, TRANS, N, K, ALPHA, AA, LDA,+ $ BETA, CC, LDC )+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9993 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLOS.EQ.UPLO+ ISAME( 2 ) = TRANSS.EQ.TRANS+ ISAME( 3 ) = NS.EQ.N+ ISAME( 4 ) = KS.EQ.K+ ISAME( 5 ) = ALS.EQ.ALPHA+ ISAME( 6 ) = LDE( AS, AA, LAA )+ ISAME( 7 ) = LDAS.EQ.LDA+ ISAME( 8 ) = BETS.EQ.BETA+ IF( NULL )THEN+ ISAME( 9 ) = LDE( CS, CC, LCC )+ ELSE+ ISAME( 9 ) = LDERES( 'SY', UPLO, N, N, CS,+ $ CC, LDC )+ END IF+ ISAME( 10 ) = LDCS.EQ.LDC+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 30 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 30 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ JC = 1+ DO 40 J = 1, N+ IF( UPPER )THEN+ JJ = 1+ LJ = J+ ELSE+ JJ = J+ LJ = N - J + 1+ END IF+ IF( TRAN )THEN+ CALL DMMCH( 'T', 'N', LJ, 1, K, ALPHA,+ $ A( 1, JJ ), NMAX,+ $ A( 1, J ), NMAX, BETA,+ $ C( JJ, J ), NMAX, CT, G,+ $ CC( JC ), LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ELSE+ CALL DMMCH( 'N', 'T', LJ, 1, K, ALPHA,+ $ A( JJ, 1 ), NMAX,+ $ A( J, 1 ), NMAX, BETA,+ $ C( JJ, J ), NMAX, CT, G,+ $ CC( JC ), LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ END IF+ IF( UPPER )THEN+ JC = JC + LDC+ ELSE+ JC = JC + LDC + 1+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 110+ 40 CONTINUE+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 110 CONTINUE+ IF( N.GT.1 )+ $ WRITE( NOUT, FMT = 9995 )J+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, TRANS, N, K, ALPHA,+ $ LDA, BETA, LDC+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(', 2( '''', A1, ''',' ), 2( I3, ',' ),+ $ F4.1, ', A,', I3, ',', F4.1, ', C,', I3, ') .' )+ 9993 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of DCHK4.+*+ END+ SUBROUTINE DCHK5( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET, NMAX,+ $ AB, AA, AS, BB, BS, C, CC, CS, CT, G, W )+*+* Tests DSYR2K.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ DOUBLE PRECISION ZERO+ PARAMETER ( ZERO = 0.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER NALF, NBET, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ DOUBLE PRECISION AA( NMAX*NMAX ), AB( 2*NMAX*NMAX ),+ $ ALF( NALF ), AS( NMAX*NMAX ), BB( NMAX*NMAX ),+ $ BET( NBET ), BS( NMAX*NMAX ), C( NMAX, NMAX ),+ $ CC( NMAX*NMAX ), CS( NMAX*NMAX ), CT( NMAX ),+ $ G( NMAX ), W( 2*NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ DOUBLE PRECISION ALPHA, ALS, BETA, BETS, ERR, ERRMAX+ INTEGER I, IA, IB, ICT, ICU, IK, IN, J, JC, JJ, JJAB,+ $ K, KS, LAA, LBB, LCC, LDA, LDAS, LDB, LDBS,+ $ LDC, LDCS, LJ, MA, N, NA, NARGS, NC, NS+ LOGICAL NULL, RESET, SAME, TRAN, UPPER+ CHARACTER*1 TRANS, TRANSS, UPLO, UPLOS+ CHARACTER*2 ICHU+ CHARACTER*3 ICHT+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LDE, LDERES+ EXTERNAL LDE, LDERES+* .. External Subroutines ..+ EXTERNAL DMAKE, DMMCH, DSYR2K+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHT/'NTC'/, ICHU/'UL'/+* .. Executable Statements ..+*+ NARGS = 12+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 130 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDC to 1 more than minimum value if room.+ LDC = N+ IF( LDC.LT.NMAX )+ $ LDC = LDC + 1+* Skip tests if not enough room.+ IF( LDC.GT.NMAX )+ $ GO TO 130+ LCC = LDC*N+ NULL = N.LE.0+*+ DO 120 IK = 1, NIDIM+ K = IDIM( IK )+*+ DO 110 ICT = 1, 3+ TRANS = ICHT( ICT: ICT )+ TRAN = TRANS.EQ.'T'.OR.TRANS.EQ.'C'+ IF( TRAN )THEN+ MA = K+ NA = N+ ELSE+ MA = N+ NA = K+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = MA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 110+ LAA = LDA*NA+*+* Generate the matrix A.+*+ IF( TRAN )THEN+ CALL DMAKE( 'GE', ' ', ' ', MA, NA, AB, 2*NMAX, AA,+ $ LDA, RESET, ZERO )+ ELSE+ CALL DMAKE( 'GE', ' ', ' ', MA, NA, AB, NMAX, AA, LDA,+ $ RESET, ZERO )+ END IF+*+* Generate the matrix B.+*+ LDB = LDA+ LBB = LAA+ IF( TRAN )THEN+ CALL DMAKE( 'GE', ' ', ' ', MA, NA, AB( K + 1 ),+ $ 2*NMAX, BB, LDB, RESET, ZERO )+ ELSE+ CALL DMAKE( 'GE', ' ', ' ', MA, NA, AB( K*NMAX + 1 ),+ $ NMAX, BB, LDB, RESET, ZERO )+ END IF+*+ DO 100 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+ UPPER = UPLO.EQ.'U'+*+ DO 90 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 80 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the matrix C.+*+ CALL DMAKE( 'SY', UPLO, ' ', N, N, C, NMAX, CC,+ $ LDC, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ TRANSS = TRANS+ NS = N+ KS = K+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LBB+ BS( I ) = BB( I )+ 20 CONTINUE+ LDBS = LDB+ BETS = BETA+ DO 30 I = 1, LCC+ CS( I ) = CC( I )+ 30 CONTINUE+ LDCS = LDC+*+* Call the subroutine.+*+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, UPLO,+ $ TRANS, N, K, ALPHA, LDA, LDB, BETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL DSYR2K( UPLO, TRANS, N, K, ALPHA, AA, LDA,+ $ BB, LDB, BETA, CC, LDC )+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9993 )+ FATAL = .TRUE.+ GO TO 150+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLOS.EQ.UPLO+ ISAME( 2 ) = TRANSS.EQ.TRANS+ ISAME( 3 ) = NS.EQ.N+ ISAME( 4 ) = KS.EQ.K+ ISAME( 5 ) = ALS.EQ.ALPHA+ ISAME( 6 ) = LDE( AS, AA, LAA )+ ISAME( 7 ) = LDAS.EQ.LDA+ ISAME( 8 ) = LDE( BS, BB, LBB )+ ISAME( 9 ) = LDBS.EQ.LDB+ ISAME( 10 ) = BETS.EQ.BETA+ IF( NULL )THEN+ ISAME( 11 ) = LDE( CS, CC, LCC )+ ELSE+ ISAME( 11 ) = LDERES( 'SY', UPLO, N, N, CS,+ $ CC, LDC )+ END IF+ ISAME( 12 ) = LDCS.EQ.LDC+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 150+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ JJAB = 1+ JC = 1+ DO 70 J = 1, N+ IF( UPPER )THEN+ JJ = 1+ LJ = J+ ELSE+ JJ = J+ LJ = N - J + 1+ END IF+ IF( TRAN )THEN+ DO 50 I = 1, K+ W( I ) = AB( ( J - 1 )*2*NMAX + K ++ $ I )+ W( K + I ) = AB( ( J - 1 )*2*NMAX ++ $ I )+ 50 CONTINUE+ CALL DMMCH( 'T', 'N', LJ, 1, 2*K,+ $ ALPHA, AB( JJAB ), 2*NMAX,+ $ W, 2*NMAX, BETA,+ $ C( JJ, J ), NMAX, CT, G,+ $ CC( JC ), LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ELSE+ DO 60 I = 1, K+ W( I ) = AB( ( K + I - 1 )*NMAX ++ $ J )+ W( K + I ) = AB( ( I - 1 )*NMAX ++ $ J )+ 60 CONTINUE+ CALL DMMCH( 'N', 'N', LJ, 1, 2*K,+ $ ALPHA, AB( JJ ), NMAX, W,+ $ 2*NMAX, BETA, C( JJ, J ),+ $ NMAX, CT, G, CC( JC ), LDC,+ $ EPS, ERR, FATAL, NOUT,+ $ .TRUE. )+ END IF+ IF( UPPER )THEN+ JC = JC + LDC+ ELSE+ JC = JC + LDC + 1+ IF( TRAN )+ $ JJAB = JJAB + 2*NMAX+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 140+ 70 CONTINUE+ END IF+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+ 130 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 160+*+ 140 CONTINUE+ IF( N.GT.1 )+ $ WRITE( NOUT, FMT = 9995 )J+*+ 150 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, TRANS, N, K, ALPHA,+ $ LDA, LDB, BETA, LDC+*+ 160 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(', 2( '''', A1, ''',' ), 2( I3, ',' ),+ $ F4.1, ', A,', I3, ', B,', I3, ',', F4.1, ', C,', I3, ') ',+ $ ' .' )+ 9993 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of DCHK5.+*+ END+ SUBROUTINE DCHKE( ISNUM, SRNAMT, NOUT )+*+* Tests the error exits from the Level 3 Blas.+* Requires a special version of the error-handling routine XERBLA.+* ALPHA, BETA, A, B and C should not need to be defined.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER ISNUM, NOUT+ CHARACTER*6 SRNAMT+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Local Scalars ..+ DOUBLE PRECISION ALPHA, BETA+* .. Local Arrays ..+ DOUBLE PRECISION A( 2, 1 ), B( 2, 1 ), C( 2, 1 )+* .. External Subroutines ..+ EXTERNAL CHKXER, DGEMM, DSYMM, DSYR2K, DSYRK, DTRMM,+ $ DTRSM+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Executable Statements ..+* OK is set to .FALSE. by the special version of XERBLA or by CHKXER+* if anything is wrong.+ OK = .TRUE.+* LERR is set to .TRUE. by the special version of XERBLA each time+* it is called, and is then tested and re-set by CHKXER.+ LERR = .FALSE.+ GO TO ( 10, 20, 30, 40, 50, 60 )ISNUM+ 10 INFOT = 1+ CALL DGEMM( '/', 'N', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 1+ CALL DGEMM( '/', 'T', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DGEMM( 'N', '/', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DGEMM( 'T', '/', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DGEMM( 'N', 'N', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DGEMM( 'N', 'T', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DGEMM( 'T', 'N', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DGEMM( 'T', 'T', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DGEMM( 'N', 'N', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DGEMM( 'N', 'T', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DGEMM( 'T', 'N', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DGEMM( 'T', 'T', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DGEMM( 'N', 'N', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DGEMM( 'N', 'T', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DGEMM( 'T', 'N', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DGEMM( 'T', 'T', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL DGEMM( 'N', 'N', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL DGEMM( 'N', 'T', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL DGEMM( 'T', 'N', 0, 0, 2, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL DGEMM( 'T', 'T', 0, 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL DGEMM( 'N', 'N', 0, 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL DGEMM( 'T', 'N', 0, 0, 2, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL DGEMM( 'N', 'T', 0, 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL DGEMM( 'T', 'T', 0, 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL DGEMM( 'N', 'N', 2, 0, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL DGEMM( 'N', 'T', 2, 0, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL DGEMM( 'T', 'N', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL DGEMM( 'T', 'T', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 70+ 20 INFOT = 1+ CALL DSYMM( '/', 'U', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DSYMM( 'L', '/', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DSYMM( 'L', 'U', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DSYMM( 'R', 'U', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DSYMM( 'L', 'L', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DSYMM( 'R', 'L', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DSYMM( 'L', 'U', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DSYMM( 'R', 'U', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DSYMM( 'L', 'L', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DSYMM( 'R', 'L', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DSYMM( 'L', 'U', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DSYMM( 'R', 'U', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DSYMM( 'L', 'L', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DSYMM( 'R', 'L', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DSYMM( 'L', 'U', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DSYMM( 'R', 'U', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DSYMM( 'L', 'L', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DSYMM( 'R', 'L', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL DSYMM( 'L', 'U', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL DSYMM( 'R', 'U', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL DSYMM( 'L', 'L', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL DSYMM( 'R', 'L', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 70+ 30 INFOT = 1+ CALL DTRMM( '/', 'U', 'N', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DTRMM( 'L', '/', 'N', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DTRMM( 'L', 'U', '/', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DTRMM( 'L', 'U', 'N', '/', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTRMM( 'L', 'U', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTRMM( 'L', 'U', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTRMM( 'R', 'U', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTRMM( 'R', 'U', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTRMM( 'L', 'L', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTRMM( 'L', 'L', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTRMM( 'R', 'L', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTRMM( 'R', 'L', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRMM( 'L', 'U', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRMM( 'L', 'U', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRMM( 'R', 'U', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRMM( 'R', 'U', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRMM( 'L', 'L', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRMM( 'L', 'L', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRMM( 'R', 'L', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRMM( 'R', 'L', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTRMM( 'L', 'U', 'N', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTRMM( 'L', 'U', 'T', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTRMM( 'R', 'U', 'N', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTRMM( 'R', 'U', 'T', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTRMM( 'L', 'L', 'N', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTRMM( 'L', 'L', 'T', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTRMM( 'R', 'L', 'N', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTRMM( 'R', 'L', 'T', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DTRMM( 'L', 'U', 'N', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DTRMM( 'L', 'U', 'T', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DTRMM( 'R', 'U', 'N', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DTRMM( 'R', 'U', 'T', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DTRMM( 'L', 'L', 'N', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DTRMM( 'L', 'L', 'T', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DTRMM( 'R', 'L', 'N', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DTRMM( 'R', 'L', 'T', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 70+ 40 INFOT = 1+ CALL DTRSM( '/', 'U', 'N', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DTRSM( 'L', '/', 'N', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DTRSM( 'L', 'U', '/', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DTRSM( 'L', 'U', 'N', '/', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTRSM( 'L', 'U', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTRSM( 'L', 'U', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTRSM( 'R', 'U', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTRSM( 'R', 'U', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTRSM( 'L', 'L', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTRSM( 'L', 'L', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTRSM( 'R', 'L', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL DTRSM( 'R', 'L', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRSM( 'L', 'U', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRSM( 'L', 'U', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRSM( 'R', 'U', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRSM( 'R', 'U', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRSM( 'L', 'L', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRSM( 'L', 'L', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRSM( 'R', 'L', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL DTRSM( 'R', 'L', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTRSM( 'L', 'U', 'N', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTRSM( 'L', 'U', 'T', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTRSM( 'R', 'U', 'N', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTRSM( 'R', 'U', 'T', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTRSM( 'L', 'L', 'N', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTRSM( 'L', 'L', 'T', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTRSM( 'R', 'L', 'N', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DTRSM( 'R', 'L', 'T', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DTRSM( 'L', 'U', 'N', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DTRSM( 'L', 'U', 'T', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DTRSM( 'R', 'U', 'N', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DTRSM( 'R', 'U', 'T', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DTRSM( 'L', 'L', 'N', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DTRSM( 'L', 'L', 'T', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DTRSM( 'R', 'L', 'N', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL DTRSM( 'R', 'L', 'T', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 70+ 50 INFOT = 1+ CALL DSYRK( '/', 'N', 0, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DSYRK( 'U', '/', 0, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DSYRK( 'U', 'N', -1, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DSYRK( 'U', 'T', -1, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DSYRK( 'L', 'N', -1, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DSYRK( 'L', 'T', -1, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DSYRK( 'U', 'N', 0, -1, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DSYRK( 'U', 'T', 0, -1, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DSYRK( 'L', 'N', 0, -1, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DSYRK( 'L', 'T', 0, -1, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DSYRK( 'U', 'N', 2, 0, ALPHA, A, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DSYRK( 'U', 'T', 0, 2, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DSYRK( 'L', 'N', 2, 0, ALPHA, A, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DSYRK( 'L', 'T', 0, 2, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL DSYRK( 'U', 'N', 2, 0, ALPHA, A, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL DSYRK( 'U', 'T', 2, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL DSYRK( 'L', 'N', 2, 0, ALPHA, A, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL DSYRK( 'L', 'T', 2, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 70+ 60 INFOT = 1+ CALL DSYR2K( '/', 'N', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL DSYR2K( 'U', '/', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DSYR2K( 'U', 'N', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DSYR2K( 'U', 'T', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DSYR2K( 'L', 'N', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL DSYR2K( 'L', 'T', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DSYR2K( 'U', 'N', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DSYR2K( 'U', 'T', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DSYR2K( 'L', 'N', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL DSYR2K( 'L', 'T', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DSYR2K( 'U', 'N', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DSYR2K( 'U', 'T', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DSYR2K( 'L', 'N', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL DSYR2K( 'L', 'T', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DSYR2K( 'U', 'N', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DSYR2K( 'U', 'T', 0, 2, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DSYR2K( 'L', 'N', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL DSYR2K( 'L', 'T', 0, 2, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL DSYR2K( 'U', 'N', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL DSYR2K( 'U', 'T', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL DSYR2K( 'L', 'N', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL DSYR2K( 'L', 'T', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+*+ 70 IF( OK )THEN+ WRITE( NOUT, FMT = 9999 )SRNAMT+ ELSE+ WRITE( NOUT, FMT = 9998 )SRNAMT+ END IF+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE TESTS OF ERROR-EXITS' )+ 9998 FORMAT( ' ******* ', A6, ' FAILED THE TESTS OF ERROR-EXITS *****',+ $ '**' )+*+* End of DCHKE.+*+ END+ SUBROUTINE DMAKE( TYPE, UPLO, DIAG, M, N, A, NMAX, AA, LDA, RESET,+ $ TRANSL )+*+* Generates values for an M by N matrix A.+* Stores the values in the array AA in the data structure required+* by the routine, with unwanted elements set to rogue value.+*+* TYPE is 'GE', 'SY' or 'TR'.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ DOUBLE PRECISION ZERO, ONE+ PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )+ DOUBLE PRECISION ROGUE+ PARAMETER ( ROGUE = -1.0D10 )+* .. Scalar Arguments ..+ DOUBLE PRECISION TRANSL+ INTEGER LDA, M, N, NMAX+ LOGICAL RESET+ CHARACTER*1 DIAG, UPLO+ CHARACTER*2 TYPE+* .. Array Arguments ..+ DOUBLE PRECISION A( NMAX, * ), AA( * )+* .. Local Scalars ..+ INTEGER I, IBEG, IEND, J+ LOGICAL GEN, LOWER, SYM, TRI, UNIT, UPPER+* .. External Functions ..+ DOUBLE PRECISION DBEG+ EXTERNAL DBEG+* .. Executable Statements ..+ GEN = TYPE.EQ.'GE'+ SYM = TYPE.EQ.'SY'+ TRI = TYPE.EQ.'TR'+ UPPER = ( SYM.OR.TRI ).AND.UPLO.EQ.'U'+ LOWER = ( SYM.OR.TRI ).AND.UPLO.EQ.'L'+ UNIT = TRI.AND.DIAG.EQ.'U'+*+* Generate data in array A.+*+ DO 20 J = 1, N+ DO 10 I = 1, M+ IF( GEN.OR.( UPPER.AND.I.LE.J ).OR.( LOWER.AND.I.GE.J ) )+ $ THEN+ A( I, J ) = DBEG( RESET ) + TRANSL+ IF( I.NE.J )THEN+* Set some elements to zero+ IF( N.GT.3.AND.J.EQ.N/2 )+ $ A( I, J ) = ZERO+ IF( SYM )THEN+ A( J, I ) = A( I, J )+ ELSE IF( TRI )THEN+ A( J, I ) = ZERO+ END IF+ END IF+ END IF+ 10 CONTINUE+ IF( TRI )+ $ A( J, J ) = A( J, J ) + ONE+ IF( UNIT )+ $ A( J, J ) = ONE+ 20 CONTINUE+*+* Store elements in array AS in data structure required by routine.+*+ IF( TYPE.EQ.'GE' )THEN+ DO 50 J = 1, N+ DO 30 I = 1, M+ AA( I + ( J - 1 )*LDA ) = A( I, J )+ 30 CONTINUE+ DO 40 I = M + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 40 CONTINUE+ 50 CONTINUE+ ELSE IF( TYPE.EQ.'SY'.OR.TYPE.EQ.'TR' )THEN+ DO 90 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IF( UNIT )THEN+ IEND = J - 1+ ELSE+ IEND = J+ END IF+ ELSE+ IF( UNIT )THEN+ IBEG = J + 1+ ELSE+ IBEG = J+ END IF+ IEND = N+ END IF+ DO 60 I = 1, IBEG - 1+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 60 CONTINUE+ DO 70 I = IBEG, IEND+ AA( I + ( J - 1 )*LDA ) = A( I, J )+ 70 CONTINUE+ DO 80 I = IEND + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 80 CONTINUE+ 90 CONTINUE+ END IF+ RETURN+*+* End of DMAKE.+*+ END+ SUBROUTINE DMMCH( TRANSA, TRANSB, M, N, KK, ALPHA, A, LDA, B, LDB,+ $ BETA, C, LDC, CT, G, CC, LDCC, EPS, ERR, FATAL,+ $ NOUT, MV )+*+* Checks the results of the computational tests.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ DOUBLE PRECISION ZERO, ONE+ PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION ALPHA, BETA, EPS, ERR+ INTEGER KK, LDA, LDB, LDC, LDCC, M, N, NOUT+ LOGICAL FATAL, MV+ CHARACTER*1 TRANSA, TRANSB+* .. Array Arguments ..+ DOUBLE PRECISION A( LDA, * ), B( LDB, * ), C( LDC, * ),+ $ CC( LDCC, * ), CT( * ), G( * )+* .. Local Scalars ..+ DOUBLE PRECISION ERRI+ INTEGER I, J, K+ LOGICAL TRANA, TRANB+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, SQRT+* .. Executable Statements ..+ TRANA = TRANSA.EQ.'T'.OR.TRANSA.EQ.'C'+ TRANB = TRANSB.EQ.'T'.OR.TRANSB.EQ.'C'+*+* Compute expected result, one column at a time, in CT using data+* in A, B and C.+* Compute gauges in G.+*+ DO 120 J = 1, N+*+ DO 10 I = 1, M+ CT( I ) = ZERO+ G( I ) = ZERO+ 10 CONTINUE+ IF( .NOT.TRANA.AND..NOT.TRANB )THEN+ DO 30 K = 1, KK+ DO 20 I = 1, M+ CT( I ) = CT( I ) + A( I, K )*B( K, J )+ G( I ) = G( I ) + ABS( A( I, K ) )*ABS( B( K, J ) )+ 20 CONTINUE+ 30 CONTINUE+ ELSE IF( TRANA.AND..NOT.TRANB )THEN+ DO 50 K = 1, KK+ DO 40 I = 1, M+ CT( I ) = CT( I ) + A( K, I )*B( K, J )+ G( I ) = G( I ) + ABS( A( K, I ) )*ABS( B( K, J ) )+ 40 CONTINUE+ 50 CONTINUE+ ELSE IF( .NOT.TRANA.AND.TRANB )THEN+ DO 70 K = 1, KK+ DO 60 I = 1, M+ CT( I ) = CT( I ) + A( I, K )*B( J, K )+ G( I ) = G( I ) + ABS( A( I, K ) )*ABS( B( J, K ) )+ 60 CONTINUE+ 70 CONTINUE+ ELSE IF( TRANA.AND.TRANB )THEN+ DO 90 K = 1, KK+ DO 80 I = 1, M+ CT( I ) = CT( I ) + A( K, I )*B( J, K )+ G( I ) = G( I ) + ABS( A( K, I ) )*ABS( B( J, K ) )+ 80 CONTINUE+ 90 CONTINUE+ END IF+ DO 100 I = 1, M+ CT( I ) = ALPHA*CT( I ) + BETA*C( I, J )+ G( I ) = ABS( ALPHA )*G( I ) + ABS( BETA )*ABS( C( I, J ) )+ 100 CONTINUE+*+* Compute the error ratio for this result.+*+ ERR = ZERO+ DO 110 I = 1, M+ ERRI = ABS( CT( I ) - CC( I, J ) )/EPS+ IF( G( I ).NE.ZERO )+ $ ERRI = ERRI/G( I )+ ERR = MAX( ERR, ERRI )+ IF( ERR*SQRT( EPS ).GE.ONE )+ $ GO TO 130+ 110 CONTINUE+*+ 120 CONTINUE+*+* If the loop completes, all results are at least half accurate.+ GO TO 150+*+* Report fatal error.+*+ 130 FATAL = .TRUE.+ WRITE( NOUT, FMT = 9999 )+ DO 140 I = 1, M+ IF( MV )THEN+ WRITE( NOUT, FMT = 9998 )I, CT( I ), CC( I, J )+ ELSE+ WRITE( NOUT, FMT = 9998 )I, CC( I, J ), CT( I )+ END IF+ 140 CONTINUE+ IF( N.GT.1 )+ $ WRITE( NOUT, FMT = 9997 )J+*+ 150 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ******* FATAL ERROR - COMPUTED RESULT IS LESS THAN HAL',+ $ 'F ACCURATE *******', /' EXPECTED RESULT COMPU',+ $ 'TED RESULT' )+ 9998 FORMAT( 1X, I7, 2G18.6 )+ 9997 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+*+* End of DMMCH.+*+ END+ LOGICAL FUNCTION LDE( RI, RJ, LR )+*+* Tests if two arrays are identical.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER LR+* .. Array Arguments ..+ DOUBLE PRECISION RI( * ), RJ( * )+* .. Local Scalars ..+ INTEGER I+* .. Executable Statements ..+ DO 10 I = 1, LR+ IF( RI( I ).NE.RJ( I ) )+ $ GO TO 20+ 10 CONTINUE+ LDE = .TRUE.+ GO TO 30+ 20 CONTINUE+ LDE = .FALSE.+ 30 RETURN+*+* End of LDE.+*+ END+ LOGICAL FUNCTION LDERES( TYPE, UPLO, M, N, AA, AS, LDA )+*+* Tests if selected elements in two arrays are equal.+*+* TYPE is 'GE' or 'SY'.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER LDA, M, N+ CHARACTER*1 UPLO+ CHARACTER*2 TYPE+* .. Array Arguments ..+ DOUBLE PRECISION AA( LDA, * ), AS( LDA, * )+* .. Local Scalars ..+ INTEGER I, IBEG, IEND, J+ LOGICAL UPPER+* .. Executable Statements ..+ UPPER = UPLO.EQ.'U'+ IF( TYPE.EQ.'GE' )THEN+ DO 20 J = 1, N+ DO 10 I = M + 1, LDA+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 10 CONTINUE+ 20 CONTINUE+ ELSE IF( TYPE.EQ.'SY' )THEN+ DO 50 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IEND = J+ ELSE+ IBEG = J+ IEND = N+ END IF+ DO 30 I = 1, IBEG - 1+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 30 CONTINUE+ DO 40 I = IEND + 1, LDA+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 40 CONTINUE+ 50 CONTINUE+ END IF+*+ 60 CONTINUE+ LDERES = .TRUE.+ GO TO 80+ 70 CONTINUE+ LDERES = .FALSE.+ 80 RETURN+*+* End of LDERES.+*+ END+ DOUBLE PRECISION FUNCTION DBEG( RESET )+*+* Generates random numbers uniformly distributed between -0.5 and 0.5.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ LOGICAL RESET+* .. Local Scalars ..+ INTEGER I, IC, MI+* .. Save statement ..+ SAVE I, IC, MI+* .. Executable Statements ..+ IF( RESET )THEN+* Initialize local variables.+ MI = 891+ I = 7+ IC = 0+ RESET = .FALSE.+ END IF+*+* The sequence of values of I is bounded between 1 and 999.+* If initial I = 1,2,3,6,7 or 9, the period will be 50.+* If initial I = 4 or 8, the period will be 25.+* If initial I = 5, the period will be 10.+* IC is used to break up the period by skipping 1 value of I in 6.+*+ IC = IC + 1+ 10 I = I*MI+ I = I - 1000*( I/1000 )+ IF( IC.GE.5 )THEN+ IC = 0+ GO TO 10+ END IF+ DBEG = ( I - 500 )/1001.0D0+ RETURN+*+* End of DBEG.+*+ END+ DOUBLE PRECISION FUNCTION DDIFF( X, Y )+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ DOUBLE PRECISION X, Y+* .. Executable Statements ..+ DDIFF = X - Y+ RETURN+*+* End of DDIFF.+*+ END+ SUBROUTINE CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+*+* Tests whether XERBLA has detected an error when it should.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER INFOT, NOUT+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Executable Statements ..+ IF( .NOT.LERR )THEN+ WRITE( NOUT, FMT = 9999 )INFOT, SRNAMT+ OK = .FALSE.+ END IF+ LERR = .FALSE.+ RETURN+*+ 9999 FORMAT( ' ***** ILLEGAL VALUE OF PARAMETER NUMBER ', I2, ' NOT D',+ $ 'ETECTED BY ', A6, ' *****' )+*+* End of CHKXER.+*+ END+ SUBROUTINE XERBLA( SRNAME, INFO )+*+* This is a special version of XERBLA to be used only as part of+* the test program for testing error exits from the Level 3 BLAS+* routines.+*+* XERBLA is an error handler for the Level 3 BLAS routines.+*+* It is called by the Level 3 BLAS routines if an input parameter is+* invalid.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER INFO+ CHARACTER*6 SRNAME+* .. Scalars in Common ..+ INTEGER INFOT, NOUT+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUT, OK, LERR+ COMMON /SRNAMC/SRNAMT+* .. Executable Statements ..+ LERR = .TRUE.+ IF( INFO.NE.INFOT )THEN+ IF( INFOT.NE.0 )THEN+ WRITE( NOUT, FMT = 9999 )INFO, INFOT+ ELSE+ WRITE( NOUT, FMT = 9997 )INFO+ END IF+ OK = .FALSE.+ END IF+ IF( SRNAME.NE.SRNAMT )THEN+ WRITE( NOUT, FMT = 9998 )SRNAME, SRNAMT+ OK = .FALSE.+ END IF+ RETURN+*+ 9999 FORMAT( ' ******* XERBLA WAS CALLED WITH INFO = ', I6, ' INSTEAD',+ $ ' OF ', I2, ' *******' )+ 9998 FORMAT( ' ******* XERBLA WAS CALLED WITH SRNAME = ', A6, ' INSTE',+ $ 'AD OF ', A6, ' *******' )+ 9997 FORMAT( ' ******* XERBLA WAS CALLED WITH INFO = ', I6,+ $ ' *******' )+*+* End of XERBLA+*+ END+
+ eigen3/blas/testing/runblastest.sh view
@@ -0,0 +1,45 @@+#!/bin/bash++black='\E[30m'+red='\E[31m'+green='\E[32m'+yellow='\E[33m'+blue='\E[34m'+magenta='\E[35m'+cyan='\E[36m'+white='\E[37m'++if [ -f $2 ]; then+ data=$2+ if [ -f $1.summ ]; then rm $1.summ; fi+ if [ -f $1.snap ]; then rm $1.snap; fi+else+ data=$1+fi++if ! ./$1 < $data > /dev/null 2> .runtest.log ; then+ echo -e $red Test $1 failed: $black+ echo -e $blue+ cat .runtest.log+ echo -e $black+ exit 1+else+ if [ -f $1.summ ]; then+ if [ `grep "FATAL ERROR" $1.summ | wc -l` -gt 0 ]; then+ echo -e $red "Test $1 failed (FATAL ERROR, read the file $1.summ for details)" $black+ echo -e $blue+ cat .runtest.log+ echo -e $black+ exit 1;+ fi++ if [ `grep "FAILED THE TESTS OF ERROR-EXITS" $1.summ | wc -l` -gt 0 ]; then+ echo -e $red "Test $1 failed (FAILED THE TESTS OF ERROR-EXITS, read the file $1.summ for details)" $black+ echo -e $blue+ cat .runtest.log+ echo -e $black+ exit 1;+ fi + fi+ echo -e $green Test $1 passed$black+fi
+ eigen3/blas/testing/sblat1.f view
@@ -0,0 +1,1021 @@+*> \brief \b SBLAT1+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+* Definition:+* ===========+*+* PROGRAM SBLAT1+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> Test program for the REAL Level 1 BLAS.+*>+*> Based upon the original BLAS test routine together with:+*> F06EAF Example Program Text+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date April 2012+*+*> \ingroup single_blas_testing+*+* =====================================================================+ PROGRAM SBLAT1+*+* -- Reference BLAS test routine (version 3.4.1) --+* -- Reference BLAS is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* April 2012+*+* =====================================================================+*+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, N+ LOGICAL PASS+* .. Local Scalars ..+ REAL SFAC+ INTEGER IC+* .. External Subroutines ..+ EXTERNAL CHECK0, CHECK1, CHECK2, CHECK3, HEADER+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, PASS+* .. Data statements ..+ DATA SFAC/9.765625E-4/+* .. Executable Statements ..+ WRITE (NOUT,99999)+ DO 20 IC = 1, 13+ ICASE = IC+ CALL HEADER+*+* .. Initialize PASS, INCX, and INCY for a new case. ..+* .. the value 9999 for INCX or INCY will appear in the ..+* .. detailed output, if any, for cases that do not involve ..+* .. these parameters ..+*+ PASS = .TRUE.+ INCX = 9999+ INCY = 9999+ IF (ICASE.EQ.3 .OR. ICASE.EQ.11) THEN+ CALL CHECK0(SFAC)+ ELSE IF (ICASE.EQ.7 .OR. ICASE.EQ.8 .OR. ICASE.EQ.9 .OR.+ + ICASE.EQ.10) THEN+ CALL CHECK1(SFAC)+ ELSE IF (ICASE.EQ.1 .OR. ICASE.EQ.2 .OR. ICASE.EQ.5 .OR.+ + ICASE.EQ.6 .OR. ICASE.EQ.12 .OR. ICASE.EQ.13) THEN+ CALL CHECK2(SFAC)+ ELSE IF (ICASE.EQ.4) THEN+ CALL CHECK3(SFAC)+ END IF+* -- Print+ IF (PASS) WRITE (NOUT,99998)+ 20 CONTINUE+ STOP+*+99999 FORMAT (' Real BLAS Test Program Results',/1X)+99998 FORMAT (' ----- PASS -----')+ END+ SUBROUTINE HEADER+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, N+ LOGICAL PASS+* .. Local Arrays ..+ CHARACTER*6 L(13)+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, PASS+* .. Data statements ..+ DATA L(1)/' SDOT '/+ DATA L(2)/'SAXPY '/+ DATA L(3)/'SROTG '/+ DATA L(4)/' SROT '/+ DATA L(5)/'SCOPY '/+ DATA L(6)/'SSWAP '/+ DATA L(7)/'SNRM2 '/+ DATA L(8)/'SASUM '/+ DATA L(9)/'SSCAL '/+ DATA L(10)/'ISAMAX'/+ DATA L(11)/'SROTMG'/+ DATA L(12)/'SROTM '/+ DATA L(13)/'SDSDOT'/+* .. Executable Statements ..+ WRITE (NOUT,99999) ICASE, L(ICASE)+ RETURN+*+99999 FORMAT (/' Test of subprogram number',I3,12X,A6)+ END+ SUBROUTINE CHECK0(SFAC)+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ REAL SFAC+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, N+ LOGICAL PASS+* .. Local Scalars ..+ REAL D12, SA, SB, SC, SS+ INTEGER I, K+* .. Local Arrays ..+ REAL DA1(8), DATRUE(8), DB1(8), DBTRUE(8), DC1(8),+ + DS1(8), DAB(4,9), DTEMP(9), DTRUE(9,9)+* .. External Subroutines ..+ EXTERNAL SROTG, SROTMG, STEST1+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, PASS+* .. Data statements ..+ DATA DA1/0.3E0, 0.4E0, -0.3E0, -0.4E0, -0.3E0, 0.0E0,+ + 0.0E0, 1.0E0/+ DATA DB1/0.4E0, 0.3E0, 0.4E0, 0.3E0, -0.4E0, 0.0E0,+ + 1.0E0, 0.0E0/+ DATA DC1/0.6E0, 0.8E0, -0.6E0, 0.8E0, 0.6E0, 1.0E0,+ + 0.0E0, 1.0E0/+ DATA DS1/0.8E0, 0.6E0, 0.8E0, -0.6E0, 0.8E0, 0.0E0,+ + 1.0E0, 0.0E0/+ DATA DATRUE/0.5E0, 0.5E0, 0.5E0, -0.5E0, -0.5E0,+ + 0.0E0, 1.0E0, 1.0E0/+ DATA DBTRUE/0.0E0, 0.6E0, 0.0E0, -0.6E0, 0.0E0,+ + 0.0E0, 1.0E0, 0.0E0/+* INPUT FOR MODIFIED GIVENS+ DATA DAB/ .1E0,.3E0,1.2E0,.2E0,+ A .7E0, .2E0, .6E0, 4.2E0,+ B 0.E0,0.E0,0.E0,0.E0,+ C 4.E0, -1.E0, 2.E0, 4.E0,+ D 6.E-10, 2.E-2, 1.E5, 10.E0,+ E 4.E10, 2.E-2, 1.E-5, 10.E0,+ F 2.E-10, 4.E-2, 1.E5, 10.E0,+ G 2.E10, 4.E-2, 1.E-5, 10.E0,+ H 4.E0, -2.E0, 8.E0, 4.E0 /+* TRUE RESULTS FOR MODIFIED GIVENS+ DATA DTRUE/0.E0,0.E0, 1.3E0, .2E0, 0.E0,0.E0,0.E0, .5E0, 0.E0,+ A 0.E0,0.E0, 4.5E0, 4.2E0, 1.E0, .5E0, 0.E0,0.E0,0.E0,+ B 0.E0,0.E0,0.E0,0.E0, -2.E0, 0.E0,0.E0,0.E0,0.E0,+ C 0.E0,0.E0,0.E0, 4.E0, -1.E0, 0.E0,0.E0,0.E0,0.E0,+ D 0.E0, 15.E-3, 0.E0, 10.E0, -1.E0, 0.E0, -1.E-4,+ E 0.E0, 1.E0,+ F 0.E0,0.E0, 6144.E-5, 10.E0, -1.E0, 4096.E0, -1.E6,+ G 0.E0, 1.E0,+ H 0.E0,0.E0,15.E0,10.E0,-1.E0, 5.E-5, 0.E0,1.E0,0.E0,+ I 0.E0,0.E0, 15.E0, 10.E0, -1. E0, 5.E5, -4096.E0,+ J 1.E0, 4096.E-6,+ K 0.E0,0.E0, 7.E0, 4.E0, 0.E0,0.E0, -.5E0, -.25E0, 0.E0/+* 4096 = 2 ** 12+ DATA D12 /4096.E0/+ DTRUE(1,1) = 12.E0 / 130.E0+ DTRUE(2,1) = 36.E0 / 130.E0+ DTRUE(7,1) = -1.E0 / 6.E0+ DTRUE(1,2) = 14.E0 / 75.E0+ DTRUE(2,2) = 49.E0 / 75.E0+ DTRUE(9,2) = 1.E0 / 7.E0+ DTRUE(1,5) = 45.E-11 * (D12 * D12)+ DTRUE(3,5) = 4.E5 / (3.E0 * D12)+ DTRUE(6,5) = 1.E0 / D12+ DTRUE(8,5) = 1.E4 / (3.E0 * D12)+ DTRUE(1,6) = 4.E10 / (1.5E0 * D12 * D12)+ DTRUE(2,6) = 2.E-2 / 1.5E0+ DTRUE(8,6) = 5.E-7 * D12+ DTRUE(1,7) = 4.E0 / 150.E0+ DTRUE(2,7) = (2.E-10 / 1.5E0) * (D12 * D12)+ DTRUE(7,7) = -DTRUE(6,5)+ DTRUE(9,7) = 1.E4 / D12+ DTRUE(1,8) = DTRUE(1,7)+ DTRUE(2,8) = 2.E10 / (1.5E0 * D12 * D12)+ DTRUE(1,9) = 32.E0 / 7.E0+ DTRUE(2,9) = -16.E0 / 7.E0+* .. Executable Statements ..+*+* Compute true values which cannot be prestored+* in decimal notation+*+ DBTRUE(1) = 1.0E0/0.6E0+ DBTRUE(3) = -1.0E0/0.6E0+ DBTRUE(5) = 1.0E0/0.6E0+*+ DO 20 K = 1, 8+* .. Set N=K for identification in output if any ..+ N = K+ IF (ICASE.EQ.3) THEN+* .. SROTG ..+ IF (K.GT.8) GO TO 40+ SA = DA1(K)+ SB = DB1(K)+ CALL SROTG(SA,SB,SC,SS)+ CALL STEST1(SA,DATRUE(K),DATRUE(K),SFAC)+ CALL STEST1(SB,DBTRUE(K),DBTRUE(K),SFAC)+ CALL STEST1(SC,DC1(K),DC1(K),SFAC)+ CALL STEST1(SS,DS1(K),DS1(K),SFAC)+ ELSEIF (ICASE.EQ.11) THEN+* .. SROTMG ..+ DO I=1,4+ DTEMP(I)= DAB(I,K)+ DTEMP(I+4) = 0.0+ END DO+ DTEMP(9) = 0.0+ CALL SROTMG(DTEMP(1),DTEMP(2),DTEMP(3),DTEMP(4),DTEMP(5))+ CALL STEST(9,DTEMP,DTRUE(1,K),DTRUE(1,K),SFAC)+ ELSE+ WRITE (NOUT,*) ' Shouldn''t be here in CHECK0'+ STOP+ END IF+ 20 CONTINUE+ 40 RETURN+ END+ SUBROUTINE CHECK1(SFAC)+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ REAL SFAC+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, N+ LOGICAL PASS+* .. Local Scalars ..+ INTEGER I, LEN, NP1+* .. Local Arrays ..+ REAL DTRUE1(5), DTRUE3(5), DTRUE5(8,5,2), DV(8,5,2),+ + SA(10), STEMP(1), STRUE(8), SX(8)+ INTEGER ITRUE2(5)+* .. External Functions ..+ REAL SASUM, SNRM2+ INTEGER ISAMAX+ EXTERNAL SASUM, SNRM2, ISAMAX+* .. External Subroutines ..+ EXTERNAL ITEST1, SSCAL, STEST, STEST1+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, PASS+* .. Data statements ..+ DATA SA/0.3E0, -1.0E0, 0.0E0, 1.0E0, 0.3E0, 0.3E0,+ + 0.3E0, 0.3E0, 0.3E0, 0.3E0/+ DATA DV/0.1E0, 2.0E0, 2.0E0, 2.0E0, 2.0E0, 2.0E0,+ + 2.0E0, 2.0E0, 0.3E0, 3.0E0, 3.0E0, 3.0E0, 3.0E0,+ + 3.0E0, 3.0E0, 3.0E0, 0.3E0, -0.4E0, 4.0E0,+ + 4.0E0, 4.0E0, 4.0E0, 4.0E0, 4.0E0, 0.2E0,+ + -0.6E0, 0.3E0, 5.0E0, 5.0E0, 5.0E0, 5.0E0,+ + 5.0E0, 0.1E0, -0.3E0, 0.5E0, -0.1E0, 6.0E0,+ + 6.0E0, 6.0E0, 6.0E0, 0.1E0, 8.0E0, 8.0E0, 8.0E0,+ + 8.0E0, 8.0E0, 8.0E0, 8.0E0, 0.3E0, 9.0E0, 9.0E0,+ + 9.0E0, 9.0E0, 9.0E0, 9.0E0, 9.0E0, 0.3E0, 2.0E0,+ + -0.4E0, 2.0E0, 2.0E0, 2.0E0, 2.0E0, 2.0E0,+ + 0.2E0, 3.0E0, -0.6E0, 5.0E0, 0.3E0, 2.0E0,+ + 2.0E0, 2.0E0, 0.1E0, 4.0E0, -0.3E0, 6.0E0,+ + -0.5E0, 7.0E0, -0.1E0, 3.0E0/+ DATA DTRUE1/0.0E0, 0.3E0, 0.5E0, 0.7E0, 0.6E0/+ DATA DTRUE3/0.0E0, 0.3E0, 0.7E0, 1.1E0, 1.0E0/+ DATA DTRUE5/0.10E0, 2.0E0, 2.0E0, 2.0E0, 2.0E0,+ + 2.0E0, 2.0E0, 2.0E0, -0.3E0, 3.0E0, 3.0E0,+ + 3.0E0, 3.0E0, 3.0E0, 3.0E0, 3.0E0, 0.0E0, 0.0E0,+ + 4.0E0, 4.0E0, 4.0E0, 4.0E0, 4.0E0, 4.0E0,+ + 0.20E0, -0.60E0, 0.30E0, 5.0E0, 5.0E0, 5.0E0,+ + 5.0E0, 5.0E0, 0.03E0, -0.09E0, 0.15E0, -0.03E0,+ + 6.0E0, 6.0E0, 6.0E0, 6.0E0, 0.10E0, 8.0E0,+ + 8.0E0, 8.0E0, 8.0E0, 8.0E0, 8.0E0, 8.0E0,+ + 0.09E0, 9.0E0, 9.0E0, 9.0E0, 9.0E0, 9.0E0,+ + 9.0E0, 9.0E0, 0.09E0, 2.0E0, -0.12E0, 2.0E0,+ + 2.0E0, 2.0E0, 2.0E0, 2.0E0, 0.06E0, 3.0E0,+ + -0.18E0, 5.0E0, 0.09E0, 2.0E0, 2.0E0, 2.0E0,+ + 0.03E0, 4.0E0, -0.09E0, 6.0E0, -0.15E0, 7.0E0,+ + -0.03E0, 3.0E0/+ DATA ITRUE2/0, 1, 2, 2, 3/+* .. Executable Statements ..+ DO 80 INCX = 1, 2+ DO 60 NP1 = 1, 5+ N = NP1 - 1+ LEN = 2*MAX(N,1)+* .. Set vector arguments ..+ DO 20 I = 1, LEN+ SX(I) = DV(I,NP1,INCX)+ 20 CONTINUE+*+ IF (ICASE.EQ.7) THEN+* .. SNRM2 ..+ STEMP(1) = DTRUE1(NP1)+ CALL STEST1(SNRM2(N,SX,INCX),STEMP(1),STEMP,SFAC)+ ELSE IF (ICASE.EQ.8) THEN+* .. SASUM ..+ STEMP(1) = DTRUE3(NP1)+ CALL STEST1(SASUM(N,SX,INCX),STEMP(1),STEMP,SFAC)+ ELSE IF (ICASE.EQ.9) THEN+* .. SSCAL ..+ CALL SSCAL(N,SA((INCX-1)*5+NP1),SX,INCX)+ DO 40 I = 1, LEN+ STRUE(I) = DTRUE5(I,NP1,INCX)+ 40 CONTINUE+ CALL STEST(LEN,SX,STRUE,STRUE,SFAC)+ ELSE IF (ICASE.EQ.10) THEN+* .. ISAMAX ..+ CALL ITEST1(ISAMAX(N,SX,INCX),ITRUE2(NP1))+ ELSE+ WRITE (NOUT,*) ' Shouldn''t be here in CHECK1'+ STOP+ END IF+ 60 CONTINUE+ 80 CONTINUE+ RETURN+ END+ SUBROUTINE CHECK2(SFAC)+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ REAL SFAC+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, N+ LOGICAL PASS+* .. Local Scalars ..+ REAL SA+ INTEGER I, J, KI, KN, KNI, KPAR, KSIZE, LENX, LENY,+ $ MX, MY +* .. Local Arrays ..+ REAL DT10X(7,4,4), DT10Y(7,4,4), DT7(4,4),+ $ DT8(7,4,4), DX1(7),+ $ DY1(7), SSIZE1(4), SSIZE2(14,2), SSIZE3(4),+ $ SSIZE(7), STX(7), STY(7), SX(7), SY(7),+ $ DPAR(5,4), DT19X(7,4,16),DT19XA(7,4,4),+ $ DT19XB(7,4,4), DT19XC(7,4,4),DT19XD(7,4,4),+ $ DT19Y(7,4,16), DT19YA(7,4,4),DT19YB(7,4,4),+ $ DT19YC(7,4,4), DT19YD(7,4,4), DTEMP(5),+ $ ST7B(4,4)+ INTEGER INCXS(4), INCYS(4), LENS(4,2), NS(4)+* .. External Functions ..+ REAL SDOT, SDSDOT+ EXTERNAL SDOT, SDSDOT+* .. External Subroutines ..+ EXTERNAL SAXPY, SCOPY, SROTM, SSWAP, STEST, STEST1+* .. Intrinsic Functions ..+ INTRINSIC ABS, MIN+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, PASS+* .. Data statements ..+ EQUIVALENCE (DT19X(1,1,1),DT19XA(1,1,1)),(DT19X(1,1,5),+ A DT19XB(1,1,1)),(DT19X(1,1,9),DT19XC(1,1,1)),+ B (DT19X(1,1,13),DT19XD(1,1,1))+ EQUIVALENCE (DT19Y(1,1,1),DT19YA(1,1,1)),(DT19Y(1,1,5),+ A DT19YB(1,1,1)),(DT19Y(1,1,9),DT19YC(1,1,1)),+ B (DT19Y(1,1,13),DT19YD(1,1,1))++ DATA SA/0.3E0/+ DATA INCXS/1, 2, -2, -1/+ DATA INCYS/1, -2, 1, -2/+ DATA LENS/1, 1, 2, 4, 1, 1, 3, 7/+ DATA NS/0, 1, 2, 4/+ DATA DX1/0.6E0, 0.1E0, -0.5E0, 0.8E0, 0.9E0, -0.3E0,+ + -0.4E0/+ DATA DY1/0.5E0, -0.9E0, 0.3E0, 0.7E0, -0.6E0, 0.2E0,+ + 0.8E0/+ DATA DT7/0.0E0, 0.30E0, 0.21E0, 0.62E0, 0.0E0,+ + 0.30E0, -0.07E0, 0.85E0, 0.0E0, 0.30E0, -0.79E0,+ + -0.74E0, 0.0E0, 0.30E0, 0.33E0, 1.27E0/+ DATA ST7B/ .1, .4, .31, .72, .1, .4, .03, .95,+ + .1, .4, -.69, -.64, .1, .4, .43, 1.37/+ DATA DT8/0.5E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.68E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.68E0, -0.87E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.68E0, -0.87E0, 0.15E0,+ + 0.94E0, 0.0E0, 0.0E0, 0.0E0, 0.5E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.68E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.35E0, -0.9E0, 0.48E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.38E0, -0.9E0, 0.57E0, 0.7E0, -0.75E0,+ + 0.2E0, 0.98E0, 0.5E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.68E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.35E0, -0.72E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.38E0,+ + -0.63E0, 0.15E0, 0.88E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.5E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.68E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.68E0, -0.9E0, 0.33E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.68E0, -0.9E0, 0.33E0, 0.7E0,+ + -0.75E0, 0.2E0, 1.04E0/+ DATA DT10X/0.6E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.5E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.5E0, -0.9E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.5E0, -0.9E0, 0.3E0, 0.7E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.6E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.5E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.3E0, 0.1E0, 0.5E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.8E0, 0.1E0, -0.6E0,+ + 0.8E0, 0.3E0, -0.3E0, 0.5E0, 0.6E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.5E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, -0.9E0,+ + 0.1E0, 0.5E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.7E0,+ + 0.1E0, 0.3E0, 0.8E0, -0.9E0, -0.3E0, 0.5E0,+ + 0.6E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.5E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.5E0, 0.3E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.5E0, 0.3E0, -0.6E0, 0.8E0, 0.0E0, 0.0E0,+ + 0.0E0/+ DATA DT10Y/0.5E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.6E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.6E0, 0.1E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.6E0, 0.1E0, -0.5E0, 0.8E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.5E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.6E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, -0.5E0, -0.9E0, 0.6E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, -0.4E0, -0.9E0, 0.9E0,+ + 0.7E0, -0.5E0, 0.2E0, 0.6E0, 0.5E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.6E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, -0.5E0,+ + 0.6E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + -0.4E0, 0.9E0, -0.5E0, 0.6E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.5E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.6E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.6E0, -0.9E0, 0.1E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.6E0, -0.9E0, 0.1E0, 0.7E0,+ + -0.5E0, 0.2E0, 0.8E0/+ DATA SSIZE1/0.0E0, 0.3E0, 1.6E0, 3.2E0/+ DATA SSIZE2/0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 1.17E0, 1.17E0, 1.17E0, 1.17E0, 1.17E0,+ + 1.17E0, 1.17E0, 1.17E0, 1.17E0, 1.17E0, 1.17E0,+ + 1.17E0, 1.17E0, 1.17E0/+ DATA SSIZE3/ .1, .4, 1.7, 3.3 /+*+* FOR DROTM+*+ DATA DPAR/-2.E0, 0.E0,0.E0,0.E0,0.E0,+ A -1.E0, 2.E0, -3.E0, -4.E0, 5.E0,+ B 0.E0, 0.E0, 2.E0, -3.E0, 0.E0,+ C 1.E0, 5.E0, 2.E0, 0.E0, -4.E0/+* TRUE X RESULTS F0R ROTATIONS DROTM+ DATA DT19XA/.6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ A .6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ B .6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ C .6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ D .6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ E -.8E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ F -.9E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ G 3.5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ H .6E0, .1E0, 0.E0,0.E0,0.E0,0.E0,0.E0,+ I -.8E0, 3.8E0, 0.E0,0.E0,0.E0,0.E0,0.E0,+ J -.9E0, 2.8E0, 0.E0,0.E0,0.E0,0.E0,0.E0,+ K 3.5E0, -.4E0, 0.E0,0.E0,0.E0,0.E0,0.E0,+ L .6E0, .1E0, -.5E0, .8E0, 0.E0,0.E0,0.E0,+ M -.8E0, 3.8E0, -2.2E0, -1.2E0, 0.E0,0.E0,0.E0,+ N -.9E0, 2.8E0, -1.4E0, -1.3E0, 0.E0,0.E0,0.E0,+ O 3.5E0, -.4E0, -2.2E0, 4.7E0, 0.E0,0.E0,0.E0/+*+ DATA DT19XB/.6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ A .6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ B .6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ C .6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ D .6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ E -.8E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ F -.9E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ G 3.5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ H .6E0, .1E0, -.5E0, 0.E0,0.E0,0.E0,0.E0,+ I 0.E0, .1E0, -3.0E0, 0.E0,0.E0,0.E0,0.E0,+ J -.3E0, .1E0, -2.0E0, 0.E0,0.E0,0.E0,0.E0,+ K 3.3E0, .1E0, -2.0E0, 0.E0,0.E0,0.E0,0.E0,+ L .6E0, .1E0, -.5E0, .8E0, .9E0, -.3E0, -.4E0,+ M -2.0E0, .1E0, 1.4E0, .8E0, .6E0, -.3E0, -2.8E0,+ N -1.8E0, .1E0, 1.3E0, .8E0, 0.E0, -.3E0, -1.9E0,+ O 3.8E0, .1E0, -3.1E0, .8E0, 4.8E0, -.3E0, -1.5E0 /+*+ DATA DT19XC/.6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ A .6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ B .6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ C .6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ D .6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ E -.8E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ F -.9E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ G 3.5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ H .6E0, .1E0, -.5E0, 0.E0,0.E0,0.E0,0.E0,+ I 4.8E0, .1E0, -3.0E0, 0.E0,0.E0,0.E0,0.E0,+ J 3.3E0, .1E0, -2.0E0, 0.E0,0.E0,0.E0,0.E0,+ K 2.1E0, .1E0, -2.0E0, 0.E0,0.E0,0.E0,0.E0,+ L .6E0, .1E0, -.5E0, .8E0, .9E0, -.3E0, -.4E0,+ M -1.6E0, .1E0, -2.2E0, .8E0, 5.4E0, -.3E0, -2.8E0,+ N -1.5E0, .1E0, -1.4E0, .8E0, 3.6E0, -.3E0, -1.9E0,+ O 3.7E0, .1E0, -2.2E0, .8E0, 3.6E0, -.3E0, -1.5E0 /+*+ DATA DT19XD/.6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ A .6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ B .6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ C .6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ D .6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ E -.8E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ F -.9E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ G 3.5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ H .6E0, .1E0, 0.E0,0.E0,0.E0,0.E0,0.E0,+ I -.8E0, -1.0E0, 0.E0,0.E0,0.E0,0.E0,0.E0,+ J -.9E0, -.8E0, 0.E0,0.E0,0.E0,0.E0,0.E0,+ K 3.5E0, .8E0, 0.E0,0.E0,0.E0,0.E0,0.E0,+ L .6E0, .1E0, -.5E0, .8E0, 0.E0,0.E0,0.E0,+ M -.8E0, -1.0E0, 1.4E0, -1.6E0, 0.E0,0.E0,0.E0,+ N -.9E0, -.8E0, 1.3E0, -1.6E0, 0.E0,0.E0,0.E0,+ O 3.5E0, .8E0, -3.1E0, 4.8E0, 0.E0,0.E0,0.E0/+* TRUE Y RESULTS FOR ROTATIONS DROTM+ DATA DT19YA/.5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ A .5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ B .5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ C .5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ D .5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ E .7E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ F 1.7E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ G -2.6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ H .5E0, -.9E0, 0.E0,0.E0,0.E0,0.E0,0.E0,+ I .7E0, -4.8E0, 0.E0,0.E0,0.E0,0.E0,0.E0,+ J 1.7E0, -.7E0, 0.E0,0.E0,0.E0,0.E0,0.E0,+ K -2.6E0, 3.5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,+ L .5E0, -.9E0, .3E0, .7E0, 0.E0,0.E0,0.E0,+ M .7E0, -4.8E0, 3.0E0, 1.1E0, 0.E0,0.E0,0.E0,+ N 1.7E0, -.7E0, -.7E0, 2.3E0, 0.E0,0.E0,0.E0,+ O -2.6E0, 3.5E0, -.7E0, -3.6E0, 0.E0,0.E0,0.E0/+*+ DATA DT19YB/.5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ A .5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ B .5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ C .5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ D .5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ E .7E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ F 1.7E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ G -2.6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ H .5E0, -.9E0, .3E0, 0.E0,0.E0,0.E0,0.E0,+ I 4.0E0, -.9E0, -.3E0, 0.E0,0.E0,0.E0,0.E0,+ J -.5E0, -.9E0, 1.5E0, 0.E0,0.E0,0.E0,0.E0,+ K -1.5E0, -.9E0, -1.8E0, 0.E0,0.E0,0.E0,0.E0,+ L .5E0, -.9E0, .3E0, .7E0, -.6E0, .2E0, .8E0,+ M 3.7E0, -.9E0, -1.2E0, .7E0, -1.5E0, .2E0, 2.2E0,+ N -.3E0, -.9E0, 2.1E0, .7E0, -1.6E0, .2E0, 2.0E0,+ O -1.6E0, -.9E0, -2.1E0, .7E0, 2.9E0, .2E0, -3.8E0 /+*+ DATA DT19YC/.5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ A .5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ B .5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ C .5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ D .5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ E .7E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ F 1.7E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ G -2.6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ H .5E0, -.9E0, 0.E0,0.E0,0.E0,0.E0,0.E0,+ I 4.0E0, -6.3E0, 0.E0,0.E0,0.E0,0.E0,0.E0,+ J -.5E0, .3E0, 0.E0,0.E0,0.E0,0.E0,0.E0,+ K -1.5E0, 3.0E0, 0.E0,0.E0,0.E0,0.E0,0.E0,+ L .5E0, -.9E0, .3E0, .7E0, 0.E0,0.E0,0.E0,+ M 3.7E0, -7.2E0, 3.0E0, 1.7E0, 0.E0,0.E0,0.E0,+ N -.3E0, .9E0, -.7E0, 1.9E0, 0.E0,0.E0,0.E0,+ O -1.6E0, 2.7E0, -.7E0, -3.4E0, 0.E0,0.E0,0.E0/+*+ DATA DT19YD/.5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ A .5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ B .5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ C .5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ D .5E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ E .7E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ F 1.7E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ G -2.6E0, 0.E0,0.E0,0.E0,0.E0,0.E0,0.E0,+ H .5E0, -.9E0, .3E0, 0.E0,0.E0,0.E0,0.E0,+ I .7E0, -.9E0, 1.2E0, 0.E0,0.E0,0.E0,0.E0,+ J 1.7E0, -.9E0, .5E0, 0.E0,0.E0,0.E0,0.E0,+ K -2.6E0, -.9E0, -1.3E0, 0.E0,0.E0,0.E0,0.E0,+ L .5E0, -.9E0, .3E0, .7E0, -.6E0, .2E0, .8E0,+ M .7E0, -.9E0, 1.2E0, .7E0, -1.5E0, .2E0, 1.6E0,+ N 1.7E0, -.9E0, .5E0, .7E0, -1.6E0, .2E0, 2.4E0,+ O -2.6E0, -.9E0, -1.3E0, .7E0, 2.9E0, .2E0, -4.0E0 /+*+* .. Executable Statements ..+*+ DO 120 KI = 1, 4+ INCX = INCXS(KI)+ INCY = INCYS(KI)+ MX = ABS(INCX)+ MY = ABS(INCY)+*+ DO 100 KN = 1, 4+ N = NS(KN)+ KSIZE = MIN(2,KN)+ LENX = LENS(KN,MX)+ LENY = LENS(KN,MY)+* .. Initialize all argument arrays ..+ DO 20 I = 1, 7+ SX(I) = DX1(I)+ SY(I) = DY1(I)+ 20 CONTINUE+*+ IF (ICASE.EQ.1) THEN+* .. SDOT ..+ CALL STEST1(SDOT(N,SX,INCX,SY,INCY),DT7(KN,KI),SSIZE1(KN)+ + ,SFAC)+ ELSE IF (ICASE.EQ.2) THEN+* .. SAXPY ..+ CALL SAXPY(N,SA,SX,INCX,SY,INCY)+ DO 40 J = 1, LENY+ STY(J) = DT8(J,KN,KI)+ 40 CONTINUE+ CALL STEST(LENY,SY,STY,SSIZE2(1,KSIZE),SFAC)+ ELSE IF (ICASE.EQ.5) THEN+* .. SCOPY ..+ DO 60 I = 1, 7+ STY(I) = DT10Y(I,KN,KI)+ 60 CONTINUE+ CALL SCOPY(N,SX,INCX,SY,INCY)+ CALL STEST(LENY,SY,STY,SSIZE2(1,1),1.0E0)+ ELSE IF (ICASE.EQ.6) THEN+* .. SSWAP ..+ CALL SSWAP(N,SX,INCX,SY,INCY)+ DO 80 I = 1, 7+ STX(I) = DT10X(I,KN,KI)+ STY(I) = DT10Y(I,KN,KI)+ 80 CONTINUE+ CALL STEST(LENX,SX,STX,SSIZE2(1,1),1.0E0)+ CALL STEST(LENY,SY,STY,SSIZE2(1,1),1.0E0)+ ELSEIF (ICASE.EQ.12) THEN+* .. SROTM ..+ KNI=KN+4*(KI-1)+ DO KPAR=1,4+ DO I=1,7+ SX(I) = DX1(I)+ SY(I) = DY1(I)+ STX(I)= DT19X(I,KPAR,KNI)+ STY(I)= DT19Y(I,KPAR,KNI)+ END DO+*+ DO I=1,5+ DTEMP(I) = DPAR(I,KPAR)+ END DO+*+ DO I=1,LENX+ SSIZE(I)=STX(I)+ END DO+* SEE REMARK ABOVE ABOUT DT11X(1,2,7)+* AND DT11X(5,3,8).+ IF ((KPAR .EQ. 2) .AND. (KNI .EQ. 7))+ $ SSIZE(1) = 2.4E0+ IF ((KPAR .EQ. 3) .AND. (KNI .EQ. 8))+ $ SSIZE(5) = 1.8E0+*+ CALL SROTM(N,SX,INCX,SY,INCY,DTEMP)+ CALL STEST(LENX,SX,STX,SSIZE,SFAC)+ CALL STEST(LENY,SY,STY,STY,SFAC)+ END DO+ ELSEIF (ICASE.EQ.13) THEN+* .. SDSROT ..+ CALL STEST1 (SDSDOT(N,.1,SX,INCX,SY,INCY),+ $ ST7B(KN,KI),SSIZE3(KN),SFAC)+ ELSE+ WRITE (NOUT,*) ' Shouldn''t be here in CHECK2'+ STOP+ END IF+ 100 CONTINUE+ 120 CONTINUE+ RETURN+ END+ SUBROUTINE CHECK3(SFAC)+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ REAL SFAC+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, N+ LOGICAL PASS+* .. Local Scalars ..+ REAL SC, SS+ INTEGER I, K, KI, KN, KSIZE, LENX, LENY, MX, MY+* .. Local Arrays ..+ REAL COPYX(5), COPYY(5), DT9X(7,4,4), DT9Y(7,4,4),+ + DX1(7), DY1(7), MWPC(11), MWPS(11), MWPSTX(5),+ + MWPSTY(5), MWPTX(11,5), MWPTY(11,5), MWPX(5),+ + MWPY(5), SSIZE2(14,2), STX(7), STY(7), SX(7),+ + SY(7)+ INTEGER INCXS(4), INCYS(4), LENS(4,2), MWPINX(11),+ + MWPINY(11), MWPN(11), NS(4)+* .. External Subroutines ..+ EXTERNAL SROT, STEST+* .. Intrinsic Functions ..+ INTRINSIC ABS, MIN+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, PASS+* .. Data statements ..+ DATA INCXS/1, 2, -2, -1/+ DATA INCYS/1, -2, 1, -2/+ DATA LENS/1, 1, 2, 4, 1, 1, 3, 7/+ DATA NS/0, 1, 2, 4/+ DATA DX1/0.6E0, 0.1E0, -0.5E0, 0.8E0, 0.9E0, -0.3E0,+ + -0.4E0/+ DATA DY1/0.5E0, -0.9E0, 0.3E0, 0.7E0, -0.6E0, 0.2E0,+ + 0.8E0/+ DATA SC, SS/0.8E0, 0.6E0/+ DATA DT9X/0.6E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.78E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.78E0, -0.46E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.78E0, -0.46E0, -0.22E0,+ + 1.06E0, 0.0E0, 0.0E0, 0.0E0, 0.6E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.78E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.66E0, 0.1E0, -0.1E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.96E0, 0.1E0, -0.76E0, 0.8E0, 0.90E0,+ + -0.3E0, -0.02E0, 0.6E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.78E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.0E0, -0.06E0, 0.1E0,+ + -0.1E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.90E0,+ + 0.1E0, -0.22E0, 0.8E0, 0.18E0, -0.3E0, -0.02E0,+ + 0.6E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.78E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.78E0, 0.26E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.78E0, 0.26E0, -0.76E0, 1.12E0,+ + 0.0E0, 0.0E0, 0.0E0/+ DATA DT9Y/0.5E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.04E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.04E0, -0.78E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.04E0, -0.78E0, 0.54E0,+ + 0.08E0, 0.0E0, 0.0E0, 0.0E0, 0.5E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.04E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.7E0,+ + -0.9E0, -0.12E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.64E0, -0.9E0, -0.30E0, 0.7E0, -0.18E0, 0.2E0,+ + 0.28E0, 0.5E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.04E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.7E0, -1.08E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.64E0, -1.26E0,+ + 0.54E0, 0.20E0, 0.0E0, 0.0E0, 0.0E0, 0.5E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.04E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.04E0, -0.9E0, 0.18E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.04E0, -0.9E0, 0.18E0, 0.7E0,+ + -0.18E0, 0.2E0, 0.16E0/+ DATA SSIZE2/0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0, 0.0E0,+ + 0.0E0, 1.17E0, 1.17E0, 1.17E0, 1.17E0, 1.17E0,+ + 1.17E0, 1.17E0, 1.17E0, 1.17E0, 1.17E0, 1.17E0,+ + 1.17E0, 1.17E0, 1.17E0/+* .. Executable Statements ..+*+ DO 60 KI = 1, 4+ INCX = INCXS(KI)+ INCY = INCYS(KI)+ MX = ABS(INCX)+ MY = ABS(INCY)+*+ DO 40 KN = 1, 4+ N = NS(KN)+ KSIZE = MIN(2,KN)+ LENX = LENS(KN,MX)+ LENY = LENS(KN,MY)+*+ IF (ICASE.EQ.4) THEN+* .. SROT ..+ DO 20 I = 1, 7+ SX(I) = DX1(I)+ SY(I) = DY1(I)+ STX(I) = DT9X(I,KN,KI)+ STY(I) = DT9Y(I,KN,KI)+ 20 CONTINUE+ CALL SROT(N,SX,INCX,SY,INCY,SC,SS)+ CALL STEST(LENX,SX,STX,SSIZE2(1,KSIZE),SFAC)+ CALL STEST(LENY,SY,STY,SSIZE2(1,KSIZE),SFAC)+ ELSE+ WRITE (NOUT,*) ' Shouldn''t be here in CHECK3'+ STOP+ END IF+ 40 CONTINUE+ 60 CONTINUE+*+ MWPC(1) = 1+ DO 80 I = 2, 11+ MWPC(I) = 0+ 80 CONTINUE+ MWPS(1) = 0+ DO 100 I = 2, 6+ MWPS(I) = 1+ 100 CONTINUE+ DO 120 I = 7, 11+ MWPS(I) = -1+ 120 CONTINUE+ MWPINX(1) = 1+ MWPINX(2) = 1+ MWPINX(3) = 1+ MWPINX(4) = -1+ MWPINX(5) = 1+ MWPINX(6) = -1+ MWPINX(7) = 1+ MWPINX(8) = 1+ MWPINX(9) = -1+ MWPINX(10) = 1+ MWPINX(11) = -1+ MWPINY(1) = 1+ MWPINY(2) = 1+ MWPINY(3) = -1+ MWPINY(4) = -1+ MWPINY(5) = 2+ MWPINY(6) = 1+ MWPINY(7) = 1+ MWPINY(8) = -1+ MWPINY(9) = -1+ MWPINY(10) = 2+ MWPINY(11) = 1+ DO 140 I = 1, 11+ MWPN(I) = 5+ 140 CONTINUE+ MWPN(5) = 3+ MWPN(10) = 3+ DO 160 I = 1, 5+ MWPX(I) = I+ MWPY(I) = I+ MWPTX(1,I) = I+ MWPTY(1,I) = I+ MWPTX(2,I) = I+ MWPTY(2,I) = -I+ MWPTX(3,I) = 6 - I+ MWPTY(3,I) = I - 6+ MWPTX(4,I) = I+ MWPTY(4,I) = -I+ MWPTX(6,I) = 6 - I+ MWPTY(6,I) = I - 6+ MWPTX(7,I) = -I+ MWPTY(7,I) = I+ MWPTX(8,I) = I - 6+ MWPTY(8,I) = 6 - I+ MWPTX(9,I) = -I+ MWPTY(9,I) = I+ MWPTX(11,I) = I - 6+ MWPTY(11,I) = 6 - I+ 160 CONTINUE+ MWPTX(5,1) = 1+ MWPTX(5,2) = 3+ MWPTX(5,3) = 5+ MWPTX(5,4) = 4+ MWPTX(5,5) = 5+ MWPTY(5,1) = -1+ MWPTY(5,2) = 2+ MWPTY(5,3) = -2+ MWPTY(5,4) = 4+ MWPTY(5,5) = -3+ MWPTX(10,1) = -1+ MWPTX(10,2) = -3+ MWPTX(10,3) = -5+ MWPTX(10,4) = 4+ MWPTX(10,5) = 5+ MWPTY(10,1) = 1+ MWPTY(10,2) = 2+ MWPTY(10,3) = 2+ MWPTY(10,4) = 4+ MWPTY(10,5) = 3+ DO 200 I = 1, 11+ INCX = MWPINX(I)+ INCY = MWPINY(I)+ DO 180 K = 1, 5+ COPYX(K) = MWPX(K)+ COPYY(K) = MWPY(K)+ MWPSTX(K) = MWPTX(I,K)+ MWPSTY(K) = MWPTY(I,K)+ 180 CONTINUE+ CALL SROT(MWPN(I),COPYX,INCX,COPYY,INCY,MWPC(I),MWPS(I))+ CALL STEST(5,COPYX,MWPSTX,MWPSTX,SFAC)+ CALL STEST(5,COPYY,MWPSTY,MWPSTY,SFAC)+ 200 CONTINUE+ RETURN+ END+ SUBROUTINE STEST(LEN,SCOMP,STRUE,SSIZE,SFAC)+* ********************************* STEST **************************+*+* THIS SUBR COMPARES ARRAYS SCOMP() AND STRUE() OF LENGTH LEN TO+* SEE IF THE TERM BY TERM DIFFERENCES, MULTIPLIED BY SFAC, ARE+* NEGLIGIBLE.+*+* C. L. LAWSON, JPL, 1974 DEC 10+*+* .. Parameters ..+ INTEGER NOUT+ REAL ZERO+ PARAMETER (NOUT=6, ZERO=0.0E0)+* .. Scalar Arguments ..+ REAL SFAC+ INTEGER LEN+* .. Array Arguments ..+ REAL SCOMP(LEN), SSIZE(LEN), STRUE(LEN)+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, N+ LOGICAL PASS+* .. Local Scalars ..+ REAL SD+ INTEGER I+* .. External Functions ..+ REAL SDIFF+ EXTERNAL SDIFF+* .. Intrinsic Functions ..+ INTRINSIC ABS+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, PASS+* .. Executable Statements ..+*+ DO 40 I = 1, LEN+ SD = SCOMP(I) - STRUE(I)+ IF (ABS(SFAC*SD) .LE. ABS(SSIZE(I))*EPSILON(ZERO))+ + GO TO 40+*+* HERE SCOMP(I) IS NOT CLOSE TO STRUE(I).+*+ IF ( .NOT. PASS) GO TO 20+* PRINT FAIL MESSAGE AND HEADER.+ PASS = .FALSE.+ WRITE (NOUT,99999)+ WRITE (NOUT,99998)+ 20 WRITE (NOUT,99997) ICASE, N, INCX, INCY, I, SCOMP(I),+ + STRUE(I), SD, SSIZE(I)+ 40 CONTINUE+ RETURN+*+99999 FORMAT (' FAIL')+99998 FORMAT (/' CASE N INCX INCY I ',+ + ' COMP(I) TRUE(I) DIFFERENCE',+ + ' SIZE(I)',/1X)+99997 FORMAT (1X,I4,I3,2I5,I3,2E36.8,2E12.4)+ END+ SUBROUTINE STEST1(SCOMP1,STRUE1,SSIZE,SFAC)+* ************************* STEST1 *****************************+*+* THIS IS AN INTERFACE SUBROUTINE TO ACCOMODATE THE FORTRAN+* REQUIREMENT THAT WHEN A DUMMY ARGUMENT IS AN ARRAY, THE+* ACTUAL ARGUMENT MUST ALSO BE AN ARRAY OR AN ARRAY ELEMENT.+*+* C.L. LAWSON, JPL, 1978 DEC 6+*+* .. Scalar Arguments ..+ REAL SCOMP1, SFAC, STRUE1+* .. Array Arguments ..+ REAL SSIZE(*)+* .. Local Arrays ..+ REAL SCOMP(1), STRUE(1)+* .. External Subroutines ..+ EXTERNAL STEST+* .. Executable Statements ..+*+ SCOMP(1) = SCOMP1+ STRUE(1) = STRUE1+ CALL STEST(1,SCOMP,STRUE,SSIZE,SFAC)+*+ RETURN+ END+ REAL FUNCTION SDIFF(SA,SB)+* ********************************* SDIFF **************************+* COMPUTES DIFFERENCE OF TWO NUMBERS. C. L. LAWSON, JPL 1974 FEB 15+*+* .. Scalar Arguments ..+ REAL SA, SB+* .. Executable Statements ..+ SDIFF = SA - SB+ RETURN+ END+ SUBROUTINE ITEST1(ICOMP,ITRUE)+* ********************************* ITEST1 *************************+*+* THIS SUBROUTINE COMPARES THE VARIABLES ICOMP AND ITRUE FOR+* EQUALITY.+* C. L. LAWSON, JPL, 1974 DEC 10+*+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ INTEGER ICOMP, ITRUE+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, N+ LOGICAL PASS+* .. Local Scalars ..+ INTEGER ID+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, PASS+* .. Executable Statements ..+*+ IF (ICOMP.EQ.ITRUE) GO TO 40+*+* HERE ICOMP IS NOT EQUAL TO ITRUE.+*+ IF ( .NOT. PASS) GO TO 20+* PRINT FAIL MESSAGE AND HEADER.+ PASS = .FALSE.+ WRITE (NOUT,99999)+ WRITE (NOUT,99998)+ 20 ID = ICOMP - ITRUE+ WRITE (NOUT,99997) ICASE, N, INCX, INCY, ICOMP, ITRUE, ID+ 40 CONTINUE+ RETURN+*+99999 FORMAT (' FAIL')+99998 FORMAT (/' CASE N INCX INCY ',+ + ' COMP TRUE DIFFERENCE',+ + /1X)+99997 FORMAT (1X,I4,I3,2I5,2I36,I12)+ END
+ eigen3/blas/testing/sblat2.dat view
@@ -0,0 +1,34 @@+'sblat2.summ' NAME OF SUMMARY OUTPUT FILE+6 UNIT NUMBER OF SUMMARY FILE+'sblat2.snap' NAME OF SNAPSHOT OUTPUT FILE+-1 UNIT NUMBER OF SNAPSHOT FILE (NOT USED IF .LT. 0)+F LOGICAL FLAG, T TO REWIND SNAPSHOT FILE AFTER EACH RECORD.+F LOGICAL FLAG, T TO STOP ON FAILURES.+T LOGICAL FLAG, T TO TEST ERROR EXITS.+16.0 THRESHOLD VALUE OF TEST RATIO+6 NUMBER OF VALUES OF N+0 1 2 3 5 9 VALUES OF N+4 NUMBER OF VALUES OF K+0 1 2 4 VALUES OF K+4 NUMBER OF VALUES OF INCX AND INCY+1 2 -1 -2 VALUES OF INCX AND INCY+3 NUMBER OF VALUES OF ALPHA+0.0 1.0 0.7 VALUES OF ALPHA+3 NUMBER OF VALUES OF BETA+0.0 1.0 0.9 VALUES OF BETA+SGEMV T PUT F FOR NO TEST. SAME COLUMNS.+SGBMV T PUT F FOR NO TEST. SAME COLUMNS.+SSYMV T PUT F FOR NO TEST. SAME COLUMNS.+SSBMV T PUT F FOR NO TEST. SAME COLUMNS.+SSPMV T PUT F FOR NO TEST. SAME COLUMNS.+STRMV T PUT F FOR NO TEST. SAME COLUMNS.+STBMV T PUT F FOR NO TEST. SAME COLUMNS.+STPMV T PUT F FOR NO TEST. SAME COLUMNS.+STRSV T PUT F FOR NO TEST. SAME COLUMNS.+STBSV T PUT F FOR NO TEST. SAME COLUMNS.+STPSV T PUT F FOR NO TEST. SAME COLUMNS.+SGER T PUT F FOR NO TEST. SAME COLUMNS.+SSYR T PUT F FOR NO TEST. SAME COLUMNS.+SSPR T PUT F FOR NO TEST. SAME COLUMNS.+SSYR2 T PUT F FOR NO TEST. SAME COLUMNS.+SSPR2 T PUT F FOR NO TEST. SAME COLUMNS.
+ eigen3/blas/testing/sblat2.f view
@@ -0,0 +1,3138 @@+ PROGRAM SBLAT2+*+* Test program for the REAL Level 2 Blas.+*+* The program must be driven by a short data file. The first 18 records+* of the file are read using list-directed input, the last 16 records+* are read using the format ( A6, L2 ). An annotated example of a data+* file can be obtained by deleting the first 3 characters from the+* following 34 lines:+* 'SBLAT2.SUMM' NAME OF SUMMARY OUTPUT FILE+* 6 UNIT NUMBER OF SUMMARY FILE+* 'SBLAT2.SNAP' NAME OF SNAPSHOT OUTPUT FILE+* -1 UNIT NUMBER OF SNAPSHOT FILE (NOT USED IF .LT. 0)+* F LOGICAL FLAG, T TO REWIND SNAPSHOT FILE AFTER EACH RECORD.+* F LOGICAL FLAG, T TO STOP ON FAILURES.+* T LOGICAL FLAG, T TO TEST ERROR EXITS.+* 16.0 THRESHOLD VALUE OF TEST RATIO+* 6 NUMBER OF VALUES OF N+* 0 1 2 3 5 9 VALUES OF N+* 4 NUMBER OF VALUES OF K+* 0 1 2 4 VALUES OF K+* 4 NUMBER OF VALUES OF INCX AND INCY+* 1 2 -1 -2 VALUES OF INCX AND INCY+* 3 NUMBER OF VALUES OF ALPHA+* 0.0 1.0 0.7 VALUES OF ALPHA+* 3 NUMBER OF VALUES OF BETA+* 0.0 1.0 0.9 VALUES OF BETA+* SGEMV T PUT F FOR NO TEST. SAME COLUMNS.+* SGBMV T PUT F FOR NO TEST. SAME COLUMNS.+* SSYMV T PUT F FOR NO TEST. SAME COLUMNS.+* SSBMV T PUT F FOR NO TEST. SAME COLUMNS.+* SSPMV T PUT F FOR NO TEST. SAME COLUMNS.+* STRMV T PUT F FOR NO TEST. SAME COLUMNS.+* STBMV T PUT F FOR NO TEST. SAME COLUMNS.+* STPMV T PUT F FOR NO TEST. SAME COLUMNS.+* STRSV T PUT F FOR NO TEST. SAME COLUMNS.+* STBSV T PUT F FOR NO TEST. SAME COLUMNS.+* STPSV T PUT F FOR NO TEST. SAME COLUMNS.+* SGER T PUT F FOR NO TEST. SAME COLUMNS.+* SSYR T PUT F FOR NO TEST. SAME COLUMNS.+* SSPR T PUT F FOR NO TEST. SAME COLUMNS.+* SSYR2 T PUT F FOR NO TEST. SAME COLUMNS.+* SSPR2 T PUT F FOR NO TEST. SAME COLUMNS.+*+* See:+*+* Dongarra J. J., Du Croz J. J., Hammarling S. and Hanson R. J..+* An extended set of Fortran Basic Linear Algebra Subprograms.+*+* Technical Memoranda Nos. 41 (revision 3) and 81, Mathematics+* and Computer Science Division, Argonne National Laboratory,+* 9700 South Cass Avenue, Argonne, Illinois 60439, US.+*+* Or+*+* NAG Technical Reports TR3/87 and TR4/87, Numerical Algorithms+* Group Ltd., NAG Central Office, 256 Banbury Road, Oxford+* OX2 7DE, UK, and Numerical Algorithms Group Inc., 1101 31st+* Street, Suite 100, Downers Grove, Illinois 60515-1263, USA.+*+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ INTEGER NIN+ PARAMETER ( NIN = 5 )+ INTEGER NSUBS+ PARAMETER ( NSUBS = 16 )+ REAL ZERO, HALF, ONE+ PARAMETER ( ZERO = 0.0, HALF = 0.5, ONE = 1.0 )+ INTEGER NMAX, INCMAX+ PARAMETER ( NMAX = 65, INCMAX = 2 )+ INTEGER NINMAX, NIDMAX, NKBMAX, NALMAX, NBEMAX+ PARAMETER ( NINMAX = 7, NIDMAX = 9, NKBMAX = 7,+ $ NALMAX = 7, NBEMAX = 7 )+* .. Local Scalars ..+ REAL EPS, ERR, THRESH+ INTEGER I, ISNUM, J, N, NALF, NBET, NIDIM, NINC, NKB,+ $ NOUT, NTRA+ LOGICAL FATAL, LTESTT, REWI, SAME, SFATAL, TRACE,+ $ TSTERR+ CHARACTER*1 TRANS+ CHARACTER*6 SNAMET+ CHARACTER*32 SNAPS, SUMMRY+* .. Local Arrays ..+ REAL A( NMAX, NMAX ), AA( NMAX*NMAX ),+ $ ALF( NALMAX ), AS( NMAX*NMAX ), BET( NBEMAX ),+ $ G( NMAX ), X( NMAX ), XS( NMAX*INCMAX ),+ $ XX( NMAX*INCMAX ), Y( NMAX ),+ $ YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX ), Z( 2*NMAX )+ INTEGER IDIM( NIDMAX ), INC( NINMAX ), KB( NKBMAX )+ LOGICAL LTEST( NSUBS )+ CHARACTER*6 SNAMES( NSUBS )+* .. External Functions ..+ REAL SDIFF+ LOGICAL LSE+ EXTERNAL SDIFF, LSE+* .. External Subroutines ..+ EXTERNAL SCHK1, SCHK2, SCHK3, SCHK4, SCHK5, SCHK6,+ $ SCHKE, SMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, MIN+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+ COMMON /SRNAMC/SRNAMT+* .. Data statements ..+ DATA SNAMES/'SGEMV ', 'SGBMV ', 'SSYMV ', 'SSBMV ',+ $ 'SSPMV ', 'STRMV ', 'STBMV ', 'STPMV ',+ $ 'STRSV ', 'STBSV ', 'STPSV ', 'SGER ',+ $ 'SSYR ', 'SSPR ', 'SSYR2 ', 'SSPR2 '/+* .. Executable Statements ..+*+* Read name and unit number for summary output file and open file.+*+ READ( NIN, FMT = * )SUMMRY+ READ( NIN, FMT = * )NOUT+ OPEN( NOUT, FILE = SUMMRY, STATUS = 'NEW' )+ NOUTC = NOUT+*+* Read name and unit number for snapshot output file and open file.+*+ READ( NIN, FMT = * )SNAPS+ READ( NIN, FMT = * )NTRA+ TRACE = NTRA.GE.0+ IF( TRACE )THEN+ OPEN( NTRA, FILE = SNAPS, STATUS = 'NEW' )+ END IF+* Read the flag that directs rewinding of the snapshot file.+ READ( NIN, FMT = * )REWI+ REWI = REWI.AND.TRACE+* Read the flag that directs stopping on any failure.+ READ( NIN, FMT = * )SFATAL+* Read the flag that indicates whether error exits are to be tested.+ READ( NIN, FMT = * )TSTERR+* Read the threshold value of the test ratio+ READ( NIN, FMT = * )THRESH+*+* Read and check the parameter values for the tests.+*+* Values of N+ READ( NIN, FMT = * )NIDIM+ IF( NIDIM.LT.1.OR.NIDIM.GT.NIDMAX )THEN+ WRITE( NOUT, FMT = 9997 )'N', NIDMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( IDIM( I ), I = 1, NIDIM )+ DO 10 I = 1, NIDIM+ IF( IDIM( I ).LT.0.OR.IDIM( I ).GT.NMAX )THEN+ WRITE( NOUT, FMT = 9996 )NMAX+ GO TO 230+ END IF+ 10 CONTINUE+* Values of K+ READ( NIN, FMT = * )NKB+ IF( NKB.LT.1.OR.NKB.GT.NKBMAX )THEN+ WRITE( NOUT, FMT = 9997 )'K', NKBMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( KB( I ), I = 1, NKB )+ DO 20 I = 1, NKB+ IF( KB( I ).LT.0 )THEN+ WRITE( NOUT, FMT = 9995 )+ GO TO 230+ END IF+ 20 CONTINUE+* Values of INCX and INCY+ READ( NIN, FMT = * )NINC+ IF( NINC.LT.1.OR.NINC.GT.NINMAX )THEN+ WRITE( NOUT, FMT = 9997 )'INCX AND INCY', NINMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( INC( I ), I = 1, NINC )+ DO 30 I = 1, NINC+ IF( INC( I ).EQ.0.OR.ABS( INC( I ) ).GT.INCMAX )THEN+ WRITE( NOUT, FMT = 9994 )INCMAX+ GO TO 230+ END IF+ 30 CONTINUE+* Values of ALPHA+ READ( NIN, FMT = * )NALF+ IF( NALF.LT.1.OR.NALF.GT.NALMAX )THEN+ WRITE( NOUT, FMT = 9997 )'ALPHA', NALMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( ALF( I ), I = 1, NALF )+* Values of BETA+ READ( NIN, FMT = * )NBET+ IF( NBET.LT.1.OR.NBET.GT.NBEMAX )THEN+ WRITE( NOUT, FMT = 9997 )'BETA', NBEMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( BET( I ), I = 1, NBET )+*+* Report values of parameters.+*+ WRITE( NOUT, FMT = 9993 )+ WRITE( NOUT, FMT = 9992 )( IDIM( I ), I = 1, NIDIM )+ WRITE( NOUT, FMT = 9991 )( KB( I ), I = 1, NKB )+ WRITE( NOUT, FMT = 9990 )( INC( I ), I = 1, NINC )+ WRITE( NOUT, FMT = 9989 )( ALF( I ), I = 1, NALF )+ WRITE( NOUT, FMT = 9988 )( BET( I ), I = 1, NBET )+ IF( .NOT.TSTERR )THEN+ WRITE( NOUT, FMT = * )+ WRITE( NOUT, FMT = 9980 )+ END IF+ WRITE( NOUT, FMT = * )+ WRITE( NOUT, FMT = 9999 )THRESH+ WRITE( NOUT, FMT = * )+*+* Read names of subroutines and flags which indicate+* whether they are to be tested.+*+ DO 40 I = 1, NSUBS+ LTEST( I ) = .FALSE.+ 40 CONTINUE+ 50 READ( NIN, FMT = 9984, END = 80 )SNAMET, LTESTT+ DO 60 I = 1, NSUBS+ IF( SNAMET.EQ.SNAMES( I ) )+ $ GO TO 70+ 60 CONTINUE+ WRITE( NOUT, FMT = 9986 )SNAMET+ STOP+ 70 LTEST( I ) = LTESTT+ GO TO 50+*+ 80 CONTINUE+ CLOSE ( NIN )+*+* Compute EPS (the machine precision).+*+ EPS = ONE+ 90 CONTINUE+ IF( SDIFF( ONE + EPS, ONE ).EQ.ZERO )+ $ GO TO 100+ EPS = HALF*EPS+ GO TO 90+ 100 CONTINUE+ EPS = EPS + EPS+ WRITE( NOUT, FMT = 9998 )EPS+*+* Check the reliability of SMVCH using exact data.+*+ N = MIN( 32, NMAX )+ DO 120 J = 1, N+ DO 110 I = 1, N+ A( I, J ) = MAX( I - J + 1, 0 )+ 110 CONTINUE+ X( J ) = J+ Y( J ) = ZERO+ 120 CONTINUE+ DO 130 J = 1, N+ YY( J ) = J*( ( J + 1 )*J )/2 - ( ( J + 1 )*J*( J - 1 ) )/3+ 130 CONTINUE+* YY holds the exact result. On exit from SMVCH YT holds+* the result computed by SMVCH.+ TRANS = 'N'+ CALL SMVCH( TRANS, N, N, ONE, A, NMAX, X, 1, ZERO, Y, 1, YT, G,+ $ YY, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LSE( YY, YT, N )+ IF( .NOT.SAME.OR.ERR.NE.ZERO )THEN+ WRITE( NOUT, FMT = 9985 )TRANS, SAME, ERR+ STOP+ END IF+ TRANS = 'T'+ CALL SMVCH( TRANS, N, N, ONE, A, NMAX, X, -1, ZERO, Y, -1, YT, G,+ $ YY, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LSE( YY, YT, N )+ IF( .NOT.SAME.OR.ERR.NE.ZERO )THEN+ WRITE( NOUT, FMT = 9985 )TRANS, SAME, ERR+ STOP+ END IF+*+* Test each subroutine in turn.+*+ DO 210 ISNUM = 1, NSUBS+ WRITE( NOUT, FMT = * )+ IF( .NOT.LTEST( ISNUM ) )THEN+* Subprogram is not to be tested.+ WRITE( NOUT, FMT = 9983 )SNAMES( ISNUM )+ ELSE+ SRNAMT = SNAMES( ISNUM )+* Test error exits.+ IF( TSTERR )THEN+ CALL SCHKE( ISNUM, SNAMES( ISNUM ), NOUT )+ WRITE( NOUT, FMT = * )+ END IF+* Test computations.+ INFOT = 0+ OK = .TRUE.+ FATAL = .FALSE.+ GO TO ( 140, 140, 150, 150, 150, 160, 160,+ $ 160, 160, 160, 160, 170, 180, 180,+ $ 190, 190 )ISNUM+* Test SGEMV, 01, and SGBMV, 02.+ 140 CALL SCHK1( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NKB, KB, NALF, ALF,+ $ NBET, BET, NINC, INC, NMAX, INCMAX, A, AA, AS,+ $ X, XX, XS, Y, YY, YS, YT, G )+ GO TO 200+* Test SSYMV, 03, SSBMV, 04, and SSPMV, 05.+ 150 CALL SCHK2( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NKB, KB, NALF, ALF,+ $ NBET, BET, NINC, INC, NMAX, INCMAX, A, AA, AS,+ $ X, XX, XS, Y, YY, YS, YT, G )+ GO TO 200+* Test STRMV, 06, STBMV, 07, STPMV, 08,+* STRSV, 09, STBSV, 10, and STPSV, 11.+ 160 CALL SCHK3( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NKB, KB, NINC, INC,+ $ NMAX, INCMAX, A, AA, AS, Y, YY, YS, YT, G, Z )+ GO TO 200+* Test SGER, 12.+ 170 CALL SCHK4( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC,+ $ NMAX, INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS,+ $ YT, G, Z )+ GO TO 200+* Test SSYR, 13, and SSPR, 14.+ 180 CALL SCHK5( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC,+ $ NMAX, INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS,+ $ YT, G, Z )+ GO TO 200+* Test SSYR2, 15, and SSPR2, 16.+ 190 CALL SCHK6( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC,+ $ NMAX, INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS,+ $ YT, G, Z )+*+ 200 IF( FATAL.AND.SFATAL )+ $ GO TO 220+ END IF+ 210 CONTINUE+ WRITE( NOUT, FMT = 9982 )+ GO TO 240+*+ 220 CONTINUE+ WRITE( NOUT, FMT = 9981 )+ GO TO 240+*+ 230 CONTINUE+ WRITE( NOUT, FMT = 9987 )+*+ 240 CONTINUE+ IF( TRACE )+ $ CLOSE ( NTRA )+ CLOSE ( NOUT )+ STOP+*+ 9999 FORMAT( ' ROUTINES PASS COMPUTATIONAL TESTS IF TEST RATIO IS LES',+ $ 'S THAN', F8.2 )+ 9998 FORMAT( ' RELATIVE MACHINE PRECISION IS TAKEN TO BE', 1P, E9.1 )+ 9997 FORMAT( ' NUMBER OF VALUES OF ', A, ' IS LESS THAN 1 OR GREATER ',+ $ 'THAN ', I2 )+ 9996 FORMAT( ' VALUE OF N IS LESS THAN 0 OR GREATER THAN ', I2 )+ 9995 FORMAT( ' VALUE OF K IS LESS THAN 0' )+ 9994 FORMAT( ' ABSOLUTE VALUE OF INCX OR INCY IS 0 OR GREATER THAN ',+ $ I2 )+ 9993 FORMAT( ' TESTS OF THE REAL LEVEL 2 BLAS', //' THE F',+ $ 'OLLOWING PARAMETER VALUES WILL BE USED:' )+ 9992 FORMAT( ' FOR N ', 9I6 )+ 9991 FORMAT( ' FOR K ', 7I6 )+ 9990 FORMAT( ' FOR INCX AND INCY ', 7I6 )+ 9989 FORMAT( ' FOR ALPHA ', 7F6.1 )+ 9988 FORMAT( ' FOR BETA ', 7F6.1 )+ 9987 FORMAT( ' AMEND DATA FILE OR INCREASE ARRAY SIZES IN PROGRAM',+ $ /' ******* TESTS ABANDONED *******' )+ 9986 FORMAT( ' SUBPROGRAM NAME ', A6, ' NOT RECOGNIZED', /' ******* T',+ $ 'ESTS ABANDONED *******' )+ 9985 FORMAT( ' ERROR IN SMVCH - IN-LINE DOT PRODUCTS ARE BEING EVALU',+ $ 'ATED WRONGLY.', /' SMVCH WAS CALLED WITH TRANS = ', A1,+ $ ' AND RETURNED SAME = ', L1, ' AND ERR = ', F12.3, '.', /+ $ ' THIS MAY BE DUE TO FAULTS IN THE ARITHMETIC OR THE COMPILER.'+ $ , /' ******* TESTS ABANDONED *******' )+ 9984 FORMAT( A6, L2 )+ 9983 FORMAT( 1X, A6, ' WAS NOT TESTED' )+ 9982 FORMAT( /' END OF TESTS' )+ 9981 FORMAT( /' ******* FATAL ERROR - TESTS ABANDONED *******' )+ 9980 FORMAT( ' ERROR-EXITS WILL NOT BE TESTED' )+*+* End of SBLAT2.+*+ END+ SUBROUTINE SCHK1( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NKB, KB, NALF, ALF, NBET,+ $ BET, NINC, INC, NMAX, INCMAX, A, AA, AS, X, XX,+ $ XS, Y, YY, YS, YT, G )+*+* Tests SGEMV and SGBMV.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ REAL ZERO, HALF+ PARAMETER ( ZERO = 0.0, HALF = 0.5 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER INCMAX, NALF, NBET, NIDIM, NINC, NKB, NMAX,+ $ NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ REAL A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), BET( NBET ), G( NMAX ),+ $ X( NMAX ), XS( NMAX*INCMAX ),+ $ XX( NMAX*INCMAX ), Y( NMAX ),+ $ YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX )+ INTEGER IDIM( NIDIM ), INC( NINC ), KB( NKB )+* .. Local Scalars ..+ REAL ALPHA, ALS, BETA, BLS, ERR, ERRMAX, TRANSL+ INTEGER I, IA, IB, IC, IKU, IM, IN, INCX, INCXS, INCY,+ $ INCYS, IX, IY, KL, KLS, KU, KUS, LAA, LDA,+ $ LDAS, LX, LY, M, ML, MS, N, NARGS, NC, ND, NK,+ $ NL, NS+ LOGICAL BANDED, FULL, NULL, RESET, SAME, TRAN+ CHARACTER*1 TRANS, TRANSS+ CHARACTER*3 ICH+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LSE, LSERES+ EXTERNAL LSE, LSERES+* .. External Subroutines ..+ EXTERNAL SGBMV, SGEMV, SMAKE, SMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, MIN+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'NTC'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'E'+ BANDED = SNAME( 3: 3 ).EQ.'B'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 11+ ELSE IF( BANDED )THEN+ NARGS = 13+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 120 IN = 1, NIDIM+ N = IDIM( IN )+ ND = N/2 + 1+*+ DO 110 IM = 1, 2+ IF( IM.EQ.1 )+ $ M = MAX( N - ND, 0 )+ IF( IM.EQ.2 )+ $ M = MIN( N + ND, NMAX )+*+ IF( BANDED )THEN+ NK = NKB+ ELSE+ NK = 1+ END IF+ DO 100 IKU = 1, NK+ IF( BANDED )THEN+ KU = KB( IKU )+ KL = MAX( KU - 1, 0 )+ ELSE+ KU = N - 1+ KL = M - 1+ END IF+* Set LDA to 1 more than minimum value if room.+ IF( BANDED )THEN+ LDA = KL + KU + 1+ ELSE+ LDA = M+ END IF+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 100+ LAA = LDA*N+ NULL = N.LE.0.OR.M.LE.0+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL SMAKE( SNAME( 2: 3 ), ' ', ' ', M, N, A, NMAX, AA,+ $ LDA, KL, KU, RESET, TRANSL )+*+ DO 90 IC = 1, 3+ TRANS = ICH( IC: IC )+ TRAN = TRANS.EQ.'T'.OR.TRANS.EQ.'C'+*+ IF( TRAN )THEN+ ML = N+ NL = M+ ELSE+ ML = M+ NL = N+ END IF+*+ DO 80 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*NL+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL SMAKE( 'GE', ' ', ' ', 1, NL, X, 1, XX,+ $ ABS( INCX ), 0, NL - 1, RESET, TRANSL )+ IF( NL.GT.1 )THEN+ X( NL/2 ) = ZERO+ XX( 1 + ABS( INCX )*( NL/2 - 1 ) ) = ZERO+ END IF+*+ DO 70 IY = 1, NINC+ INCY = INC( IY )+ LY = ABS( INCY )*ML+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the vector Y.+*+ TRANSL = ZERO+ CALL SMAKE( 'GE', ' ', ' ', 1, ML, Y, 1,+ $ YY, ABS( INCY ), 0, ML - 1,+ $ RESET, TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ TRANSS = TRANS+ MS = M+ NS = N+ KLS = KL+ KUS = KU+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+ BLS = BETA+ DO 30 I = 1, LY+ YS( I ) = YY( I )+ 30 CONTINUE+ INCYS = INCY+*+* Call the subroutine.+*+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME,+ $ TRANS, M, N, ALPHA, LDA, INCX, BETA,+ $ INCY+ IF( REWI )+ $ REWIND NTRA+ CALL SGEMV( TRANS, M, N, ALPHA, AA,+ $ LDA, XX, INCX, BETA, YY,+ $ INCY )+ ELSE IF( BANDED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ TRANS, M, N, KL, KU, ALPHA, LDA,+ $ INCX, BETA, INCY+ IF( REWI )+ $ REWIND NTRA+ CALL SGBMV( TRANS, M, N, KL, KU, ALPHA,+ $ AA, LDA, XX, INCX, BETA,+ $ YY, INCY )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9993 )+ FATAL = .TRUE.+ GO TO 130+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = TRANS.EQ.TRANSS+ ISAME( 2 ) = MS.EQ.M+ ISAME( 3 ) = NS.EQ.N+ IF( FULL )THEN+ ISAME( 4 ) = ALS.EQ.ALPHA+ ISAME( 5 ) = LSE( AS, AA, LAA )+ ISAME( 6 ) = LDAS.EQ.LDA+ ISAME( 7 ) = LSE( XS, XX, LX )+ ISAME( 8 ) = INCXS.EQ.INCX+ ISAME( 9 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 10 ) = LSE( YS, YY, LY )+ ELSE+ ISAME( 10 ) = LSERES( 'GE', ' ', 1,+ $ ML, YS, YY,+ $ ABS( INCY ) )+ END IF+ ISAME( 11 ) = INCYS.EQ.INCY+ ELSE IF( BANDED )THEN+ ISAME( 4 ) = KLS.EQ.KL+ ISAME( 5 ) = KUS.EQ.KU+ ISAME( 6 ) = ALS.EQ.ALPHA+ ISAME( 7 ) = LSE( AS, AA, LAA )+ ISAME( 8 ) = LDAS.EQ.LDA+ ISAME( 9 ) = LSE( XS, XX, LX )+ ISAME( 10 ) = INCXS.EQ.INCX+ ISAME( 11 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 12 ) = LSE( YS, YY, LY )+ ELSE+ ISAME( 12 ) = LSERES( 'GE', ' ', 1,+ $ ML, YS, YY,+ $ ABS( INCY ) )+ END IF+ ISAME( 13 ) = INCYS.EQ.INCY+ END IF+*+* If data was incorrectly changed, report+* and return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 130+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result.+*+ CALL SMVCH( TRANS, M, N, ALPHA, A,+ $ NMAX, X, INCX, BETA, Y,+ $ INCY, YT, G, YY, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 130+ ELSE+* Avoid repeating tests with M.le.0 or+* N.le.0.+ GO TO 110+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 140+*+ 130 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, TRANS, M, N, ALPHA, LDA,+ $ INCX, BETA, INCY+ ELSE IF( BANDED )THEN+ WRITE( NOUT, FMT = 9995 )NC, SNAME, TRANS, M, N, KL, KU,+ $ ALPHA, LDA, INCX, BETA, INCY+ END IF+*+ 140 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', 4( I3, ',' ), F4.1,+ $ ', A,', I3, ', X,', I2, ',', F4.1, ', Y,', I2, ') .' )+ 9994 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', 2( I3, ',' ), F4.1,+ $ ', A,', I3, ', X,', I2, ',', F4.1, ', Y,', I2,+ $ ') .' )+ 9993 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of SCHK1.+*+ END+ SUBROUTINE SCHK2( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NKB, KB, NALF, ALF, NBET,+ $ BET, NINC, INC, NMAX, INCMAX, A, AA, AS, X, XX,+ $ XS, Y, YY, YS, YT, G )+*+* Tests SSYMV, SSBMV and SSPMV.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ REAL ZERO, HALF+ PARAMETER ( ZERO = 0.0, HALF = 0.5 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER INCMAX, NALF, NBET, NIDIM, NINC, NKB, NMAX,+ $ NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ REAL A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), BET( NBET ), G( NMAX ),+ $ X( NMAX ), XS( NMAX*INCMAX ),+ $ XX( NMAX*INCMAX ), Y( NMAX ),+ $ YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX )+ INTEGER IDIM( NIDIM ), INC( NINC ), KB( NKB )+* .. Local Scalars ..+ REAL ALPHA, ALS, BETA, BLS, ERR, ERRMAX, TRANSL+ INTEGER I, IA, IB, IC, IK, IN, INCX, INCXS, INCY,+ $ INCYS, IX, IY, K, KS, LAA, LDA, LDAS, LX, LY,+ $ N, NARGS, NC, NK, NS+ LOGICAL BANDED, FULL, NULL, PACKED, RESET, SAME+ CHARACTER*1 UPLO, UPLOS+ CHARACTER*2 ICH+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LSE, LSERES+ EXTERNAL LSE, LSERES+* .. External Subroutines ..+ EXTERNAL SMAKE, SMVCH, SSBMV, SSPMV, SSYMV+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'UL'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'Y'+ BANDED = SNAME( 3: 3 ).EQ.'B'+ PACKED = SNAME( 3: 3 ).EQ.'P'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 10+ ELSE IF( BANDED )THEN+ NARGS = 11+ ELSE IF( PACKED )THEN+ NARGS = 9+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 110 IN = 1, NIDIM+ N = IDIM( IN )+*+ IF( BANDED )THEN+ NK = NKB+ ELSE+ NK = 1+ END IF+ DO 100 IK = 1, NK+ IF( BANDED )THEN+ K = KB( IK )+ ELSE+ K = N - 1+ END IF+* Set LDA to 1 more than minimum value if room.+ IF( BANDED )THEN+ LDA = K + 1+ ELSE+ LDA = N+ END IF+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 100+ IF( PACKED )THEN+ LAA = ( N*( N + 1 ) )/2+ ELSE+ LAA = LDA*N+ END IF+ NULL = N.LE.0+*+ DO 90 IC = 1, 2+ UPLO = ICH( IC: IC )+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL SMAKE( SNAME( 2: 3 ), UPLO, ' ', N, N, A, NMAX, AA,+ $ LDA, K, K, RESET, TRANSL )+*+ DO 80 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*N+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL SMAKE( 'GE', ' ', ' ', 1, N, X, 1, XX,+ $ ABS( INCX ), 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ X( N/2 ) = ZERO+ XX( 1 + ABS( INCX )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 70 IY = 1, NINC+ INCY = INC( IY )+ LY = ABS( INCY )*N+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the vector Y.+*+ TRANSL = ZERO+ CALL SMAKE( 'GE', ' ', ' ', 1, N, Y, 1, YY,+ $ ABS( INCY ), 0, N - 1, RESET,+ $ TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ UPLOS = UPLO+ NS = N+ KS = K+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+ BLS = BETA+ DO 30 I = 1, LY+ YS( I ) = YY( I )+ 30 CONTINUE+ INCYS = INCY+*+* Call the subroutine.+*+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME,+ $ UPLO, N, ALPHA, LDA, INCX, BETA, INCY+ IF( REWI )+ $ REWIND NTRA+ CALL SSYMV( UPLO, N, ALPHA, AA, LDA, XX,+ $ INCX, BETA, YY, INCY )+ ELSE IF( BANDED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME,+ $ UPLO, N, K, ALPHA, LDA, INCX, BETA,+ $ INCY+ IF( REWI )+ $ REWIND NTRA+ CALL SSBMV( UPLO, N, K, ALPHA, AA, LDA,+ $ XX, INCX, BETA, YY, INCY )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ UPLO, N, ALPHA, INCX, BETA, INCY+ IF( REWI )+ $ REWIND NTRA+ CALL SSPMV( UPLO, N, ALPHA, AA, XX, INCX,+ $ BETA, YY, INCY )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLO.EQ.UPLOS+ ISAME( 2 ) = NS.EQ.N+ IF( FULL )THEN+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LSE( AS, AA, LAA )+ ISAME( 5 ) = LDAS.EQ.LDA+ ISAME( 6 ) = LSE( XS, XX, LX )+ ISAME( 7 ) = INCXS.EQ.INCX+ ISAME( 8 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 9 ) = LSE( YS, YY, LY )+ ELSE+ ISAME( 9 ) = LSERES( 'GE', ' ', 1, N,+ $ YS, YY, ABS( INCY ) )+ END IF+ ISAME( 10 ) = INCYS.EQ.INCY+ ELSE IF( BANDED )THEN+ ISAME( 3 ) = KS.EQ.K+ ISAME( 4 ) = ALS.EQ.ALPHA+ ISAME( 5 ) = LSE( AS, AA, LAA )+ ISAME( 6 ) = LDAS.EQ.LDA+ ISAME( 7 ) = LSE( XS, XX, LX )+ ISAME( 8 ) = INCXS.EQ.INCX+ ISAME( 9 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 10 ) = LSE( YS, YY, LY )+ ELSE+ ISAME( 10 ) = LSERES( 'GE', ' ', 1, N,+ $ YS, YY, ABS( INCY ) )+ END IF+ ISAME( 11 ) = INCYS.EQ.INCY+ ELSE IF( PACKED )THEN+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LSE( AS, AA, LAA )+ ISAME( 5 ) = LSE( XS, XX, LX )+ ISAME( 6 ) = INCXS.EQ.INCX+ ISAME( 7 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 8 ) = LSE( YS, YY, LY )+ ELSE+ ISAME( 8 ) = LSERES( 'GE', ' ', 1, N,+ $ YS, YY, ABS( INCY ) )+ END IF+ ISAME( 9 ) = INCYS.EQ.INCY+ END IF+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result.+*+ CALL SMVCH( 'N', N, N, ALPHA, A, NMAX, X,+ $ INCX, BETA, Y, INCY, YT, G,+ $ YY, EPS, ERR, FATAL, NOUT,+ $ .TRUE. )+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 120+ ELSE+* Avoid repeating tests with N.le.0+ GO TO 110+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, N, ALPHA, LDA, INCX,+ $ BETA, INCY+ ELSE IF( BANDED )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, N, K, ALPHA, LDA,+ $ INCX, BETA, INCY+ ELSE IF( PACKED )THEN+ WRITE( NOUT, FMT = 9995 )NC, SNAME, UPLO, N, ALPHA, INCX,+ $ BETA, INCY+ END IF+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',', F4.1, ', AP',+ $ ', X,', I2, ',', F4.1, ', Y,', I2, ') .' )+ 9994 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', 2( I3, ',' ), F4.1,+ $ ', A,', I3, ', X,', I2, ',', F4.1, ', Y,', I2,+ $ ') .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',', F4.1, ', A,',+ $ I3, ', X,', I2, ',', F4.1, ', Y,', I2, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of SCHK2.+*+ END+ SUBROUTINE SCHK3( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NKB, KB, NINC, INC, NMAX,+ $ INCMAX, A, AA, AS, X, XX, XS, XT, G, Z )+*+* Tests STRMV, STBMV, STPMV, STRSV, STBSV and STPSV.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ REAL ZERO, HALF, ONE+ PARAMETER ( ZERO = 0.0, HALF = 0.5, ONE = 1.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER INCMAX, NIDIM, NINC, NKB, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ REAL A( NMAX, NMAX ), AA( NMAX*NMAX ),+ $ AS( NMAX*NMAX ), G( NMAX ), X( NMAX ),+ $ XS( NMAX*INCMAX ), XT( NMAX ),+ $ XX( NMAX*INCMAX ), Z( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC ), KB( NKB )+* .. Local Scalars ..+ REAL ERR, ERRMAX, TRANSL+ INTEGER I, ICD, ICT, ICU, IK, IN, INCX, INCXS, IX, K,+ $ KS, LAA, LDA, LDAS, LX, N, NARGS, NC, NK, NS+ LOGICAL BANDED, FULL, NULL, PACKED, RESET, SAME+ CHARACTER*1 DIAG, DIAGS, TRANS, TRANSS, UPLO, UPLOS+ CHARACTER*2 ICHD, ICHU+ CHARACTER*3 ICHT+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LSE, LSERES+ EXTERNAL LSE, LSERES+* .. External Subroutines ..+ EXTERNAL SMAKE, SMVCH, STBMV, STBSV, STPMV, STPSV,+ $ STRMV, STRSV+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHU/'UL'/, ICHT/'NTC'/, ICHD/'UN'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'R'+ BANDED = SNAME( 3: 3 ).EQ.'B'+ PACKED = SNAME( 3: 3 ).EQ.'P'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 8+ ELSE IF( BANDED )THEN+ NARGS = 9+ ELSE IF( PACKED )THEN+ NARGS = 7+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+* Set up zero vector for SMVCH.+ DO 10 I = 1, NMAX+ Z( I ) = ZERO+ 10 CONTINUE+*+ DO 110 IN = 1, NIDIM+ N = IDIM( IN )+*+ IF( BANDED )THEN+ NK = NKB+ ELSE+ NK = 1+ END IF+ DO 100 IK = 1, NK+ IF( BANDED )THEN+ K = KB( IK )+ ELSE+ K = N - 1+ END IF+* Set LDA to 1 more than minimum value if room.+ IF( BANDED )THEN+ LDA = K + 1+ ELSE+ LDA = N+ END IF+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 100+ IF( PACKED )THEN+ LAA = ( N*( N + 1 ) )/2+ ELSE+ LAA = LDA*N+ END IF+ NULL = N.LE.0+*+ DO 90 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+*+ DO 80 ICT = 1, 3+ TRANS = ICHT( ICT: ICT )+*+ DO 70 ICD = 1, 2+ DIAG = ICHD( ICD: ICD )+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL SMAKE( SNAME( 2: 3 ), UPLO, DIAG, N, N, A,+ $ NMAX, AA, LDA, K, K, RESET, TRANSL )+*+ DO 60 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*N+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL SMAKE( 'GE', ' ', ' ', 1, N, X, 1, XX,+ $ ABS( INCX ), 0, N - 1, RESET,+ $ TRANSL )+ IF( N.GT.1 )THEN+ X( N/2 ) = ZERO+ XX( 1 + ABS( INCX )*( N/2 - 1 ) ) = ZERO+ END IF+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ TRANSS = TRANS+ DIAGS = DIAG+ NS = N+ KS = K+ DO 20 I = 1, LAA+ AS( I ) = AA( I )+ 20 CONTINUE+ LDAS = LDA+ DO 30 I = 1, LX+ XS( I ) = XX( I )+ 30 CONTINUE+ INCXS = INCX+*+* Call the subroutine.+*+ IF( SNAME( 4: 5 ).EQ.'MV' )THEN+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, LDA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL STRMV( UPLO, TRANS, DIAG, N, AA, LDA,+ $ XX, INCX )+ ELSE IF( BANDED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, K, LDA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL STBMV( UPLO, TRANS, DIAG, N, K, AA,+ $ LDA, XX, INCX )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL STPMV( UPLO, TRANS, DIAG, N, AA, XX,+ $ INCX )+ END IF+ ELSE IF( SNAME( 4: 5 ).EQ.'SV' )THEN+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, LDA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL STRSV( UPLO, TRANS, DIAG, N, AA, LDA,+ $ XX, INCX )+ ELSE IF( BANDED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, K, LDA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL STBSV( UPLO, TRANS, DIAG, N, K, AA,+ $ LDA, XX, INCX )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL STPSV( UPLO, TRANS, DIAG, N, AA, XX,+ $ INCX )+ END IF+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLO.EQ.UPLOS+ ISAME( 2 ) = TRANS.EQ.TRANSS+ ISAME( 3 ) = DIAG.EQ.DIAGS+ ISAME( 4 ) = NS.EQ.N+ IF( FULL )THEN+ ISAME( 5 ) = LSE( AS, AA, LAA )+ ISAME( 6 ) = LDAS.EQ.LDA+ IF( NULL )THEN+ ISAME( 7 ) = LSE( XS, XX, LX )+ ELSE+ ISAME( 7 ) = LSERES( 'GE', ' ', 1, N, XS,+ $ XX, ABS( INCX ) )+ END IF+ ISAME( 8 ) = INCXS.EQ.INCX+ ELSE IF( BANDED )THEN+ ISAME( 5 ) = KS.EQ.K+ ISAME( 6 ) = LSE( AS, AA, LAA )+ ISAME( 7 ) = LDAS.EQ.LDA+ IF( NULL )THEN+ ISAME( 8 ) = LSE( XS, XX, LX )+ ELSE+ ISAME( 8 ) = LSERES( 'GE', ' ', 1, N, XS,+ $ XX, ABS( INCX ) )+ END IF+ ISAME( 9 ) = INCXS.EQ.INCX+ ELSE IF( PACKED )THEN+ ISAME( 5 ) = LSE( AS, AA, LAA )+ IF( NULL )THEN+ ISAME( 6 ) = LSE( XS, XX, LX )+ ELSE+ ISAME( 6 ) = LSERES( 'GE', ' ', 1, N, XS,+ $ XX, ABS( INCX ) )+ END IF+ ISAME( 7 ) = INCXS.EQ.INCX+ END IF+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+ IF( SNAME( 4: 5 ).EQ.'MV' )THEN+*+* Check the result.+*+ CALL SMVCH( TRANS, N, N, ONE, A, NMAX, X,+ $ INCX, ZERO, Z, INCX, XT, G,+ $ XX, EPS, ERR, FATAL, NOUT,+ $ .TRUE. )+ ELSE IF( SNAME( 4: 5 ).EQ.'SV' )THEN+*+* Compute approximation to original vector.+*+ DO 50 I = 1, N+ Z( I ) = XX( 1 + ( I - 1 )*+ $ ABS( INCX ) )+ XX( 1 + ( I - 1 )*ABS( INCX ) )+ $ = X( I )+ 50 CONTINUE+ CALL SMVCH( TRANS, N, N, ONE, A, NMAX, Z,+ $ INCX, ZERO, X, INCX, XT, G,+ $ XX, EPS, ERR, FATAL, NOUT,+ $ .FALSE. )+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and return.+ IF( FATAL )+ $ GO TO 120+ ELSE+* Avoid repeating tests with N.le.0.+ GO TO 110+ END IF+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, TRANS, DIAG, N, LDA,+ $ INCX+ ELSE IF( BANDED )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, TRANS, DIAG, N, K,+ $ LDA, INCX+ ELSE IF( PACKED )THEN+ WRITE( NOUT, FMT = 9995 )NC, SNAME, UPLO, TRANS, DIAG, N, INCX+ END IF+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(', 3( '''', A1, ''',' ), I3, ', AP, ',+ $ 'X,', I2, ') .' )+ 9994 FORMAT( 1X, I6, ': ', A6, '(', 3( '''', A1, ''',' ), 2( I3, ',' ),+ $ ' A,', I3, ', X,', I2, ') .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(', 3( '''', A1, ''',' ), I3, ', A,',+ $ I3, ', X,', I2, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of SCHK3.+*+ END+ SUBROUTINE SCHK4( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC, NMAX,+ $ INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS, YT, G,+ $ Z )+*+* Tests SGER.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ REAL ZERO, HALF, ONE+ PARAMETER ( ZERO = 0.0, HALF = 0.5, ONE = 1.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER INCMAX, NALF, NIDIM, NINC, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ REAL A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), G( NMAX ), X( NMAX ),+ $ XS( NMAX*INCMAX ), XX( NMAX*INCMAX ),+ $ Y( NMAX ), YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX ), Z( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC )+* .. Local Scalars ..+ REAL ALPHA, ALS, ERR, ERRMAX, TRANSL+ INTEGER I, IA, IM, IN, INCX, INCXS, INCY, INCYS, IX,+ $ IY, J, LAA, LDA, LDAS, LX, LY, M, MS, N, NARGS,+ $ NC, ND, NS+ LOGICAL NULL, RESET, SAME+* .. Local Arrays ..+ REAL W( 1 )+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LSE, LSERES+ EXTERNAL LSE, LSERES+* .. External Subroutines ..+ EXTERNAL SGER, SMAKE, SMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, MIN+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Executable Statements ..+* Define the number of arguments.+ NARGS = 9+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 120 IN = 1, NIDIM+ N = IDIM( IN )+ ND = N/2 + 1+*+ DO 110 IM = 1, 2+ IF( IM.EQ.1 )+ $ M = MAX( N - ND, 0 )+ IF( IM.EQ.2 )+ $ M = MIN( N + ND, NMAX )+*+* Set LDA to 1 more than minimum value if room.+ LDA = M+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 110+ LAA = LDA*N+ NULL = N.LE.0.OR.M.LE.0+*+ DO 100 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*M+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL SMAKE( 'GE', ' ', ' ', 1, M, X, 1, XX, ABS( INCX ),+ $ 0, M - 1, RESET, TRANSL )+ IF( M.GT.1 )THEN+ X( M/2 ) = ZERO+ XX( 1 + ABS( INCX )*( M/2 - 1 ) ) = ZERO+ END IF+*+ DO 90 IY = 1, NINC+ INCY = INC( IY )+ LY = ABS( INCY )*N+*+* Generate the vector Y.+*+ TRANSL = ZERO+ CALL SMAKE( 'GE', ' ', ' ', 1, N, Y, 1, YY,+ $ ABS( INCY ), 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ Y( N/2 ) = ZERO+ YY( 1 + ABS( INCY )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 80 IA = 1, NALF+ ALPHA = ALF( IA )+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL SMAKE( SNAME( 2: 3 ), ' ', ' ', M, N, A, NMAX,+ $ AA, LDA, M - 1, N - 1, RESET, TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ MS = M+ NS = N+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+ DO 30 I = 1, LY+ YS( I ) = YY( I )+ 30 CONTINUE+ INCYS = INCY+*+* Call the subroutine.+*+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, M, N,+ $ ALPHA, INCX, INCY, LDA+ IF( REWI )+ $ REWIND NTRA+ CALL SGER( M, N, ALPHA, XX, INCX, YY, INCY, AA,+ $ LDA )+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9993 )+ FATAL = .TRUE.+ GO TO 140+ END IF+*+* See what data changed inside subroutine.+*+ ISAME( 1 ) = MS.EQ.M+ ISAME( 2 ) = NS.EQ.N+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LSE( XS, XX, LX )+ ISAME( 5 ) = INCXS.EQ.INCX+ ISAME( 6 ) = LSE( YS, YY, LY )+ ISAME( 7 ) = INCYS.EQ.INCY+ IF( NULL )THEN+ ISAME( 8 ) = LSE( AS, AA, LAA )+ ELSE+ ISAME( 8 ) = LSERES( 'GE', ' ', M, N, AS, AA,+ $ LDA )+ END IF+ ISAME( 9 ) = LDAS.EQ.LDA+*+* If data was incorrectly changed, report and return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 140+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ IF( INCX.GT.0 )THEN+ DO 50 I = 1, M+ Z( I ) = X( I )+ 50 CONTINUE+ ELSE+ DO 60 I = 1, M+ Z( I ) = X( M - I + 1 )+ 60 CONTINUE+ END IF+ DO 70 J = 1, N+ IF( INCY.GT.0 )THEN+ W( 1 ) = Y( J )+ ELSE+ W( 1 ) = Y( N - J + 1 )+ END IF+ CALL SMVCH( 'N', M, 1, ALPHA, Z, NMAX, W, 1,+ $ ONE, A( 1, J ), 1, YT, G,+ $ AA( 1 + ( J - 1 )*LDA ), EPS,+ $ ERR, FATAL, NOUT, .TRUE. )+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and return.+ IF( FATAL )+ $ GO TO 130+ 70 CONTINUE+ ELSE+* Avoid repeating tests with M.le.0 or N.le.0.+ GO TO 110+ END IF+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 150+*+ 130 CONTINUE+ WRITE( NOUT, FMT = 9995 )J+*+ 140 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9994 )NC, SNAME, M, N, ALPHA, INCX, INCY, LDA+*+ 150 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(', 2( I3, ',' ), F4.1, ', X,', I2,+ $ ', Y,', I2, ', A,', I3, ') .' )+ 9993 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of SCHK4.+*+ END+ SUBROUTINE SCHK5( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC, NMAX,+ $ INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS, YT, G,+ $ Z )+*+* Tests SSYR and SSPR.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ REAL ZERO, HALF, ONE+ PARAMETER ( ZERO = 0.0, HALF = 0.5, ONE = 1.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER INCMAX, NALF, NIDIM, NINC, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ REAL A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), G( NMAX ), X( NMAX ),+ $ XS( NMAX*INCMAX ), XX( NMAX*INCMAX ),+ $ Y( NMAX ), YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX ), Z( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC )+* .. Local Scalars ..+ REAL ALPHA, ALS, ERR, ERRMAX, TRANSL+ INTEGER I, IA, IC, IN, INCX, INCXS, IX, J, JA, JJ, LAA,+ $ LDA, LDAS, LJ, LX, N, NARGS, NC, NS+ LOGICAL FULL, NULL, PACKED, RESET, SAME, UPPER+ CHARACTER*1 UPLO, UPLOS+ CHARACTER*2 ICH+* .. Local Arrays ..+ REAL W( 1 )+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LSE, LSERES+ EXTERNAL LSE, LSERES+* .. External Subroutines ..+ EXTERNAL SMAKE, SMVCH, SSPR, SSYR+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'UL'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'Y'+ PACKED = SNAME( 3: 3 ).EQ.'P'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 7+ ELSE IF( PACKED )THEN+ NARGS = 6+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 100 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDA to 1 more than minimum value if room.+ LDA = N+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 100+ IF( PACKED )THEN+ LAA = ( N*( N + 1 ) )/2+ ELSE+ LAA = LDA*N+ END IF+*+ DO 90 IC = 1, 2+ UPLO = ICH( IC: IC )+ UPPER = UPLO.EQ.'U'+*+ DO 80 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*N+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL SMAKE( 'GE', ' ', ' ', 1, N, X, 1, XX, ABS( INCX ),+ $ 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ X( N/2 ) = ZERO+ XX( 1 + ABS( INCX )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 70 IA = 1, NALF+ ALPHA = ALF( IA )+ NULL = N.LE.0.OR.ALPHA.EQ.ZERO+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL SMAKE( SNAME( 2: 3 ), UPLO, ' ', N, N, A, NMAX,+ $ AA, LDA, N - 1, N - 1, RESET, TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ NS = N+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+*+* Call the subroutine.+*+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME, UPLO, N,+ $ ALPHA, INCX, LDA+ IF( REWI )+ $ REWIND NTRA+ CALL SSYR( UPLO, N, ALPHA, XX, INCX, AA, LDA )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, UPLO, N,+ $ ALPHA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL SSPR( UPLO, N, ALPHA, XX, INCX, AA )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLO.EQ.UPLOS+ ISAME( 2 ) = NS.EQ.N+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LSE( XS, XX, LX )+ ISAME( 5 ) = INCXS.EQ.INCX+ IF( NULL )THEN+ ISAME( 6 ) = LSE( AS, AA, LAA )+ ELSE+ ISAME( 6 ) = LSERES( SNAME( 2: 3 ), UPLO, N, N, AS,+ $ AA, LDA )+ END IF+ IF( .NOT.PACKED )THEN+ ISAME( 7 ) = LDAS.EQ.LDA+ END IF+*+* If data was incorrectly changed, report and return.+*+ SAME = .TRUE.+ DO 30 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 30 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ IF( INCX.GT.0 )THEN+ DO 40 I = 1, N+ Z( I ) = X( I )+ 40 CONTINUE+ ELSE+ DO 50 I = 1, N+ Z( I ) = X( N - I + 1 )+ 50 CONTINUE+ END IF+ JA = 1+ DO 60 J = 1, N+ W( 1 ) = Z( J )+ IF( UPPER )THEN+ JJ = 1+ LJ = J+ ELSE+ JJ = J+ LJ = N - J + 1+ END IF+ CALL SMVCH( 'N', LJ, 1, ALPHA, Z( JJ ), LJ, W,+ $ 1, ONE, A( JJ, J ), 1, YT, G,+ $ AA( JA ), EPS, ERR, FATAL, NOUT,+ $ .TRUE. )+ IF( FULL )THEN+ IF( UPPER )THEN+ JA = JA + LDA+ ELSE+ JA = JA + LDA + 1+ END IF+ ELSE+ JA = JA + LJ+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and return.+ IF( FATAL )+ $ GO TO 110+ 60 CONTINUE+ ELSE+* Avoid repeating tests if N.le.0.+ IF( N.LE.0 )+ $ GO TO 100+ END IF+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 110 CONTINUE+ WRITE( NOUT, FMT = 9995 )J+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, N, ALPHA, INCX, LDA+ ELSE IF( PACKED )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, N, ALPHA, INCX+ END IF+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',', F4.1, ', X,',+ $ I2, ', AP) .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',', F4.1, ', X,',+ $ I2, ', A,', I3, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of SCHK5.+*+ END+ SUBROUTINE SCHK6( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC, NMAX,+ $ INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS, YT, G,+ $ Z )+*+* Tests SSYR2 and SSPR2.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ REAL ZERO, HALF, ONE+ PARAMETER ( ZERO = 0.0, HALF = 0.5, ONE = 1.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER INCMAX, NALF, NIDIM, NINC, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ REAL A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), G( NMAX ), X( NMAX ),+ $ XS( NMAX*INCMAX ), XX( NMAX*INCMAX ),+ $ Y( NMAX ), YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX ), Z( NMAX, 2 )+ INTEGER IDIM( NIDIM ), INC( NINC )+* .. Local Scalars ..+ REAL ALPHA, ALS, ERR, ERRMAX, TRANSL+ INTEGER I, IA, IC, IN, INCX, INCXS, INCY, INCYS, IX,+ $ IY, J, JA, JJ, LAA, LDA, LDAS, LJ, LX, LY, N,+ $ NARGS, NC, NS+ LOGICAL FULL, NULL, PACKED, RESET, SAME, UPPER+ CHARACTER*1 UPLO, UPLOS+ CHARACTER*2 ICH+* .. Local Arrays ..+ REAL W( 2 )+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LSE, LSERES+ EXTERNAL LSE, LSERES+* .. External Subroutines ..+ EXTERNAL SMAKE, SMVCH, SSPR2, SSYR2+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'UL'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'Y'+ PACKED = SNAME( 3: 3 ).EQ.'P'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 9+ ELSE IF( PACKED )THEN+ NARGS = 8+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 140 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDA to 1 more than minimum value if room.+ LDA = N+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 140+ IF( PACKED )THEN+ LAA = ( N*( N + 1 ) )/2+ ELSE+ LAA = LDA*N+ END IF+*+ DO 130 IC = 1, 2+ UPLO = ICH( IC: IC )+ UPPER = UPLO.EQ.'U'+*+ DO 120 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*N+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL SMAKE( 'GE', ' ', ' ', 1, N, X, 1, XX, ABS( INCX ),+ $ 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ X( N/2 ) = ZERO+ XX( 1 + ABS( INCX )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 110 IY = 1, NINC+ INCY = INC( IY )+ LY = ABS( INCY )*N+*+* Generate the vector Y.+*+ TRANSL = ZERO+ CALL SMAKE( 'GE', ' ', ' ', 1, N, Y, 1, YY,+ $ ABS( INCY ), 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ Y( N/2 ) = ZERO+ YY( 1 + ABS( INCY )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 100 IA = 1, NALF+ ALPHA = ALF( IA )+ NULL = N.LE.0.OR.ALPHA.EQ.ZERO+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL SMAKE( SNAME( 2: 3 ), UPLO, ' ', N, N, A,+ $ NMAX, AA, LDA, N - 1, N - 1, RESET,+ $ TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ NS = N+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+ DO 30 I = 1, LY+ YS( I ) = YY( I )+ 30 CONTINUE+ INCYS = INCY+*+* Call the subroutine.+*+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME, UPLO, N,+ $ ALPHA, INCX, INCY, LDA+ IF( REWI )+ $ REWIND NTRA+ CALL SSYR2( UPLO, N, ALPHA, XX, INCX, YY, INCY,+ $ AA, LDA )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, UPLO, N,+ $ ALPHA, INCX, INCY+ IF( REWI )+ $ REWIND NTRA+ CALL SSPR2( UPLO, N, ALPHA, XX, INCX, YY, INCY,+ $ AA )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 160+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLO.EQ.UPLOS+ ISAME( 2 ) = NS.EQ.N+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LSE( XS, XX, LX )+ ISAME( 5 ) = INCXS.EQ.INCX+ ISAME( 6 ) = LSE( YS, YY, LY )+ ISAME( 7 ) = INCYS.EQ.INCY+ IF( NULL )THEN+ ISAME( 8 ) = LSE( AS, AA, LAA )+ ELSE+ ISAME( 8 ) = LSERES( SNAME( 2: 3 ), UPLO, N, N,+ $ AS, AA, LDA )+ END IF+ IF( .NOT.PACKED )THEN+ ISAME( 9 ) = LDAS.EQ.LDA+ END IF+*+* If data was incorrectly changed, report and return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 160+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ IF( INCX.GT.0 )THEN+ DO 50 I = 1, N+ Z( I, 1 ) = X( I )+ 50 CONTINUE+ ELSE+ DO 60 I = 1, N+ Z( I, 1 ) = X( N - I + 1 )+ 60 CONTINUE+ END IF+ IF( INCY.GT.0 )THEN+ DO 70 I = 1, N+ Z( I, 2 ) = Y( I )+ 70 CONTINUE+ ELSE+ DO 80 I = 1, N+ Z( I, 2 ) = Y( N - I + 1 )+ 80 CONTINUE+ END IF+ JA = 1+ DO 90 J = 1, N+ W( 1 ) = Z( J, 2 )+ W( 2 ) = Z( J, 1 )+ IF( UPPER )THEN+ JJ = 1+ LJ = J+ ELSE+ JJ = J+ LJ = N - J + 1+ END IF+ CALL SMVCH( 'N', LJ, 2, ALPHA, Z( JJ, 1 ),+ $ NMAX, W, 1, ONE, A( JJ, J ), 1,+ $ YT, G, AA( JA ), EPS, ERR, FATAL,+ $ NOUT, .TRUE. )+ IF( FULL )THEN+ IF( UPPER )THEN+ JA = JA + LDA+ ELSE+ JA = JA + LDA + 1+ END IF+ ELSE+ JA = JA + LJ+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and return.+ IF( FATAL )+ $ GO TO 150+ 90 CONTINUE+ ELSE+* Avoid repeating tests with N.le.0.+ IF( N.LE.0 )+ $ GO TO 140+ END IF+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+ 130 CONTINUE+*+ 140 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 170+*+ 150 CONTINUE+ WRITE( NOUT, FMT = 9995 )J+*+ 160 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, N, ALPHA, INCX,+ $ INCY, LDA+ ELSE IF( PACKED )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, N, ALPHA, INCX, INCY+ END IF+*+ 170 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',', F4.1, ', X,',+ $ I2, ', Y,', I2, ', AP) .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',', F4.1, ', X,',+ $ I2, ', Y,', I2, ', A,', I3, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of SCHK6.+*+ END+ SUBROUTINE SCHKE( ISNUM, SRNAMT, NOUT )+*+* Tests the error exits from the Level 2 Blas.+* Requires a special version of the error-handling routine XERBLA.+* ALPHA, BETA, A, X and Y should not need to be defined.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER ISNUM, NOUT+ CHARACTER*6 SRNAMT+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Local Scalars ..+ REAL ALPHA, BETA+* .. Local Arrays ..+ REAL A( 1, 1 ), X( 1 ), Y( 1 )+* .. External Subroutines ..+ EXTERNAL CHKXER, SGBMV, SGEMV, SGER, SSBMV, SSPMV, SSPR,+ $ SSPR2, SSYMV, SSYR, SSYR2, STBMV, STBSV, STPMV,+ $ STPSV, STRMV, STRSV+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Executable Statements ..+* OK is set to .FALSE. by the special version of XERBLA or by CHKXER+* if anything is wrong.+ OK = .TRUE.+* LERR is set to .TRUE. by the special version of XERBLA each time+* it is called, and is then tested and re-set by CHKXER.+ LERR = .FALSE.+ GO TO ( 10, 20, 30, 40, 50, 60, 70, 80,+ $ 90, 100, 110, 120, 130, 140, 150,+ $ 160 )ISNUM+ 10 INFOT = 1+ CALL SGEMV( '/', 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL SGEMV( 'N', -1, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SGEMV( 'N', 0, -1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL SGEMV( 'N', 2, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL SGEMV( 'N', 0, 0, ALPHA, A, 1, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL SGEMV( 'N', 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 20 INFOT = 1+ CALL SGBMV( '/', 0, 0, 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL SGBMV( 'N', -1, 0, 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SGBMV( 'N', 0, -1, 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL SGBMV( 'N', 0, 0, -1, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL SGBMV( 'N', 2, 0, 0, -1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL SGBMV( 'N', 0, 0, 1, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL SGBMV( 'N', 0, 0, 0, 0, ALPHA, A, 1, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL SGBMV( 'N', 0, 0, 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 30 INFOT = 1+ CALL SSYMV( '/', 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL SSYMV( 'U', -1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL SSYMV( 'U', 2, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL SSYMV( 'U', 0, ALPHA, A, 1, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL SSYMV( 'U', 0, ALPHA, A, 1, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 40 INFOT = 1+ CALL SSBMV( '/', 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL SSBMV( 'U', -1, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SSBMV( 'U', 0, -1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL SSBMV( 'U', 0, 1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL SSBMV( 'U', 0, 0, ALPHA, A, 1, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL SSBMV( 'U', 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 50 INFOT = 1+ CALL SSPMV( '/', 0, ALPHA, A, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL SSPMV( 'U', -1, ALPHA, A, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL SSPMV( 'U', 0, ALPHA, A, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL SSPMV( 'U', 0, ALPHA, A, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 60 INFOT = 1+ CALL STRMV( '/', 'N', 'N', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL STRMV( 'U', '/', 'N', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL STRMV( 'U', 'N', '/', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL STRMV( 'U', 'N', 'N', -1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRMV( 'U', 'N', 'N', 2, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL STRMV( 'U', 'N', 'N', 0, A, 1, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 70 INFOT = 1+ CALL STBMV( '/', 'N', 'N', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL STBMV( 'U', '/', 'N', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL STBMV( 'U', 'N', '/', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL STBMV( 'U', 'N', 'N', -1, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STBMV( 'U', 'N', 'N', 0, -1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL STBMV( 'U', 'N', 'N', 0, 1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STBMV( 'U', 'N', 'N', 0, 0, A, 1, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 80 INFOT = 1+ CALL STPMV( '/', 'N', 'N', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL STPMV( 'U', '/', 'N', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL STPMV( 'U', 'N', '/', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL STPMV( 'U', 'N', 'N', -1, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL STPMV( 'U', 'N', 'N', 0, A, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 90 INFOT = 1+ CALL STRSV( '/', 'N', 'N', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL STRSV( 'U', '/', 'N', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL STRSV( 'U', 'N', '/', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL STRSV( 'U', 'N', 'N', -1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRSV( 'U', 'N', 'N', 2, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL STRSV( 'U', 'N', 'N', 0, A, 1, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 100 INFOT = 1+ CALL STBSV( '/', 'N', 'N', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL STBSV( 'U', '/', 'N', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL STBSV( 'U', 'N', '/', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL STBSV( 'U', 'N', 'N', -1, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STBSV( 'U', 'N', 'N', 0, -1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL STBSV( 'U', 'N', 'N', 0, 1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STBSV( 'U', 'N', 'N', 0, 0, A, 1, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 110 INFOT = 1+ CALL STPSV( '/', 'N', 'N', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL STPSV( 'U', '/', 'N', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL STPSV( 'U', 'N', '/', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL STPSV( 'U', 'N', 'N', -1, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL STPSV( 'U', 'N', 'N', 0, A, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 120 INFOT = 1+ CALL SGER( -1, 0, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL SGER( 0, -1, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL SGER( 0, 0, ALPHA, X, 0, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL SGER( 0, 0, ALPHA, X, 1, Y, 0, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL SGER( 2, 0, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 130 INFOT = 1+ CALL SSYR( '/', 0, ALPHA, X, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL SSYR( 'U', -1, ALPHA, X, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL SSYR( 'U', 0, ALPHA, X, 0, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL SSYR( 'U', 2, ALPHA, X, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 140 INFOT = 1+ CALL SSPR( '/', 0, ALPHA, X, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL SSPR( 'U', -1, ALPHA, X, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL SSPR( 'U', 0, ALPHA, X, 0, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 150 INFOT = 1+ CALL SSYR2( '/', 0, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL SSYR2( 'U', -1, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL SSYR2( 'U', 0, ALPHA, X, 0, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL SSYR2( 'U', 0, ALPHA, X, 1, Y, 0, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL SSYR2( 'U', 2, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 170+ 160 INFOT = 1+ CALL SSPR2( '/', 0, ALPHA, X, 1, Y, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL SSPR2( 'U', -1, ALPHA, X, 1, Y, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL SSPR2( 'U', 0, ALPHA, X, 0, Y, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL SSPR2( 'U', 0, ALPHA, X, 1, Y, 0, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+*+ 170 IF( OK )THEN+ WRITE( NOUT, FMT = 9999 )SRNAMT+ ELSE+ WRITE( NOUT, FMT = 9998 )SRNAMT+ END IF+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE TESTS OF ERROR-EXITS' )+ 9998 FORMAT( ' ******* ', A6, ' FAILED THE TESTS OF ERROR-EXITS *****',+ $ '**' )+*+* End of SCHKE.+*+ END+ SUBROUTINE SMAKE( TYPE, UPLO, DIAG, M, N, A, NMAX, AA, LDA, KL,+ $ KU, RESET, TRANSL )+*+* Generates values for an M by N matrix A within the bandwidth+* defined by KL and KU.+* Stores the values in the array AA in the data structure required+* by the routine, with unwanted elements set to rogue value.+*+* TYPE is 'GE', 'GB', 'SY', 'SB', 'SP', 'TR', 'TB' OR 'TP'.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ REAL ZERO, ONE+ PARAMETER ( ZERO = 0.0, ONE = 1.0 )+ REAL ROGUE+ PARAMETER ( ROGUE = -1.0E10 )+* .. Scalar Arguments ..+ REAL TRANSL+ INTEGER KL, KU, LDA, M, N, NMAX+ LOGICAL RESET+ CHARACTER*1 DIAG, UPLO+ CHARACTER*2 TYPE+* .. Array Arguments ..+ REAL A( NMAX, * ), AA( * )+* .. Local Scalars ..+ INTEGER I, I1, I2, I3, IBEG, IEND, IOFF, J, KK+ LOGICAL GEN, LOWER, SYM, TRI, UNIT, UPPER+* .. External Functions ..+ REAL SBEG+ EXTERNAL SBEG+* .. Intrinsic Functions ..+ INTRINSIC MAX, MIN+* .. Executable Statements ..+ GEN = TYPE( 1: 1 ).EQ.'G'+ SYM = TYPE( 1: 1 ).EQ.'S'+ TRI = TYPE( 1: 1 ).EQ.'T'+ UPPER = ( SYM.OR.TRI ).AND.UPLO.EQ.'U'+ LOWER = ( SYM.OR.TRI ).AND.UPLO.EQ.'L'+ UNIT = TRI.AND.DIAG.EQ.'U'+*+* Generate data in array A.+*+ DO 20 J = 1, N+ DO 10 I = 1, M+ IF( GEN.OR.( UPPER.AND.I.LE.J ).OR.( LOWER.AND.I.GE.J ) )+ $ THEN+ IF( ( I.LE.J.AND.J - I.LE.KU ).OR.+ $ ( I.GE.J.AND.I - J.LE.KL ) )THEN+ A( I, J ) = SBEG( RESET ) + TRANSL+ ELSE+ A( I, J ) = ZERO+ END IF+ IF( I.NE.J )THEN+ IF( SYM )THEN+ A( J, I ) = A( I, J )+ ELSE IF( TRI )THEN+ A( J, I ) = ZERO+ END IF+ END IF+ END IF+ 10 CONTINUE+ IF( TRI )+ $ A( J, J ) = A( J, J ) + ONE+ IF( UNIT )+ $ A( J, J ) = ONE+ 20 CONTINUE+*+* Store elements in array AS in data structure required by routine.+*+ IF( TYPE.EQ.'GE' )THEN+ DO 50 J = 1, N+ DO 30 I = 1, M+ AA( I + ( J - 1 )*LDA ) = A( I, J )+ 30 CONTINUE+ DO 40 I = M + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 40 CONTINUE+ 50 CONTINUE+ ELSE IF( TYPE.EQ.'GB' )THEN+ DO 90 J = 1, N+ DO 60 I1 = 1, KU + 1 - J+ AA( I1 + ( J - 1 )*LDA ) = ROGUE+ 60 CONTINUE+ DO 70 I2 = I1, MIN( KL + KU + 1, KU + 1 + M - J )+ AA( I2 + ( J - 1 )*LDA ) = A( I2 + J - KU - 1, J )+ 70 CONTINUE+ DO 80 I3 = I2, LDA+ AA( I3 + ( J - 1 )*LDA ) = ROGUE+ 80 CONTINUE+ 90 CONTINUE+ ELSE IF( TYPE.EQ.'SY'.OR.TYPE.EQ.'TR' )THEN+ DO 130 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IF( UNIT )THEN+ IEND = J - 1+ ELSE+ IEND = J+ END IF+ ELSE+ IF( UNIT )THEN+ IBEG = J + 1+ ELSE+ IBEG = J+ END IF+ IEND = N+ END IF+ DO 100 I = 1, IBEG - 1+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 100 CONTINUE+ DO 110 I = IBEG, IEND+ AA( I + ( J - 1 )*LDA ) = A( I, J )+ 110 CONTINUE+ DO 120 I = IEND + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 120 CONTINUE+ 130 CONTINUE+ ELSE IF( TYPE.EQ.'SB'.OR.TYPE.EQ.'TB' )THEN+ DO 170 J = 1, N+ IF( UPPER )THEN+ KK = KL + 1+ IBEG = MAX( 1, KL + 2 - J )+ IF( UNIT )THEN+ IEND = KL+ ELSE+ IEND = KL + 1+ END IF+ ELSE+ KK = 1+ IF( UNIT )THEN+ IBEG = 2+ ELSE+ IBEG = 1+ END IF+ IEND = MIN( KL + 1, 1 + M - J )+ END IF+ DO 140 I = 1, IBEG - 1+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 140 CONTINUE+ DO 150 I = IBEG, IEND+ AA( I + ( J - 1 )*LDA ) = A( I + J - KK, J )+ 150 CONTINUE+ DO 160 I = IEND + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 160 CONTINUE+ 170 CONTINUE+ ELSE IF( TYPE.EQ.'SP'.OR.TYPE.EQ.'TP' )THEN+ IOFF = 0+ DO 190 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IEND = J+ ELSE+ IBEG = J+ IEND = N+ END IF+ DO 180 I = IBEG, IEND+ IOFF = IOFF + 1+ AA( IOFF ) = A( I, J )+ IF( I.EQ.J )THEN+ IF( UNIT )+ $ AA( IOFF ) = ROGUE+ END IF+ 180 CONTINUE+ 190 CONTINUE+ END IF+ RETURN+*+* End of SMAKE.+*+ END+ SUBROUTINE SMVCH( TRANS, M, N, ALPHA, A, NMAX, X, INCX, BETA, Y,+ $ INCY, YT, G, YY, EPS, ERR, FATAL, NOUT, MV )+*+* Checks the results of the computational tests.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ REAL ZERO, ONE+ PARAMETER ( ZERO = 0.0, ONE = 1.0 )+* .. Scalar Arguments ..+ REAL ALPHA, BETA, EPS, ERR+ INTEGER INCX, INCY, M, N, NMAX, NOUT+ LOGICAL FATAL, MV+ CHARACTER*1 TRANS+* .. Array Arguments ..+ REAL A( NMAX, * ), G( * ), X( * ), Y( * ), YT( * ),+ $ YY( * )+* .. Local Scalars ..+ REAL ERRI+ INTEGER I, INCXL, INCYL, IY, J, JX, KX, KY, ML, NL+ LOGICAL TRAN+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, SQRT+* .. Executable Statements ..+ TRAN = TRANS.EQ.'T'.OR.TRANS.EQ.'C'+ IF( TRAN )THEN+ ML = N+ NL = M+ ELSE+ ML = M+ NL = N+ END IF+ IF( INCX.LT.0 )THEN+ KX = NL+ INCXL = -1+ ELSE+ KX = 1+ INCXL = 1+ END IF+ IF( INCY.LT.0 )THEN+ KY = ML+ INCYL = -1+ ELSE+ KY = 1+ INCYL = 1+ END IF+*+* Compute expected result in YT using data in A, X and Y.+* Compute gauges in G.+*+ IY = KY+ DO 30 I = 1, ML+ YT( IY ) = ZERO+ G( IY ) = ZERO+ JX = KX+ IF( TRAN )THEN+ DO 10 J = 1, NL+ YT( IY ) = YT( IY ) + A( J, I )*X( JX )+ G( IY ) = G( IY ) + ABS( A( J, I )*X( JX ) )+ JX = JX + INCXL+ 10 CONTINUE+ ELSE+ DO 20 J = 1, NL+ YT( IY ) = YT( IY ) + A( I, J )*X( JX )+ G( IY ) = G( IY ) + ABS( A( I, J )*X( JX ) )+ JX = JX + INCXL+ 20 CONTINUE+ END IF+ YT( IY ) = ALPHA*YT( IY ) + BETA*Y( IY )+ G( IY ) = ABS( ALPHA )*G( IY ) + ABS( BETA*Y( IY ) )+ IY = IY + INCYL+ 30 CONTINUE+*+* Compute the error ratio for this result.+*+ ERR = ZERO+ DO 40 I = 1, ML+ ERRI = ABS( YT( I ) - YY( 1 + ( I - 1 )*ABS( INCY ) ) )/EPS+ IF( G( I ).NE.ZERO )+ $ ERRI = ERRI/G( I )+ ERR = MAX( ERR, ERRI )+ IF( ERR*SQRT( EPS ).GE.ONE )+ $ GO TO 50+ 40 CONTINUE+* If the loop completes, all results are at least half accurate.+ GO TO 70+*+* Report fatal error.+*+ 50 FATAL = .TRUE.+ WRITE( NOUT, FMT = 9999 )+ DO 60 I = 1, ML+ IF( MV )THEN+ WRITE( NOUT, FMT = 9998 )I, YT( I ),+ $ YY( 1 + ( I - 1 )*ABS( INCY ) )+ ELSE+ WRITE( NOUT, FMT = 9998 )I, + $ YY( 1 + ( I - 1 )*ABS( INCY ) ), YT(I)+ END IF+ 60 CONTINUE+*+ 70 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ******* FATAL ERROR - COMPUTED RESULT IS LESS THAN HAL',+ $ 'F ACCURATE *******', /' EXPECTED RESULT COMPU',+ $ 'TED RESULT' )+ 9998 FORMAT( 1X, I7, 2G18.6 )+*+* End of SMVCH.+*+ END+ LOGICAL FUNCTION LSE( RI, RJ, LR )+*+* Tests if two arrays are identical.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER LR+* .. Array Arguments ..+ REAL RI( * ), RJ( * )+* .. Local Scalars ..+ INTEGER I+* .. Executable Statements ..+ DO 10 I = 1, LR+ IF( RI( I ).NE.RJ( I ) )+ $ GO TO 20+ 10 CONTINUE+ LSE = .TRUE.+ GO TO 30+ 20 CONTINUE+ LSE = .FALSE.+ 30 RETURN+*+* End of LSE.+*+ END+ LOGICAL FUNCTION LSERES( TYPE, UPLO, M, N, AA, AS, LDA )+*+* Tests if selected elements in two arrays are equal.+*+* TYPE is 'GE', 'SY' or 'SP'.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER LDA, M, N+ CHARACTER*1 UPLO+ CHARACTER*2 TYPE+* .. Array Arguments ..+ REAL AA( LDA, * ), AS( LDA, * )+* .. Local Scalars ..+ INTEGER I, IBEG, IEND, J+ LOGICAL UPPER+* .. Executable Statements ..+ UPPER = UPLO.EQ.'U'+ IF( TYPE.EQ.'GE' )THEN+ DO 20 J = 1, N+ DO 10 I = M + 1, LDA+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 10 CONTINUE+ 20 CONTINUE+ ELSE IF( TYPE.EQ.'SY' )THEN+ DO 50 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IEND = J+ ELSE+ IBEG = J+ IEND = N+ END IF+ DO 30 I = 1, IBEG - 1+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 30 CONTINUE+ DO 40 I = IEND + 1, LDA+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 40 CONTINUE+ 50 CONTINUE+ END IF+*+ 60 CONTINUE+ LSERES = .TRUE.+ GO TO 80+ 70 CONTINUE+ LSERES = .FALSE.+ 80 RETURN+*+* End of LSERES.+*+ END+ REAL FUNCTION SBEG( RESET )+*+* Generates random numbers uniformly distributed between -0.5 and 0.5.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ LOGICAL RESET+* .. Local Scalars ..+ INTEGER I, IC, MI+* .. Save statement ..+ SAVE I, IC, MI+* .. Intrinsic Functions ..+ INTRINSIC REAL+* .. Executable Statements ..+ IF( RESET )THEN+* Initialize local variables.+ MI = 891+ I = 7+ IC = 0+ RESET = .FALSE.+ END IF+*+* The sequence of values of I is bounded between 1 and 999.+* If initial I = 1,2,3,6,7 or 9, the period will be 50.+* If initial I = 4 or 8, the period will be 25.+* If initial I = 5, the period will be 10.+* IC is used to break up the period by skipping 1 value of I in 6.+*+ IC = IC + 1+ 10 I = I*MI+ I = I - 1000*( I/1000 )+ IF( IC.GE.5 )THEN+ IC = 0+ GO TO 10+ END IF+ SBEG = REAL( I - 500 )/1001.0+ RETURN+*+* End of SBEG.+*+ END+ REAL FUNCTION SDIFF( X, Y )+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+*+* .. Scalar Arguments ..+ REAL X, Y+* .. Executable Statements ..+ SDIFF = X - Y+ RETURN+*+* End of SDIFF.+*+ END+ SUBROUTINE CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+*+* Tests whether XERBLA has detected an error when it should.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER INFOT, NOUT+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Executable Statements ..+ IF( .NOT.LERR )THEN+ WRITE( NOUT, FMT = 9999 )INFOT, SRNAMT+ OK = .FALSE.+ END IF+ LERR = .FALSE.+ RETURN+*+ 9999 FORMAT( ' ***** ILLEGAL VALUE OF PARAMETER NUMBER ', I2, ' NOT D',+ $ 'ETECTED BY ', A6, ' *****' )+*+* End of CHKXER.+*+ END+ SUBROUTINE XERBLA( SRNAME, INFO )+*+* This is a special version of XERBLA to be used only as part of+* the test program for testing error exits from the Level 2 BLAS+* routines.+*+* XERBLA is an error handler for the Level 2 BLAS routines.+*+* It is called by the Level 2 BLAS routines if an input parameter is+* invalid.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER INFO+ CHARACTER*6 SRNAME+* .. Scalars in Common ..+ INTEGER INFOT, NOUT+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUT, OK, LERR+ COMMON /SRNAMC/SRNAMT+* .. Executable Statements ..+ LERR = .TRUE.+ IF( INFO.NE.INFOT )THEN+ IF( INFOT.NE.0 )THEN+ WRITE( NOUT, FMT = 9999 )INFO, INFOT+ ELSE+ WRITE( NOUT, FMT = 9997 )INFO+ END IF+ OK = .FALSE.+ END IF+ IF( SRNAME.NE.SRNAMT )THEN+ WRITE( NOUT, FMT = 9998 )SRNAME, SRNAMT+ OK = .FALSE.+ END IF+ RETURN+*+ 9999 FORMAT( ' ******* XERBLA WAS CALLED WITH INFO = ', I6, ' INSTEAD',+ $ ' OF ', I2, ' *******' )+ 9998 FORMAT( ' ******* XERBLA WAS CALLED WITH SRNAME = ', A6, ' INSTE',+ $ 'AD OF ', A6, ' *******' )+ 9997 FORMAT( ' ******* XERBLA WAS CALLED WITH INFO = ', I6,+ $ ' *******' )+*+* End of XERBLA+*+ END+
+ eigen3/blas/testing/sblat3.dat view
@@ -0,0 +1,20 @@+'sblat3.summ' NAME OF SUMMARY OUTPUT FILE+6 UNIT NUMBER OF SUMMARY FILE+'sblat3.snap' NAME OF SNAPSHOT OUTPUT FILE+-1 UNIT NUMBER OF SNAPSHOT FILE (NOT USED IF .LT. 0)+F LOGICAL FLAG, T TO REWIND SNAPSHOT FILE AFTER EACH RECORD.+F LOGICAL FLAG, T TO STOP ON FAILURES.+T LOGICAL FLAG, T TO TEST ERROR EXITS.+16.0 THRESHOLD VALUE OF TEST RATIO+6 NUMBER OF VALUES OF N+0 1 2 3 5 9 VALUES OF N+3 NUMBER OF VALUES OF ALPHA+0.0 1.0 0.7 VALUES OF ALPHA+3 NUMBER OF VALUES OF BETA+0.0 1.0 1.3 VALUES OF BETA+SGEMM T PUT F FOR NO TEST. SAME COLUMNS.+SSYMM T PUT F FOR NO TEST. SAME COLUMNS.+STRMM T PUT F FOR NO TEST. SAME COLUMNS.+STRSM T PUT F FOR NO TEST. SAME COLUMNS.+SSYRK T PUT F FOR NO TEST. SAME COLUMNS.+SSYR2K T PUT F FOR NO TEST. SAME COLUMNS.
+ eigen3/blas/testing/sblat3.f view
@@ -0,0 +1,2823 @@+ PROGRAM SBLAT3+*+* Test program for the REAL Level 3 Blas.+*+* The program must be driven by a short data file. The first 14 records+* of the file are read using list-directed input, the last 6 records+* are read using the format ( A6, L2 ). An annotated example of a data+* file can be obtained by deleting the first 3 characters from the+* following 20 lines:+* 'SBLAT3.SUMM' NAME OF SUMMARY OUTPUT FILE+* 6 UNIT NUMBER OF SUMMARY FILE+* 'SBLAT3.SNAP' NAME OF SNAPSHOT OUTPUT FILE+* -1 UNIT NUMBER OF SNAPSHOT FILE (NOT USED IF .LT. 0)+* F LOGICAL FLAG, T TO REWIND SNAPSHOT FILE AFTER EACH RECORD.+* F LOGICAL FLAG, T TO STOP ON FAILURES.+* T LOGICAL FLAG, T TO TEST ERROR EXITS.+* 16.0 THRESHOLD VALUE OF TEST RATIO+* 6 NUMBER OF VALUES OF N+* 0 1 2 3 5 9 VALUES OF N+* 3 NUMBER OF VALUES OF ALPHA+* 0.0 1.0 0.7 VALUES OF ALPHA+* 3 NUMBER OF VALUES OF BETA+* 0.0 1.0 1.3 VALUES OF BETA+* SGEMM T PUT F FOR NO TEST. SAME COLUMNS.+* SSYMM T PUT F FOR NO TEST. SAME COLUMNS.+* STRMM T PUT F FOR NO TEST. SAME COLUMNS.+* STRSM T PUT F FOR NO TEST. SAME COLUMNS.+* SSYRK T PUT F FOR NO TEST. SAME COLUMNS.+* SSYR2K T PUT F FOR NO TEST. SAME COLUMNS.+*+* See:+*+* Dongarra J. J., Du Croz J. J., Duff I. S. and Hammarling S.+* A Set of Level 3 Basic Linear Algebra Subprograms.+*+* Technical Memorandum No.88 (Revision 1), Mathematics and+* Computer Science Division, Argonne National Laboratory, 9700+* South Cass Avenue, Argonne, Illinois 60439, US.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ INTEGER NIN+ PARAMETER ( NIN = 5 )+ INTEGER NSUBS+ PARAMETER ( NSUBS = 6 )+ REAL ZERO, HALF, ONE+ PARAMETER ( ZERO = 0.0, HALF = 0.5, ONE = 1.0 )+ INTEGER NMAX+ PARAMETER ( NMAX = 65 )+ INTEGER NIDMAX, NALMAX, NBEMAX+ PARAMETER ( NIDMAX = 9, NALMAX = 7, NBEMAX = 7 )+* .. Local Scalars ..+ REAL EPS, ERR, THRESH+ INTEGER I, ISNUM, J, N, NALF, NBET, NIDIM, NOUT, NTRA+ LOGICAL FATAL, LTESTT, REWI, SAME, SFATAL, TRACE,+ $ TSTERR+ CHARACTER*1 TRANSA, TRANSB+ CHARACTER*6 SNAMET+ CHARACTER*32 SNAPS, SUMMRY+* .. Local Arrays ..+ REAL AA( NMAX*NMAX ), AB( NMAX, 2*NMAX ),+ $ ALF( NALMAX ), AS( NMAX*NMAX ),+ $ BB( NMAX*NMAX ), BET( NBEMAX ),+ $ BS( NMAX*NMAX ), C( NMAX, NMAX ),+ $ CC( NMAX*NMAX ), CS( NMAX*NMAX ), CT( NMAX ),+ $ G( NMAX ), W( 2*NMAX )+ INTEGER IDIM( NIDMAX )+ LOGICAL LTEST( NSUBS )+ CHARACTER*6 SNAMES( NSUBS )+* .. External Functions ..+ REAL SDIFF+ LOGICAL LSE+ EXTERNAL SDIFF, LSE+* .. External Subroutines ..+ EXTERNAL SCHK1, SCHK2, SCHK3, SCHK4, SCHK5, SCHKE, SMMCH+* .. Intrinsic Functions ..+ INTRINSIC MAX, MIN+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+ COMMON /SRNAMC/SRNAMT+* .. Data statements ..+ DATA SNAMES/'SGEMM ', 'SSYMM ', 'STRMM ', 'STRSM ',+ $ 'SSYRK ', 'SSYR2K'/+* .. Executable Statements ..+*+* Read name and unit number for summary output file and open file.+*+ READ( NIN, FMT = * )SUMMRY+ READ( NIN, FMT = * )NOUT+ OPEN( NOUT, FILE = SUMMRY, STATUS = 'NEW' )+ NOUTC = NOUT+*+* Read name and unit number for snapshot output file and open file.+*+ READ( NIN, FMT = * )SNAPS+ READ( NIN, FMT = * )NTRA+ TRACE = NTRA.GE.0+ IF( TRACE )THEN+ OPEN( NTRA, FILE = SNAPS, STATUS = 'NEW' )+ END IF+* Read the flag that directs rewinding of the snapshot file.+ READ( NIN, FMT = * )REWI+ REWI = REWI.AND.TRACE+* Read the flag that directs stopping on any failure.+ READ( NIN, FMT = * )SFATAL+* Read the flag that indicates whether error exits are to be tested.+ READ( NIN, FMT = * )TSTERR+* Read the threshold value of the test ratio+ READ( NIN, FMT = * )THRESH+*+* Read and check the parameter values for the tests.+*+* Values of N+ READ( NIN, FMT = * )NIDIM+ IF( NIDIM.LT.1.OR.NIDIM.GT.NIDMAX )THEN+ WRITE( NOUT, FMT = 9997 )'N', NIDMAX+ GO TO 220+ END IF+ READ( NIN, FMT = * )( IDIM( I ), I = 1, NIDIM )+ DO 10 I = 1, NIDIM+ IF( IDIM( I ).LT.0.OR.IDIM( I ).GT.NMAX )THEN+ WRITE( NOUT, FMT = 9996 )NMAX+ GO TO 220+ END IF+ 10 CONTINUE+* Values of ALPHA+ READ( NIN, FMT = * )NALF+ IF( NALF.LT.1.OR.NALF.GT.NALMAX )THEN+ WRITE( NOUT, FMT = 9997 )'ALPHA', NALMAX+ GO TO 220+ END IF+ READ( NIN, FMT = * )( ALF( I ), I = 1, NALF )+* Values of BETA+ READ( NIN, FMT = * )NBET+ IF( NBET.LT.1.OR.NBET.GT.NBEMAX )THEN+ WRITE( NOUT, FMT = 9997 )'BETA', NBEMAX+ GO TO 220+ END IF+ READ( NIN, FMT = * )( BET( I ), I = 1, NBET )+*+* Report values of parameters.+*+ WRITE( NOUT, FMT = 9995 )+ WRITE( NOUT, FMT = 9994 )( IDIM( I ), I = 1, NIDIM )+ WRITE( NOUT, FMT = 9993 )( ALF( I ), I = 1, NALF )+ WRITE( NOUT, FMT = 9992 )( BET( I ), I = 1, NBET )+ IF( .NOT.TSTERR )THEN+ WRITE( NOUT, FMT = * )+ WRITE( NOUT, FMT = 9984 )+ END IF+ WRITE( NOUT, FMT = * )+ WRITE( NOUT, FMT = 9999 )THRESH+ WRITE( NOUT, FMT = * )+*+* Read names of subroutines and flags which indicate+* whether they are to be tested.+*+ DO 20 I = 1, NSUBS+ LTEST( I ) = .FALSE.+ 20 CONTINUE+ 30 READ( NIN, FMT = 9988, END = 60 )SNAMET, LTESTT+ DO 40 I = 1, NSUBS+ IF( SNAMET.EQ.SNAMES( I ) )+ $ GO TO 50+ 40 CONTINUE+ WRITE( NOUT, FMT = 9990 )SNAMET+ STOP+ 50 LTEST( I ) = LTESTT+ GO TO 30+*+ 60 CONTINUE+ CLOSE ( NIN )+*+* Compute EPS (the machine precision).+*+ EPS = ONE+ 70 CONTINUE+ IF( SDIFF( ONE + EPS, ONE ).EQ.ZERO )+ $ GO TO 80+ EPS = HALF*EPS+ GO TO 70+ 80 CONTINUE+ EPS = EPS + EPS+ WRITE( NOUT, FMT = 9998 )EPS+*+* Check the reliability of SMMCH using exact data.+*+ N = MIN( 32, NMAX )+ DO 100 J = 1, N+ DO 90 I = 1, N+ AB( I, J ) = MAX( I - J + 1, 0 )+ 90 CONTINUE+ AB( J, NMAX + 1 ) = J+ AB( 1, NMAX + J ) = J+ C( J, 1 ) = ZERO+ 100 CONTINUE+ DO 110 J = 1, N+ CC( J ) = J*( ( J + 1 )*J )/2 - ( ( J + 1 )*J*( J - 1 ) )/3+ 110 CONTINUE+* CC holds the exact result. On exit from SMMCH CT holds+* the result computed by SMMCH.+ TRANSA = 'N'+ TRANSB = 'N'+ CALL SMMCH( TRANSA, TRANSB, N, 1, N, ONE, AB, NMAX,+ $ AB( 1, NMAX + 1 ), NMAX, ZERO, C, NMAX, CT, G, CC,+ $ NMAX, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LSE( CC, CT, N )+ IF( .NOT.SAME.OR.ERR.NE.ZERO )THEN+ WRITE( NOUT, FMT = 9989 )TRANSA, TRANSB, SAME, ERR+ STOP+ END IF+ TRANSB = 'T'+ CALL SMMCH( TRANSA, TRANSB, N, 1, N, ONE, AB, NMAX,+ $ AB( 1, NMAX + 1 ), NMAX, ZERO, C, NMAX, CT, G, CC,+ $ NMAX, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LSE( CC, CT, N )+ IF( .NOT.SAME.OR.ERR.NE.ZERO )THEN+ WRITE( NOUT, FMT = 9989 )TRANSA, TRANSB, SAME, ERR+ STOP+ END IF+ DO 120 J = 1, N+ AB( J, NMAX + 1 ) = N - J + 1+ AB( 1, NMAX + J ) = N - J + 1+ 120 CONTINUE+ DO 130 J = 1, N+ CC( N - J + 1 ) = J*( ( J + 1 )*J )/2 -+ $ ( ( J + 1 )*J*( J - 1 ) )/3+ 130 CONTINUE+ TRANSA = 'T'+ TRANSB = 'N'+ CALL SMMCH( TRANSA, TRANSB, N, 1, N, ONE, AB, NMAX,+ $ AB( 1, NMAX + 1 ), NMAX, ZERO, C, NMAX, CT, G, CC,+ $ NMAX, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LSE( CC, CT, N )+ IF( .NOT.SAME.OR.ERR.NE.ZERO )THEN+ WRITE( NOUT, FMT = 9989 )TRANSA, TRANSB, SAME, ERR+ STOP+ END IF+ TRANSB = 'T'+ CALL SMMCH( TRANSA, TRANSB, N, 1, N, ONE, AB, NMAX,+ $ AB( 1, NMAX + 1 ), NMAX, ZERO, C, NMAX, CT, G, CC,+ $ NMAX, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LSE( CC, CT, N )+ IF( .NOT.SAME.OR.ERR.NE.ZERO )THEN+ WRITE( NOUT, FMT = 9989 )TRANSA, TRANSB, SAME, ERR+ STOP+ END IF+*+* Test each subroutine in turn.+*+ DO 200 ISNUM = 1, NSUBS+ WRITE( NOUT, FMT = * )+ IF( .NOT.LTEST( ISNUM ) )THEN+* Subprogram is not to be tested.+ WRITE( NOUT, FMT = 9987 )SNAMES( ISNUM )+ ELSE+ SRNAMT = SNAMES( ISNUM )+* Test error exits.+ IF( TSTERR )THEN+ CALL SCHKE( ISNUM, SNAMES( ISNUM ), NOUT )+ WRITE( NOUT, FMT = * )+ END IF+* Test computations.+ INFOT = 0+ OK = .TRUE.+ FATAL = .FALSE.+ GO TO ( 140, 150, 160, 160, 170, 180 )ISNUM+* Test SGEMM, 01.+ 140 CALL SCHK1( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET,+ $ NMAX, AB, AA, AS, AB( 1, NMAX + 1 ), BB, BS, C,+ $ CC, CS, CT, G )+ GO TO 190+* Test SSYMM, 02.+ 150 CALL SCHK2( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET,+ $ NMAX, AB, AA, AS, AB( 1, NMAX + 1 ), BB, BS, C,+ $ CC, CS, CT, G )+ GO TO 190+* Test STRMM, 03, STRSM, 04.+ 160 CALL SCHK3( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NMAX, AB,+ $ AA, AS, AB( 1, NMAX + 1 ), BB, BS, CT, G, C )+ GO TO 190+* Test SSYRK, 05.+ 170 CALL SCHK4( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET,+ $ NMAX, AB, AA, AS, AB( 1, NMAX + 1 ), BB, BS, C,+ $ CC, CS, CT, G )+ GO TO 190+* Test SSYR2K, 06.+ 180 CALL SCHK5( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET,+ $ NMAX, AB, AA, AS, BB, BS, C, CC, CS, CT, G, W )+ GO TO 190+*+ 190 IF( FATAL.AND.SFATAL )+ $ GO TO 210+ END IF+ 200 CONTINUE+ WRITE( NOUT, FMT = 9986 )+ GO TO 230+*+ 210 CONTINUE+ WRITE( NOUT, FMT = 9985 )+ GO TO 230+*+ 220 CONTINUE+ WRITE( NOUT, FMT = 9991 )+*+ 230 CONTINUE+ IF( TRACE )+ $ CLOSE ( NTRA )+ CLOSE ( NOUT )+ STOP+*+ 9999 FORMAT( ' ROUTINES PASS COMPUTATIONAL TESTS IF TEST RATIO IS LES',+ $ 'S THAN', F8.2 )+ 9998 FORMAT( ' RELATIVE MACHINE PRECISION IS TAKEN TO BE', 1P, E9.1 )+ 9997 FORMAT( ' NUMBER OF VALUES OF ', A, ' IS LESS THAN 1 OR GREATER ',+ $ 'THAN ', I2 )+ 9996 FORMAT( ' VALUE OF N IS LESS THAN 0 OR GREATER THAN ', I2 )+ 9995 FORMAT( ' TESTS OF THE REAL LEVEL 3 BLAS', //' THE F',+ $ 'OLLOWING PARAMETER VALUES WILL BE USED:' )+ 9994 FORMAT( ' FOR N ', 9I6 )+ 9993 FORMAT( ' FOR ALPHA ', 7F6.1 )+ 9992 FORMAT( ' FOR BETA ', 7F6.1 )+ 9991 FORMAT( ' AMEND DATA FILE OR INCREASE ARRAY SIZES IN PROGRAM',+ $ /' ******* TESTS ABANDONED *******' )+ 9990 FORMAT( ' SUBPROGRAM NAME ', A6, ' NOT RECOGNIZED', /' ******* T',+ $ 'ESTS ABANDONED *******' )+ 9989 FORMAT( ' ERROR IN SMMCH - IN-LINE DOT PRODUCTS ARE BEING EVALU',+ $ 'ATED WRONGLY.', /' SMMCH WAS CALLED WITH TRANSA = ', A1,+ $ ' AND TRANSB = ', A1, /' AND RETURNED SAME = ', L1, ' AND ',+ $ 'ERR = ', F12.3, '.', /' THIS MAY BE DUE TO FAULTS IN THE ',+ $ 'ARITHMETIC OR THE COMPILER.', /' ******* TESTS ABANDONED ',+ $ '*******' )+ 9988 FORMAT( A6, L2 )+ 9987 FORMAT( 1X, A6, ' WAS NOT TESTED' )+ 9986 FORMAT( /' END OF TESTS' )+ 9985 FORMAT( /' ******* FATAL ERROR - TESTS ABANDONED *******' )+ 9984 FORMAT( ' ERROR-EXITS WILL NOT BE TESTED' )+*+* End of SBLAT3.+*+ END+ SUBROUTINE SCHK1( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET, NMAX,+ $ A, AA, AS, B, BB, BS, C, CC, CS, CT, G )+*+* Tests SGEMM.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ REAL ZERO+ PARAMETER ( ZERO = 0.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER NALF, NBET, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ REAL A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), B( NMAX, NMAX ),+ $ BB( NMAX*NMAX ), BET( NBET ), BS( NMAX*NMAX ),+ $ C( NMAX, NMAX ), CC( NMAX*NMAX ),+ $ CS( NMAX*NMAX ), CT( NMAX ), G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ REAL ALPHA, ALS, BETA, BLS, ERR, ERRMAX+ INTEGER I, IA, IB, ICA, ICB, IK, IM, IN, K, KS, LAA,+ $ LBB, LCC, LDA, LDAS, LDB, LDBS, LDC, LDCS, M,+ $ MA, MB, MS, N, NA, NARGS, NB, NC, NS+ LOGICAL NULL, RESET, SAME, TRANA, TRANB+ CHARACTER*1 TRANAS, TRANBS, TRANSA, TRANSB+ CHARACTER*3 ICH+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LSE, LSERES+ EXTERNAL LSE, LSERES+* .. External Subroutines ..+ EXTERNAL SGEMM, SMAKE, SMMCH+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'NTC'/+* .. Executable Statements ..+*+ NARGS = 13+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 110 IM = 1, NIDIM+ M = IDIM( IM )+*+ DO 100 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDC to 1 more than minimum value if room.+ LDC = M+ IF( LDC.LT.NMAX )+ $ LDC = LDC + 1+* Skip tests if not enough room.+ IF( LDC.GT.NMAX )+ $ GO TO 100+ LCC = LDC*N+ NULL = N.LE.0.OR.M.LE.0+*+ DO 90 IK = 1, NIDIM+ K = IDIM( IK )+*+ DO 80 ICA = 1, 3+ TRANSA = ICH( ICA: ICA )+ TRANA = TRANSA.EQ.'T'.OR.TRANSA.EQ.'C'+*+ IF( TRANA )THEN+ MA = K+ NA = M+ ELSE+ MA = M+ NA = K+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = MA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 80+ LAA = LDA*NA+*+* Generate the matrix A.+*+ CALL SMAKE( 'GE', ' ', ' ', MA, NA, A, NMAX, AA, LDA,+ $ RESET, ZERO )+*+ DO 70 ICB = 1, 3+ TRANSB = ICH( ICB: ICB )+ TRANB = TRANSB.EQ.'T'.OR.TRANSB.EQ.'C'+*+ IF( TRANB )THEN+ MB = N+ NB = K+ ELSE+ MB = K+ NB = N+ END IF+* Set LDB to 1 more than minimum value if room.+ LDB = MB+ IF( LDB.LT.NMAX )+ $ LDB = LDB + 1+* Skip tests if not enough room.+ IF( LDB.GT.NMAX )+ $ GO TO 70+ LBB = LDB*NB+*+* Generate the matrix B.+*+ CALL SMAKE( 'GE', ' ', ' ', MB, NB, B, NMAX, BB,+ $ LDB, RESET, ZERO )+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the matrix C.+*+ CALL SMAKE( 'GE', ' ', ' ', M, N, C, NMAX,+ $ CC, LDC, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ TRANAS = TRANSA+ TRANBS = TRANSB+ MS = M+ NS = N+ KS = K+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LBB+ BS( I ) = BB( I )+ 20 CONTINUE+ LDBS = LDB+ BLS = BETA+ DO 30 I = 1, LCC+ CS( I ) = CC( I )+ 30 CONTINUE+ LDCS = LDC+*+* Call the subroutine.+*+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ TRANSA, TRANSB, M, N, K, ALPHA, LDA, LDB,+ $ BETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL SGEMM( TRANSA, TRANSB, M, N, K, ALPHA,+ $ AA, LDA, BB, LDB, BETA, CC, LDC )+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9994 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = TRANSA.EQ.TRANAS+ ISAME( 2 ) = TRANSB.EQ.TRANBS+ ISAME( 3 ) = MS.EQ.M+ ISAME( 4 ) = NS.EQ.N+ ISAME( 5 ) = KS.EQ.K+ ISAME( 6 ) = ALS.EQ.ALPHA+ ISAME( 7 ) = LSE( AS, AA, LAA )+ ISAME( 8 ) = LDAS.EQ.LDA+ ISAME( 9 ) = LSE( BS, BB, LBB )+ ISAME( 10 ) = LDBS.EQ.LDB+ ISAME( 11 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 12 ) = LSE( CS, CC, LCC )+ ELSE+ ISAME( 12 ) = LSERES( 'GE', ' ', M, N, CS,+ $ CC, LDC )+ END IF+ ISAME( 13 ) = LDCS.EQ.LDC+*+* If data was incorrectly changed, report+* and return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result.+*+ CALL SMMCH( TRANSA, TRANSB, M, N, K,+ $ ALPHA, A, NMAX, B, NMAX, BETA,+ $ C, NMAX, CT, G, CC, LDC, EPS,+ $ ERR, FATAL, NOUT, .TRUE. )+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 120+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9995 )NC, SNAME, TRANSA, TRANSB, M, N, K,+ $ ALPHA, LDA, LDB, BETA, LDC+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',''', A1, ''',',+ $ 3( I3, ',' ), F4.1, ', A,', I3, ', B,', I3, ',', F4.1, ', ',+ $ 'C,', I3, ').' )+ 9994 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of SCHK1.+*+ END+ SUBROUTINE SCHK2( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET, NMAX,+ $ A, AA, AS, B, BB, BS, C, CC, CS, CT, G )+*+* Tests SSYMM.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ REAL ZERO+ PARAMETER ( ZERO = 0.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER NALF, NBET, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ REAL A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), B( NMAX, NMAX ),+ $ BB( NMAX*NMAX ), BET( NBET ), BS( NMAX*NMAX ),+ $ C( NMAX, NMAX ), CC( NMAX*NMAX ),+ $ CS( NMAX*NMAX ), CT( NMAX ), G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ REAL ALPHA, ALS, BETA, BLS, ERR, ERRMAX+ INTEGER I, IA, IB, ICS, ICU, IM, IN, LAA, LBB, LCC,+ $ LDA, LDAS, LDB, LDBS, LDC, LDCS, M, MS, N, NA,+ $ NARGS, NC, NS+ LOGICAL LEFT, NULL, RESET, SAME+ CHARACTER*1 SIDE, SIDES, UPLO, UPLOS+ CHARACTER*2 ICHS, ICHU+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LSE, LSERES+ EXTERNAL LSE, LSERES+* .. External Subroutines ..+ EXTERNAL SMAKE, SMMCH, SSYMM+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHS/'LR'/, ICHU/'UL'/+* .. Executable Statements ..+*+ NARGS = 12+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 100 IM = 1, NIDIM+ M = IDIM( IM )+*+ DO 90 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDC to 1 more than minimum value if room.+ LDC = M+ IF( LDC.LT.NMAX )+ $ LDC = LDC + 1+* Skip tests if not enough room.+ IF( LDC.GT.NMAX )+ $ GO TO 90+ LCC = LDC*N+ NULL = N.LE.0.OR.M.LE.0+*+* Set LDB to 1 more than minimum value if room.+ LDB = M+ IF( LDB.LT.NMAX )+ $ LDB = LDB + 1+* Skip tests if not enough room.+ IF( LDB.GT.NMAX )+ $ GO TO 90+ LBB = LDB*N+*+* Generate the matrix B.+*+ CALL SMAKE( 'GE', ' ', ' ', M, N, B, NMAX, BB, LDB, RESET,+ $ ZERO )+*+ DO 80 ICS = 1, 2+ SIDE = ICHS( ICS: ICS )+ LEFT = SIDE.EQ.'L'+*+ IF( LEFT )THEN+ NA = M+ ELSE+ NA = N+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = NA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 80+ LAA = LDA*NA+*+ DO 70 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+*+* Generate the symmetric matrix A.+*+ CALL SMAKE( 'SY', UPLO, ' ', NA, NA, A, NMAX, AA, LDA,+ $ RESET, ZERO )+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the matrix C.+*+ CALL SMAKE( 'GE', ' ', ' ', M, N, C, NMAX, CC,+ $ LDC, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ SIDES = SIDE+ UPLOS = UPLO+ MS = M+ NS = N+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LBB+ BS( I ) = BB( I )+ 20 CONTINUE+ LDBS = LDB+ BLS = BETA+ DO 30 I = 1, LCC+ CS( I ) = CC( I )+ 30 CONTINUE+ LDCS = LDC+*+* Call the subroutine.+*+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME, SIDE,+ $ UPLO, M, N, ALPHA, LDA, LDB, BETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL SSYMM( SIDE, UPLO, M, N, ALPHA, AA, LDA,+ $ BB, LDB, BETA, CC, LDC )+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9994 )+ FATAL = .TRUE.+ GO TO 110+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = SIDES.EQ.SIDE+ ISAME( 2 ) = UPLOS.EQ.UPLO+ ISAME( 3 ) = MS.EQ.M+ ISAME( 4 ) = NS.EQ.N+ ISAME( 5 ) = ALS.EQ.ALPHA+ ISAME( 6 ) = LSE( AS, AA, LAA )+ ISAME( 7 ) = LDAS.EQ.LDA+ ISAME( 8 ) = LSE( BS, BB, LBB )+ ISAME( 9 ) = LDBS.EQ.LDB+ ISAME( 10 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 11 ) = LSE( CS, CC, LCC )+ ELSE+ ISAME( 11 ) = LSERES( 'GE', ' ', M, N, CS,+ $ CC, LDC )+ END IF+ ISAME( 12 ) = LDCS.EQ.LDC+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 110+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result.+*+ IF( LEFT )THEN+ CALL SMMCH( 'N', 'N', M, N, M, ALPHA, A,+ $ NMAX, B, NMAX, BETA, C, NMAX,+ $ CT, G, CC, LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ELSE+ CALL SMMCH( 'N', 'N', M, N, N, ALPHA, B,+ $ NMAX, A, NMAX, BETA, C, NMAX,+ $ CT, G, CC, LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 110+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 120+*+ 110 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9995 )NC, SNAME, SIDE, UPLO, M, N, ALPHA, LDA,+ $ LDB, BETA, LDC+*+ 120 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(', 2( '''', A1, ''',' ), 2( I3, ',' ),+ $ F4.1, ', A,', I3, ', B,', I3, ',', F4.1, ', C,', I3, ') ',+ $ ' .' )+ 9994 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of SCHK2.+*+ END+ SUBROUTINE SCHK3( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NMAX, A, AA, AS,+ $ B, BB, BS, CT, G, C )+*+* Tests STRMM and STRSM.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ REAL ZERO, ONE+ PARAMETER ( ZERO = 0.0, ONE = 1.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER NALF, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ REAL A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), B( NMAX, NMAX ),+ $ BB( NMAX*NMAX ), BS( NMAX*NMAX ),+ $ C( NMAX, NMAX ), CT( NMAX ), G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ REAL ALPHA, ALS, ERR, ERRMAX+ INTEGER I, IA, ICD, ICS, ICT, ICU, IM, IN, J, LAA, LBB,+ $ LDA, LDAS, LDB, LDBS, M, MS, N, NA, NARGS, NC,+ $ NS+ LOGICAL LEFT, NULL, RESET, SAME+ CHARACTER*1 DIAG, DIAGS, SIDE, SIDES, TRANAS, TRANSA, UPLO,+ $ UPLOS+ CHARACTER*2 ICHD, ICHS, ICHU+ CHARACTER*3 ICHT+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LSE, LSERES+ EXTERNAL LSE, LSERES+* .. External Subroutines ..+ EXTERNAL SMAKE, SMMCH, STRMM, STRSM+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHU/'UL'/, ICHT/'NTC'/, ICHD/'UN'/, ICHS/'LR'/+* .. Executable Statements ..+*+ NARGS = 11+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+* Set up zero matrix for SMMCH.+ DO 20 J = 1, NMAX+ DO 10 I = 1, NMAX+ C( I, J ) = ZERO+ 10 CONTINUE+ 20 CONTINUE+*+ DO 140 IM = 1, NIDIM+ M = IDIM( IM )+*+ DO 130 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDB to 1 more than minimum value if room.+ LDB = M+ IF( LDB.LT.NMAX )+ $ LDB = LDB + 1+* Skip tests if not enough room.+ IF( LDB.GT.NMAX )+ $ GO TO 130+ LBB = LDB*N+ NULL = M.LE.0.OR.N.LE.0+*+ DO 120 ICS = 1, 2+ SIDE = ICHS( ICS: ICS )+ LEFT = SIDE.EQ.'L'+ IF( LEFT )THEN+ NA = M+ ELSE+ NA = N+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = NA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 130+ LAA = LDA*NA+*+ DO 110 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+*+ DO 100 ICT = 1, 3+ TRANSA = ICHT( ICT: ICT )+*+ DO 90 ICD = 1, 2+ DIAG = ICHD( ICD: ICD )+*+ DO 80 IA = 1, NALF+ ALPHA = ALF( IA )+*+* Generate the matrix A.+*+ CALL SMAKE( 'TR', UPLO, DIAG, NA, NA, A,+ $ NMAX, AA, LDA, RESET, ZERO )+*+* Generate the matrix B.+*+ CALL SMAKE( 'GE', ' ', ' ', M, N, B, NMAX,+ $ BB, LDB, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ SIDES = SIDE+ UPLOS = UPLO+ TRANAS = TRANSA+ DIAGS = DIAG+ MS = M+ NS = N+ ALS = ALPHA+ DO 30 I = 1, LAA+ AS( I ) = AA( I )+ 30 CONTINUE+ LDAS = LDA+ DO 40 I = 1, LBB+ BS( I ) = BB( I )+ 40 CONTINUE+ LDBS = LDB+*+* Call the subroutine.+*+ IF( SNAME( 4: 5 ).EQ.'MM' )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA,+ $ LDA, LDB+ IF( REWI )+ $ REWIND NTRA+ CALL STRMM( SIDE, UPLO, TRANSA, DIAG, M,+ $ N, ALPHA, AA, LDA, BB, LDB )+ ELSE IF( SNAME( 4: 5 ).EQ.'SM' )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA,+ $ LDA, LDB+ IF( REWI )+ $ REWIND NTRA+ CALL STRSM( SIDE, UPLO, TRANSA, DIAG, M,+ $ N, ALPHA, AA, LDA, BB, LDB )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9994 )+ FATAL = .TRUE.+ GO TO 150+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = SIDES.EQ.SIDE+ ISAME( 2 ) = UPLOS.EQ.UPLO+ ISAME( 3 ) = TRANAS.EQ.TRANSA+ ISAME( 4 ) = DIAGS.EQ.DIAG+ ISAME( 5 ) = MS.EQ.M+ ISAME( 6 ) = NS.EQ.N+ ISAME( 7 ) = ALS.EQ.ALPHA+ ISAME( 8 ) = LSE( AS, AA, LAA )+ ISAME( 9 ) = LDAS.EQ.LDA+ IF( NULL )THEN+ ISAME( 10 ) = LSE( BS, BB, LBB )+ ELSE+ ISAME( 10 ) = LSERES( 'GE', ' ', M, N, BS,+ $ BB, LDB )+ END IF+ ISAME( 11 ) = LDBS.EQ.LDB+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 50 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 50 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 150+ END IF+*+ IF( .NOT.NULL )THEN+ IF( SNAME( 4: 5 ).EQ.'MM' )THEN+*+* Check the result.+*+ IF( LEFT )THEN+ CALL SMMCH( TRANSA, 'N', M, N, M,+ $ ALPHA, A, NMAX, B, NMAX,+ $ ZERO, C, NMAX, CT, G,+ $ BB, LDB, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ELSE+ CALL SMMCH( 'N', TRANSA, M, N, N,+ $ ALPHA, B, NMAX, A, NMAX,+ $ ZERO, C, NMAX, CT, G,+ $ BB, LDB, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ END IF+ ELSE IF( SNAME( 4: 5 ).EQ.'SM' )THEN+*+* Compute approximation to original+* matrix.+*+ DO 70 J = 1, N+ DO 60 I = 1, M+ C( I, J ) = BB( I + ( J - 1 )*+ $ LDB )+ BB( I + ( J - 1 )*LDB ) = ALPHA*+ $ B( I, J )+ 60 CONTINUE+ 70 CONTINUE+*+ IF( LEFT )THEN+ CALL SMMCH( TRANSA, 'N', M, N, M,+ $ ONE, A, NMAX, C, NMAX,+ $ ZERO, B, NMAX, CT, G,+ $ BB, LDB, EPS, ERR,+ $ FATAL, NOUT, .FALSE. )+ ELSE+ CALL SMMCH( 'N', TRANSA, M, N, N,+ $ ONE, C, NMAX, A, NMAX,+ $ ZERO, B, NMAX, CT, G,+ $ BB, LDB, EPS, ERR,+ $ FATAL, NOUT, .FALSE. )+ END IF+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 150+ END IF+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+ 130 CONTINUE+*+ 140 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 160+*+ 150 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9995 )NC, SNAME, SIDE, UPLO, TRANSA, DIAG, M,+ $ N, ALPHA, LDA, LDB+*+ 160 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(', 4( '''', A1, ''',' ), 2( I3, ',' ),+ $ F4.1, ', A,', I3, ', B,', I3, ') .' )+ 9994 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of SCHK3.+*+ END+ SUBROUTINE SCHK4( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET, NMAX,+ $ A, AA, AS, B, BB, BS, C, CC, CS, CT, G )+*+* Tests SSYRK.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ REAL ZERO+ PARAMETER ( ZERO = 0.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER NALF, NBET, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ REAL A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), B( NMAX, NMAX ),+ $ BB( NMAX*NMAX ), BET( NBET ), BS( NMAX*NMAX ),+ $ C( NMAX, NMAX ), CC( NMAX*NMAX ),+ $ CS( NMAX*NMAX ), CT( NMAX ), G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ REAL ALPHA, ALS, BETA, BETS, ERR, ERRMAX+ INTEGER I, IA, IB, ICT, ICU, IK, IN, J, JC, JJ, K, KS,+ $ LAA, LCC, LDA, LDAS, LDC, LDCS, LJ, MA, N, NA,+ $ NARGS, NC, NS+ LOGICAL NULL, RESET, SAME, TRAN, UPPER+ CHARACTER*1 TRANS, TRANSS, UPLO, UPLOS+ CHARACTER*2 ICHU+ CHARACTER*3 ICHT+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LSE, LSERES+ EXTERNAL LSE, LSERES+* .. External Subroutines ..+ EXTERNAL SMAKE, SMMCH, SSYRK+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHT/'NTC'/, ICHU/'UL'/+* .. Executable Statements ..+*+ NARGS = 10+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 100 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDC to 1 more than minimum value if room.+ LDC = N+ IF( LDC.LT.NMAX )+ $ LDC = LDC + 1+* Skip tests if not enough room.+ IF( LDC.GT.NMAX )+ $ GO TO 100+ LCC = LDC*N+ NULL = N.LE.0+*+ DO 90 IK = 1, NIDIM+ K = IDIM( IK )+*+ DO 80 ICT = 1, 3+ TRANS = ICHT( ICT: ICT )+ TRAN = TRANS.EQ.'T'.OR.TRANS.EQ.'C'+ IF( TRAN )THEN+ MA = K+ NA = N+ ELSE+ MA = N+ NA = K+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = MA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 80+ LAA = LDA*NA+*+* Generate the matrix A.+*+ CALL SMAKE( 'GE', ' ', ' ', MA, NA, A, NMAX, AA, LDA,+ $ RESET, ZERO )+*+ DO 70 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+ UPPER = UPLO.EQ.'U'+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the matrix C.+*+ CALL SMAKE( 'SY', UPLO, ' ', N, N, C, NMAX, CC,+ $ LDC, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ TRANSS = TRANS+ NS = N+ KS = K+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ BETS = BETA+ DO 20 I = 1, LCC+ CS( I ) = CC( I )+ 20 CONTINUE+ LDCS = LDC+*+* Call the subroutine.+*+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, UPLO,+ $ TRANS, N, K, ALPHA, LDA, BETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL SSYRK( UPLO, TRANS, N, K, ALPHA, AA, LDA,+ $ BETA, CC, LDC )+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9993 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLOS.EQ.UPLO+ ISAME( 2 ) = TRANSS.EQ.TRANS+ ISAME( 3 ) = NS.EQ.N+ ISAME( 4 ) = KS.EQ.K+ ISAME( 5 ) = ALS.EQ.ALPHA+ ISAME( 6 ) = LSE( AS, AA, LAA )+ ISAME( 7 ) = LDAS.EQ.LDA+ ISAME( 8 ) = BETS.EQ.BETA+ IF( NULL )THEN+ ISAME( 9 ) = LSE( CS, CC, LCC )+ ELSE+ ISAME( 9 ) = LSERES( 'SY', UPLO, N, N, CS,+ $ CC, LDC )+ END IF+ ISAME( 10 ) = LDCS.EQ.LDC+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 30 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 30 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ JC = 1+ DO 40 J = 1, N+ IF( UPPER )THEN+ JJ = 1+ LJ = J+ ELSE+ JJ = J+ LJ = N - J + 1+ END IF+ IF( TRAN )THEN+ CALL SMMCH( 'T', 'N', LJ, 1, K, ALPHA,+ $ A( 1, JJ ), NMAX,+ $ A( 1, J ), NMAX, BETA,+ $ C( JJ, J ), NMAX, CT, G,+ $ CC( JC ), LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ELSE+ CALL SMMCH( 'N', 'T', LJ, 1, K, ALPHA,+ $ A( JJ, 1 ), NMAX,+ $ A( J, 1 ), NMAX, BETA,+ $ C( JJ, J ), NMAX, CT, G,+ $ CC( JC ), LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ END IF+ IF( UPPER )THEN+ JC = JC + LDC+ ELSE+ JC = JC + LDC + 1+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 110+ 40 CONTINUE+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 110 CONTINUE+ IF( N.GT.1 )+ $ WRITE( NOUT, FMT = 9995 )J+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, TRANS, N, K, ALPHA,+ $ LDA, BETA, LDC+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(', 2( '''', A1, ''',' ), 2( I3, ',' ),+ $ F4.1, ', A,', I3, ',', F4.1, ', C,', I3, ') .' )+ 9993 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of SCHK4.+*+ END+ SUBROUTINE SCHK5( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET, NMAX,+ $ AB, AA, AS, BB, BS, C, CC, CS, CT, G, W )+*+* Tests SSYR2K.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ REAL ZERO+ PARAMETER ( ZERO = 0.0 )+* .. Scalar Arguments ..+ REAL EPS, THRESH+ INTEGER NALF, NBET, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ REAL AA( NMAX*NMAX ), AB( 2*NMAX*NMAX ),+ $ ALF( NALF ), AS( NMAX*NMAX ), BB( NMAX*NMAX ),+ $ BET( NBET ), BS( NMAX*NMAX ), C( NMAX, NMAX ),+ $ CC( NMAX*NMAX ), CS( NMAX*NMAX ), CT( NMAX ),+ $ G( NMAX ), W( 2*NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ REAL ALPHA, ALS, BETA, BETS, ERR, ERRMAX+ INTEGER I, IA, IB, ICT, ICU, IK, IN, J, JC, JJ, JJAB,+ $ K, KS, LAA, LBB, LCC, LDA, LDAS, LDB, LDBS,+ $ LDC, LDCS, LJ, MA, N, NA, NARGS, NC, NS+ LOGICAL NULL, RESET, SAME, TRAN, UPPER+ CHARACTER*1 TRANS, TRANSS, UPLO, UPLOS+ CHARACTER*2 ICHU+ CHARACTER*3 ICHT+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LSE, LSERES+ EXTERNAL LSE, LSERES+* .. External Subroutines ..+ EXTERNAL SMAKE, SMMCH, SSYR2K+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHT/'NTC'/, ICHU/'UL'/+* .. Executable Statements ..+*+ NARGS = 12+ NC = 0+ RESET = .TRUE.+ ERRMAX = ZERO+*+ DO 130 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDC to 1 more than minimum value if room.+ LDC = N+ IF( LDC.LT.NMAX )+ $ LDC = LDC + 1+* Skip tests if not enough room.+ IF( LDC.GT.NMAX )+ $ GO TO 130+ LCC = LDC*N+ NULL = N.LE.0+*+ DO 120 IK = 1, NIDIM+ K = IDIM( IK )+*+ DO 110 ICT = 1, 3+ TRANS = ICHT( ICT: ICT )+ TRAN = TRANS.EQ.'T'.OR.TRANS.EQ.'C'+ IF( TRAN )THEN+ MA = K+ NA = N+ ELSE+ MA = N+ NA = K+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = MA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 110+ LAA = LDA*NA+*+* Generate the matrix A.+*+ IF( TRAN )THEN+ CALL SMAKE( 'GE', ' ', ' ', MA, NA, AB, 2*NMAX, AA,+ $ LDA, RESET, ZERO )+ ELSE+ CALL SMAKE( 'GE', ' ', ' ', MA, NA, AB, NMAX, AA, LDA,+ $ RESET, ZERO )+ END IF+*+* Generate the matrix B.+*+ LDB = LDA+ LBB = LAA+ IF( TRAN )THEN+ CALL SMAKE( 'GE', ' ', ' ', MA, NA, AB( K + 1 ),+ $ 2*NMAX, BB, LDB, RESET, ZERO )+ ELSE+ CALL SMAKE( 'GE', ' ', ' ', MA, NA, AB( K*NMAX + 1 ),+ $ NMAX, BB, LDB, RESET, ZERO )+ END IF+*+ DO 100 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+ UPPER = UPLO.EQ.'U'+*+ DO 90 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 80 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the matrix C.+*+ CALL SMAKE( 'SY', UPLO, ' ', N, N, C, NMAX, CC,+ $ LDC, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ TRANSS = TRANS+ NS = N+ KS = K+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LBB+ BS( I ) = BB( I )+ 20 CONTINUE+ LDBS = LDB+ BETS = BETA+ DO 30 I = 1, LCC+ CS( I ) = CC( I )+ 30 CONTINUE+ LDCS = LDC+*+* Call the subroutine.+*+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, UPLO,+ $ TRANS, N, K, ALPHA, LDA, LDB, BETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL SSYR2K( UPLO, TRANS, N, K, ALPHA, AA, LDA,+ $ BB, LDB, BETA, CC, LDC )+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9993 )+ FATAL = .TRUE.+ GO TO 150+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLOS.EQ.UPLO+ ISAME( 2 ) = TRANSS.EQ.TRANS+ ISAME( 3 ) = NS.EQ.N+ ISAME( 4 ) = KS.EQ.K+ ISAME( 5 ) = ALS.EQ.ALPHA+ ISAME( 6 ) = LSE( AS, AA, LAA )+ ISAME( 7 ) = LDAS.EQ.LDA+ ISAME( 8 ) = LSE( BS, BB, LBB )+ ISAME( 9 ) = LDBS.EQ.LDB+ ISAME( 10 ) = BETS.EQ.BETA+ IF( NULL )THEN+ ISAME( 11 ) = LSE( CS, CC, LCC )+ ELSE+ ISAME( 11 ) = LSERES( 'SY', UPLO, N, N, CS,+ $ CC, LDC )+ END IF+ ISAME( 12 ) = LDCS.EQ.LDC+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 150+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ JJAB = 1+ JC = 1+ DO 70 J = 1, N+ IF( UPPER )THEN+ JJ = 1+ LJ = J+ ELSE+ JJ = J+ LJ = N - J + 1+ END IF+ IF( TRAN )THEN+ DO 50 I = 1, K+ W( I ) = AB( ( J - 1 )*2*NMAX + K ++ $ I )+ W( K + I ) = AB( ( J - 1 )*2*NMAX ++ $ I )+ 50 CONTINUE+ CALL SMMCH( 'T', 'N', LJ, 1, 2*K,+ $ ALPHA, AB( JJAB ), 2*NMAX,+ $ W, 2*NMAX, BETA,+ $ C( JJ, J ), NMAX, CT, G,+ $ CC( JC ), LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ELSE+ DO 60 I = 1, K+ W( I ) = AB( ( K + I - 1 )*NMAX ++ $ J )+ W( K + I ) = AB( ( I - 1 )*NMAX ++ $ J )+ 60 CONTINUE+ CALL SMMCH( 'N', 'N', LJ, 1, 2*K,+ $ ALPHA, AB( JJ ), NMAX, W,+ $ 2*NMAX, BETA, C( JJ, J ),+ $ NMAX, CT, G, CC( JC ), LDC,+ $ EPS, ERR, FATAL, NOUT,+ $ .TRUE. )+ END IF+ IF( UPPER )THEN+ JC = JC + LDC+ ELSE+ JC = JC + LDC + 1+ IF( TRAN )+ $ JJAB = JJAB + 2*NMAX+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 140+ 70 CONTINUE+ END IF+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+ 130 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 160+*+ 140 CONTINUE+ IF( N.GT.1 )+ $ WRITE( NOUT, FMT = 9995 )J+*+ 150 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, TRANS, N, K, ALPHA,+ $ LDA, LDB, BETA, LDC+*+ 160 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(', 2( '''', A1, ''',' ), 2( I3, ',' ),+ $ F4.1, ', A,', I3, ', B,', I3, ',', F4.1, ', C,', I3, ') ',+ $ ' .' )+ 9993 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of SCHK5.+*+ END+ SUBROUTINE SCHKE( ISNUM, SRNAMT, NOUT )+*+* Tests the error exits from the Level 3 Blas.+* Requires a special version of the error-handling routine XERBLA.+* ALPHA, BETA, A, B and C should not need to be defined.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER ISNUM, NOUT+ CHARACTER*6 SRNAMT+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Local Scalars ..+ REAL ALPHA, BETA+* .. Local Arrays ..+ REAL A( 2, 1 ), B( 2, 1 ), C( 2, 1 )+* .. External Subroutines ..+ EXTERNAL CHKXER, SGEMM, SSYMM, SSYR2K, SSYRK, STRMM,+ $ STRSM+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Executable Statements ..+* OK is set to .FALSE. by the special version of XERBLA or by CHKXER+* if anything is wrong.+ OK = .TRUE.+* LERR is set to .TRUE. by the special version of XERBLA each time+* it is called, and is then tested and re-set by CHKXER.+ LERR = .FALSE.+ GO TO ( 10, 20, 30, 40, 50, 60 )ISNUM+ 10 INFOT = 1+ CALL SGEMM( '/', 'N', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 1+ CALL SGEMM( '/', 'T', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL SGEMM( 'N', '/', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL SGEMM( 'T', '/', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SGEMM( 'N', 'N', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SGEMM( 'N', 'T', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SGEMM( 'T', 'N', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SGEMM( 'T', 'T', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL SGEMM( 'N', 'N', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL SGEMM( 'N', 'T', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL SGEMM( 'T', 'N', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL SGEMM( 'T', 'T', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL SGEMM( 'N', 'N', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL SGEMM( 'N', 'T', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL SGEMM( 'T', 'N', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL SGEMM( 'T', 'T', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL SGEMM( 'N', 'N', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL SGEMM( 'N', 'T', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL SGEMM( 'T', 'N', 0, 0, 2, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL SGEMM( 'T', 'T', 0, 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL SGEMM( 'N', 'N', 0, 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL SGEMM( 'T', 'N', 0, 0, 2, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL SGEMM( 'N', 'T', 0, 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL SGEMM( 'T', 'T', 0, 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL SGEMM( 'N', 'N', 2, 0, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL SGEMM( 'N', 'T', 2, 0, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL SGEMM( 'T', 'N', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL SGEMM( 'T', 'T', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 70+ 20 INFOT = 1+ CALL SSYMM( '/', 'U', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL SSYMM( 'L', '/', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SSYMM( 'L', 'U', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SSYMM( 'R', 'U', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SSYMM( 'L', 'L', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SSYMM( 'R', 'L', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL SSYMM( 'L', 'U', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL SSYMM( 'R', 'U', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL SSYMM( 'L', 'L', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL SSYMM( 'R', 'L', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL SSYMM( 'L', 'U', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL SSYMM( 'R', 'U', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL SSYMM( 'L', 'L', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL SSYMM( 'R', 'L', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL SSYMM( 'L', 'U', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL SSYMM( 'R', 'U', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL SSYMM( 'L', 'L', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL SSYMM( 'R', 'L', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL SSYMM( 'L', 'U', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL SSYMM( 'R', 'U', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL SSYMM( 'L', 'L', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL SSYMM( 'R', 'L', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 70+ 30 INFOT = 1+ CALL STRMM( '/', 'U', 'N', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL STRMM( 'L', '/', 'N', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL STRMM( 'L', 'U', '/', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL STRMM( 'L', 'U', 'N', '/', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STRMM( 'L', 'U', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STRMM( 'L', 'U', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STRMM( 'R', 'U', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STRMM( 'R', 'U', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STRMM( 'L', 'L', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STRMM( 'L', 'L', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STRMM( 'R', 'L', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STRMM( 'R', 'L', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRMM( 'L', 'U', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRMM( 'L', 'U', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRMM( 'R', 'U', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRMM( 'R', 'U', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRMM( 'L', 'L', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRMM( 'L', 'L', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRMM( 'R', 'L', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRMM( 'R', 'L', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STRMM( 'L', 'U', 'N', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STRMM( 'L', 'U', 'T', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STRMM( 'R', 'U', 'N', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STRMM( 'R', 'U', 'T', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STRMM( 'L', 'L', 'N', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STRMM( 'L', 'L', 'T', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STRMM( 'R', 'L', 'N', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STRMM( 'R', 'L', 'T', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL STRMM( 'L', 'U', 'N', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL STRMM( 'L', 'U', 'T', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL STRMM( 'R', 'U', 'N', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL STRMM( 'R', 'U', 'T', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL STRMM( 'L', 'L', 'N', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL STRMM( 'L', 'L', 'T', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL STRMM( 'R', 'L', 'N', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL STRMM( 'R', 'L', 'T', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 70+ 40 INFOT = 1+ CALL STRSM( '/', 'U', 'N', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL STRSM( 'L', '/', 'N', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL STRSM( 'L', 'U', '/', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL STRSM( 'L', 'U', 'N', '/', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STRSM( 'L', 'U', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STRSM( 'L', 'U', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STRSM( 'R', 'U', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STRSM( 'R', 'U', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STRSM( 'L', 'L', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STRSM( 'L', 'L', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STRSM( 'R', 'L', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL STRSM( 'R', 'L', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRSM( 'L', 'U', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRSM( 'L', 'U', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRSM( 'R', 'U', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRSM( 'R', 'U', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRSM( 'L', 'L', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRSM( 'L', 'L', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRSM( 'R', 'L', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL STRSM( 'R', 'L', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STRSM( 'L', 'U', 'N', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STRSM( 'L', 'U', 'T', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STRSM( 'R', 'U', 'N', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STRSM( 'R', 'U', 'T', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STRSM( 'L', 'L', 'N', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STRSM( 'L', 'L', 'T', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STRSM( 'R', 'L', 'N', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL STRSM( 'R', 'L', 'T', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL STRSM( 'L', 'U', 'N', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL STRSM( 'L', 'U', 'T', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL STRSM( 'R', 'U', 'N', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL STRSM( 'R', 'U', 'T', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL STRSM( 'L', 'L', 'N', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL STRSM( 'L', 'L', 'T', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL STRSM( 'R', 'L', 'N', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL STRSM( 'R', 'L', 'T', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 70+ 50 INFOT = 1+ CALL SSYRK( '/', 'N', 0, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL SSYRK( 'U', '/', 0, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SSYRK( 'U', 'N', -1, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SSYRK( 'U', 'T', -1, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SSYRK( 'L', 'N', -1, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SSYRK( 'L', 'T', -1, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL SSYRK( 'U', 'N', 0, -1, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL SSYRK( 'U', 'T', 0, -1, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL SSYRK( 'L', 'N', 0, -1, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL SSYRK( 'L', 'T', 0, -1, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL SSYRK( 'U', 'N', 2, 0, ALPHA, A, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL SSYRK( 'U', 'T', 0, 2, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL SSYRK( 'L', 'N', 2, 0, ALPHA, A, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL SSYRK( 'L', 'T', 0, 2, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL SSYRK( 'U', 'N', 2, 0, ALPHA, A, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL SSYRK( 'U', 'T', 2, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL SSYRK( 'L', 'N', 2, 0, ALPHA, A, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL SSYRK( 'L', 'T', 2, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 70+ 60 INFOT = 1+ CALL SSYR2K( '/', 'N', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL SSYR2K( 'U', '/', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SSYR2K( 'U', 'N', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SSYR2K( 'U', 'T', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SSYR2K( 'L', 'N', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL SSYR2K( 'L', 'T', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL SSYR2K( 'U', 'N', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL SSYR2K( 'U', 'T', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL SSYR2K( 'L', 'N', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL SSYR2K( 'L', 'T', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL SSYR2K( 'U', 'N', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL SSYR2K( 'U', 'T', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL SSYR2K( 'L', 'N', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL SSYR2K( 'L', 'T', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL SSYR2K( 'U', 'N', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL SSYR2K( 'U', 'T', 0, 2, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL SSYR2K( 'L', 'N', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL SSYR2K( 'L', 'T', 0, 2, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL SSYR2K( 'U', 'N', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL SSYR2K( 'U', 'T', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL SSYR2K( 'L', 'N', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL SSYR2K( 'L', 'T', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+*+ 70 IF( OK )THEN+ WRITE( NOUT, FMT = 9999 )SRNAMT+ ELSE+ WRITE( NOUT, FMT = 9998 )SRNAMT+ END IF+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE TESTS OF ERROR-EXITS' )+ 9998 FORMAT( ' ******* ', A6, ' FAILED THE TESTS OF ERROR-EXITS *****',+ $ '**' )+*+* End of SCHKE.+*+ END+ SUBROUTINE SMAKE( TYPE, UPLO, DIAG, M, N, A, NMAX, AA, LDA, RESET,+ $ TRANSL )+*+* Generates values for an M by N matrix A.+* Stores the values in the array AA in the data structure required+* by the routine, with unwanted elements set to rogue value.+*+* TYPE is 'GE', 'SY' or 'TR'.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ REAL ZERO, ONE+ PARAMETER ( ZERO = 0.0, ONE = 1.0 )+ REAL ROGUE+ PARAMETER ( ROGUE = -1.0E10 )+* .. Scalar Arguments ..+ REAL TRANSL+ INTEGER LDA, M, N, NMAX+ LOGICAL RESET+ CHARACTER*1 DIAG, UPLO+ CHARACTER*2 TYPE+* .. Array Arguments ..+ REAL A( NMAX, * ), AA( * )+* .. Local Scalars ..+ INTEGER I, IBEG, IEND, J+ LOGICAL GEN, LOWER, SYM, TRI, UNIT, UPPER+* .. External Functions ..+ REAL SBEG+ EXTERNAL SBEG+* .. Executable Statements ..+ GEN = TYPE.EQ.'GE'+ SYM = TYPE.EQ.'SY'+ TRI = TYPE.EQ.'TR'+ UPPER = ( SYM.OR.TRI ).AND.UPLO.EQ.'U'+ LOWER = ( SYM.OR.TRI ).AND.UPLO.EQ.'L'+ UNIT = TRI.AND.DIAG.EQ.'U'+*+* Generate data in array A.+*+ DO 20 J = 1, N+ DO 10 I = 1, M+ IF( GEN.OR.( UPPER.AND.I.LE.J ).OR.( LOWER.AND.I.GE.J ) )+ $ THEN+ A( I, J ) = SBEG( RESET ) + TRANSL+ IF( I.NE.J )THEN+* Set some elements to zero+ IF( N.GT.3.AND.J.EQ.N/2 )+ $ A( I, J ) = ZERO+ IF( SYM )THEN+ A( J, I ) = A( I, J )+ ELSE IF( TRI )THEN+ A( J, I ) = ZERO+ END IF+ END IF+ END IF+ 10 CONTINUE+ IF( TRI )+ $ A( J, J ) = A( J, J ) + ONE+ IF( UNIT )+ $ A( J, J ) = ONE+ 20 CONTINUE+*+* Store elements in array AS in data structure required by routine.+*+ IF( TYPE.EQ.'GE' )THEN+ DO 50 J = 1, N+ DO 30 I = 1, M+ AA( I + ( J - 1 )*LDA ) = A( I, J )+ 30 CONTINUE+ DO 40 I = M + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 40 CONTINUE+ 50 CONTINUE+ ELSE IF( TYPE.EQ.'SY'.OR.TYPE.EQ.'TR' )THEN+ DO 90 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IF( UNIT )THEN+ IEND = J - 1+ ELSE+ IEND = J+ END IF+ ELSE+ IF( UNIT )THEN+ IBEG = J + 1+ ELSE+ IBEG = J+ END IF+ IEND = N+ END IF+ DO 60 I = 1, IBEG - 1+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 60 CONTINUE+ DO 70 I = IBEG, IEND+ AA( I + ( J - 1 )*LDA ) = A( I, J )+ 70 CONTINUE+ DO 80 I = IEND + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 80 CONTINUE+ 90 CONTINUE+ END IF+ RETURN+*+* End of SMAKE.+*+ END+ SUBROUTINE SMMCH( TRANSA, TRANSB, M, N, KK, ALPHA, A, LDA, B, LDB,+ $ BETA, C, LDC, CT, G, CC, LDCC, EPS, ERR, FATAL,+ $ NOUT, MV )+*+* Checks the results of the computational tests.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ REAL ZERO, ONE+ PARAMETER ( ZERO = 0.0, ONE = 1.0 )+* .. Scalar Arguments ..+ REAL ALPHA, BETA, EPS, ERR+ INTEGER KK, LDA, LDB, LDC, LDCC, M, N, NOUT+ LOGICAL FATAL, MV+ CHARACTER*1 TRANSA, TRANSB+* .. Array Arguments ..+ REAL A( LDA, * ), B( LDB, * ), C( LDC, * ),+ $ CC( LDCC, * ), CT( * ), G( * )+* .. Local Scalars ..+ REAL ERRI+ INTEGER I, J, K+ LOGICAL TRANA, TRANB+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, SQRT+* .. Executable Statements ..+ TRANA = TRANSA.EQ.'T'.OR.TRANSA.EQ.'C'+ TRANB = TRANSB.EQ.'T'.OR.TRANSB.EQ.'C'+*+* Compute expected result, one column at a time, in CT using data+* in A, B and C.+* Compute gauges in G.+*+ DO 120 J = 1, N+*+ DO 10 I = 1, M+ CT( I ) = ZERO+ G( I ) = ZERO+ 10 CONTINUE+ IF( .NOT.TRANA.AND..NOT.TRANB )THEN+ DO 30 K = 1, KK+ DO 20 I = 1, M+ CT( I ) = CT( I ) + A( I, K )*B( K, J )+ G( I ) = G( I ) + ABS( A( I, K ) )*ABS( B( K, J ) )+ 20 CONTINUE+ 30 CONTINUE+ ELSE IF( TRANA.AND..NOT.TRANB )THEN+ DO 50 K = 1, KK+ DO 40 I = 1, M+ CT( I ) = CT( I ) + A( K, I )*B( K, J )+ G( I ) = G( I ) + ABS( A( K, I ) )*ABS( B( K, J ) )+ 40 CONTINUE+ 50 CONTINUE+ ELSE IF( .NOT.TRANA.AND.TRANB )THEN+ DO 70 K = 1, KK+ DO 60 I = 1, M+ CT( I ) = CT( I ) + A( I, K )*B( J, K )+ G( I ) = G( I ) + ABS( A( I, K ) )*ABS( B( J, K ) )+ 60 CONTINUE+ 70 CONTINUE+ ELSE IF( TRANA.AND.TRANB )THEN+ DO 90 K = 1, KK+ DO 80 I = 1, M+ CT( I ) = CT( I ) + A( K, I )*B( J, K )+ G( I ) = G( I ) + ABS( A( K, I ) )*ABS( B( J, K ) )+ 80 CONTINUE+ 90 CONTINUE+ END IF+ DO 100 I = 1, M+ CT( I ) = ALPHA*CT( I ) + BETA*C( I, J )+ G( I ) = ABS( ALPHA )*G( I ) + ABS( BETA )*ABS( C( I, J ) )+ 100 CONTINUE+*+* Compute the error ratio for this result.+*+ ERR = ZERO+ DO 110 I = 1, M+ ERRI = ABS( CT( I ) - CC( I, J ) )/EPS+ IF( G( I ).NE.ZERO )+ $ ERRI = ERRI/G( I )+ ERR = MAX( ERR, ERRI )+ IF( ERR*SQRT( EPS ).GE.ONE )+ $ GO TO 130+ 110 CONTINUE+*+ 120 CONTINUE+*+* If the loop completes, all results are at least half accurate.+ GO TO 150+*+* Report fatal error.+*+ 130 FATAL = .TRUE.+ WRITE( NOUT, FMT = 9999 )+ DO 140 I = 1, M+ IF( MV )THEN+ WRITE( NOUT, FMT = 9998 )I, CT( I ), CC( I, J )+ ELSE+ WRITE( NOUT, FMT = 9998 )I, CC( I, J ), CT( I )+ END IF+ 140 CONTINUE+ IF( N.GT.1 )+ $ WRITE( NOUT, FMT = 9997 )J+*+ 150 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ******* FATAL ERROR - COMPUTED RESULT IS LESS THAN HAL',+ $ 'F ACCURATE *******', /' EXPECTED RESULT COMPU',+ $ 'TED RESULT' )+ 9998 FORMAT( 1X, I7, 2G18.6 )+ 9997 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+*+* End of SMMCH.+*+ END+ LOGICAL FUNCTION LSE( RI, RJ, LR )+*+* Tests if two arrays are identical.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER LR+* .. Array Arguments ..+ REAL RI( * ), RJ( * )+* .. Local Scalars ..+ INTEGER I+* .. Executable Statements ..+ DO 10 I = 1, LR+ IF( RI( I ).NE.RJ( I ) )+ $ GO TO 20+ 10 CONTINUE+ LSE = .TRUE.+ GO TO 30+ 20 CONTINUE+ LSE = .FALSE.+ 30 RETURN+*+* End of LSE.+*+ END+ LOGICAL FUNCTION LSERES( TYPE, UPLO, M, N, AA, AS, LDA )+*+* Tests if selected elements in two arrays are equal.+*+* TYPE is 'GE' or 'SY'.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER LDA, M, N+ CHARACTER*1 UPLO+ CHARACTER*2 TYPE+* .. Array Arguments ..+ REAL AA( LDA, * ), AS( LDA, * )+* .. Local Scalars ..+ INTEGER I, IBEG, IEND, J+ LOGICAL UPPER+* .. Executable Statements ..+ UPPER = UPLO.EQ.'U'+ IF( TYPE.EQ.'GE' )THEN+ DO 20 J = 1, N+ DO 10 I = M + 1, LDA+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 10 CONTINUE+ 20 CONTINUE+ ELSE IF( TYPE.EQ.'SY' )THEN+ DO 50 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IEND = J+ ELSE+ IBEG = J+ IEND = N+ END IF+ DO 30 I = 1, IBEG - 1+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 30 CONTINUE+ DO 40 I = IEND + 1, LDA+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 40 CONTINUE+ 50 CONTINUE+ END IF+*+ 60 CONTINUE+ LSERES = .TRUE.+ GO TO 80+ 70 CONTINUE+ LSERES = .FALSE.+ 80 RETURN+*+* End of LSERES.+*+ END+ REAL FUNCTION SBEG( RESET )+*+* Generates random numbers uniformly distributed between -0.5 and 0.5.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ LOGICAL RESET+* .. Local Scalars ..+ INTEGER I, IC, MI+* .. Save statement ..+ SAVE I, IC, MI+* .. Executable Statements ..+ IF( RESET )THEN+* Initialize local variables.+ MI = 891+ I = 7+ IC = 0+ RESET = .FALSE.+ END IF+*+* The sequence of values of I is bounded between 1 and 999.+* If initial I = 1,2,3,6,7 or 9, the period will be 50.+* If initial I = 4 or 8, the period will be 25.+* If initial I = 5, the period will be 10.+* IC is used to break up the period by skipping 1 value of I in 6.+*+ IC = IC + 1+ 10 I = I*MI+ I = I - 1000*( I/1000 )+ IF( IC.GE.5 )THEN+ IC = 0+ GO TO 10+ END IF+ SBEG = ( I - 500 )/1001.0+ RETURN+*+* End of SBEG.+*+ END+ REAL FUNCTION SDIFF( X, Y )+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ REAL X, Y+* .. Executable Statements ..+ SDIFF = X - Y+ RETURN+*+* End of SDIFF.+*+ END+ SUBROUTINE CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+*+* Tests whether XERBLA has detected an error when it should.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER INFOT, NOUT+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Executable Statements ..+ IF( .NOT.LERR )THEN+ WRITE( NOUT, FMT = 9999 )INFOT, SRNAMT+ OK = .FALSE.+ END IF+ LERR = .FALSE.+ RETURN+*+ 9999 FORMAT( ' ***** ILLEGAL VALUE OF PARAMETER NUMBER ', I2, ' NOT D',+ $ 'ETECTED BY ', A6, ' *****' )+*+* End of CHKXER.+*+ END+ SUBROUTINE XERBLA( SRNAME, INFO )+*+* This is a special version of XERBLA to be used only as part of+* the test program for testing error exits from the Level 3 BLAS+* routines.+*+* XERBLA is an error handler for the Level 3 BLAS routines.+*+* It is called by the Level 3 BLAS routines if an input parameter is+* invalid.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER INFO+ CHARACTER*6 SRNAME+* .. Scalars in Common ..+ INTEGER INFOT, NOUT+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUT, OK, LERR+ COMMON /SRNAMC/SRNAMT+* .. Executable Statements ..+ LERR = .TRUE.+ IF( INFO.NE.INFOT )THEN+ IF( INFOT.NE.0 )THEN+ WRITE( NOUT, FMT = 9999 )INFO, INFOT+ ELSE+ WRITE( NOUT, FMT = 9997 )INFO+ END IF+ OK = .FALSE.+ END IF+ IF( SRNAME.NE.SRNAMT )THEN+ WRITE( NOUT, FMT = 9998 )SRNAME, SRNAMT+ OK = .FALSE.+ END IF+ RETURN+*+ 9999 FORMAT( ' ******* XERBLA WAS CALLED WITH INFO = ', I6, ' INSTEAD',+ $ ' OF ', I2, ' *******' )+ 9998 FORMAT( ' ******* XERBLA WAS CALLED WITH SRNAME = ', A6, ' INSTE',+ $ 'AD OF ', A6, ' *******' )+ 9997 FORMAT( ' ******* XERBLA WAS CALLED WITH INFO = ', I6,+ $ ' *******' )+*+* End of XERBLA+*+ END+
+ eigen3/blas/testing/zblat1.f view
@@ -0,0 +1,681 @@+ PROGRAM ZBLAT1+* Test program for the COMPLEX*16 Level 1 BLAS.+* Based upon the original BLAS test routine together with:+* F06GAF Example Program Text+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, MODE, N+ LOGICAL PASS+* .. Local Scalars ..+ DOUBLE PRECISION SFAC+ INTEGER IC+* .. External Subroutines ..+ EXTERNAL CHECK1, CHECK2, HEADER+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, MODE, PASS+* .. Data statements ..+ DATA SFAC/9.765625D-4/+* .. Executable Statements ..+ WRITE (NOUT,99999)+ DO 20 IC = 1, 10+ ICASE = IC+ CALL HEADER+*+* Initialize PASS, INCX, INCY, and MODE for a new case.+* The value 9999 for INCX, INCY or MODE will appear in the+* detailed output, if any, for cases that do not involve+* these parameters.+*+ PASS = .TRUE.+ INCX = 9999+ INCY = 9999+ MODE = 9999+ IF (ICASE.LE.5) THEN+ CALL CHECK2(SFAC)+ ELSE IF (ICASE.GE.6) THEN+ CALL CHECK1(SFAC)+ END IF+* -- Print+ IF (PASS) WRITE (NOUT,99998)+ 20 CONTINUE+ STOP+*+99999 FORMAT (' Complex BLAS Test Program Results',/1X)+99998 FORMAT (' ----- PASS -----')+ END+ SUBROUTINE HEADER+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, MODE, N+ LOGICAL PASS+* .. Local Arrays ..+ CHARACTER*6 L(10)+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, MODE, PASS+* .. Data statements ..+ DATA L(1)/'ZDOTC '/+ DATA L(2)/'ZDOTU '/+ DATA L(3)/'ZAXPY '/+ DATA L(4)/'ZCOPY '/+ DATA L(5)/'ZSWAP '/+ DATA L(6)/'DZNRM2'/+ DATA L(7)/'DZASUM'/+ DATA L(8)/'ZSCAL '/+ DATA L(9)/'ZDSCAL'/+ DATA L(10)/'IZAMAX'/+* .. Executable Statements ..+ WRITE (NOUT,99999) ICASE, L(ICASE)+ RETURN+*+99999 FORMAT (/' Test of subprogram number',I3,12X,A6)+ END+ SUBROUTINE CHECK1(SFAC)+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ DOUBLE PRECISION SFAC+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, MODE, N+ LOGICAL PASS+* .. Local Scalars ..+ COMPLEX*16 CA+ DOUBLE PRECISION SA+ INTEGER I, J, LEN, NP1+* .. Local Arrays ..+ COMPLEX*16 CTRUE5(8,5,2), CTRUE6(8,5,2), CV(8,5,2), CX(8),+ + MWPCS(5), MWPCT(5)+ DOUBLE PRECISION STRUE2(5), STRUE4(5)+ INTEGER ITRUE3(5)+* .. External Functions ..+ DOUBLE PRECISION DZASUM, DZNRM2+ INTEGER IZAMAX+ EXTERNAL DZASUM, DZNRM2, IZAMAX+* .. External Subroutines ..+ EXTERNAL ZSCAL, ZDSCAL, CTEST, ITEST1, STEST1+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, MODE, PASS+* .. Data statements ..+ DATA SA, CA/0.3D0, (0.4D0,-0.7D0)/+ DATA ((CV(I,J,1),I=1,8),J=1,5)/(0.1D0,0.1D0),+ + (1.0D0,2.0D0), (1.0D0,2.0D0), (1.0D0,2.0D0),+ + (1.0D0,2.0D0), (1.0D0,2.0D0), (1.0D0,2.0D0),+ + (1.0D0,2.0D0), (0.3D0,-0.4D0), (3.0D0,4.0D0),+ + (3.0D0,4.0D0), (3.0D0,4.0D0), (3.0D0,4.0D0),+ + (3.0D0,4.0D0), (3.0D0,4.0D0), (3.0D0,4.0D0),+ + (0.1D0,-0.3D0), (0.5D0,-0.1D0), (5.0D0,6.0D0),+ + (5.0D0,6.0D0), (5.0D0,6.0D0), (5.0D0,6.0D0),+ + (5.0D0,6.0D0), (5.0D0,6.0D0), (0.1D0,0.1D0),+ + (-0.6D0,0.1D0), (0.1D0,-0.3D0), (7.0D0,8.0D0),+ + (7.0D0,8.0D0), (7.0D0,8.0D0), (7.0D0,8.0D0),+ + (7.0D0,8.0D0), (0.3D0,0.1D0), (0.1D0,0.4D0),+ + (0.4D0,0.1D0), (0.1D0,0.2D0), (2.0D0,3.0D0),+ + (2.0D0,3.0D0), (2.0D0,3.0D0), (2.0D0,3.0D0)/+ DATA ((CV(I,J,2),I=1,8),J=1,5)/(0.1D0,0.1D0),+ + (4.0D0,5.0D0), (4.0D0,5.0D0), (4.0D0,5.0D0),+ + (4.0D0,5.0D0), (4.0D0,5.0D0), (4.0D0,5.0D0),+ + (4.0D0,5.0D0), (0.3D0,-0.4D0), (6.0D0,7.0D0),+ + (6.0D0,7.0D0), (6.0D0,7.0D0), (6.0D0,7.0D0),+ + (6.0D0,7.0D0), (6.0D0,7.0D0), (6.0D0,7.0D0),+ + (0.1D0,-0.3D0), (8.0D0,9.0D0), (0.5D0,-0.1D0),+ + (2.0D0,5.0D0), (2.0D0,5.0D0), (2.0D0,5.0D0),+ + (2.0D0,5.0D0), (2.0D0,5.0D0), (0.1D0,0.1D0),+ + (3.0D0,6.0D0), (-0.6D0,0.1D0), (4.0D0,7.0D0),+ + (0.1D0,-0.3D0), (7.0D0,2.0D0), (7.0D0,2.0D0),+ + (7.0D0,2.0D0), (0.3D0,0.1D0), (5.0D0,8.0D0),+ + (0.1D0,0.4D0), (6.0D0,9.0D0), (0.4D0,0.1D0),+ + (8.0D0,3.0D0), (0.1D0,0.2D0), (9.0D0,4.0D0)/+ DATA STRUE2/0.0D0, 0.5D0, 0.6D0, 0.7D0, 0.7D0/+ DATA STRUE4/0.0D0, 0.7D0, 1.0D0, 1.3D0, 1.7D0/+ DATA ((CTRUE5(I,J,1),I=1,8),J=1,5)/(0.1D0,0.1D0),+ + (1.0D0,2.0D0), (1.0D0,2.0D0), (1.0D0,2.0D0),+ + (1.0D0,2.0D0), (1.0D0,2.0D0), (1.0D0,2.0D0),+ + (1.0D0,2.0D0), (-0.16D0,-0.37D0), (3.0D0,4.0D0),+ + (3.0D0,4.0D0), (3.0D0,4.0D0), (3.0D0,4.0D0),+ + (3.0D0,4.0D0), (3.0D0,4.0D0), (3.0D0,4.0D0),+ + (-0.17D0,-0.19D0), (0.13D0,-0.39D0),+ + (5.0D0,6.0D0), (5.0D0,6.0D0), (5.0D0,6.0D0),+ + (5.0D0,6.0D0), (5.0D0,6.0D0), (5.0D0,6.0D0),+ + (0.11D0,-0.03D0), (-0.17D0,0.46D0),+ + (-0.17D0,-0.19D0), (7.0D0,8.0D0), (7.0D0,8.0D0),+ + (7.0D0,8.0D0), (7.0D0,8.0D0), (7.0D0,8.0D0),+ + (0.19D0,-0.17D0), (0.32D0,0.09D0),+ + (0.23D0,-0.24D0), (0.18D0,0.01D0),+ + (2.0D0,3.0D0), (2.0D0,3.0D0), (2.0D0,3.0D0),+ + (2.0D0,3.0D0)/+ DATA ((CTRUE5(I,J,2),I=1,8),J=1,5)/(0.1D0,0.1D0),+ + (4.0D0,5.0D0), (4.0D0,5.0D0), (4.0D0,5.0D0),+ + (4.0D0,5.0D0), (4.0D0,5.0D0), (4.0D0,5.0D0),+ + (4.0D0,5.0D0), (-0.16D0,-0.37D0), (6.0D0,7.0D0),+ + (6.0D0,7.0D0), (6.0D0,7.0D0), (6.0D0,7.0D0),+ + (6.0D0,7.0D0), (6.0D0,7.0D0), (6.0D0,7.0D0),+ + (-0.17D0,-0.19D0), (8.0D0,9.0D0),+ + (0.13D0,-0.39D0), (2.0D0,5.0D0), (2.0D0,5.0D0),+ + (2.0D0,5.0D0), (2.0D0,5.0D0), (2.0D0,5.0D0),+ + (0.11D0,-0.03D0), (3.0D0,6.0D0),+ + (-0.17D0,0.46D0), (4.0D0,7.0D0),+ + (-0.17D0,-0.19D0), (7.0D0,2.0D0), (7.0D0,2.0D0),+ + (7.0D0,2.0D0), (0.19D0,-0.17D0), (5.0D0,8.0D0),+ + (0.32D0,0.09D0), (6.0D0,9.0D0),+ + (0.23D0,-0.24D0), (8.0D0,3.0D0),+ + (0.18D0,0.01D0), (9.0D0,4.0D0)/+ DATA ((CTRUE6(I,J,1),I=1,8),J=1,5)/(0.1D0,0.1D0),+ + (1.0D0,2.0D0), (1.0D0,2.0D0), (1.0D0,2.0D0),+ + (1.0D0,2.0D0), (1.0D0,2.0D0), (1.0D0,2.0D0),+ + (1.0D0,2.0D0), (0.09D0,-0.12D0), (3.0D0,4.0D0),+ + (3.0D0,4.0D0), (3.0D0,4.0D0), (3.0D0,4.0D0),+ + (3.0D0,4.0D0), (3.0D0,4.0D0), (3.0D0,4.0D0),+ + (0.03D0,-0.09D0), (0.15D0,-0.03D0),+ + (5.0D0,6.0D0), (5.0D0,6.0D0), (5.0D0,6.0D0),+ + (5.0D0,6.0D0), (5.0D0,6.0D0), (5.0D0,6.0D0),+ + (0.03D0,0.03D0), (-0.18D0,0.03D0),+ + (0.03D0,-0.09D0), (7.0D0,8.0D0), (7.0D0,8.0D0),+ + (7.0D0,8.0D0), (7.0D0,8.0D0), (7.0D0,8.0D0),+ + (0.09D0,0.03D0), (0.03D0,0.12D0),+ + (0.12D0,0.03D0), (0.03D0,0.06D0), (2.0D0,3.0D0),+ + (2.0D0,3.0D0), (2.0D0,3.0D0), (2.0D0,3.0D0)/+ DATA ((CTRUE6(I,J,2),I=1,8),J=1,5)/(0.1D0,0.1D0),+ + (4.0D0,5.0D0), (4.0D0,5.0D0), (4.0D0,5.0D0),+ + (4.0D0,5.0D0), (4.0D0,5.0D0), (4.0D0,5.0D0),+ + (4.0D0,5.0D0), (0.09D0,-0.12D0), (6.0D0,7.0D0),+ + (6.0D0,7.0D0), (6.0D0,7.0D0), (6.0D0,7.0D0),+ + (6.0D0,7.0D0), (6.0D0,7.0D0), (6.0D0,7.0D0),+ + (0.03D0,-0.09D0), (8.0D0,9.0D0),+ + (0.15D0,-0.03D0), (2.0D0,5.0D0), (2.0D0,5.0D0),+ + (2.0D0,5.0D0), (2.0D0,5.0D0), (2.0D0,5.0D0),+ + (0.03D0,0.03D0), (3.0D0,6.0D0),+ + (-0.18D0,0.03D0), (4.0D0,7.0D0),+ + (0.03D0,-0.09D0), (7.0D0,2.0D0), (7.0D0,2.0D0),+ + (7.0D0,2.0D0), (0.09D0,0.03D0), (5.0D0,8.0D0),+ + (0.03D0,0.12D0), (6.0D0,9.0D0), (0.12D0,0.03D0),+ + (8.0D0,3.0D0), (0.03D0,0.06D0), (9.0D0,4.0D0)/+ DATA ITRUE3/0, 1, 2, 2, 2/+* .. Executable Statements ..+ DO 60 INCX = 1, 2+ DO 40 NP1 = 1, 5+ N = NP1 - 1+ LEN = 2*MAX(N,1)+* .. Set vector arguments ..+ DO 20 I = 1, LEN+ CX(I) = CV(I,NP1,INCX)+ 20 CONTINUE+ IF (ICASE.EQ.6) THEN+* .. DZNRM2 ..+ CALL STEST1(DZNRM2(N,CX,INCX),STRUE2(NP1),STRUE2(NP1),+ + SFAC)+ ELSE IF (ICASE.EQ.7) THEN+* .. DZASUM ..+ CALL STEST1(DZASUM(N,CX,INCX),STRUE4(NP1),STRUE4(NP1),+ + SFAC)+ ELSE IF (ICASE.EQ.8) THEN+* .. ZSCAL ..+ CALL ZSCAL(N,CA,CX,INCX)+ CALL CTEST(LEN,CX,CTRUE5(1,NP1,INCX),CTRUE5(1,NP1,INCX),+ + SFAC)+ ELSE IF (ICASE.EQ.9) THEN+* .. ZDSCAL ..+ CALL ZDSCAL(N,SA,CX,INCX)+ CALL CTEST(LEN,CX,CTRUE6(1,NP1,INCX),CTRUE6(1,NP1,INCX),+ + SFAC)+ ELSE IF (ICASE.EQ.10) THEN+* .. IZAMAX ..+ CALL ITEST1(IZAMAX(N,CX,INCX),ITRUE3(NP1))+ ELSE+ WRITE (NOUT,*) ' Shouldn''t be here in CHECK1'+ STOP+ END IF+*+ 40 CONTINUE+ 60 CONTINUE+*+ INCX = 1+ IF (ICASE.EQ.8) THEN+* ZSCAL+* Add a test for alpha equal to zero.+ CA = (0.0D0,0.0D0)+ DO 80 I = 1, 5+ MWPCT(I) = (0.0D0,0.0D0)+ MWPCS(I) = (1.0D0,1.0D0)+ 80 CONTINUE+ CALL ZSCAL(5,CA,CX,INCX)+ CALL CTEST(5,CX,MWPCT,MWPCS,SFAC)+ ELSE IF (ICASE.EQ.9) THEN+* ZDSCAL+* Add a test for alpha equal to zero.+ SA = 0.0D0+ DO 100 I = 1, 5+ MWPCT(I) = (0.0D0,0.0D0)+ MWPCS(I) = (1.0D0,1.0D0)+ 100 CONTINUE+ CALL ZDSCAL(5,SA,CX,INCX)+ CALL CTEST(5,CX,MWPCT,MWPCS,SFAC)+* Add a test for alpha equal to one.+ SA = 1.0D0+ DO 120 I = 1, 5+ MWPCT(I) = CX(I)+ MWPCS(I) = CX(I)+ 120 CONTINUE+ CALL ZDSCAL(5,SA,CX,INCX)+ CALL CTEST(5,CX,MWPCT,MWPCS,SFAC)+* Add a test for alpha equal to minus one.+ SA = -1.0D0+ DO 140 I = 1, 5+ MWPCT(I) = -CX(I)+ MWPCS(I) = -CX(I)+ 140 CONTINUE+ CALL ZDSCAL(5,SA,CX,INCX)+ CALL CTEST(5,CX,MWPCT,MWPCS,SFAC)+ END IF+ RETURN+ END+ SUBROUTINE CHECK2(SFAC)+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ DOUBLE PRECISION SFAC+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, MODE, N+ LOGICAL PASS+* .. Local Scalars ..+ COMPLEX*16 CA+ INTEGER I, J, KI, KN, KSIZE, LENX, LENY, MX, MY+* .. Local Arrays ..+ COMPLEX*16 CDOT(1), CSIZE1(4), CSIZE2(7,2), CSIZE3(14),+ + CT10X(7,4,4), CT10Y(7,4,4), CT6(4,4), CT7(4,4),+ + CT8(7,4,4), CX(7), CX1(7), CY(7), CY1(7)+ INTEGER INCXS(4), INCYS(4), LENS(4,2), NS(4)+* .. External Functions ..+ COMPLEX*16 ZDOTC, ZDOTU+ EXTERNAL ZDOTC, ZDOTU+* .. External Subroutines ..+ EXTERNAL ZAXPY, ZCOPY, ZSWAP, CTEST+* .. Intrinsic Functions ..+ INTRINSIC ABS, MIN+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, MODE, PASS+* .. Data statements ..+ DATA CA/(0.4D0,-0.7D0)/+ DATA INCXS/1, 2, -2, -1/+ DATA INCYS/1, -2, 1, -2/+ DATA LENS/1, 1, 2, 4, 1, 1, 3, 7/+ DATA NS/0, 1, 2, 4/+ DATA CX1/(0.7D0,-0.8D0), (-0.4D0,-0.7D0),+ + (-0.1D0,-0.9D0), (0.2D0,-0.8D0),+ + (-0.9D0,-0.4D0), (0.1D0,0.4D0), (-0.6D0,0.6D0)/+ DATA CY1/(0.6D0,-0.6D0), (-0.9D0,0.5D0),+ + (0.7D0,-0.6D0), (0.1D0,-0.5D0), (-0.1D0,-0.2D0),+ + (-0.5D0,-0.3D0), (0.8D0,-0.7D0)/+ DATA ((CT8(I,J,1),I=1,7),J=1,4)/(0.6D0,-0.6D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.32D0,-1.41D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.32D0,-1.41D0),+ + (-1.55D0,0.5D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.32D0,-1.41D0), (-1.55D0,0.5D0),+ + (0.03D0,-0.89D0), (-0.38D0,-0.96D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0)/+ DATA ((CT8(I,J,2),I=1,7),J=1,4)/(0.6D0,-0.6D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.32D0,-1.41D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (-0.07D0,-0.89D0),+ + (-0.9D0,0.5D0), (0.42D0,-1.41D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.78D0,0.06D0), (-0.9D0,0.5D0),+ + (0.06D0,-0.13D0), (0.1D0,-0.5D0),+ + (-0.77D0,-0.49D0), (-0.5D0,-0.3D0),+ + (0.52D0,-1.51D0)/+ DATA ((CT8(I,J,3),I=1,7),J=1,4)/(0.6D0,-0.6D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.32D0,-1.41D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (-0.07D0,-0.89D0),+ + (-1.18D0,-0.31D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.78D0,0.06D0), (-1.54D0,0.97D0),+ + (0.03D0,-0.89D0), (-0.18D0,-1.31D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0)/+ DATA ((CT8(I,J,4),I=1,7),J=1,4)/(0.6D0,-0.6D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.32D0,-1.41D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.32D0,-1.41D0), (-0.9D0,0.5D0),+ + (0.05D0,-0.6D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.32D0,-1.41D0),+ + (-0.9D0,0.5D0), (0.05D0,-0.6D0), (0.1D0,-0.5D0),+ + (-0.77D0,-0.49D0), (-0.5D0,-0.3D0),+ + (0.32D0,-1.16D0)/+ DATA CT7/(0.0D0,0.0D0), (-0.06D0,-0.90D0),+ + (0.65D0,-0.47D0), (-0.34D0,-1.22D0),+ + (0.0D0,0.0D0), (-0.06D0,-0.90D0),+ + (-0.59D0,-1.46D0), (-1.04D0,-0.04D0),+ + (0.0D0,0.0D0), (-0.06D0,-0.90D0),+ + (-0.83D0,0.59D0), (0.07D0,-0.37D0),+ + (0.0D0,0.0D0), (-0.06D0,-0.90D0),+ + (-0.76D0,-1.15D0), (-1.33D0,-1.82D0)/+ DATA CT6/(0.0D0,0.0D0), (0.90D0,0.06D0),+ + (0.91D0,-0.77D0), (1.80D0,-0.10D0),+ + (0.0D0,0.0D0), (0.90D0,0.06D0), (1.45D0,0.74D0),+ + (0.20D0,0.90D0), (0.0D0,0.0D0), (0.90D0,0.06D0),+ + (-0.55D0,0.23D0), (0.83D0,-0.39D0),+ + (0.0D0,0.0D0), (0.90D0,0.06D0), (1.04D0,0.79D0),+ + (1.95D0,1.22D0)/+ DATA ((CT10X(I,J,1),I=1,7),J=1,4)/(0.7D0,-0.8D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.6D0,-0.6D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.6D0,-0.6D0), (-0.9D0,0.5D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.6D0,-0.6D0),+ + (-0.9D0,0.5D0), (0.7D0,-0.6D0), (0.1D0,-0.5D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0)/+ DATA ((CT10X(I,J,2),I=1,7),J=1,4)/(0.7D0,-0.8D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.6D0,-0.6D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.7D0,-0.6D0), (-0.4D0,-0.7D0),+ + (0.6D0,-0.6D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.8D0,-0.7D0),+ + (-0.4D0,-0.7D0), (-0.1D0,-0.2D0),+ + (0.2D0,-0.8D0), (0.7D0,-0.6D0), (0.1D0,0.4D0),+ + (0.6D0,-0.6D0)/+ DATA ((CT10X(I,J,3),I=1,7),J=1,4)/(0.7D0,-0.8D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.6D0,-0.6D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (-0.9D0,0.5D0), (-0.4D0,-0.7D0),+ + (0.6D0,-0.6D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.1D0,-0.5D0),+ + (-0.4D0,-0.7D0), (0.7D0,-0.6D0), (0.2D0,-0.8D0),+ + (-0.9D0,0.5D0), (0.1D0,0.4D0), (0.6D0,-0.6D0)/+ DATA ((CT10X(I,J,4),I=1,7),J=1,4)/(0.7D0,-0.8D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.6D0,-0.6D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.6D0,-0.6D0), (0.7D0,-0.6D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.6D0,-0.6D0),+ + (0.7D0,-0.6D0), (-0.1D0,-0.2D0), (0.8D0,-0.7D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0)/+ DATA ((CT10Y(I,J,1),I=1,7),J=1,4)/(0.6D0,-0.6D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.7D0,-0.8D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.7D0,-0.8D0), (-0.4D0,-0.7D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.7D0,-0.8D0),+ + (-0.4D0,-0.7D0), (-0.1D0,-0.9D0),+ + (0.2D0,-0.8D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0)/+ DATA ((CT10Y(I,J,2),I=1,7),J=1,4)/(0.6D0,-0.6D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.7D0,-0.8D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (-0.1D0,-0.9D0), (-0.9D0,0.5D0),+ + (0.7D0,-0.8D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (-0.6D0,0.6D0),+ + (-0.9D0,0.5D0), (-0.9D0,-0.4D0), (0.1D0,-0.5D0),+ + (-0.1D0,-0.9D0), (-0.5D0,-0.3D0),+ + (0.7D0,-0.8D0)/+ DATA ((CT10Y(I,J,3),I=1,7),J=1,4)/(0.6D0,-0.6D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.7D0,-0.8D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (-0.1D0,-0.9D0), (0.7D0,-0.8D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (-0.6D0,0.6D0),+ + (-0.9D0,-0.4D0), (-0.1D0,-0.9D0),+ + (0.7D0,-0.8D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0)/+ DATA ((CT10Y(I,J,4),I=1,7),J=1,4)/(0.6D0,-0.6D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.7D0,-0.8D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.7D0,-0.8D0), (-0.9D0,0.5D0),+ + (-0.4D0,-0.7D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.7D0,-0.8D0),+ + (-0.9D0,0.5D0), (-0.4D0,-0.7D0), (0.1D0,-0.5D0),+ + (-0.1D0,-0.9D0), (-0.5D0,-0.3D0),+ + (0.2D0,-0.8D0)/+ DATA CSIZE1/(0.0D0,0.0D0), (0.9D0,0.9D0),+ + (1.63D0,1.73D0), (2.90D0,2.78D0)/+ DATA CSIZE3/(0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (1.17D0,1.17D0),+ + (1.17D0,1.17D0), (1.17D0,1.17D0),+ + (1.17D0,1.17D0), (1.17D0,1.17D0),+ + (1.17D0,1.17D0), (1.17D0,1.17D0)/+ DATA CSIZE2/(0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (0.0D0,0.0D0),+ + (0.0D0,0.0D0), (0.0D0,0.0D0), (1.54D0,1.54D0),+ + (1.54D0,1.54D0), (1.54D0,1.54D0),+ + (1.54D0,1.54D0), (1.54D0,1.54D0),+ + (1.54D0,1.54D0), (1.54D0,1.54D0)/+* .. Executable Statements ..+ DO 60 KI = 1, 4+ INCX = INCXS(KI)+ INCY = INCYS(KI)+ MX = ABS(INCX)+ MY = ABS(INCY)+*+ DO 40 KN = 1, 4+ N = NS(KN)+ KSIZE = MIN(2,KN)+ LENX = LENS(KN,MX)+ LENY = LENS(KN,MY)+* .. initialize all argument arrays ..+ DO 20 I = 1, 7+ CX(I) = CX1(I)+ CY(I) = CY1(I)+ 20 CONTINUE+ IF (ICASE.EQ.1) THEN+* .. ZDOTC ..+ CDOT(1) = ZDOTC(N,CX,INCX,CY,INCY)+ CALL CTEST(1,CDOT,CT6(KN,KI),CSIZE1(KN),SFAC)+ ELSE IF (ICASE.EQ.2) THEN+* .. ZDOTU ..+ CDOT(1) = ZDOTU(N,CX,INCX,CY,INCY)+ CALL CTEST(1,CDOT,CT7(KN,KI),CSIZE1(KN),SFAC)+ ELSE IF (ICASE.EQ.3) THEN+* .. ZAXPY ..+ CALL ZAXPY(N,CA,CX,INCX,CY,INCY)+ CALL CTEST(LENY,CY,CT8(1,KN,KI),CSIZE2(1,KSIZE),SFAC)+ ELSE IF (ICASE.EQ.4) THEN+* .. ZCOPY ..+ CALL ZCOPY(N,CX,INCX,CY,INCY)+ CALL CTEST(LENY,CY,CT10Y(1,KN,KI),CSIZE3,1.0D0)+ ELSE IF (ICASE.EQ.5) THEN+* .. ZSWAP ..+ CALL ZSWAP(N,CX,INCX,CY,INCY)+ CALL CTEST(LENX,CX,CT10X(1,KN,KI),CSIZE3,1.0D0)+ CALL CTEST(LENY,CY,CT10Y(1,KN,KI),CSIZE3,1.0D0)+ ELSE+ WRITE (NOUT,*) ' Shouldn''t be here in CHECK2'+ STOP+ END IF+*+ 40 CONTINUE+ 60 CONTINUE+ RETURN+ END+ SUBROUTINE STEST(LEN,SCOMP,STRUE,SSIZE,SFAC)+* ********************************* STEST **************************+*+* THIS SUBR COMPARES ARRAYS SCOMP() AND STRUE() OF LENGTH LEN TO+* SEE IF THE TERM BY TERM DIFFERENCES, MULTIPLIED BY SFAC, ARE+* NEGLIGIBLE.+*+* C. L. LAWSON, JPL, 1974 DEC 10+*+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ DOUBLE PRECISION SFAC+ INTEGER LEN+* .. Array Arguments ..+ DOUBLE PRECISION SCOMP(LEN), SSIZE(LEN), STRUE(LEN)+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, MODE, N+ LOGICAL PASS+* .. Local Scalars ..+ DOUBLE PRECISION SD+ INTEGER I+* .. External Functions ..+ DOUBLE PRECISION SDIFF+ EXTERNAL SDIFF+* .. Intrinsic Functions ..+ INTRINSIC ABS+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, MODE, PASS+* .. Executable Statements ..+*+ DO 40 I = 1, LEN+ SD = SCOMP(I) - STRUE(I)+ IF (SDIFF(ABS(SSIZE(I))+ABS(SFAC*SD),ABS(SSIZE(I))).EQ.0.0D0)+ + GO TO 40+*+* HERE SCOMP(I) IS NOT CLOSE TO STRUE(I).+*+ IF ( .NOT. PASS) GO TO 20+* PRINT FAIL MESSAGE AND HEADER.+ PASS = .FALSE.+ WRITE (NOUT,99999)+ WRITE (NOUT,99998)+ 20 WRITE (NOUT,99997) ICASE, N, INCX, INCY, MODE, I, SCOMP(I),+ + STRUE(I), SD, SSIZE(I)+ 40 CONTINUE+ RETURN+*+99999 FORMAT (' FAIL')+99998 FORMAT (/' CASE N INCX INCY MODE I ',+ + ' COMP(I) TRUE(I) DIFFERENCE',+ + ' SIZE(I)',/1X)+99997 FORMAT (1X,I4,I3,3I5,I3,2D36.8,2D12.4)+ END+ SUBROUTINE STEST1(SCOMP1,STRUE1,SSIZE,SFAC)+* ************************* STEST1 *****************************+*+* THIS IS AN INTERFACE SUBROUTINE TO ACCOMODATE THE FORTRAN+* REQUIREMENT THAT WHEN A DUMMY ARGUMENT IS AN ARRAY, THE+* ACTUAL ARGUMENT MUST ALSO BE AN ARRAY OR AN ARRAY ELEMENT.+*+* C.L. LAWSON, JPL, 1978 DEC 6+*+* .. Scalar Arguments ..+ DOUBLE PRECISION SCOMP1, SFAC, STRUE1+* .. Array Arguments ..+ DOUBLE PRECISION SSIZE(*)+* .. Local Arrays ..+ DOUBLE PRECISION SCOMP(1), STRUE(1)+* .. External Subroutines ..+ EXTERNAL STEST+* .. Executable Statements ..+*+ SCOMP(1) = SCOMP1+ STRUE(1) = STRUE1+ CALL STEST(1,SCOMP,STRUE,SSIZE,SFAC)+*+ RETURN+ END+ DOUBLE PRECISION FUNCTION SDIFF(SA,SB)+* ********************************* SDIFF **************************+* COMPUTES DIFFERENCE OF TWO NUMBERS. C. L. LAWSON, JPL 1974 FEB 15+*+* .. Scalar Arguments ..+ DOUBLE PRECISION SA, SB+* .. Executable Statements ..+ SDIFF = SA - SB+ RETURN+ END+ SUBROUTINE CTEST(LEN,CCOMP,CTRUE,CSIZE,SFAC)+* **************************** CTEST *****************************+*+* C.L. LAWSON, JPL, 1978 DEC 6+*+* .. Scalar Arguments ..+ DOUBLE PRECISION SFAC+ INTEGER LEN+* .. Array Arguments ..+ COMPLEX*16 CCOMP(LEN), CSIZE(LEN), CTRUE(LEN)+* .. Local Scalars ..+ INTEGER I+* .. Local Arrays ..+ DOUBLE PRECISION SCOMP(20), SSIZE(20), STRUE(20)+* .. External Subroutines ..+ EXTERNAL STEST+* .. Intrinsic Functions ..+ INTRINSIC DIMAG, DBLE+* .. Executable Statements ..+ DO 20 I = 1, LEN+ SCOMP(2*I-1) = DBLE(CCOMP(I))+ SCOMP(2*I) = DIMAG(CCOMP(I))+ STRUE(2*I-1) = DBLE(CTRUE(I))+ STRUE(2*I) = DIMAG(CTRUE(I))+ SSIZE(2*I-1) = DBLE(CSIZE(I))+ SSIZE(2*I) = DIMAG(CSIZE(I))+ 20 CONTINUE+*+ CALL STEST(2*LEN,SCOMP,STRUE,SSIZE,SFAC)+ RETURN+ END+ SUBROUTINE ITEST1(ICOMP,ITRUE)+* ********************************* ITEST1 *************************+*+* THIS SUBROUTINE COMPARES THE VARIABLES ICOMP AND ITRUE FOR+* EQUALITY.+* C. L. LAWSON, JPL, 1974 DEC 10+*+* .. Parameters ..+ INTEGER NOUT+ PARAMETER (NOUT=6)+* .. Scalar Arguments ..+ INTEGER ICOMP, ITRUE+* .. Scalars in Common ..+ INTEGER ICASE, INCX, INCY, MODE, N+ LOGICAL PASS+* .. Local Scalars ..+ INTEGER ID+* .. Common blocks ..+ COMMON /COMBLA/ICASE, N, INCX, INCY, MODE, PASS+* .. Executable Statements ..+ IF (ICOMP.EQ.ITRUE) GO TO 40+*+* HERE ICOMP IS NOT EQUAL TO ITRUE.+*+ IF ( .NOT. PASS) GO TO 20+* PRINT FAIL MESSAGE AND HEADER.+ PASS = .FALSE.+ WRITE (NOUT,99999)+ WRITE (NOUT,99998)+ 20 ID = ICOMP - ITRUE+ WRITE (NOUT,99997) ICASE, N, INCX, INCY, MODE, ICOMP, ITRUE, ID+ 40 CONTINUE+ RETURN+*+99999 FORMAT (' FAIL')+99998 FORMAT (/' CASE N INCX INCY MODE ',+ + ' COMP TRUE DIFFERENCE',+ + /1X)+99997 FORMAT (1X,I4,I3,3I5,2I36,I12)+ END
+ eigen3/blas/testing/zblat2.dat view
@@ -0,0 +1,35 @@+'zblat2.summ' NAME OF SUMMARY OUTPUT FILE+6 UNIT NUMBER OF SUMMARY FILE+'cbla2t.snap' NAME OF SNAPSHOT OUTPUT FILE+-1 UNIT NUMBER OF SNAPSHOT FILE (NOT USED IF .LT. 0)+F LOGICAL FLAG, T TO REWIND SNAPSHOT FILE AFTER EACH RECORD.+F LOGICAL FLAG, T TO STOP ON FAILURES.+T LOGICAL FLAG, T TO TEST ERROR EXITS.+16.0 THRESHOLD VALUE OF TEST RATIO+6 NUMBER OF VALUES OF N+0 1 2 3 5 9 VALUES OF N+4 NUMBER OF VALUES OF K+0 1 2 4 VALUES OF K+4 NUMBER OF VALUES OF INCX AND INCY+1 2 -1 -2 VALUES OF INCX AND INCY+3 NUMBER OF VALUES OF ALPHA+(0.0,0.0) (1.0,0.0) (0.7,-0.9) VALUES OF ALPHA+3 NUMBER OF VALUES OF BETA+(0.0,0.0) (1.0,0.0) (1.3,-1.1) VALUES OF BETA+ZGEMV T PUT F FOR NO TEST. SAME COLUMNS.+ZGBMV T PUT F FOR NO TEST. SAME COLUMNS.+ZHEMV T PUT F FOR NO TEST. SAME COLUMNS.+ZHBMV T PUT F FOR NO TEST. SAME COLUMNS.+ZHPMV T PUT F FOR NO TEST. SAME COLUMNS.+ZTRMV T PUT F FOR NO TEST. SAME COLUMNS.+ZTBMV T PUT F FOR NO TEST. SAME COLUMNS.+ZTPMV T PUT F FOR NO TEST. SAME COLUMNS.+ZTRSV T PUT F FOR NO TEST. SAME COLUMNS.+ZTBSV T PUT F FOR NO TEST. SAME COLUMNS.+ZTPSV T PUT F FOR NO TEST. SAME COLUMNS.+ZGERC T PUT F FOR NO TEST. SAME COLUMNS.+ZGERU T PUT F FOR NO TEST. SAME COLUMNS.+ZHER T PUT F FOR NO TEST. SAME COLUMNS.+ZHPR T PUT F FOR NO TEST. SAME COLUMNS.+ZHER2 T PUT F FOR NO TEST. SAME COLUMNS.+ZHPR2 T PUT F FOR NO TEST. SAME COLUMNS.
+ eigen3/blas/testing/zblat2.f view
@@ -0,0 +1,3249 @@+ PROGRAM ZBLAT2+*+* Test program for the COMPLEX*16 Level 2 Blas.+*+* The program must be driven by a short data file. The first 18 records+* of the file are read using list-directed input, the last 17 records+* are read using the format ( A6, L2 ). An annotated example of a data+* file can be obtained by deleting the first 3 characters from the+* following 35 lines:+* 'ZBLAT2.SUMM' NAME OF SUMMARY OUTPUT FILE+* 6 UNIT NUMBER OF SUMMARY FILE+* 'CBLA2T.SNAP' NAME OF SNAPSHOT OUTPUT FILE+* -1 UNIT NUMBER OF SNAPSHOT FILE (NOT USED IF .LT. 0)+* F LOGICAL FLAG, T TO REWIND SNAPSHOT FILE AFTER EACH RECORD.+* F LOGICAL FLAG, T TO STOP ON FAILURES.+* T LOGICAL FLAG, T TO TEST ERROR EXITS.+* 16.0 THRESHOLD VALUE OF TEST RATIO+* 6 NUMBER OF VALUES OF N+* 0 1 2 3 5 9 VALUES OF N+* 4 NUMBER OF VALUES OF K+* 0 1 2 4 VALUES OF K+* 4 NUMBER OF VALUES OF INCX AND INCY+* 1 2 -1 -2 VALUES OF INCX AND INCY+* 3 NUMBER OF VALUES OF ALPHA+* (0.0,0.0) (1.0,0.0) (0.7,-0.9) VALUES OF ALPHA+* 3 NUMBER OF VALUES OF BETA+* (0.0,0.0) (1.0,0.0) (1.3,-1.1) VALUES OF BETA+* ZGEMV T PUT F FOR NO TEST. SAME COLUMNS.+* ZGBMV T PUT F FOR NO TEST. SAME COLUMNS.+* ZHEMV T PUT F FOR NO TEST. SAME COLUMNS.+* ZHBMV T PUT F FOR NO TEST. SAME COLUMNS.+* ZHPMV T PUT F FOR NO TEST. SAME COLUMNS.+* ZTRMV T PUT F FOR NO TEST. SAME COLUMNS.+* ZTBMV T PUT F FOR NO TEST. SAME COLUMNS.+* ZTPMV T PUT F FOR NO TEST. SAME COLUMNS.+* ZTRSV T PUT F FOR NO TEST. SAME COLUMNS.+* ZTBSV T PUT F FOR NO TEST. SAME COLUMNS.+* ZTPSV T PUT F FOR NO TEST. SAME COLUMNS.+* ZGERC T PUT F FOR NO TEST. SAME COLUMNS.+* ZGERU T PUT F FOR NO TEST. SAME COLUMNS.+* ZHER T PUT F FOR NO TEST. SAME COLUMNS.+* ZHPR T PUT F FOR NO TEST. SAME COLUMNS.+* ZHER2 T PUT F FOR NO TEST. SAME COLUMNS.+* ZHPR2 T PUT F FOR NO TEST. SAME COLUMNS.+*+* See:+*+* Dongarra J. J., Du Croz J. J., Hammarling S. and Hanson R. J..+* An extended set of Fortran Basic Linear Algebra Subprograms.+*+* Technical Memoranda Nos. 41 (revision 3) and 81, Mathematics+* and Computer Science Division, Argonne National Laboratory,+* 9700 South Cass Avenue, Argonne, Illinois 60439, US.+*+* Or+*+* NAG Technical Reports TR3/87 and TR4/87, Numerical Algorithms+* Group Ltd., NAG Central Office, 256 Banbury Road, Oxford+* OX2 7DE, UK, and Numerical Algorithms Group Inc., 1101 31st+* Street, Suite 100, Downers Grove, Illinois 60515-1263, USA.+*+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ INTEGER NIN+ PARAMETER ( NIN = 5 )+ INTEGER NSUBS+ PARAMETER ( NSUBS = 17 )+ COMPLEX*16 ZERO, ONE+ PARAMETER ( ZERO = ( 0.0D0, 0.0D0 ),+ $ ONE = ( 1.0D0, 0.0D0 ) )+ DOUBLE PRECISION RZERO, RHALF, RONE+ PARAMETER ( RZERO = 0.0D0, RHALF = 0.5D0, RONE = 1.0D0 )+ INTEGER NMAX, INCMAX+ PARAMETER ( NMAX = 65, INCMAX = 2 )+ INTEGER NINMAX, NIDMAX, NKBMAX, NALMAX, NBEMAX+ PARAMETER ( NINMAX = 7, NIDMAX = 9, NKBMAX = 7,+ $ NALMAX = 7, NBEMAX = 7 )+* .. Local Scalars ..+ DOUBLE PRECISION EPS, ERR, THRESH+ INTEGER I, ISNUM, J, N, NALF, NBET, NIDIM, NINC, NKB,+ $ NOUT, NTRA+ LOGICAL FATAL, LTESTT, REWI, SAME, SFATAL, TRACE,+ $ TSTERR+ CHARACTER*1 TRANS+ CHARACTER*6 SNAMET+ CHARACTER*32 SNAPS, SUMMRY+* .. Local Arrays ..+ COMPLEX*16 A( NMAX, NMAX ), AA( NMAX*NMAX ),+ $ ALF( NALMAX ), AS( NMAX*NMAX ), BET( NBEMAX ),+ $ X( NMAX ), XS( NMAX*INCMAX ),+ $ XX( NMAX*INCMAX ), Y( NMAX ),+ $ YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX ), Z( 2*NMAX )+ DOUBLE PRECISION G( NMAX )+ INTEGER IDIM( NIDMAX ), INC( NINMAX ), KB( NKBMAX )+ LOGICAL LTEST( NSUBS )+ CHARACTER*6 SNAMES( NSUBS )+* .. External Functions ..+ DOUBLE PRECISION DDIFF+ LOGICAL LZE+ EXTERNAL DDIFF, LZE+* .. External Subroutines ..+ EXTERNAL ZCHK1, ZCHK2, ZCHK3, ZCHK4, ZCHK5, ZCHK6,+ $ ZCHKE, ZMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, MIN+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+ COMMON /SRNAMC/SRNAMT+* .. Data statements ..+ DATA SNAMES/'ZGEMV ', 'ZGBMV ', 'ZHEMV ', 'ZHBMV ',+ $ 'ZHPMV ', 'ZTRMV ', 'ZTBMV ', 'ZTPMV ',+ $ 'ZTRSV ', 'ZTBSV ', 'ZTPSV ', 'ZGERC ',+ $ 'ZGERU ', 'ZHER ', 'ZHPR ', 'ZHER2 ',+ $ 'ZHPR2 '/+* .. Executable Statements ..+*+* Read name and unit number for summary output file and open file.+*+ READ( NIN, FMT = * )SUMMRY+ READ( NIN, FMT = * )NOUT+ OPEN( NOUT, FILE = SUMMRY, STATUS = 'NEW' )+ NOUTC = NOUT+*+* Read name and unit number for snapshot output file and open file.+*+ READ( NIN, FMT = * )SNAPS+ READ( NIN, FMT = * )NTRA+ TRACE = NTRA.GE.0+ IF( TRACE )THEN+ OPEN( NTRA, FILE = SNAPS, STATUS = 'NEW' )+ END IF+* Read the flag that directs rewinding of the snapshot file.+ READ( NIN, FMT = * )REWI+ REWI = REWI.AND.TRACE+* Read the flag that directs stopping on any failure.+ READ( NIN, FMT = * )SFATAL+* Read the flag that indicates whether error exits are to be tested.+ READ( NIN, FMT = * )TSTERR+* Read the threshold value of the test ratio+ READ( NIN, FMT = * )THRESH+*+* Read and check the parameter values for the tests.+*+* Values of N+ READ( NIN, FMT = * )NIDIM+ IF( NIDIM.LT.1.OR.NIDIM.GT.NIDMAX )THEN+ WRITE( NOUT, FMT = 9997 )'N', NIDMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( IDIM( I ), I = 1, NIDIM )+ DO 10 I = 1, NIDIM+ IF( IDIM( I ).LT.0.OR.IDIM( I ).GT.NMAX )THEN+ WRITE( NOUT, FMT = 9996 )NMAX+ GO TO 230+ END IF+ 10 CONTINUE+* Values of K+ READ( NIN, FMT = * )NKB+ IF( NKB.LT.1.OR.NKB.GT.NKBMAX )THEN+ WRITE( NOUT, FMT = 9997 )'K', NKBMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( KB( I ), I = 1, NKB )+ DO 20 I = 1, NKB+ IF( KB( I ).LT.0 )THEN+ WRITE( NOUT, FMT = 9995 )+ GO TO 230+ END IF+ 20 CONTINUE+* Values of INCX and INCY+ READ( NIN, FMT = * )NINC+ IF( NINC.LT.1.OR.NINC.GT.NINMAX )THEN+ WRITE( NOUT, FMT = 9997 )'INCX AND INCY', NINMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( INC( I ), I = 1, NINC )+ DO 30 I = 1, NINC+ IF( INC( I ).EQ.0.OR.ABS( INC( I ) ).GT.INCMAX )THEN+ WRITE( NOUT, FMT = 9994 )INCMAX+ GO TO 230+ END IF+ 30 CONTINUE+* Values of ALPHA+ READ( NIN, FMT = * )NALF+ IF( NALF.LT.1.OR.NALF.GT.NALMAX )THEN+ WRITE( NOUT, FMT = 9997 )'ALPHA', NALMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( ALF( I ), I = 1, NALF )+* Values of BETA+ READ( NIN, FMT = * )NBET+ IF( NBET.LT.1.OR.NBET.GT.NBEMAX )THEN+ WRITE( NOUT, FMT = 9997 )'BETA', NBEMAX+ GO TO 230+ END IF+ READ( NIN, FMT = * )( BET( I ), I = 1, NBET )+*+* Report values of parameters.+*+ WRITE( NOUT, FMT = 9993 )+ WRITE( NOUT, FMT = 9992 )( IDIM( I ), I = 1, NIDIM )+ WRITE( NOUT, FMT = 9991 )( KB( I ), I = 1, NKB )+ WRITE( NOUT, FMT = 9990 )( INC( I ), I = 1, NINC )+ WRITE( NOUT, FMT = 9989 )( ALF( I ), I = 1, NALF )+ WRITE( NOUT, FMT = 9988 )( BET( I ), I = 1, NBET )+ IF( .NOT.TSTERR )THEN+ WRITE( NOUT, FMT = * )+ WRITE( NOUT, FMT = 9980 )+ END IF+ WRITE( NOUT, FMT = * )+ WRITE( NOUT, FMT = 9999 )THRESH+ WRITE( NOUT, FMT = * )+*+* Read names of subroutines and flags which indicate+* whether they are to be tested.+*+ DO 40 I = 1, NSUBS+ LTEST( I ) = .FALSE.+ 40 CONTINUE+ 50 READ( NIN, FMT = 9984, END = 80 )SNAMET, LTESTT+ DO 60 I = 1, NSUBS+ IF( SNAMET.EQ.SNAMES( I ) )+ $ GO TO 70+ 60 CONTINUE+ WRITE( NOUT, FMT = 9986 )SNAMET+ STOP+ 70 LTEST( I ) = LTESTT+ GO TO 50+*+ 80 CONTINUE+ CLOSE ( NIN )+*+* Compute EPS (the machine precision).+*+ EPS = RONE+ 90 CONTINUE+ IF( DDIFF( RONE + EPS, RONE ).EQ.RZERO )+ $ GO TO 100+ EPS = RHALF*EPS+ GO TO 90+ 100 CONTINUE+ EPS = EPS + EPS+ WRITE( NOUT, FMT = 9998 )EPS+*+* Check the reliability of ZMVCH using exact data.+*+ N = MIN( 32, NMAX )+ DO 120 J = 1, N+ DO 110 I = 1, N+ A( I, J ) = MAX( I - J + 1, 0 )+ 110 CONTINUE+ X( J ) = J+ Y( J ) = ZERO+ 120 CONTINUE+ DO 130 J = 1, N+ YY( J ) = J*( ( J + 1 )*J )/2 - ( ( J + 1 )*J*( J - 1 ) )/3+ 130 CONTINUE+* YY holds the exact result. On exit from ZMVCH YT holds+* the result computed by ZMVCH.+ TRANS = 'N'+ CALL ZMVCH( TRANS, N, N, ONE, A, NMAX, X, 1, ZERO, Y, 1, YT, G,+ $ YY, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LZE( YY, YT, N )+ IF( .NOT.SAME.OR.ERR.NE.RZERO )THEN+ WRITE( NOUT, FMT = 9985 )TRANS, SAME, ERR+ STOP+ END IF+ TRANS = 'T'+ CALL ZMVCH( TRANS, N, N, ONE, A, NMAX, X, -1, ZERO, Y, -1, YT, G,+ $ YY, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LZE( YY, YT, N )+ IF( .NOT.SAME.OR.ERR.NE.RZERO )THEN+ WRITE( NOUT, FMT = 9985 )TRANS, SAME, ERR+ STOP+ END IF+*+* Test each subroutine in turn.+*+ DO 210 ISNUM = 1, NSUBS+ WRITE( NOUT, FMT = * )+ IF( .NOT.LTEST( ISNUM ) )THEN+* Subprogram is not to be tested.+ WRITE( NOUT, FMT = 9983 )SNAMES( ISNUM )+ ELSE+ SRNAMT = SNAMES( ISNUM )+* Test error exits.+ IF( TSTERR )THEN+ CALL ZCHKE( ISNUM, SNAMES( ISNUM ), NOUT )+ WRITE( NOUT, FMT = * )+ END IF+* Test computations.+ INFOT = 0+ OK = .TRUE.+ FATAL = .FALSE.+ GO TO ( 140, 140, 150, 150, 150, 160, 160,+ $ 160, 160, 160, 160, 170, 170, 180,+ $ 180, 190, 190 )ISNUM+* Test ZGEMV, 01, and ZGBMV, 02.+ 140 CALL ZCHK1( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NKB, KB, NALF, ALF,+ $ NBET, BET, NINC, INC, NMAX, INCMAX, A, AA, AS,+ $ X, XX, XS, Y, YY, YS, YT, G )+ GO TO 200+* Test ZHEMV, 03, ZHBMV, 04, and ZHPMV, 05.+ 150 CALL ZCHK2( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NKB, KB, NALF, ALF,+ $ NBET, BET, NINC, INC, NMAX, INCMAX, A, AA, AS,+ $ X, XX, XS, Y, YY, YS, YT, G )+ GO TO 200+* Test ZTRMV, 06, ZTBMV, 07, ZTPMV, 08,+* ZTRSV, 09, ZTBSV, 10, and ZTPSV, 11.+ 160 CALL ZCHK3( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NKB, KB, NINC, INC,+ $ NMAX, INCMAX, A, AA, AS, Y, YY, YS, YT, G, Z )+ GO TO 200+* Test ZGERC, 12, ZGERU, 13.+ 170 CALL ZCHK4( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC,+ $ NMAX, INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS,+ $ YT, G, Z )+ GO TO 200+* Test ZHER, 14, and ZHPR, 15.+ 180 CALL ZCHK5( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC,+ $ NMAX, INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS,+ $ YT, G, Z )+ GO TO 200+* Test ZHER2, 16, and ZHPR2, 17.+ 190 CALL ZCHK6( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC,+ $ NMAX, INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS,+ $ YT, G, Z )+*+ 200 IF( FATAL.AND.SFATAL )+ $ GO TO 220+ END IF+ 210 CONTINUE+ WRITE( NOUT, FMT = 9982 )+ GO TO 240+*+ 220 CONTINUE+ WRITE( NOUT, FMT = 9981 )+ GO TO 240+*+ 230 CONTINUE+ WRITE( NOUT, FMT = 9987 )+*+ 240 CONTINUE+ IF( TRACE )+ $ CLOSE ( NTRA )+ CLOSE ( NOUT )+ STOP+*+ 9999 FORMAT( ' ROUTINES PASS COMPUTATIONAL TESTS IF TEST RATIO IS LES',+ $ 'S THAN', F8.2 )+ 9998 FORMAT( ' RELATIVE MACHINE PRECISION IS TAKEN TO BE', 1P, D9.1 )+ 9997 FORMAT( ' NUMBER OF VALUES OF ', A, ' IS LESS THAN 1 OR GREATER ',+ $ 'THAN ', I2 )+ 9996 FORMAT( ' VALUE OF N IS LESS THAN 0 OR GREATER THAN ', I2 )+ 9995 FORMAT( ' VALUE OF K IS LESS THAN 0' )+ 9994 FORMAT( ' ABSOLUTE VALUE OF INCX OR INCY IS 0 OR GREATER THAN ',+ $ I2 )+ 9993 FORMAT( ' TESTS OF THE COMPLEX*16 LEVEL 2 BLAS', //' THE F',+ $ 'OLLOWING PARAMETER VALUES WILL BE USED:' )+ 9992 FORMAT( ' FOR N ', 9I6 )+ 9991 FORMAT( ' FOR K ', 7I6 )+ 9990 FORMAT( ' FOR INCX AND INCY ', 7I6 )+ 9989 FORMAT( ' FOR ALPHA ',+ $ 7( '(', F4.1, ',', F4.1, ') ', : ) )+ 9988 FORMAT( ' FOR BETA ',+ $ 7( '(', F4.1, ',', F4.1, ') ', : ) )+ 9987 FORMAT( ' AMEND DATA FILE OR INCREASE ARRAY SIZES IN PROGRAM',+ $ /' ******* TESTS ABANDONED *******' )+ 9986 FORMAT( ' SUBPROGRAM NAME ', A6, ' NOT RECOGNIZED', /' ******* T',+ $ 'ESTS ABANDONED *******' )+ 9985 FORMAT( ' ERROR IN ZMVCH - IN-LINE DOT PRODUCTS ARE BEING EVALU',+ $ 'ATED WRONGLY.', /' ZMVCH WAS CALLED WITH TRANS = ', A1,+ $ ' AND RETURNED SAME = ', L1, ' AND ERR = ', F12.3, '.', /+ $ ' THIS MAY BE DUE TO FAULTS IN THE ARITHMETIC OR THE COMPILER.'+ $ , /' ******* TESTS ABANDONED *******' )+ 9984 FORMAT( A6, L2 )+ 9983 FORMAT( 1X, A6, ' WAS NOT TESTED' )+ 9982 FORMAT( /' END OF TESTS' )+ 9981 FORMAT( /' ******* FATAL ERROR - TESTS ABANDONED *******' )+ 9980 FORMAT( ' ERROR-EXITS WILL NOT BE TESTED' )+*+* End of ZBLAT2.+*+ END+ SUBROUTINE ZCHK1( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NKB, KB, NALF, ALF, NBET,+ $ BET, NINC, INC, NMAX, INCMAX, A, AA, AS, X, XX,+ $ XS, Y, YY, YS, YT, G )+*+* Tests ZGEMV and ZGBMV.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ COMPLEX*16 ZERO, HALF+ PARAMETER ( ZERO = ( 0.0D0, 0.0D0 ),+ $ HALF = ( 0.5D0, 0.0D0 ) )+ DOUBLE PRECISION RZERO+ PARAMETER ( RZERO = 0.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER INCMAX, NALF, NBET, NIDIM, NINC, NKB, NMAX,+ $ NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX*16 A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), BET( NBET ), X( NMAX ),+ $ XS( NMAX*INCMAX ), XX( NMAX*INCMAX ),+ $ Y( NMAX ), YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX )+ DOUBLE PRECISION G( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC ), KB( NKB )+* .. Local Scalars ..+ COMPLEX*16 ALPHA, ALS, BETA, BLS, TRANSL+ DOUBLE PRECISION ERR, ERRMAX+ INTEGER I, IA, IB, IC, IKU, IM, IN, INCX, INCXS, INCY,+ $ INCYS, IX, IY, KL, KLS, KU, KUS, LAA, LDA,+ $ LDAS, LX, LY, M, ML, MS, N, NARGS, NC, ND, NK,+ $ NL, NS+ LOGICAL BANDED, FULL, NULL, RESET, SAME, TRAN+ CHARACTER*1 TRANS, TRANSS+ CHARACTER*3 ICH+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LZE, LZERES+ EXTERNAL LZE, LZERES+* .. External Subroutines ..+ EXTERNAL ZGBMV, ZGEMV, ZMAKE, ZMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, MIN+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'NTC'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'E'+ BANDED = SNAME( 3: 3 ).EQ.'B'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 11+ ELSE IF( BANDED )THEN+ NARGS = 13+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 120 IN = 1, NIDIM+ N = IDIM( IN )+ ND = N/2 + 1+*+ DO 110 IM = 1, 2+ IF( IM.EQ.1 )+ $ M = MAX( N - ND, 0 )+ IF( IM.EQ.2 )+ $ M = MIN( N + ND, NMAX )+*+ IF( BANDED )THEN+ NK = NKB+ ELSE+ NK = 1+ END IF+ DO 100 IKU = 1, NK+ IF( BANDED )THEN+ KU = KB( IKU )+ KL = MAX( KU - 1, 0 )+ ELSE+ KU = N - 1+ KL = M - 1+ END IF+* Set LDA to 1 more than minimum value if room.+ IF( BANDED )THEN+ LDA = KL + KU + 1+ ELSE+ LDA = M+ END IF+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 100+ LAA = LDA*N+ NULL = N.LE.0.OR.M.LE.0+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL ZMAKE( SNAME( 2: 3 ), ' ', ' ', M, N, A, NMAX, AA,+ $ LDA, KL, KU, RESET, TRANSL )+*+ DO 90 IC = 1, 3+ TRANS = ICH( IC: IC )+ TRAN = TRANS.EQ.'T'.OR.TRANS.EQ.'C'+*+ IF( TRAN )THEN+ ML = N+ NL = M+ ELSE+ ML = M+ NL = N+ END IF+*+ DO 80 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*NL+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL ZMAKE( 'GE', ' ', ' ', 1, NL, X, 1, XX,+ $ ABS( INCX ), 0, NL - 1, RESET, TRANSL )+ IF( NL.GT.1 )THEN+ X( NL/2 ) = ZERO+ XX( 1 + ABS( INCX )*( NL/2 - 1 ) ) = ZERO+ END IF+*+ DO 70 IY = 1, NINC+ INCY = INC( IY )+ LY = ABS( INCY )*ML+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the vector Y.+*+ TRANSL = ZERO+ CALL ZMAKE( 'GE', ' ', ' ', 1, ML, Y, 1,+ $ YY, ABS( INCY ), 0, ML - 1,+ $ RESET, TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ TRANSS = TRANS+ MS = M+ NS = N+ KLS = KL+ KUS = KU+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+ BLS = BETA+ DO 30 I = 1, LY+ YS( I ) = YY( I )+ 30 CONTINUE+ INCYS = INCY+*+* Call the subroutine.+*+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME,+ $ TRANS, M, N, ALPHA, LDA, INCX, BETA,+ $ INCY+ IF( REWI )+ $ REWIND NTRA+ CALL ZGEMV( TRANS, M, N, ALPHA, AA,+ $ LDA, XX, INCX, BETA, YY,+ $ INCY )+ ELSE IF( BANDED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ TRANS, M, N, KL, KU, ALPHA, LDA,+ $ INCX, BETA, INCY+ IF( REWI )+ $ REWIND NTRA+ CALL ZGBMV( TRANS, M, N, KL, KU, ALPHA,+ $ AA, LDA, XX, INCX, BETA,+ $ YY, INCY )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9993 )+ FATAL = .TRUE.+ GO TO 130+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = TRANS.EQ.TRANSS+ ISAME( 2 ) = MS.EQ.M+ ISAME( 3 ) = NS.EQ.N+ IF( FULL )THEN+ ISAME( 4 ) = ALS.EQ.ALPHA+ ISAME( 5 ) = LZE( AS, AA, LAA )+ ISAME( 6 ) = LDAS.EQ.LDA+ ISAME( 7 ) = LZE( XS, XX, LX )+ ISAME( 8 ) = INCXS.EQ.INCX+ ISAME( 9 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 10 ) = LZE( YS, YY, LY )+ ELSE+ ISAME( 10 ) = LZERES( 'GE', ' ', 1,+ $ ML, YS, YY,+ $ ABS( INCY ) )+ END IF+ ISAME( 11 ) = INCYS.EQ.INCY+ ELSE IF( BANDED )THEN+ ISAME( 4 ) = KLS.EQ.KL+ ISAME( 5 ) = KUS.EQ.KU+ ISAME( 6 ) = ALS.EQ.ALPHA+ ISAME( 7 ) = LZE( AS, AA, LAA )+ ISAME( 8 ) = LDAS.EQ.LDA+ ISAME( 9 ) = LZE( XS, XX, LX )+ ISAME( 10 ) = INCXS.EQ.INCX+ ISAME( 11 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 12 ) = LZE( YS, YY, LY )+ ELSE+ ISAME( 12 ) = LZERES( 'GE', ' ', 1,+ $ ML, YS, YY,+ $ ABS( INCY ) )+ END IF+ ISAME( 13 ) = INCYS.EQ.INCY+ END IF+*+* If data was incorrectly changed, report+* and return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 130+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result.+*+ CALL ZMVCH( TRANS, M, N, ALPHA, A,+ $ NMAX, X, INCX, BETA, Y,+ $ INCY, YT, G, YY, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 130+ ELSE+* Avoid repeating tests with M.le.0 or+* N.le.0.+ GO TO 110+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 140+*+ 130 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, TRANS, M, N, ALPHA, LDA,+ $ INCX, BETA, INCY+ ELSE IF( BANDED )THEN+ WRITE( NOUT, FMT = 9995 )NC, SNAME, TRANS, M, N, KL, KU,+ $ ALPHA, LDA, INCX, BETA, INCY+ END IF+*+ 140 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', 4( I3, ',' ), '(',+ $ F4.1, ',', F4.1, '), A,', I3, ', X,', I2, ',(', F4.1, ',',+ $ F4.1, '), Y,', I2, ') .' )+ 9994 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', 2( I3, ',' ), '(',+ $ F4.1, ',', F4.1, '), A,', I3, ', X,', I2, ',(', F4.1, ',',+ $ F4.1, '), Y,', I2, ') .' )+ 9993 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of ZCHK1.+*+ END+ SUBROUTINE ZCHK2( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NKB, KB, NALF, ALF, NBET,+ $ BET, NINC, INC, NMAX, INCMAX, A, AA, AS, X, XX,+ $ XS, Y, YY, YS, YT, G )+*+* Tests ZHEMV, ZHBMV and ZHPMV.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ COMPLEX*16 ZERO, HALF+ PARAMETER ( ZERO = ( 0.0D0, 0.0D0 ),+ $ HALF = ( 0.5D0, 0.0D0 ) )+ DOUBLE PRECISION RZERO+ PARAMETER ( RZERO = 0.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER INCMAX, NALF, NBET, NIDIM, NINC, NKB, NMAX,+ $ NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX*16 A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), BET( NBET ), X( NMAX ),+ $ XS( NMAX*INCMAX ), XX( NMAX*INCMAX ),+ $ Y( NMAX ), YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX )+ DOUBLE PRECISION G( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC ), KB( NKB )+* .. Local Scalars ..+ COMPLEX*16 ALPHA, ALS, BETA, BLS, TRANSL+ DOUBLE PRECISION ERR, ERRMAX+ INTEGER I, IA, IB, IC, IK, IN, INCX, INCXS, INCY,+ $ INCYS, IX, IY, K, KS, LAA, LDA, LDAS, LX, LY,+ $ N, NARGS, NC, NK, NS+ LOGICAL BANDED, FULL, NULL, PACKED, RESET, SAME+ CHARACTER*1 UPLO, UPLOS+ CHARACTER*2 ICH+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LZE, LZERES+ EXTERNAL LZE, LZERES+* .. External Subroutines ..+ EXTERNAL ZHBMV, ZHEMV, ZHPMV, ZMAKE, ZMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'UL'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'E'+ BANDED = SNAME( 3: 3 ).EQ.'B'+ PACKED = SNAME( 3: 3 ).EQ.'P'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 10+ ELSE IF( BANDED )THEN+ NARGS = 11+ ELSE IF( PACKED )THEN+ NARGS = 9+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 110 IN = 1, NIDIM+ N = IDIM( IN )+*+ IF( BANDED )THEN+ NK = NKB+ ELSE+ NK = 1+ END IF+ DO 100 IK = 1, NK+ IF( BANDED )THEN+ K = KB( IK )+ ELSE+ K = N - 1+ END IF+* Set LDA to 1 more than minimum value if room.+ IF( BANDED )THEN+ LDA = K + 1+ ELSE+ LDA = N+ END IF+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 100+ IF( PACKED )THEN+ LAA = ( N*( N + 1 ) )/2+ ELSE+ LAA = LDA*N+ END IF+ NULL = N.LE.0+*+ DO 90 IC = 1, 2+ UPLO = ICH( IC: IC )+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL ZMAKE( SNAME( 2: 3 ), UPLO, ' ', N, N, A, NMAX, AA,+ $ LDA, K, K, RESET, TRANSL )+*+ DO 80 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*N+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL ZMAKE( 'GE', ' ', ' ', 1, N, X, 1, XX,+ $ ABS( INCX ), 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ X( N/2 ) = ZERO+ XX( 1 + ABS( INCX )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 70 IY = 1, NINC+ INCY = INC( IY )+ LY = ABS( INCY )*N+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the vector Y.+*+ TRANSL = ZERO+ CALL ZMAKE( 'GE', ' ', ' ', 1, N, Y, 1, YY,+ $ ABS( INCY ), 0, N - 1, RESET,+ $ TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ UPLOS = UPLO+ NS = N+ KS = K+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+ BLS = BETA+ DO 30 I = 1, LY+ YS( I ) = YY( I )+ 30 CONTINUE+ INCYS = INCY+*+* Call the subroutine.+*+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME,+ $ UPLO, N, ALPHA, LDA, INCX, BETA, INCY+ IF( REWI )+ $ REWIND NTRA+ CALL ZHEMV( UPLO, N, ALPHA, AA, LDA, XX,+ $ INCX, BETA, YY, INCY )+ ELSE IF( BANDED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME,+ $ UPLO, N, K, ALPHA, LDA, INCX, BETA,+ $ INCY+ IF( REWI )+ $ REWIND NTRA+ CALL ZHBMV( UPLO, N, K, ALPHA, AA, LDA,+ $ XX, INCX, BETA, YY, INCY )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ UPLO, N, ALPHA, INCX, BETA, INCY+ IF( REWI )+ $ REWIND NTRA+ CALL ZHPMV( UPLO, N, ALPHA, AA, XX, INCX,+ $ BETA, YY, INCY )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLO.EQ.UPLOS+ ISAME( 2 ) = NS.EQ.N+ IF( FULL )THEN+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LZE( AS, AA, LAA )+ ISAME( 5 ) = LDAS.EQ.LDA+ ISAME( 6 ) = LZE( XS, XX, LX )+ ISAME( 7 ) = INCXS.EQ.INCX+ ISAME( 8 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 9 ) = LZE( YS, YY, LY )+ ELSE+ ISAME( 9 ) = LZERES( 'GE', ' ', 1, N,+ $ YS, YY, ABS( INCY ) )+ END IF+ ISAME( 10 ) = INCYS.EQ.INCY+ ELSE IF( BANDED )THEN+ ISAME( 3 ) = KS.EQ.K+ ISAME( 4 ) = ALS.EQ.ALPHA+ ISAME( 5 ) = LZE( AS, AA, LAA )+ ISAME( 6 ) = LDAS.EQ.LDA+ ISAME( 7 ) = LZE( XS, XX, LX )+ ISAME( 8 ) = INCXS.EQ.INCX+ ISAME( 9 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 10 ) = LZE( YS, YY, LY )+ ELSE+ ISAME( 10 ) = LZERES( 'GE', ' ', 1, N,+ $ YS, YY, ABS( INCY ) )+ END IF+ ISAME( 11 ) = INCYS.EQ.INCY+ ELSE IF( PACKED )THEN+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LZE( AS, AA, LAA )+ ISAME( 5 ) = LZE( XS, XX, LX )+ ISAME( 6 ) = INCXS.EQ.INCX+ ISAME( 7 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 8 ) = LZE( YS, YY, LY )+ ELSE+ ISAME( 8 ) = LZERES( 'GE', ' ', 1, N,+ $ YS, YY, ABS( INCY ) )+ END IF+ ISAME( 9 ) = INCYS.EQ.INCY+ END IF+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result.+*+ CALL ZMVCH( 'N', N, N, ALPHA, A, NMAX, X,+ $ INCX, BETA, Y, INCY, YT, G,+ $ YY, EPS, ERR, FATAL, NOUT,+ $ .TRUE. )+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 120+ ELSE+* Avoid repeating tests with N.le.0+ GO TO 110+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, N, ALPHA, LDA, INCX,+ $ BETA, INCY+ ELSE IF( BANDED )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, N, K, ALPHA, LDA,+ $ INCX, BETA, INCY+ ELSE IF( PACKED )THEN+ WRITE( NOUT, FMT = 9995 )NC, SNAME, UPLO, N, ALPHA, INCX,+ $ BETA, INCY+ END IF+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',(', F4.1, ',',+ $ F4.1, '), AP, X,', I2, ',(', F4.1, ',', F4.1, '), Y,', I2,+ $ ') .' )+ 9994 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', 2( I3, ',' ), '(',+ $ F4.1, ',', F4.1, '), A,', I3, ', X,', I2, ',(', F4.1, ',',+ $ F4.1, '), Y,', I2, ') .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',(', F4.1, ',',+ $ F4.1, '), A,', I3, ', X,', I2, ',(', F4.1, ',', F4.1, '), ',+ $ 'Y,', I2, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of ZCHK2.+*+ END+ SUBROUTINE ZCHK3( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NKB, KB, NINC, INC, NMAX,+ $ INCMAX, A, AA, AS, X, XX, XS, XT, G, Z )+*+* Tests ZTRMV, ZTBMV, ZTPMV, ZTRSV, ZTBSV and ZTPSV.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ COMPLEX*16 ZERO, HALF, ONE+ PARAMETER ( ZERO = ( 0.0D0, 0.0D0 ),+ $ HALF = ( 0.5D0, 0.0D0 ),+ $ ONE = ( 1.0D0, 0.0D0 ) )+ DOUBLE PRECISION RZERO+ PARAMETER ( RZERO = 0.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER INCMAX, NIDIM, NINC, NKB, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX*16 A( NMAX, NMAX ), AA( NMAX*NMAX ),+ $ AS( NMAX*NMAX ), X( NMAX ), XS( NMAX*INCMAX ),+ $ XT( NMAX ), XX( NMAX*INCMAX ), Z( NMAX )+ DOUBLE PRECISION G( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC ), KB( NKB )+* .. Local Scalars ..+ COMPLEX*16 TRANSL+ DOUBLE PRECISION ERR, ERRMAX+ INTEGER I, ICD, ICT, ICU, IK, IN, INCX, INCXS, IX, K,+ $ KS, LAA, LDA, LDAS, LX, N, NARGS, NC, NK, NS+ LOGICAL BANDED, FULL, NULL, PACKED, RESET, SAME+ CHARACTER*1 DIAG, DIAGS, TRANS, TRANSS, UPLO, UPLOS+ CHARACTER*2 ICHD, ICHU+ CHARACTER*3 ICHT+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LZE, LZERES+ EXTERNAL LZE, LZERES+* .. External Subroutines ..+ EXTERNAL ZMAKE, ZMVCH, ZTBMV, ZTBSV, ZTPMV, ZTPSV,+ $ ZTRMV, ZTRSV+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHU/'UL'/, ICHT/'NTC'/, ICHD/'UN'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'R'+ BANDED = SNAME( 3: 3 ).EQ.'B'+ PACKED = SNAME( 3: 3 ).EQ.'P'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 8+ ELSE IF( BANDED )THEN+ NARGS = 9+ ELSE IF( PACKED )THEN+ NARGS = 7+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+* Set up zero vector for ZMVCH.+ DO 10 I = 1, NMAX+ Z( I ) = ZERO+ 10 CONTINUE+*+ DO 110 IN = 1, NIDIM+ N = IDIM( IN )+*+ IF( BANDED )THEN+ NK = NKB+ ELSE+ NK = 1+ END IF+ DO 100 IK = 1, NK+ IF( BANDED )THEN+ K = KB( IK )+ ELSE+ K = N - 1+ END IF+* Set LDA to 1 more than minimum value if room.+ IF( BANDED )THEN+ LDA = K + 1+ ELSE+ LDA = N+ END IF+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 100+ IF( PACKED )THEN+ LAA = ( N*( N + 1 ) )/2+ ELSE+ LAA = LDA*N+ END IF+ NULL = N.LE.0+*+ DO 90 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+*+ DO 80 ICT = 1, 3+ TRANS = ICHT( ICT: ICT )+*+ DO 70 ICD = 1, 2+ DIAG = ICHD( ICD: ICD )+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL ZMAKE( SNAME( 2: 3 ), UPLO, DIAG, N, N, A,+ $ NMAX, AA, LDA, K, K, RESET, TRANSL )+*+ DO 60 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*N+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL ZMAKE( 'GE', ' ', ' ', 1, N, X, 1, XX,+ $ ABS( INCX ), 0, N - 1, RESET,+ $ TRANSL )+ IF( N.GT.1 )THEN+ X( N/2 ) = ZERO+ XX( 1 + ABS( INCX )*( N/2 - 1 ) ) = ZERO+ END IF+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ TRANSS = TRANS+ DIAGS = DIAG+ NS = N+ KS = K+ DO 20 I = 1, LAA+ AS( I ) = AA( I )+ 20 CONTINUE+ LDAS = LDA+ DO 30 I = 1, LX+ XS( I ) = XX( I )+ 30 CONTINUE+ INCXS = INCX+*+* Call the subroutine.+*+ IF( SNAME( 4: 5 ).EQ.'MV' )THEN+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, LDA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL ZTRMV( UPLO, TRANS, DIAG, N, AA, LDA,+ $ XX, INCX )+ ELSE IF( BANDED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, K, LDA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL ZTBMV( UPLO, TRANS, DIAG, N, K, AA,+ $ LDA, XX, INCX )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL ZTPMV( UPLO, TRANS, DIAG, N, AA, XX,+ $ INCX )+ END IF+ ELSE IF( SNAME( 4: 5 ).EQ.'SV' )THEN+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, LDA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL ZTRSV( UPLO, TRANS, DIAG, N, AA, LDA,+ $ XX, INCX )+ ELSE IF( BANDED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, K, LDA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL ZTBSV( UPLO, TRANS, DIAG, N, K, AA,+ $ LDA, XX, INCX )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ UPLO, TRANS, DIAG, N, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL ZTPSV( UPLO, TRANS, DIAG, N, AA, XX,+ $ INCX )+ END IF+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLO.EQ.UPLOS+ ISAME( 2 ) = TRANS.EQ.TRANSS+ ISAME( 3 ) = DIAG.EQ.DIAGS+ ISAME( 4 ) = NS.EQ.N+ IF( FULL )THEN+ ISAME( 5 ) = LZE( AS, AA, LAA )+ ISAME( 6 ) = LDAS.EQ.LDA+ IF( NULL )THEN+ ISAME( 7 ) = LZE( XS, XX, LX )+ ELSE+ ISAME( 7 ) = LZERES( 'GE', ' ', 1, N, XS,+ $ XX, ABS( INCX ) )+ END IF+ ISAME( 8 ) = INCXS.EQ.INCX+ ELSE IF( BANDED )THEN+ ISAME( 5 ) = KS.EQ.K+ ISAME( 6 ) = LZE( AS, AA, LAA )+ ISAME( 7 ) = LDAS.EQ.LDA+ IF( NULL )THEN+ ISAME( 8 ) = LZE( XS, XX, LX )+ ELSE+ ISAME( 8 ) = LZERES( 'GE', ' ', 1, N, XS,+ $ XX, ABS( INCX ) )+ END IF+ ISAME( 9 ) = INCXS.EQ.INCX+ ELSE IF( PACKED )THEN+ ISAME( 5 ) = LZE( AS, AA, LAA )+ IF( NULL )THEN+ ISAME( 6 ) = LZE( XS, XX, LX )+ ELSE+ ISAME( 6 ) = LZERES( 'GE', ' ', 1, N, XS,+ $ XX, ABS( INCX ) )+ END IF+ ISAME( 7 ) = INCXS.EQ.INCX+ END IF+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+ IF( SNAME( 4: 5 ).EQ.'MV' )THEN+*+* Check the result.+*+ CALL ZMVCH( TRANS, N, N, ONE, A, NMAX, X,+ $ INCX, ZERO, Z, INCX, XT, G,+ $ XX, EPS, ERR, FATAL, NOUT,+ $ .TRUE. )+ ELSE IF( SNAME( 4: 5 ).EQ.'SV' )THEN+*+* Compute approximation to original vector.+*+ DO 50 I = 1, N+ Z( I ) = XX( 1 + ( I - 1 )*+ $ ABS( INCX ) )+ XX( 1 + ( I - 1 )*ABS( INCX ) )+ $ = X( I )+ 50 CONTINUE+ CALL ZMVCH( TRANS, N, N, ONE, A, NMAX, Z,+ $ INCX, ZERO, X, INCX, XT, G,+ $ XX, EPS, ERR, FATAL, NOUT,+ $ .FALSE. )+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and return.+ IF( FATAL )+ $ GO TO 120+ ELSE+* Avoid repeating tests with N.le.0.+ GO TO 110+ END IF+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, TRANS, DIAG, N, LDA,+ $ INCX+ ELSE IF( BANDED )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, TRANS, DIAG, N, K,+ $ LDA, INCX+ ELSE IF( PACKED )THEN+ WRITE( NOUT, FMT = 9995 )NC, SNAME, UPLO, TRANS, DIAG, N, INCX+ END IF+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(', 3( '''', A1, ''',' ), I3, ', AP, ',+ $ 'X,', I2, ') .' )+ 9994 FORMAT( 1X, I6, ': ', A6, '(', 3( '''', A1, ''',' ), 2( I3, ',' ),+ $ ' A,', I3, ', X,', I2, ') .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(', 3( '''', A1, ''',' ), I3, ', A,',+ $ I3, ', X,', I2, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of ZCHK3.+*+ END+ SUBROUTINE ZCHK4( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC, NMAX,+ $ INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS, YT, G,+ $ Z )+*+* Tests ZGERC and ZGERU.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ COMPLEX*16 ZERO, HALF, ONE+ PARAMETER ( ZERO = ( 0.0D0, 0.0D0 ),+ $ HALF = ( 0.5D0, 0.0D0 ),+ $ ONE = ( 1.0D0, 0.0D0 ) )+ DOUBLE PRECISION RZERO+ PARAMETER ( RZERO = 0.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER INCMAX, NALF, NIDIM, NINC, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX*16 A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), X( NMAX ), XS( NMAX*INCMAX ),+ $ XX( NMAX*INCMAX ), Y( NMAX ),+ $ YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX ), Z( NMAX )+ DOUBLE PRECISION G( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC )+* .. Local Scalars ..+ COMPLEX*16 ALPHA, ALS, TRANSL+ DOUBLE PRECISION ERR, ERRMAX+ INTEGER I, IA, IM, IN, INCX, INCXS, INCY, INCYS, IX,+ $ IY, J, LAA, LDA, LDAS, LX, LY, M, MS, N, NARGS,+ $ NC, ND, NS+ LOGICAL CONJ, NULL, RESET, SAME+* .. Local Arrays ..+ COMPLEX*16 W( 1 )+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LZE, LZERES+ EXTERNAL LZE, LZERES+* .. External Subroutines ..+ EXTERNAL ZGERC, ZGERU, ZMAKE, ZMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, DCONJG, MAX, MIN+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Executable Statements ..+ CONJ = SNAME( 5: 5 ).EQ.'C'+* Define the number of arguments.+ NARGS = 9+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 120 IN = 1, NIDIM+ N = IDIM( IN )+ ND = N/2 + 1+*+ DO 110 IM = 1, 2+ IF( IM.EQ.1 )+ $ M = MAX( N - ND, 0 )+ IF( IM.EQ.2 )+ $ M = MIN( N + ND, NMAX )+*+* Set LDA to 1 more than minimum value if room.+ LDA = M+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 110+ LAA = LDA*N+ NULL = N.LE.0.OR.M.LE.0+*+ DO 100 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*M+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL ZMAKE( 'GE', ' ', ' ', 1, M, X, 1, XX, ABS( INCX ),+ $ 0, M - 1, RESET, TRANSL )+ IF( M.GT.1 )THEN+ X( M/2 ) = ZERO+ XX( 1 + ABS( INCX )*( M/2 - 1 ) ) = ZERO+ END IF+*+ DO 90 IY = 1, NINC+ INCY = INC( IY )+ LY = ABS( INCY )*N+*+* Generate the vector Y.+*+ TRANSL = ZERO+ CALL ZMAKE( 'GE', ' ', ' ', 1, N, Y, 1, YY,+ $ ABS( INCY ), 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ Y( N/2 ) = ZERO+ YY( 1 + ABS( INCY )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 80 IA = 1, NALF+ ALPHA = ALF( IA )+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL ZMAKE( SNAME( 2: 3 ), ' ', ' ', M, N, A, NMAX,+ $ AA, LDA, M - 1, N - 1, RESET, TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ MS = M+ NS = N+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+ DO 30 I = 1, LY+ YS( I ) = YY( I )+ 30 CONTINUE+ INCYS = INCY+*+* Call the subroutine.+*+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, M, N,+ $ ALPHA, INCX, INCY, LDA+ IF( CONJ )THEN+ IF( REWI )+ $ REWIND NTRA+ CALL ZGERC( M, N, ALPHA, XX, INCX, YY, INCY, AA,+ $ LDA )+ ELSE+ IF( REWI )+ $ REWIND NTRA+ CALL ZGERU( M, N, ALPHA, XX, INCX, YY, INCY, AA,+ $ LDA )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9993 )+ FATAL = .TRUE.+ GO TO 140+ END IF+*+* See what data changed inside subroutine.+*+ ISAME( 1 ) = MS.EQ.M+ ISAME( 2 ) = NS.EQ.N+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LZE( XS, XX, LX )+ ISAME( 5 ) = INCXS.EQ.INCX+ ISAME( 6 ) = LZE( YS, YY, LY )+ ISAME( 7 ) = INCYS.EQ.INCY+ IF( NULL )THEN+ ISAME( 8 ) = LZE( AS, AA, LAA )+ ELSE+ ISAME( 8 ) = LZERES( 'GE', ' ', M, N, AS, AA,+ $ LDA )+ END IF+ ISAME( 9 ) = LDAS.EQ.LDA+*+* If data was incorrectly changed, report and return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 140+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ IF( INCX.GT.0 )THEN+ DO 50 I = 1, M+ Z( I ) = X( I )+ 50 CONTINUE+ ELSE+ DO 60 I = 1, M+ Z( I ) = X( M - I + 1 )+ 60 CONTINUE+ END IF+ DO 70 J = 1, N+ IF( INCY.GT.0 )THEN+ W( 1 ) = Y( J )+ ELSE+ W( 1 ) = Y( N - J + 1 )+ END IF+ IF( CONJ )+ $ W( 1 ) = DCONJG( W( 1 ) )+ CALL ZMVCH( 'N', M, 1, ALPHA, Z, NMAX, W, 1,+ $ ONE, A( 1, J ), 1, YT, G,+ $ AA( 1 + ( J - 1 )*LDA ), EPS,+ $ ERR, FATAL, NOUT, .TRUE. )+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and return.+ IF( FATAL )+ $ GO TO 130+ 70 CONTINUE+ ELSE+* Avoid repeating tests with M.le.0 or N.le.0.+ GO TO 110+ END IF+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 150+*+ 130 CONTINUE+ WRITE( NOUT, FMT = 9995 )J+*+ 140 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9994 )NC, SNAME, M, N, ALPHA, INCX, INCY, LDA+*+ 150 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(', 2( I3, ',' ), '(', F4.1, ',', F4.1,+ $ '), X,', I2, ', Y,', I2, ', A,', I3, ') ',+ $ ' .' )+ 9993 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of ZCHK4.+*+ END+ SUBROUTINE ZCHK5( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC, NMAX,+ $ INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS, YT, G,+ $ Z )+*+* Tests ZHER and ZHPR.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ COMPLEX*16 ZERO, HALF, ONE+ PARAMETER ( ZERO = ( 0.0D0, 0.0D0 ),+ $ HALF = ( 0.5D0, 0.0D0 ),+ $ ONE = ( 1.0D0, 0.0D0 ) )+ DOUBLE PRECISION RZERO+ PARAMETER ( RZERO = 0.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER INCMAX, NALF, NIDIM, NINC, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX*16 A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), X( NMAX ), XS( NMAX*INCMAX ),+ $ XX( NMAX*INCMAX ), Y( NMAX ),+ $ YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX ), Z( NMAX )+ DOUBLE PRECISION G( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC )+* .. Local Scalars ..+ COMPLEX*16 ALPHA, TRANSL+ DOUBLE PRECISION ERR, ERRMAX, RALPHA, RALS+ INTEGER I, IA, IC, IN, INCX, INCXS, IX, J, JA, JJ, LAA,+ $ LDA, LDAS, LJ, LX, N, NARGS, NC, NS+ LOGICAL FULL, NULL, PACKED, RESET, SAME, UPPER+ CHARACTER*1 UPLO, UPLOS+ CHARACTER*2 ICH+* .. Local Arrays ..+ COMPLEX*16 W( 1 )+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LZE, LZERES+ EXTERNAL LZE, LZERES+* .. External Subroutines ..+ EXTERNAL ZHER, ZHPR, ZMAKE, ZMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, DBLE, DCMPLX, DCONJG, MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'UL'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'E'+ PACKED = SNAME( 3: 3 ).EQ.'P'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 7+ ELSE IF( PACKED )THEN+ NARGS = 6+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 100 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDA to 1 more than minimum value if room.+ LDA = N+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 100+ IF( PACKED )THEN+ LAA = ( N*( N + 1 ) )/2+ ELSE+ LAA = LDA*N+ END IF+*+ DO 90 IC = 1, 2+ UPLO = ICH( IC: IC )+ UPPER = UPLO.EQ.'U'+*+ DO 80 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*N+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL ZMAKE( 'GE', ' ', ' ', 1, N, X, 1, XX, ABS( INCX ),+ $ 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ X( N/2 ) = ZERO+ XX( 1 + ABS( INCX )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 70 IA = 1, NALF+ RALPHA = DBLE( ALF( IA ) )+ ALPHA = DCMPLX( RALPHA, RZERO )+ NULL = N.LE.0.OR.RALPHA.EQ.RZERO+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL ZMAKE( SNAME( 2: 3 ), UPLO, ' ', N, N, A, NMAX,+ $ AA, LDA, N - 1, N - 1, RESET, TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ NS = N+ RALS = RALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+*+* Call the subroutine.+*+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME, UPLO, N,+ $ RALPHA, INCX, LDA+ IF( REWI )+ $ REWIND NTRA+ CALL ZHER( UPLO, N, RALPHA, XX, INCX, AA, LDA )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, UPLO, N,+ $ RALPHA, INCX+ IF( REWI )+ $ REWIND NTRA+ CALL ZHPR( UPLO, N, RALPHA, XX, INCX, AA )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLO.EQ.UPLOS+ ISAME( 2 ) = NS.EQ.N+ ISAME( 3 ) = RALS.EQ.RALPHA+ ISAME( 4 ) = LZE( XS, XX, LX )+ ISAME( 5 ) = INCXS.EQ.INCX+ IF( NULL )THEN+ ISAME( 6 ) = LZE( AS, AA, LAA )+ ELSE+ ISAME( 6 ) = LZERES( SNAME( 2: 3 ), UPLO, N, N, AS,+ $ AA, LDA )+ END IF+ IF( .NOT.PACKED )THEN+ ISAME( 7 ) = LDAS.EQ.LDA+ END IF+*+* If data was incorrectly changed, report and return.+*+ SAME = .TRUE.+ DO 30 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 30 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ IF( INCX.GT.0 )THEN+ DO 40 I = 1, N+ Z( I ) = X( I )+ 40 CONTINUE+ ELSE+ DO 50 I = 1, N+ Z( I ) = X( N - I + 1 )+ 50 CONTINUE+ END IF+ JA = 1+ DO 60 J = 1, N+ W( 1 ) = DCONJG( Z( J ) )+ IF( UPPER )THEN+ JJ = 1+ LJ = J+ ELSE+ JJ = J+ LJ = N - J + 1+ END IF+ CALL ZMVCH( 'N', LJ, 1, ALPHA, Z( JJ ), LJ, W,+ $ 1, ONE, A( JJ, J ), 1, YT, G,+ $ AA( JA ), EPS, ERR, FATAL, NOUT,+ $ .TRUE. )+ IF( FULL )THEN+ IF( UPPER )THEN+ JA = JA + LDA+ ELSE+ JA = JA + LDA + 1+ END IF+ ELSE+ JA = JA + LJ+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and return.+ IF( FATAL )+ $ GO TO 110+ 60 CONTINUE+ ELSE+* Avoid repeating tests if N.le.0.+ IF( N.LE.0 )+ $ GO TO 100+ END IF+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 110 CONTINUE+ WRITE( NOUT, FMT = 9995 )J+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, N, RALPHA, INCX, LDA+ ELSE IF( PACKED )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, N, RALPHA, INCX+ END IF+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',', F4.1, ', X,',+ $ I2, ', AP) .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',', F4.1, ', X,',+ $ I2, ', A,', I3, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of ZCHK5.+*+ END+ SUBROUTINE ZCHK6( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NINC, INC, NMAX,+ $ INCMAX, A, AA, AS, X, XX, XS, Y, YY, YS, YT, G,+ $ Z )+*+* Tests ZHER2 and ZHPR2.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ COMPLEX*16 ZERO, HALF, ONE+ PARAMETER ( ZERO = ( 0.0D0, 0.0D0 ),+ $ HALF = ( 0.5D0, 0.0D0 ),+ $ ONE = ( 1.0D0, 0.0D0 ) )+ DOUBLE PRECISION RZERO+ PARAMETER ( RZERO = 0.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER INCMAX, NALF, NIDIM, NINC, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX*16 A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), X( NMAX ), XS( NMAX*INCMAX ),+ $ XX( NMAX*INCMAX ), Y( NMAX ),+ $ YS( NMAX*INCMAX ), YT( NMAX ),+ $ YY( NMAX*INCMAX ), Z( NMAX, 2 )+ DOUBLE PRECISION G( NMAX )+ INTEGER IDIM( NIDIM ), INC( NINC )+* .. Local Scalars ..+ COMPLEX*16 ALPHA, ALS, TRANSL+ DOUBLE PRECISION ERR, ERRMAX+ INTEGER I, IA, IC, IN, INCX, INCXS, INCY, INCYS, IX,+ $ IY, J, JA, JJ, LAA, LDA, LDAS, LJ, LX, LY, N,+ $ NARGS, NC, NS+ LOGICAL FULL, NULL, PACKED, RESET, SAME, UPPER+ CHARACTER*1 UPLO, UPLOS+ CHARACTER*2 ICH+* .. Local Arrays ..+ COMPLEX*16 W( 2 )+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LZE, LZERES+ EXTERNAL LZE, LZERES+* .. External Subroutines ..+ EXTERNAL ZHER2, ZHPR2, ZMAKE, ZMVCH+* .. Intrinsic Functions ..+ INTRINSIC ABS, DCONJG, MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'UL'/+* .. Executable Statements ..+ FULL = SNAME( 3: 3 ).EQ.'E'+ PACKED = SNAME( 3: 3 ).EQ.'P'+* Define the number of arguments.+ IF( FULL )THEN+ NARGS = 9+ ELSE IF( PACKED )THEN+ NARGS = 8+ END IF+*+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 140 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDA to 1 more than minimum value if room.+ LDA = N+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 140+ IF( PACKED )THEN+ LAA = ( N*( N + 1 ) )/2+ ELSE+ LAA = LDA*N+ END IF+*+ DO 130 IC = 1, 2+ UPLO = ICH( IC: IC )+ UPPER = UPLO.EQ.'U'+*+ DO 120 IX = 1, NINC+ INCX = INC( IX )+ LX = ABS( INCX )*N+*+* Generate the vector X.+*+ TRANSL = HALF+ CALL ZMAKE( 'GE', ' ', ' ', 1, N, X, 1, XX, ABS( INCX ),+ $ 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ X( N/2 ) = ZERO+ XX( 1 + ABS( INCX )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 110 IY = 1, NINC+ INCY = INC( IY )+ LY = ABS( INCY )*N+*+* Generate the vector Y.+*+ TRANSL = ZERO+ CALL ZMAKE( 'GE', ' ', ' ', 1, N, Y, 1, YY,+ $ ABS( INCY ), 0, N - 1, RESET, TRANSL )+ IF( N.GT.1 )THEN+ Y( N/2 ) = ZERO+ YY( 1 + ABS( INCY )*( N/2 - 1 ) ) = ZERO+ END IF+*+ DO 100 IA = 1, NALF+ ALPHA = ALF( IA )+ NULL = N.LE.0.OR.ALPHA.EQ.ZERO+*+* Generate the matrix A.+*+ TRANSL = ZERO+ CALL ZMAKE( SNAME( 2: 3 ), UPLO, ' ', N, N, A,+ $ NMAX, AA, LDA, N - 1, N - 1, RESET,+ $ TRANSL )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ NS = N+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LX+ XS( I ) = XX( I )+ 20 CONTINUE+ INCXS = INCX+ DO 30 I = 1, LY+ YS( I ) = YY( I )+ 30 CONTINUE+ INCYS = INCY+*+* Call the subroutine.+*+ IF( FULL )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME, UPLO, N,+ $ ALPHA, INCX, INCY, LDA+ IF( REWI )+ $ REWIND NTRA+ CALL ZHER2( UPLO, N, ALPHA, XX, INCX, YY, INCY,+ $ AA, LDA )+ ELSE IF( PACKED )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, UPLO, N,+ $ ALPHA, INCX, INCY+ IF( REWI )+ $ REWIND NTRA+ CALL ZHPR2( UPLO, N, ALPHA, XX, INCX, YY, INCY,+ $ AA )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 160+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLO.EQ.UPLOS+ ISAME( 2 ) = NS.EQ.N+ ISAME( 3 ) = ALS.EQ.ALPHA+ ISAME( 4 ) = LZE( XS, XX, LX )+ ISAME( 5 ) = INCXS.EQ.INCX+ ISAME( 6 ) = LZE( YS, YY, LY )+ ISAME( 7 ) = INCYS.EQ.INCY+ IF( NULL )THEN+ ISAME( 8 ) = LZE( AS, AA, LAA )+ ELSE+ ISAME( 8 ) = LZERES( SNAME( 2: 3 ), UPLO, N, N,+ $ AS, AA, LDA )+ END IF+ IF( .NOT.PACKED )THEN+ ISAME( 9 ) = LDAS.EQ.LDA+ END IF+*+* If data was incorrectly changed, report and return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 160+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ IF( INCX.GT.0 )THEN+ DO 50 I = 1, N+ Z( I, 1 ) = X( I )+ 50 CONTINUE+ ELSE+ DO 60 I = 1, N+ Z( I, 1 ) = X( N - I + 1 )+ 60 CONTINUE+ END IF+ IF( INCY.GT.0 )THEN+ DO 70 I = 1, N+ Z( I, 2 ) = Y( I )+ 70 CONTINUE+ ELSE+ DO 80 I = 1, N+ Z( I, 2 ) = Y( N - I + 1 )+ 80 CONTINUE+ END IF+ JA = 1+ DO 90 J = 1, N+ W( 1 ) = ALPHA*DCONJG( Z( J, 2 ) )+ W( 2 ) = DCONJG( ALPHA )*DCONJG( Z( J, 1 ) )+ IF( UPPER )THEN+ JJ = 1+ LJ = J+ ELSE+ JJ = J+ LJ = N - J + 1+ END IF+ CALL ZMVCH( 'N', LJ, 2, ONE, Z( JJ, 1 ),+ $ NMAX, W, 1, ONE, A( JJ, J ), 1,+ $ YT, G, AA( JA ), EPS, ERR, FATAL,+ $ NOUT, .TRUE. )+ IF( FULL )THEN+ IF( UPPER )THEN+ JA = JA + LDA+ ELSE+ JA = JA + LDA + 1+ END IF+ ELSE+ JA = JA + LJ+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and return.+ IF( FATAL )+ $ GO TO 150+ 90 CONTINUE+ ELSE+* Avoid repeating tests with N.le.0.+ IF( N.LE.0 )+ $ GO TO 140+ END IF+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+ 130 CONTINUE+*+ 140 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 170+*+ 150 CONTINUE+ WRITE( NOUT, FMT = 9995 )J+*+ 160 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( FULL )THEN+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, N, ALPHA, INCX,+ $ INCY, LDA+ ELSE IF( PACKED )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, N, ALPHA, INCX, INCY+ END IF+*+ 170 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',(', F4.1, ',',+ $ F4.1, '), X,', I2, ', Y,', I2, ', AP) ',+ $ ' .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',', I3, ',(', F4.1, ',',+ $ F4.1, '), X,', I2, ', Y,', I2, ', A,', I3, ') ',+ $ ' .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of ZCHK6.+*+ END+ SUBROUTINE ZCHKE( ISNUM, SRNAMT, NOUT )+*+* Tests the error exits from the Level 2 Blas.+* Requires a special version of the error-handling routine XERBLA.+* ALPHA, RALPHA, BETA, A, X and Y should not need to be defined.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER ISNUM, NOUT+ CHARACTER*6 SRNAMT+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Local Scalars ..+ COMPLEX*16 ALPHA, BETA+ DOUBLE PRECISION RALPHA+* .. Local Arrays ..+ COMPLEX*16 A( 1, 1 ), X( 1 ), Y( 1 )+* .. External Subroutines ..+ EXTERNAL CHKXER, ZGBMV, ZGEMV, ZGERC, ZGERU, ZHBMV,+ $ ZHEMV, ZHER, ZHER2, ZHPMV, ZHPR, ZHPR2, ZTBMV,+ $ ZTBSV, ZTPMV, ZTPSV, ZTRMV, ZTRSV+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Executable Statements ..+* OK is set to .FALSE. by the special version of XERBLA or by CHKXER+* if anything is wrong.+ OK = .TRUE.+* LERR is set to .TRUE. by the special version of XERBLA each time+* it is called, and is then tested and re-set by CHKXER.+ LERR = .FALSE.+ GO TO ( 10, 20, 30, 40, 50, 60, 70, 80,+ $ 90, 100, 110, 120, 130, 140, 150, 160,+ $ 170 )ISNUM+ 10 INFOT = 1+ CALL ZGEMV( '/', 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZGEMV( 'N', -1, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZGEMV( 'N', 0, -1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZGEMV( 'N', 2, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL ZGEMV( 'N', 0, 0, ALPHA, A, 1, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZGEMV( 'N', 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 20 INFOT = 1+ CALL ZGBMV( '/', 0, 0, 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZGBMV( 'N', -1, 0, 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZGBMV( 'N', 0, -1, 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZGBMV( 'N', 0, 0, -1, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZGBMV( 'N', 2, 0, 0, -1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL ZGBMV( 'N', 0, 0, 1, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZGBMV( 'N', 0, 0, 0, 0, ALPHA, A, 1, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL ZGBMV( 'N', 0, 0, 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 30 INFOT = 1+ CALL ZHEMV( '/', 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZHEMV( 'U', -1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZHEMV( 'U', 2, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZHEMV( 'U', 0, ALPHA, A, 1, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZHEMV( 'U', 0, ALPHA, A, 1, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 40 INFOT = 1+ CALL ZHBMV( '/', 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZHBMV( 'U', -1, 0, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZHBMV( 'U', 0, -1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZHBMV( 'U', 0, 1, ALPHA, A, 1, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL ZHBMV( 'U', 0, 0, ALPHA, A, 1, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZHBMV( 'U', 0, 0, ALPHA, A, 1, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 50 INFOT = 1+ CALL ZHPMV( '/', 0, ALPHA, A, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZHPMV( 'U', -1, ALPHA, A, X, 1, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZHPMV( 'U', 0, ALPHA, A, X, 0, BETA, Y, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZHPMV( 'U', 0, ALPHA, A, X, 1, BETA, Y, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 60 INFOT = 1+ CALL ZTRMV( '/', 'N', 'N', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZTRMV( 'U', '/', 'N', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZTRMV( 'U', 'N', '/', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZTRMV( 'U', 'N', 'N', -1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRMV( 'U', 'N', 'N', 2, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL ZTRMV( 'U', 'N', 'N', 0, A, 1, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 70 INFOT = 1+ CALL ZTBMV( '/', 'N', 'N', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZTBMV( 'U', '/', 'N', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZTBMV( 'U', 'N', '/', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZTBMV( 'U', 'N', 'N', -1, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTBMV( 'U', 'N', 'N', 0, -1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZTBMV( 'U', 'N', 'N', 0, 1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTBMV( 'U', 'N', 'N', 0, 0, A, 1, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 80 INFOT = 1+ CALL ZTPMV( '/', 'N', 'N', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZTPMV( 'U', '/', 'N', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZTPMV( 'U', 'N', '/', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZTPMV( 'U', 'N', 'N', -1, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZTPMV( 'U', 'N', 'N', 0, A, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 90 INFOT = 1+ CALL ZTRSV( '/', 'N', 'N', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZTRSV( 'U', '/', 'N', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZTRSV( 'U', 'N', '/', 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZTRSV( 'U', 'N', 'N', -1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRSV( 'U', 'N', 'N', 2, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL ZTRSV( 'U', 'N', 'N', 0, A, 1, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 100 INFOT = 1+ CALL ZTBSV( '/', 'N', 'N', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZTBSV( 'U', '/', 'N', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZTBSV( 'U', 'N', '/', 0, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZTBSV( 'U', 'N', 'N', -1, 0, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTBSV( 'U', 'N', 'N', 0, -1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZTBSV( 'U', 'N', 'N', 0, 1, A, 1, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTBSV( 'U', 'N', 'N', 0, 0, A, 1, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 110 INFOT = 1+ CALL ZTPSV( '/', 'N', 'N', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZTPSV( 'U', '/', 'N', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZTPSV( 'U', 'N', '/', 0, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZTPSV( 'U', 'N', 'N', -1, A, X, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZTPSV( 'U', 'N', 'N', 0, A, X, 0 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 120 INFOT = 1+ CALL ZGERC( -1, 0, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZGERC( 0, -1, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZGERC( 0, 0, ALPHA, X, 0, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZGERC( 0, 0, ALPHA, X, 1, Y, 0, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZGERC( 2, 0, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 130 INFOT = 1+ CALL ZGERU( -1, 0, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZGERU( 0, -1, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZGERU( 0, 0, ALPHA, X, 0, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZGERU( 0, 0, ALPHA, X, 1, Y, 0, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZGERU( 2, 0, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 140 INFOT = 1+ CALL ZHER( '/', 0, RALPHA, X, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZHER( 'U', -1, RALPHA, X, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZHER( 'U', 0, RALPHA, X, 0, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZHER( 'U', 2, RALPHA, X, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 150 INFOT = 1+ CALL ZHPR( '/', 0, RALPHA, X, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZHPR( 'U', -1, RALPHA, X, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZHPR( 'U', 0, RALPHA, X, 0, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 160 INFOT = 1+ CALL ZHER2( '/', 0, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZHER2( 'U', -1, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZHER2( 'U', 0, ALPHA, X, 0, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZHER2( 'U', 0, ALPHA, X, 1, Y, 0, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZHER2( 'U', 2, ALPHA, X, 1, Y, 1, A, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 180+ 170 INFOT = 1+ CALL ZHPR2( '/', 0, ALPHA, X, 1, Y, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZHPR2( 'U', -1, ALPHA, X, 1, Y, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZHPR2( 'U', 0, ALPHA, X, 0, Y, 1, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZHPR2( 'U', 0, ALPHA, X, 1, Y, 0, A )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+*+ 180 IF( OK )THEN+ WRITE( NOUT, FMT = 9999 )SRNAMT+ ELSE+ WRITE( NOUT, FMT = 9998 )SRNAMT+ END IF+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE TESTS OF ERROR-EXITS' )+ 9998 FORMAT( ' ******* ', A6, ' FAILED THE TESTS OF ERROR-EXITS *****',+ $ '**' )+*+* End of ZCHKE.+*+ END+ SUBROUTINE ZMAKE( TYPE, UPLO, DIAG, M, N, A, NMAX, AA, LDA, KL,+ $ KU, RESET, TRANSL )+*+* Generates values for an M by N matrix A within the bandwidth+* defined by KL and KU.+* Stores the values in the array AA in the data structure required+* by the routine, with unwanted elements set to rogue value.+*+* TYPE is 'GE', 'GB', 'HE', 'HB', 'HP', 'TR', 'TB' OR 'TP'.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ COMPLEX*16 ZERO, ONE+ PARAMETER ( ZERO = ( 0.0D0, 0.0D0 ),+ $ ONE = ( 1.0D0, 0.0D0 ) )+ COMPLEX*16 ROGUE+ PARAMETER ( ROGUE = ( -1.0D10, 1.0D10 ) )+ DOUBLE PRECISION RZERO+ PARAMETER ( RZERO = 0.0D0 )+ DOUBLE PRECISION RROGUE+ PARAMETER ( RROGUE = -1.0D10 )+* .. Scalar Arguments ..+ COMPLEX*16 TRANSL+ INTEGER KL, KU, LDA, M, N, NMAX+ LOGICAL RESET+ CHARACTER*1 DIAG, UPLO+ CHARACTER*2 TYPE+* .. Array Arguments ..+ COMPLEX*16 A( NMAX, * ), AA( * )+* .. Local Scalars ..+ INTEGER I, I1, I2, I3, IBEG, IEND, IOFF, J, JJ, KK+ LOGICAL GEN, LOWER, SYM, TRI, UNIT, UPPER+* .. External Functions ..+ COMPLEX*16 ZBEG+ EXTERNAL ZBEG+* .. Intrinsic Functions ..+ INTRINSIC DBLE, DCMPLX, DCONJG, MAX, MIN+* .. Executable Statements ..+ GEN = TYPE( 1: 1 ).EQ.'G'+ SYM = TYPE( 1: 1 ).EQ.'H'+ TRI = TYPE( 1: 1 ).EQ.'T'+ UPPER = ( SYM.OR.TRI ).AND.UPLO.EQ.'U'+ LOWER = ( SYM.OR.TRI ).AND.UPLO.EQ.'L'+ UNIT = TRI.AND.DIAG.EQ.'U'+*+* Generate data in array A.+*+ DO 20 J = 1, N+ DO 10 I = 1, M+ IF( GEN.OR.( UPPER.AND.I.LE.J ).OR.( LOWER.AND.I.GE.J ) )+ $ THEN+ IF( ( I.LE.J.AND.J - I.LE.KU ).OR.+ $ ( I.GE.J.AND.I - J.LE.KL ) )THEN+ A( I, J ) = ZBEG( RESET ) + TRANSL+ ELSE+ A( I, J ) = ZERO+ END IF+ IF( I.NE.J )THEN+ IF( SYM )THEN+ A( J, I ) = DCONJG( A( I, J ) )+ ELSE IF( TRI )THEN+ A( J, I ) = ZERO+ END IF+ END IF+ END IF+ 10 CONTINUE+ IF( SYM )+ $ A( J, J ) = DCMPLX( DBLE( A( J, J ) ), RZERO )+ IF( TRI )+ $ A( J, J ) = A( J, J ) + ONE+ IF( UNIT )+ $ A( J, J ) = ONE+ 20 CONTINUE+*+* Store elements in array AS in data structure required by routine.+*+ IF( TYPE.EQ.'GE' )THEN+ DO 50 J = 1, N+ DO 30 I = 1, M+ AA( I + ( J - 1 )*LDA ) = A( I, J )+ 30 CONTINUE+ DO 40 I = M + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 40 CONTINUE+ 50 CONTINUE+ ELSE IF( TYPE.EQ.'GB' )THEN+ DO 90 J = 1, N+ DO 60 I1 = 1, KU + 1 - J+ AA( I1 + ( J - 1 )*LDA ) = ROGUE+ 60 CONTINUE+ DO 70 I2 = I1, MIN( KL + KU + 1, KU + 1 + M - J )+ AA( I2 + ( J - 1 )*LDA ) = A( I2 + J - KU - 1, J )+ 70 CONTINUE+ DO 80 I3 = I2, LDA+ AA( I3 + ( J - 1 )*LDA ) = ROGUE+ 80 CONTINUE+ 90 CONTINUE+ ELSE IF( TYPE.EQ.'HE'.OR.TYPE.EQ.'TR' )THEN+ DO 130 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IF( UNIT )THEN+ IEND = J - 1+ ELSE+ IEND = J+ END IF+ ELSE+ IF( UNIT )THEN+ IBEG = J + 1+ ELSE+ IBEG = J+ END IF+ IEND = N+ END IF+ DO 100 I = 1, IBEG - 1+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 100 CONTINUE+ DO 110 I = IBEG, IEND+ AA( I + ( J - 1 )*LDA ) = A( I, J )+ 110 CONTINUE+ DO 120 I = IEND + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 120 CONTINUE+ IF( SYM )THEN+ JJ = J + ( J - 1 )*LDA+ AA( JJ ) = DCMPLX( DBLE( AA( JJ ) ), RROGUE )+ END IF+ 130 CONTINUE+ ELSE IF( TYPE.EQ.'HB'.OR.TYPE.EQ.'TB' )THEN+ DO 170 J = 1, N+ IF( UPPER )THEN+ KK = KL + 1+ IBEG = MAX( 1, KL + 2 - J )+ IF( UNIT )THEN+ IEND = KL+ ELSE+ IEND = KL + 1+ END IF+ ELSE+ KK = 1+ IF( UNIT )THEN+ IBEG = 2+ ELSE+ IBEG = 1+ END IF+ IEND = MIN( KL + 1, 1 + M - J )+ END IF+ DO 140 I = 1, IBEG - 1+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 140 CONTINUE+ DO 150 I = IBEG, IEND+ AA( I + ( J - 1 )*LDA ) = A( I + J - KK, J )+ 150 CONTINUE+ DO 160 I = IEND + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 160 CONTINUE+ IF( SYM )THEN+ JJ = KK + ( J - 1 )*LDA+ AA( JJ ) = DCMPLX( DBLE( AA( JJ ) ), RROGUE )+ END IF+ 170 CONTINUE+ ELSE IF( TYPE.EQ.'HP'.OR.TYPE.EQ.'TP' )THEN+ IOFF = 0+ DO 190 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IEND = J+ ELSE+ IBEG = J+ IEND = N+ END IF+ DO 180 I = IBEG, IEND+ IOFF = IOFF + 1+ AA( IOFF ) = A( I, J )+ IF( I.EQ.J )THEN+ IF( UNIT )+ $ AA( IOFF ) = ROGUE+ IF( SYM )+ $ AA( IOFF ) = DCMPLX( DBLE( AA( IOFF ) ), RROGUE )+ END IF+ 180 CONTINUE+ 190 CONTINUE+ END IF+ RETURN+*+* End of ZMAKE.+*+ END+ SUBROUTINE ZMVCH( TRANS, M, N, ALPHA, A, NMAX, X, INCX, BETA, Y,+ $ INCY, YT, G, YY, EPS, ERR, FATAL, NOUT, MV )+*+* Checks the results of the computational tests.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Parameters ..+ COMPLEX*16 ZERO+ PARAMETER ( ZERO = ( 0.0D0, 0.0D0 ) )+ DOUBLE PRECISION RZERO, RONE+ PARAMETER ( RZERO = 0.0D0, RONE = 1.0D0 )+* .. Scalar Arguments ..+ COMPLEX*16 ALPHA, BETA+ DOUBLE PRECISION EPS, ERR+ INTEGER INCX, INCY, M, N, NMAX, NOUT+ LOGICAL FATAL, MV+ CHARACTER*1 TRANS+* .. Array Arguments ..+ COMPLEX*16 A( NMAX, * ), X( * ), Y( * ), YT( * ), YY( * )+ DOUBLE PRECISION G( * )+* .. Local Scalars ..+ COMPLEX*16 C+ DOUBLE PRECISION ERRI+ INTEGER I, INCXL, INCYL, IY, J, JX, KX, KY, ML, NL+ LOGICAL CTRAN, TRAN+* .. Intrinsic Functions ..+ INTRINSIC ABS, DBLE, DCONJG, DIMAG, MAX, SQRT+* .. Statement Functions ..+ DOUBLE PRECISION ABS1+* .. Statement Function definitions ..+ ABS1( C ) = ABS( DBLE( C ) ) + ABS( DIMAG( C ) )+* .. Executable Statements ..+ TRAN = TRANS.EQ.'T'+ CTRAN = TRANS.EQ.'C'+ IF( TRAN.OR.CTRAN )THEN+ ML = N+ NL = M+ ELSE+ ML = M+ NL = N+ END IF+ IF( INCX.LT.0 )THEN+ KX = NL+ INCXL = -1+ ELSE+ KX = 1+ INCXL = 1+ END IF+ IF( INCY.LT.0 )THEN+ KY = ML+ INCYL = -1+ ELSE+ KY = 1+ INCYL = 1+ END IF+*+* Compute expected result in YT using data in A, X and Y.+* Compute gauges in G.+*+ IY = KY+ DO 40 I = 1, ML+ YT( IY ) = ZERO+ G( IY ) = RZERO+ JX = KX+ IF( TRAN )THEN+ DO 10 J = 1, NL+ YT( IY ) = YT( IY ) + A( J, I )*X( JX )+ G( IY ) = G( IY ) + ABS1( A( J, I ) )*ABS1( X( JX ) )+ JX = JX + INCXL+ 10 CONTINUE+ ELSE IF( CTRAN )THEN+ DO 20 J = 1, NL+ YT( IY ) = YT( IY ) + DCONJG( A( J, I ) )*X( JX )+ G( IY ) = G( IY ) + ABS1( A( J, I ) )*ABS1( X( JX ) )+ JX = JX + INCXL+ 20 CONTINUE+ ELSE+ DO 30 J = 1, NL+ YT( IY ) = YT( IY ) + A( I, J )*X( JX )+ G( IY ) = G( IY ) + ABS1( A( I, J ) )*ABS1( X( JX ) )+ JX = JX + INCXL+ 30 CONTINUE+ END IF+ YT( IY ) = ALPHA*YT( IY ) + BETA*Y( IY )+ G( IY ) = ABS1( ALPHA )*G( IY ) + ABS1( BETA )*ABS1( Y( IY ) )+ IY = IY + INCYL+ 40 CONTINUE+*+* Compute the error ratio for this result.+*+ ERR = ZERO+ DO 50 I = 1, ML+ ERRI = ABS( YT( I ) - YY( 1 + ( I - 1 )*ABS( INCY ) ) )/EPS+ IF( G( I ).NE.RZERO )+ $ ERRI = ERRI/G( I )+ ERR = MAX( ERR, ERRI )+ IF( ERR*SQRT( EPS ).GE.RONE )+ $ GO TO 60+ 50 CONTINUE+* If the loop completes, all results are at least half accurate.+ GO TO 80+*+* Report fatal error.+*+ 60 FATAL = .TRUE.+ WRITE( NOUT, FMT = 9999 )+ DO 70 I = 1, ML+ IF( MV )THEN+ WRITE( NOUT, FMT = 9998 )I, YT( I ),+ $ YY( 1 + ( I - 1 )*ABS( INCY ) )+ ELSE+ WRITE( NOUT, FMT = 9998 )I,+ $ YY( 1 + ( I - 1 )*ABS( INCY ) ), YT( I )+ END IF+ 70 CONTINUE+*+ 80 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ******* FATAL ERROR - COMPUTED RESULT IS LESS THAN HAL',+ $ 'F ACCURATE *******', /' EXPECTED RE',+ $ 'SULT COMPUTED RESULT' )+ 9998 FORMAT( 1X, I7, 2( ' (', G15.6, ',', G15.6, ')' ) )+*+* End of ZMVCH.+*+ END+ LOGICAL FUNCTION LZE( RI, RJ, LR )+*+* Tests if two arrays are identical.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER LR+* .. Array Arguments ..+ COMPLEX*16 RI( * ), RJ( * )+* .. Local Scalars ..+ INTEGER I+* .. Executable Statements ..+ DO 10 I = 1, LR+ IF( RI( I ).NE.RJ( I ) )+ $ GO TO 20+ 10 CONTINUE+ LZE = .TRUE.+ GO TO 30+ 20 CONTINUE+ LZE = .FALSE.+ 30 RETURN+*+* End of LZE.+*+ END+ LOGICAL FUNCTION LZERES( TYPE, UPLO, M, N, AA, AS, LDA )+*+* Tests if selected elements in two arrays are equal.+*+* TYPE is 'GE', 'HE' or 'HP'.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER LDA, M, N+ CHARACTER*1 UPLO+ CHARACTER*2 TYPE+* .. Array Arguments ..+ COMPLEX*16 AA( LDA, * ), AS( LDA, * )+* .. Local Scalars ..+ INTEGER I, IBEG, IEND, J+ LOGICAL UPPER+* .. Executable Statements ..+ UPPER = UPLO.EQ.'U'+ IF( TYPE.EQ.'GE' )THEN+ DO 20 J = 1, N+ DO 10 I = M + 1, LDA+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 10 CONTINUE+ 20 CONTINUE+ ELSE IF( TYPE.EQ.'HE' )THEN+ DO 50 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IEND = J+ ELSE+ IBEG = J+ IEND = N+ END IF+ DO 30 I = 1, IBEG - 1+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 30 CONTINUE+ DO 40 I = IEND + 1, LDA+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 40 CONTINUE+ 50 CONTINUE+ END IF+*+ 60 CONTINUE+ LZERES = .TRUE.+ GO TO 80+ 70 CONTINUE+ LZERES = .FALSE.+ 80 RETURN+*+* End of LZERES.+*+ END+ COMPLEX*16 FUNCTION ZBEG( RESET )+*+* Generates complex numbers as pairs of random numbers uniformly+* distributed between -0.5 and 0.5.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ LOGICAL RESET+* .. Local Scalars ..+ INTEGER I, IC, J, MI, MJ+* .. Save statement ..+ SAVE I, IC, J, MI, MJ+* .. Intrinsic Functions ..+ INTRINSIC DCMPLX+* .. Executable Statements ..+ IF( RESET )THEN+* Initialize local variables.+ MI = 891+ MJ = 457+ I = 7+ J = 7+ IC = 0+ RESET = .FALSE.+ END IF+*+* The sequence of values of I or J is bounded between 1 and 999.+* If initial I or J = 1,2,3,6,7 or 9, the period will be 50.+* If initial I or J = 4 or 8, the period will be 25.+* If initial I or J = 5, the period will be 10.+* IC is used to break up the period by skipping 1 value of I or J+* in 6.+*+ IC = IC + 1+ 10 I = I*MI+ J = J*MJ+ I = I - 1000*( I/1000 )+ J = J - 1000*( J/1000 )+ IF( IC.GE.5 )THEN+ IC = 0+ GO TO 10+ END IF+ ZBEG = DCMPLX( ( I - 500 )/1001.0D0, ( J - 500 )/1001.0D0 )+ RETURN+*+* End of ZBEG.+*+ END+ DOUBLE PRECISION FUNCTION DDIFF( X, Y )+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+*+* .. Scalar Arguments ..+ DOUBLE PRECISION X, Y+* .. Executable Statements ..+ DDIFF = X - Y+ RETURN+*+* End of DDIFF.+*+ END+ SUBROUTINE CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+*+* Tests whether XERBLA has detected an error when it should.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER INFOT, NOUT+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Executable Statements ..+ IF( .NOT.LERR )THEN+ WRITE( NOUT, FMT = 9999 )INFOT, SRNAMT+ OK = .FALSE.+ END IF+ LERR = .FALSE.+ RETURN+*+ 9999 FORMAT( ' ***** ILLEGAL VALUE OF PARAMETER NUMBER ', I2, ' NOT D',+ $ 'ETECTED BY ', A6, ' *****' )+*+* End of CHKXER.+*+ END+ SUBROUTINE XERBLA( SRNAME, INFO )+*+* This is a special version of XERBLA to be used only as part of+* the test program for testing error exits from the Level 2 BLAS+* routines.+*+* XERBLA is an error handler for the Level 2 BLAS routines.+*+* It is called by the Level 2 BLAS routines if an input parameter is+* invalid.+*+* Auxiliary routine for test program for Level 2 Blas.+*+* -- Written on 10-August-1987.+* Richard Hanson, Sandia National Labs.+* Jeremy Du Croz, NAG Central Office.+*+* .. Scalar Arguments ..+ INTEGER INFO+ CHARACTER*6 SRNAME+* .. Scalars in Common ..+ INTEGER INFOT, NOUT+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUT, OK, LERR+ COMMON /SRNAMC/SRNAMT+* .. Executable Statements ..+ LERR = .TRUE.+ IF( INFO.NE.INFOT )THEN+ IF( INFOT.NE.0 )THEN+ WRITE( NOUT, FMT = 9999 )INFO, INFOT+ ELSE+ WRITE( NOUT, FMT = 9997 )INFO+ END IF+ OK = .FALSE.+ END IF+ IF( SRNAME.NE.SRNAMT )THEN+ WRITE( NOUT, FMT = 9998 )SRNAME, SRNAMT+ OK = .FALSE.+ END IF+ RETURN+*+ 9999 FORMAT( ' ******* XERBLA WAS CALLED WITH INFO = ', I6, ' INSTEAD',+ $ ' OF ', I2, ' *******' )+ 9998 FORMAT( ' ******* XERBLA WAS CALLED WITH SRNAME = ', A6, ' INSTE',+ $ 'AD OF ', A6, ' *******' )+ 9997 FORMAT( ' ******* XERBLA WAS CALLED WITH INFO = ', I6,+ $ ' *******' )+*+* End of XERBLA+*+ END+
+ eigen3/blas/testing/zblat3.dat view
@@ -0,0 +1,23 @@+'zblat3.summ' NAME OF SUMMARY OUTPUT FILE+6 UNIT NUMBER OF SUMMARY FILE+'zblat3.snap' NAME OF SNAPSHOT OUTPUT FILE+-1 UNIT NUMBER OF SNAPSHOT FILE (NOT USED IF .LT. 0)+F LOGICAL FLAG, T TO REWIND SNAPSHOT FILE AFTER EACH RECORD.+F LOGICAL FLAG, T TO STOP ON FAILURES.+F LOGICAL FLAG, T TO TEST ERROR EXITS.+16.0 THRESHOLD VALUE OF TEST RATIO+6 NUMBER OF VALUES OF N+0 1 2 3 5 9 VALUES OF N+3 NUMBER OF VALUES OF ALPHA+(0.0,0.0) (1.0,0.0) (0.7,-0.9) VALUES OF ALPHA+3 NUMBER OF VALUES OF BETA+(0.0,0.0) (1.0,0.0) (1.3,-1.1) VALUES OF BETA+ZGEMM T PUT F FOR NO TEST. SAME COLUMNS.+ZHEMM T PUT F FOR NO TEST. SAME COLUMNS.+ZSYMM T PUT F FOR NO TEST. SAME COLUMNS.+ZTRMM T PUT F FOR NO TEST. SAME COLUMNS.+ZTRSM T PUT F FOR NO TEST. SAME COLUMNS.+ZHERK T PUT F FOR NO TEST. SAME COLUMNS.+ZSYRK T PUT F FOR NO TEST. SAME COLUMNS.+ZHER2K T PUT F FOR NO TEST. SAME COLUMNS.+ZSYR2K T PUT F FOR NO TEST. SAME COLUMNS.
+ eigen3/blas/testing/zblat3.f view
@@ -0,0 +1,3445 @@+ PROGRAM ZBLAT3+*+* Test program for the COMPLEX*16 Level 3 Blas.+*+* The program must be driven by a short data file. The first 14 records+* of the file are read using list-directed input, the last 9 records+* are read using the format ( A6, L2 ). An annotated example of a data+* file can be obtained by deleting the first 3 characters from the+* following 23 lines:+* 'ZBLAT3.SUMM' NAME OF SUMMARY OUTPUT FILE+* 6 UNIT NUMBER OF SUMMARY FILE+* 'ZBLAT3.SNAP' NAME OF SNAPSHOT OUTPUT FILE+* -1 UNIT NUMBER OF SNAPSHOT FILE (NOT USED IF .LT. 0)+* F LOGICAL FLAG, T TO REWIND SNAPSHOT FILE AFTER EACH RECORD.+* F LOGICAL FLAG, T TO STOP ON FAILURES.+* T LOGICAL FLAG, T TO TEST ERROR EXITS.+* 16.0 THRESHOLD VALUE OF TEST RATIO+* 6 NUMBER OF VALUES OF N+* 0 1 2 3 5 9 VALUES OF N+* 3 NUMBER OF VALUES OF ALPHA+* (0.0,0.0) (1.0,0.0) (0.7,-0.9) VALUES OF ALPHA+* 3 NUMBER OF VALUES OF BETA+* (0.0,0.0) (1.0,0.0) (1.3,-1.1) VALUES OF BETA+* ZGEMM T PUT F FOR NO TEST. SAME COLUMNS.+* ZHEMM T PUT F FOR NO TEST. SAME COLUMNS.+* ZSYMM T PUT F FOR NO TEST. SAME COLUMNS.+* ZTRMM T PUT F FOR NO TEST. SAME COLUMNS.+* ZTRSM T PUT F FOR NO TEST. SAME COLUMNS.+* ZHERK T PUT F FOR NO TEST. SAME COLUMNS.+* ZSYRK T PUT F FOR NO TEST. SAME COLUMNS.+* ZHER2K T PUT F FOR NO TEST. SAME COLUMNS.+* ZSYR2K T PUT F FOR NO TEST. SAME COLUMNS.+*+* See:+*+* Dongarra J. J., Du Croz J. J., Duff I. S. and Hammarling S.+* A Set of Level 3 Basic Linear Algebra Subprograms.+*+* Technical Memorandum No.88 (Revision 1), Mathematics and+* Computer Science Division, Argonne National Laboratory, 9700+* South Cass Avenue, Argonne, Illinois 60439, US.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ INTEGER NIN+ PARAMETER ( NIN = 5 )+ INTEGER NSUBS+ PARAMETER ( NSUBS = 9 )+ COMPLEX*16 ZERO, ONE+ PARAMETER ( ZERO = ( 0.0D0, 0.0D0 ),+ $ ONE = ( 1.0D0, 0.0D0 ) )+ DOUBLE PRECISION RZERO, RHALF, RONE+ PARAMETER ( RZERO = 0.0D0, RHALF = 0.5D0, RONE = 1.0D0 )+ INTEGER NMAX+ PARAMETER ( NMAX = 65 )+ INTEGER NIDMAX, NALMAX, NBEMAX+ PARAMETER ( NIDMAX = 9, NALMAX = 7, NBEMAX = 7 )+* .. Local Scalars ..+ DOUBLE PRECISION EPS, ERR, THRESH+ INTEGER I, ISNUM, J, N, NALF, NBET, NIDIM, NOUT, NTRA+ LOGICAL FATAL, LTESTT, REWI, SAME, SFATAL, TRACE,+ $ TSTERR+ CHARACTER*1 TRANSA, TRANSB+ CHARACTER*6 SNAMET+ CHARACTER*32 SNAPS, SUMMRY+* .. Local Arrays ..+ COMPLEX*16 AA( NMAX*NMAX ), AB( NMAX, 2*NMAX ),+ $ ALF( NALMAX ), AS( NMAX*NMAX ),+ $ BB( NMAX*NMAX ), BET( NBEMAX ),+ $ BS( NMAX*NMAX ), C( NMAX, NMAX ),+ $ CC( NMAX*NMAX ), CS( NMAX*NMAX ), CT( NMAX ),+ $ W( 2*NMAX )+ DOUBLE PRECISION G( NMAX )+ INTEGER IDIM( NIDMAX )+ LOGICAL LTEST( NSUBS )+ CHARACTER*6 SNAMES( NSUBS )+* .. External Functions ..+ DOUBLE PRECISION DDIFF+ LOGICAL LZE+ EXTERNAL DDIFF, LZE+* .. External Subroutines ..+ EXTERNAL ZCHK1, ZCHK2, ZCHK3, ZCHK4, ZCHK5, ZCHKE, ZMMCH+* .. Intrinsic Functions ..+ INTRINSIC MAX, MIN+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+ COMMON /SRNAMC/SRNAMT+* .. Data statements ..+ DATA SNAMES/'ZGEMM ', 'ZHEMM ', 'ZSYMM ', 'ZTRMM ',+ $ 'ZTRSM ', 'ZHERK ', 'ZSYRK ', 'ZHER2K',+ $ 'ZSYR2K'/+* .. Executable Statements ..+*+* Read name and unit number for summary output file and open file.+*+ READ( NIN, FMT = * )SUMMRY+ READ( NIN, FMT = * )NOUT+ OPEN( NOUT, FILE = SUMMRY, STATUS = 'NEW' )+ NOUTC = NOUT+*+* Read name and unit number for snapshot output file and open file.+*+ READ( NIN, FMT = * )SNAPS+ READ( NIN, FMT = * )NTRA+ TRACE = NTRA.GE.0+ IF( TRACE )THEN+ OPEN( NTRA, FILE = SNAPS, STATUS = 'NEW' )+ END IF+* Read the flag that directs rewinding of the snapshot file.+ READ( NIN, FMT = * )REWI+ REWI = REWI.AND.TRACE+* Read the flag that directs stopping on any failure.+ READ( NIN, FMT = * )SFATAL+* Read the flag that indicates whether error exits are to be tested.+ READ( NIN, FMT = * )TSTERR+* Read the threshold value of the test ratio+ READ( NIN, FMT = * )THRESH+*+* Read and check the parameter values for the tests.+*+* Values of N+ READ( NIN, FMT = * )NIDIM+ IF( NIDIM.LT.1.OR.NIDIM.GT.NIDMAX )THEN+ WRITE( NOUT, FMT = 9997 )'N', NIDMAX+ GO TO 220+ END IF+ READ( NIN, FMT = * )( IDIM( I ), I = 1, NIDIM )+ DO 10 I = 1, NIDIM+ IF( IDIM( I ).LT.0.OR.IDIM( I ).GT.NMAX )THEN+ WRITE( NOUT, FMT = 9996 )NMAX+ GO TO 220+ END IF+ 10 CONTINUE+* Values of ALPHA+ READ( NIN, FMT = * )NALF+ IF( NALF.LT.1.OR.NALF.GT.NALMAX )THEN+ WRITE( NOUT, FMT = 9997 )'ALPHA', NALMAX+ GO TO 220+ END IF+ READ( NIN, FMT = * )( ALF( I ), I = 1, NALF )+* Values of BETA+ READ( NIN, FMT = * )NBET+ IF( NBET.LT.1.OR.NBET.GT.NBEMAX )THEN+ WRITE( NOUT, FMT = 9997 )'BETA', NBEMAX+ GO TO 220+ END IF+ READ( NIN, FMT = * )( BET( I ), I = 1, NBET )+*+* Report values of parameters.+*+ WRITE( NOUT, FMT = 9995 )+ WRITE( NOUT, FMT = 9994 )( IDIM( I ), I = 1, NIDIM )+ WRITE( NOUT, FMT = 9993 )( ALF( I ), I = 1, NALF )+ WRITE( NOUT, FMT = 9992 )( BET( I ), I = 1, NBET )+ IF( .NOT.TSTERR )THEN+ WRITE( NOUT, FMT = * )+ WRITE( NOUT, FMT = 9984 )+ END IF+ WRITE( NOUT, FMT = * )+ WRITE( NOUT, FMT = 9999 )THRESH+ WRITE( NOUT, FMT = * )+*+* Read names of subroutines and flags which indicate+* whether they are to be tested.+*+ DO 20 I = 1, NSUBS+ LTEST( I ) = .FALSE.+ 20 CONTINUE+ 30 READ( NIN, FMT = 9988, END = 60 )SNAMET, LTESTT+ DO 40 I = 1, NSUBS+ IF( SNAMET.EQ.SNAMES( I ) )+ $ GO TO 50+ 40 CONTINUE+ WRITE( NOUT, FMT = 9990 )SNAMET+ STOP+ 50 LTEST( I ) = LTESTT+ GO TO 30+*+ 60 CONTINUE+ CLOSE ( NIN )+*+* Compute EPS (the machine precision).+*+ EPS = RONE+ 70 CONTINUE+ IF( DDIFF( RONE + EPS, RONE ).EQ.RZERO )+ $ GO TO 80+ EPS = RHALF*EPS+ GO TO 70+ 80 CONTINUE+ EPS = EPS + EPS+ WRITE( NOUT, FMT = 9998 )EPS+*+* Check the reliability of ZMMCH using exact data.+*+ N = MIN( 32, NMAX )+ DO 100 J = 1, N+ DO 90 I = 1, N+ AB( I, J ) = MAX( I - J + 1, 0 )+ 90 CONTINUE+ AB( J, NMAX + 1 ) = J+ AB( 1, NMAX + J ) = J+ C( J, 1 ) = ZERO+ 100 CONTINUE+ DO 110 J = 1, N+ CC( J ) = J*( ( J + 1 )*J )/2 - ( ( J + 1 )*J*( J - 1 ) )/3+ 110 CONTINUE+* CC holds the exact result. On exit from ZMMCH CT holds+* the result computed by ZMMCH.+ TRANSA = 'N'+ TRANSB = 'N'+ CALL ZMMCH( TRANSA, TRANSB, N, 1, N, ONE, AB, NMAX,+ $ AB( 1, NMAX + 1 ), NMAX, ZERO, C, NMAX, CT, G, CC,+ $ NMAX, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LZE( CC, CT, N )+ IF( .NOT.SAME.OR.ERR.NE.RZERO )THEN+ WRITE( NOUT, FMT = 9989 )TRANSA, TRANSB, SAME, ERR+ STOP+ END IF+ TRANSB = 'C'+ CALL ZMMCH( TRANSA, TRANSB, N, 1, N, ONE, AB, NMAX,+ $ AB( 1, NMAX + 1 ), NMAX, ZERO, C, NMAX, CT, G, CC,+ $ NMAX, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LZE( CC, CT, N )+ IF( .NOT.SAME.OR.ERR.NE.RZERO )THEN+ WRITE( NOUT, FMT = 9989 )TRANSA, TRANSB, SAME, ERR+ STOP+ END IF+ DO 120 J = 1, N+ AB( J, NMAX + 1 ) = N - J + 1+ AB( 1, NMAX + J ) = N - J + 1+ 120 CONTINUE+ DO 130 J = 1, N+ CC( N - J + 1 ) = J*( ( J + 1 )*J )/2 -+ $ ( ( J + 1 )*J*( J - 1 ) )/3+ 130 CONTINUE+ TRANSA = 'C'+ TRANSB = 'N'+ CALL ZMMCH( TRANSA, TRANSB, N, 1, N, ONE, AB, NMAX,+ $ AB( 1, NMAX + 1 ), NMAX, ZERO, C, NMAX, CT, G, CC,+ $ NMAX, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LZE( CC, CT, N )+ IF( .NOT.SAME.OR.ERR.NE.RZERO )THEN+ WRITE( NOUT, FMT = 9989 )TRANSA, TRANSB, SAME, ERR+ STOP+ END IF+ TRANSB = 'C'+ CALL ZMMCH( TRANSA, TRANSB, N, 1, N, ONE, AB, NMAX,+ $ AB( 1, NMAX + 1 ), NMAX, ZERO, C, NMAX, CT, G, CC,+ $ NMAX, EPS, ERR, FATAL, NOUT, .TRUE. )+ SAME = LZE( CC, CT, N )+ IF( .NOT.SAME.OR.ERR.NE.RZERO )THEN+ WRITE( NOUT, FMT = 9989 )TRANSA, TRANSB, SAME, ERR+ STOP+ END IF+*+* Test each subroutine in turn.+*+ DO 200 ISNUM = 1, NSUBS+ WRITE( NOUT, FMT = * )+ IF( .NOT.LTEST( ISNUM ) )THEN+* Subprogram is not to be tested.+ WRITE( NOUT, FMT = 9987 )SNAMES( ISNUM )+ ELSE+ SRNAMT = SNAMES( ISNUM )+* Test error exits.+ IF( TSTERR )THEN+ CALL ZCHKE( ISNUM, SNAMES( ISNUM ), NOUT )+ WRITE( NOUT, FMT = * )+ END IF+* Test computations.+ INFOT = 0+ OK = .TRUE.+ FATAL = .FALSE.+ GO TO ( 140, 150, 150, 160, 160, 170, 170,+ $ 180, 180 )ISNUM+* Test ZGEMM, 01.+ 140 CALL ZCHK1( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET,+ $ NMAX, AB, AA, AS, AB( 1, NMAX + 1 ), BB, BS, C,+ $ CC, CS, CT, G )+ GO TO 190+* Test ZHEMM, 02, ZSYMM, 03.+ 150 CALL ZCHK2( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET,+ $ NMAX, AB, AA, AS, AB( 1, NMAX + 1 ), BB, BS, C,+ $ CC, CS, CT, G )+ GO TO 190+* Test ZTRMM, 04, ZTRSM, 05.+ 160 CALL ZCHK3( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NMAX, AB,+ $ AA, AS, AB( 1, NMAX + 1 ), BB, BS, CT, G, C )+ GO TO 190+* Test ZHERK, 06, ZSYRK, 07.+ 170 CALL ZCHK4( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET,+ $ NMAX, AB, AA, AS, AB( 1, NMAX + 1 ), BB, BS, C,+ $ CC, CS, CT, G )+ GO TO 190+* Test ZHER2K, 08, ZSYR2K, 09.+ 180 CALL ZCHK5( SNAMES( ISNUM ), EPS, THRESH, NOUT, NTRA, TRACE,+ $ REWI, FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET,+ $ NMAX, AB, AA, AS, BB, BS, C, CC, CS, CT, G, W )+ GO TO 190+*+ 190 IF( FATAL.AND.SFATAL )+ $ GO TO 210+ END IF+ 200 CONTINUE+ WRITE( NOUT, FMT = 9986 )+ GO TO 230+*+ 210 CONTINUE+ WRITE( NOUT, FMT = 9985 )+ GO TO 230+*+ 220 CONTINUE+ WRITE( NOUT, FMT = 9991 )+*+ 230 CONTINUE+ IF( TRACE )+ $ CLOSE ( NTRA )+ CLOSE ( NOUT )+ STOP+*+ 9999 FORMAT( ' ROUTINES PASS COMPUTATIONAL TESTS IF TEST RATIO IS LES',+ $ 'S THAN', F8.2 )+ 9998 FORMAT( ' RELATIVE MACHINE PRECISION IS TAKEN TO BE', 1P, D9.1 )+ 9997 FORMAT( ' NUMBER OF VALUES OF ', A, ' IS LESS THAN 1 OR GREATER ',+ $ 'THAN ', I2 )+ 9996 FORMAT( ' VALUE OF N IS LESS THAN 0 OR GREATER THAN ', I2 )+ 9995 FORMAT( ' TESTS OF THE COMPLEX*16 LEVEL 3 BLAS', //' THE F',+ $ 'OLLOWING PARAMETER VALUES WILL BE USED:' )+ 9994 FORMAT( ' FOR N ', 9I6 )+ 9993 FORMAT( ' FOR ALPHA ',+ $ 7( '(', F4.1, ',', F4.1, ') ', : ) )+ 9992 FORMAT( ' FOR BETA ',+ $ 7( '(', F4.1, ',', F4.1, ') ', : ) )+ 9991 FORMAT( ' AMEND DATA FILE OR INCREASE ARRAY SIZES IN PROGRAM',+ $ /' ******* TESTS ABANDONED *******' )+ 9990 FORMAT( ' SUBPROGRAM NAME ', A6, ' NOT RECOGNIZED', /' ******* T',+ $ 'ESTS ABANDONED *******' )+ 9989 FORMAT( ' ERROR IN ZMMCH - IN-LINE DOT PRODUCTS ARE BEING EVALU',+ $ 'ATED WRONGLY.', /' ZMMCH WAS CALLED WITH TRANSA = ', A1,+ $ ' AND TRANSB = ', A1, /' AND RETURNED SAME = ', L1, ' AND ',+ $ 'ERR = ', F12.3, '.', /' THIS MAY BE DUE TO FAULTS IN THE ',+ $ 'ARITHMETIC OR THE COMPILER.', /' ******* TESTS ABANDONED ',+ $ '*******' )+ 9988 FORMAT( A6, L2 )+ 9987 FORMAT( 1X, A6, ' WAS NOT TESTED' )+ 9986 FORMAT( /' END OF TESTS' )+ 9985 FORMAT( /' ******* FATAL ERROR - TESTS ABANDONED *******' )+ 9984 FORMAT( ' ERROR-EXITS WILL NOT BE TESTED' )+*+* End of ZBLAT3.+*+ END+ SUBROUTINE ZCHK1( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET, NMAX,+ $ A, AA, AS, B, BB, BS, C, CC, CS, CT, G )+*+* Tests ZGEMM.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ COMPLEX*16 ZERO+ PARAMETER ( ZERO = ( 0.0D0, 0.0D0 ) )+ DOUBLE PRECISION RZERO+ PARAMETER ( RZERO = 0.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER NALF, NBET, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX*16 A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), B( NMAX, NMAX ),+ $ BB( NMAX*NMAX ), BET( NBET ), BS( NMAX*NMAX ),+ $ C( NMAX, NMAX ), CC( NMAX*NMAX ),+ $ CS( NMAX*NMAX ), CT( NMAX )+ DOUBLE PRECISION G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ COMPLEX*16 ALPHA, ALS, BETA, BLS+ DOUBLE PRECISION ERR, ERRMAX+ INTEGER I, IA, IB, ICA, ICB, IK, IM, IN, K, KS, LAA,+ $ LBB, LCC, LDA, LDAS, LDB, LDBS, LDC, LDCS, M,+ $ MA, MB, MS, N, NA, NARGS, NB, NC, NS+ LOGICAL NULL, RESET, SAME, TRANA, TRANB+ CHARACTER*1 TRANAS, TRANBS, TRANSA, TRANSB+ CHARACTER*3 ICH+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LZE, LZERES+ EXTERNAL LZE, LZERES+* .. External Subroutines ..+ EXTERNAL ZGEMM, ZMAKE, ZMMCH+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICH/'NTC'/+* .. Executable Statements ..+*+ NARGS = 13+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 110 IM = 1, NIDIM+ M = IDIM( IM )+*+ DO 100 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDC to 1 more than minimum value if room.+ LDC = M+ IF( LDC.LT.NMAX )+ $ LDC = LDC + 1+* Skip tests if not enough room.+ IF( LDC.GT.NMAX )+ $ GO TO 100+ LCC = LDC*N+ NULL = N.LE.0.OR.M.LE.0+*+ DO 90 IK = 1, NIDIM+ K = IDIM( IK )+*+ DO 80 ICA = 1, 3+ TRANSA = ICH( ICA: ICA )+ TRANA = TRANSA.EQ.'T'.OR.TRANSA.EQ.'C'+*+ IF( TRANA )THEN+ MA = K+ NA = M+ ELSE+ MA = M+ NA = K+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = MA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 80+ LAA = LDA*NA+*+* Generate the matrix A.+*+ CALL ZMAKE( 'GE', ' ', ' ', MA, NA, A, NMAX, AA, LDA,+ $ RESET, ZERO )+*+ DO 70 ICB = 1, 3+ TRANSB = ICH( ICB: ICB )+ TRANB = TRANSB.EQ.'T'.OR.TRANSB.EQ.'C'+*+ IF( TRANB )THEN+ MB = N+ NB = K+ ELSE+ MB = K+ NB = N+ END IF+* Set LDB to 1 more than minimum value if room.+ LDB = MB+ IF( LDB.LT.NMAX )+ $ LDB = LDB + 1+* Skip tests if not enough room.+ IF( LDB.GT.NMAX )+ $ GO TO 70+ LBB = LDB*NB+*+* Generate the matrix B.+*+ CALL ZMAKE( 'GE', ' ', ' ', MB, NB, B, NMAX, BB,+ $ LDB, RESET, ZERO )+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the matrix C.+*+ CALL ZMAKE( 'GE', ' ', ' ', M, N, C, NMAX,+ $ CC, LDC, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ TRANAS = TRANSA+ TRANBS = TRANSB+ MS = M+ NS = N+ KS = K+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LBB+ BS( I ) = BB( I )+ 20 CONTINUE+ LDBS = LDB+ BLS = BETA+ DO 30 I = 1, LCC+ CS( I ) = CC( I )+ 30 CONTINUE+ LDCS = LDC+*+* Call the subroutine.+*+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ TRANSA, TRANSB, M, N, K, ALPHA, LDA, LDB,+ $ BETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL ZGEMM( TRANSA, TRANSB, M, N, K, ALPHA,+ $ AA, LDA, BB, LDB, BETA, CC, LDC )+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9994 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = TRANSA.EQ.TRANAS+ ISAME( 2 ) = TRANSB.EQ.TRANBS+ ISAME( 3 ) = MS.EQ.M+ ISAME( 4 ) = NS.EQ.N+ ISAME( 5 ) = KS.EQ.K+ ISAME( 6 ) = ALS.EQ.ALPHA+ ISAME( 7 ) = LZE( AS, AA, LAA )+ ISAME( 8 ) = LDAS.EQ.LDA+ ISAME( 9 ) = LZE( BS, BB, LBB )+ ISAME( 10 ) = LDBS.EQ.LDB+ ISAME( 11 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 12 ) = LZE( CS, CC, LCC )+ ELSE+ ISAME( 12 ) = LZERES( 'GE', ' ', M, N, CS,+ $ CC, LDC )+ END IF+ ISAME( 13 ) = LDCS.EQ.LDC+*+* If data was incorrectly changed, report+* and return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result.+*+ CALL ZMMCH( TRANSA, TRANSB, M, N, K,+ $ ALPHA, A, NMAX, B, NMAX, BETA,+ $ C, NMAX, CT, G, CC, LDC, EPS,+ $ ERR, FATAL, NOUT, .TRUE. )+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 120+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9995 )NC, SNAME, TRANSA, TRANSB, M, N, K,+ $ ALPHA, LDA, LDB, BETA, LDC+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(''', A1, ''',''', A1, ''',',+ $ 3( I3, ',' ), '(', F4.1, ',', F4.1, '), A,', I3, ', B,', I3,+ $ ',(', F4.1, ',', F4.1, '), C,', I3, ').' )+ 9994 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of ZCHK1.+*+ END+ SUBROUTINE ZCHK2( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET, NMAX,+ $ A, AA, AS, B, BB, BS, C, CC, CS, CT, G )+*+* Tests ZHEMM and ZSYMM.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ COMPLEX*16 ZERO+ PARAMETER ( ZERO = ( 0.0D0, 0.0D0 ) )+ DOUBLE PRECISION RZERO+ PARAMETER ( RZERO = 0.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER NALF, NBET, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX*16 A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), B( NMAX, NMAX ),+ $ BB( NMAX*NMAX ), BET( NBET ), BS( NMAX*NMAX ),+ $ C( NMAX, NMAX ), CC( NMAX*NMAX ),+ $ CS( NMAX*NMAX ), CT( NMAX )+ DOUBLE PRECISION G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ COMPLEX*16 ALPHA, ALS, BETA, BLS+ DOUBLE PRECISION ERR, ERRMAX+ INTEGER I, IA, IB, ICS, ICU, IM, IN, LAA, LBB, LCC,+ $ LDA, LDAS, LDB, LDBS, LDC, LDCS, M, MS, N, NA,+ $ NARGS, NC, NS+ LOGICAL CONJ, LEFT, NULL, RESET, SAME+ CHARACTER*1 SIDE, SIDES, UPLO, UPLOS+ CHARACTER*2 ICHS, ICHU+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LZE, LZERES+ EXTERNAL LZE, LZERES+* .. External Subroutines ..+ EXTERNAL ZHEMM, ZMAKE, ZMMCH, ZSYMM+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHS/'LR'/, ICHU/'UL'/+* .. Executable Statements ..+ CONJ = SNAME( 2: 3 ).EQ.'HE'+*+ NARGS = 12+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 100 IM = 1, NIDIM+ M = IDIM( IM )+*+ DO 90 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDC to 1 more than minimum value if room.+ LDC = M+ IF( LDC.LT.NMAX )+ $ LDC = LDC + 1+* Skip tests if not enough room.+ IF( LDC.GT.NMAX )+ $ GO TO 90+ LCC = LDC*N+ NULL = N.LE.0.OR.M.LE.0+* Set LDB to 1 more than minimum value if room.+ LDB = M+ IF( LDB.LT.NMAX )+ $ LDB = LDB + 1+* Skip tests if not enough room.+ IF( LDB.GT.NMAX )+ $ GO TO 90+ LBB = LDB*N+*+* Generate the matrix B.+*+ CALL ZMAKE( 'GE', ' ', ' ', M, N, B, NMAX, BB, LDB, RESET,+ $ ZERO )+*+ DO 80 ICS = 1, 2+ SIDE = ICHS( ICS: ICS )+ LEFT = SIDE.EQ.'L'+*+ IF( LEFT )THEN+ NA = M+ ELSE+ NA = N+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = NA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 80+ LAA = LDA*NA+*+ DO 70 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+*+* Generate the hermitian or symmetric matrix A.+*+ CALL ZMAKE( SNAME( 2: 3 ), UPLO, ' ', NA, NA, A, NMAX,+ $ AA, LDA, RESET, ZERO )+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+*+* Generate the matrix C.+*+ CALL ZMAKE( 'GE', ' ', ' ', M, N, C, NMAX, CC,+ $ LDC, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ SIDES = SIDE+ UPLOS = UPLO+ MS = M+ NS = N+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LBB+ BS( I ) = BB( I )+ 20 CONTINUE+ LDBS = LDB+ BLS = BETA+ DO 30 I = 1, LCC+ CS( I ) = CC( I )+ 30 CONTINUE+ LDCS = LDC+*+* Call the subroutine.+*+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME, SIDE,+ $ UPLO, M, N, ALPHA, LDA, LDB, BETA, LDC+ IF( REWI )+ $ REWIND NTRA+ IF( CONJ )THEN+ CALL ZHEMM( SIDE, UPLO, M, N, ALPHA, AA, LDA,+ $ BB, LDB, BETA, CC, LDC )+ ELSE+ CALL ZSYMM( SIDE, UPLO, M, N, ALPHA, AA, LDA,+ $ BB, LDB, BETA, CC, LDC )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9994 )+ FATAL = .TRUE.+ GO TO 110+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = SIDES.EQ.SIDE+ ISAME( 2 ) = UPLOS.EQ.UPLO+ ISAME( 3 ) = MS.EQ.M+ ISAME( 4 ) = NS.EQ.N+ ISAME( 5 ) = ALS.EQ.ALPHA+ ISAME( 6 ) = LZE( AS, AA, LAA )+ ISAME( 7 ) = LDAS.EQ.LDA+ ISAME( 8 ) = LZE( BS, BB, LBB )+ ISAME( 9 ) = LDBS.EQ.LDB+ ISAME( 10 ) = BLS.EQ.BETA+ IF( NULL )THEN+ ISAME( 11 ) = LZE( CS, CC, LCC )+ ELSE+ ISAME( 11 ) = LZERES( 'GE', ' ', M, N, CS,+ $ CC, LDC )+ END IF+ ISAME( 12 ) = LDCS.EQ.LDC+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 110+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result.+*+ IF( LEFT )THEN+ CALL ZMMCH( 'N', 'N', M, N, M, ALPHA, A,+ $ NMAX, B, NMAX, BETA, C, NMAX,+ $ CT, G, CC, LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ELSE+ CALL ZMMCH( 'N', 'N', M, N, N, ALPHA, B,+ $ NMAX, A, NMAX, BETA, C, NMAX,+ $ CT, G, CC, LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 110+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 120+*+ 110 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9995 )NC, SNAME, SIDE, UPLO, M, N, ALPHA, LDA,+ $ LDB, BETA, LDC+*+ 120 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(', 2( '''', A1, ''',' ), 2( I3, ',' ),+ $ '(', F4.1, ',', F4.1, '), A,', I3, ', B,', I3, ',(', F4.1,+ $ ',', F4.1, '), C,', I3, ') .' )+ 9994 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of ZCHK2.+*+ END+ SUBROUTINE ZCHK3( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NMAX, A, AA, AS,+ $ B, BB, BS, CT, G, C )+*+* Tests ZTRMM and ZTRSM.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ COMPLEX*16 ZERO, ONE+ PARAMETER ( ZERO = ( 0.0D0, 0.0D0 ),+ $ ONE = ( 1.0D0, 0.0D0 ) )+ DOUBLE PRECISION RZERO+ PARAMETER ( RZERO = 0.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER NALF, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX*16 A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), B( NMAX, NMAX ),+ $ BB( NMAX*NMAX ), BS( NMAX*NMAX ),+ $ C( NMAX, NMAX ), CT( NMAX )+ DOUBLE PRECISION G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ COMPLEX*16 ALPHA, ALS+ DOUBLE PRECISION ERR, ERRMAX+ INTEGER I, IA, ICD, ICS, ICT, ICU, IM, IN, J, LAA, LBB,+ $ LDA, LDAS, LDB, LDBS, M, MS, N, NA, NARGS, NC,+ $ NS+ LOGICAL LEFT, NULL, RESET, SAME+ CHARACTER*1 DIAG, DIAGS, SIDE, SIDES, TRANAS, TRANSA, UPLO,+ $ UPLOS+ CHARACTER*2 ICHD, ICHS, ICHU+ CHARACTER*3 ICHT+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LZE, LZERES+ EXTERNAL LZE, LZERES+* .. External Subroutines ..+ EXTERNAL ZMAKE, ZMMCH, ZTRMM, ZTRSM+* .. Intrinsic Functions ..+ INTRINSIC MAX+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHU/'UL'/, ICHT/'NTC'/, ICHD/'UN'/, ICHS/'LR'/+* .. Executable Statements ..+*+ NARGS = 11+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+* Set up zero matrix for ZMMCH.+ DO 20 J = 1, NMAX+ DO 10 I = 1, NMAX+ C( I, J ) = ZERO+ 10 CONTINUE+ 20 CONTINUE+*+ DO 140 IM = 1, NIDIM+ M = IDIM( IM )+*+ DO 130 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDB to 1 more than minimum value if room.+ LDB = M+ IF( LDB.LT.NMAX )+ $ LDB = LDB + 1+* Skip tests if not enough room.+ IF( LDB.GT.NMAX )+ $ GO TO 130+ LBB = LDB*N+ NULL = M.LE.0.OR.N.LE.0+*+ DO 120 ICS = 1, 2+ SIDE = ICHS( ICS: ICS )+ LEFT = SIDE.EQ.'L'+ IF( LEFT )THEN+ NA = M+ ELSE+ NA = N+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = NA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 130+ LAA = LDA*NA+*+ DO 110 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+*+ DO 100 ICT = 1, 3+ TRANSA = ICHT( ICT: ICT )+*+ DO 90 ICD = 1, 2+ DIAG = ICHD( ICD: ICD )+*+ DO 80 IA = 1, NALF+ ALPHA = ALF( IA )+*+* Generate the matrix A.+*+ CALL ZMAKE( 'TR', UPLO, DIAG, NA, NA, A,+ $ NMAX, AA, LDA, RESET, ZERO )+*+* Generate the matrix B.+*+ CALL ZMAKE( 'GE', ' ', ' ', M, N, B, NMAX,+ $ BB, LDB, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the+* subroutine.+*+ SIDES = SIDE+ UPLOS = UPLO+ TRANAS = TRANSA+ DIAGS = DIAG+ MS = M+ NS = N+ ALS = ALPHA+ DO 30 I = 1, LAA+ AS( I ) = AA( I )+ 30 CONTINUE+ LDAS = LDA+ DO 40 I = 1, LBB+ BS( I ) = BB( I )+ 40 CONTINUE+ LDBS = LDB+*+* Call the subroutine.+*+ IF( SNAME( 4: 5 ).EQ.'MM' )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA,+ $ LDA, LDB+ IF( REWI )+ $ REWIND NTRA+ CALL ZTRMM( SIDE, UPLO, TRANSA, DIAG, M,+ $ N, ALPHA, AA, LDA, BB, LDB )+ ELSE IF( SNAME( 4: 5 ).EQ.'SM' )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9995 )NC, SNAME,+ $ SIDE, UPLO, TRANSA, DIAG, M, N, ALPHA,+ $ LDA, LDB+ IF( REWI )+ $ REWIND NTRA+ CALL ZTRSM( SIDE, UPLO, TRANSA, DIAG, M,+ $ N, ALPHA, AA, LDA, BB, LDB )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9994 )+ FATAL = .TRUE.+ GO TO 150+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = SIDES.EQ.SIDE+ ISAME( 2 ) = UPLOS.EQ.UPLO+ ISAME( 3 ) = TRANAS.EQ.TRANSA+ ISAME( 4 ) = DIAGS.EQ.DIAG+ ISAME( 5 ) = MS.EQ.M+ ISAME( 6 ) = NS.EQ.N+ ISAME( 7 ) = ALS.EQ.ALPHA+ ISAME( 8 ) = LZE( AS, AA, LAA )+ ISAME( 9 ) = LDAS.EQ.LDA+ IF( NULL )THEN+ ISAME( 10 ) = LZE( BS, BB, LBB )+ ELSE+ ISAME( 10 ) = LZERES( 'GE', ' ', M, N, BS,+ $ BB, LDB )+ END IF+ ISAME( 11 ) = LDBS.EQ.LDB+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 50 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 50 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 150+ END IF+*+ IF( .NOT.NULL )THEN+ IF( SNAME( 4: 5 ).EQ.'MM' )THEN+*+* Check the result.+*+ IF( LEFT )THEN+ CALL ZMMCH( TRANSA, 'N', M, N, M,+ $ ALPHA, A, NMAX, B, NMAX,+ $ ZERO, C, NMAX, CT, G,+ $ BB, LDB, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ELSE+ CALL ZMMCH( 'N', TRANSA, M, N, N,+ $ ALPHA, B, NMAX, A, NMAX,+ $ ZERO, C, NMAX, CT, G,+ $ BB, LDB, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ END IF+ ELSE IF( SNAME( 4: 5 ).EQ.'SM' )THEN+*+* Compute approximation to original+* matrix.+*+ DO 70 J = 1, N+ DO 60 I = 1, M+ C( I, J ) = BB( I + ( J - 1 )*+ $ LDB )+ BB( I + ( J - 1 )*LDB ) = ALPHA*+ $ B( I, J )+ 60 CONTINUE+ 70 CONTINUE+*+ IF( LEFT )THEN+ CALL ZMMCH( TRANSA, 'N', M, N, M,+ $ ONE, A, NMAX, C, NMAX,+ $ ZERO, B, NMAX, CT, G,+ $ BB, LDB, EPS, ERR,+ $ FATAL, NOUT, .FALSE. )+ ELSE+ CALL ZMMCH( 'N', TRANSA, M, N, N,+ $ ONE, C, NMAX, A, NMAX,+ $ ZERO, B, NMAX, CT, G,+ $ BB, LDB, EPS, ERR,+ $ FATAL, NOUT, .FALSE. )+ END IF+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 150+ END IF+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+ 130 CONTINUE+*+ 140 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 160+*+ 150 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ WRITE( NOUT, FMT = 9995 )NC, SNAME, SIDE, UPLO, TRANSA, DIAG, M,+ $ N, ALPHA, LDA, LDB+*+ 160 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( 1X, I6, ': ', A6, '(', 4( '''', A1, ''',' ), 2( I3, ',' ),+ $ '(', F4.1, ',', F4.1, '), A,', I3, ', B,', I3, ') ',+ $ ' .' )+ 9994 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of ZCHK3.+*+ END+ SUBROUTINE ZCHK4( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET, NMAX,+ $ A, AA, AS, B, BB, BS, C, CC, CS, CT, G )+*+* Tests ZHERK and ZSYRK.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ COMPLEX*16 ZERO+ PARAMETER ( ZERO = ( 0.0D0, 0.0D0 ) )+ DOUBLE PRECISION RONE, RZERO+ PARAMETER ( RONE = 1.0D0, RZERO = 0.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER NALF, NBET, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX*16 A( NMAX, NMAX ), AA( NMAX*NMAX ), ALF( NALF ),+ $ AS( NMAX*NMAX ), B( NMAX, NMAX ),+ $ BB( NMAX*NMAX ), BET( NBET ), BS( NMAX*NMAX ),+ $ C( NMAX, NMAX ), CC( NMAX*NMAX ),+ $ CS( NMAX*NMAX ), CT( NMAX )+ DOUBLE PRECISION G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ COMPLEX*16 ALPHA, ALS, BETA, BETS+ DOUBLE PRECISION ERR, ERRMAX, RALPHA, RALS, RBETA, RBETS+ INTEGER I, IA, IB, ICT, ICU, IK, IN, J, JC, JJ, K, KS,+ $ LAA, LCC, LDA, LDAS, LDC, LDCS, LJ, MA, N, NA,+ $ NARGS, NC, NS+ LOGICAL CONJ, NULL, RESET, SAME, TRAN, UPPER+ CHARACTER*1 TRANS, TRANSS, TRANST, UPLO, UPLOS+ CHARACTER*2 ICHT, ICHU+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LZE, LZERES+ EXTERNAL LZE, LZERES+* .. External Subroutines ..+ EXTERNAL ZHERK, ZMAKE, ZMMCH, ZSYRK+* .. Intrinsic Functions ..+ INTRINSIC DCMPLX, MAX, DBLE+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHT/'NC'/, ICHU/'UL'/+* .. Executable Statements ..+ CONJ = SNAME( 2: 3 ).EQ.'HE'+*+ NARGS = 10+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 100 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDC to 1 more than minimum value if room.+ LDC = N+ IF( LDC.LT.NMAX )+ $ LDC = LDC + 1+* Skip tests if not enough room.+ IF( LDC.GT.NMAX )+ $ GO TO 100+ LCC = LDC*N+*+ DO 90 IK = 1, NIDIM+ K = IDIM( IK )+*+ DO 80 ICT = 1, 2+ TRANS = ICHT( ICT: ICT )+ TRAN = TRANS.EQ.'C'+ IF( TRAN.AND..NOT.CONJ )+ $ TRANS = 'T'+ IF( TRAN )THEN+ MA = K+ NA = N+ ELSE+ MA = N+ NA = K+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = MA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 80+ LAA = LDA*NA+*+* Generate the matrix A.+*+ CALL ZMAKE( 'GE', ' ', ' ', MA, NA, A, NMAX, AA, LDA,+ $ RESET, ZERO )+*+ DO 70 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+ UPPER = UPLO.EQ.'U'+*+ DO 60 IA = 1, NALF+ ALPHA = ALF( IA )+ IF( CONJ )THEN+ RALPHA = DBLE( ALPHA )+ ALPHA = DCMPLX( RALPHA, RZERO )+ END IF+*+ DO 50 IB = 1, NBET+ BETA = BET( IB )+ IF( CONJ )THEN+ RBETA = DBLE( BETA )+ BETA = DCMPLX( RBETA, RZERO )+ END IF+ NULL = N.LE.0+ IF( CONJ )+ $ NULL = NULL.OR.( ( K.LE.0.OR.RALPHA.EQ.+ $ RZERO ).AND.RBETA.EQ.RONE )+*+* Generate the matrix C.+*+ CALL ZMAKE( SNAME( 2: 3 ), UPLO, ' ', N, N, C,+ $ NMAX, CC, LDC, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ TRANSS = TRANS+ NS = N+ KS = K+ IF( CONJ )THEN+ RALS = RALPHA+ ELSE+ ALS = ALPHA+ END IF+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ IF( CONJ )THEN+ RBETS = RBETA+ ELSE+ BETS = BETA+ END IF+ DO 20 I = 1, LCC+ CS( I ) = CC( I )+ 20 CONTINUE+ LDCS = LDC+*+* Call the subroutine.+*+ IF( CONJ )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, UPLO,+ $ TRANS, N, K, RALPHA, LDA, RBETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL ZHERK( UPLO, TRANS, N, K, RALPHA, AA,+ $ LDA, RBETA, CC, LDC )+ ELSE+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME, UPLO,+ $ TRANS, N, K, ALPHA, LDA, BETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL ZSYRK( UPLO, TRANS, N, K, ALPHA, AA,+ $ LDA, BETA, CC, LDC )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 120+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLOS.EQ.UPLO+ ISAME( 2 ) = TRANSS.EQ.TRANS+ ISAME( 3 ) = NS.EQ.N+ ISAME( 4 ) = KS.EQ.K+ IF( CONJ )THEN+ ISAME( 5 ) = RALS.EQ.RALPHA+ ELSE+ ISAME( 5 ) = ALS.EQ.ALPHA+ END IF+ ISAME( 6 ) = LZE( AS, AA, LAA )+ ISAME( 7 ) = LDAS.EQ.LDA+ IF( CONJ )THEN+ ISAME( 8 ) = RBETS.EQ.RBETA+ ELSE+ ISAME( 8 ) = BETS.EQ.BETA+ END IF+ IF( NULL )THEN+ ISAME( 9 ) = LZE( CS, CC, LCC )+ ELSE+ ISAME( 9 ) = LZERES( SNAME( 2: 3 ), UPLO, N,+ $ N, CS, CC, LDC )+ END IF+ ISAME( 10 ) = LDCS.EQ.LDC+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 30 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 30 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 120+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ IF( CONJ )THEN+ TRANST = 'C'+ ELSE+ TRANST = 'T'+ END IF+ JC = 1+ DO 40 J = 1, N+ IF( UPPER )THEN+ JJ = 1+ LJ = J+ ELSE+ JJ = J+ LJ = N - J + 1+ END IF+ IF( TRAN )THEN+ CALL ZMMCH( TRANST, 'N', LJ, 1, K,+ $ ALPHA, A( 1, JJ ), NMAX,+ $ A( 1, J ), NMAX, BETA,+ $ C( JJ, J ), NMAX, CT, G,+ $ CC( JC ), LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ ELSE+ CALL ZMMCH( 'N', TRANST, LJ, 1, K,+ $ ALPHA, A( JJ, 1 ), NMAX,+ $ A( J, 1 ), NMAX, BETA,+ $ C( JJ, J ), NMAX, CT, G,+ $ CC( JC ), LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ END IF+ IF( UPPER )THEN+ JC = JC + LDC+ ELSE+ JC = JC + LDC + 1+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 110+ 40 CONTINUE+ END IF+*+ 50 CONTINUE+*+ 60 CONTINUE+*+ 70 CONTINUE+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 130+*+ 110 CONTINUE+ IF( N.GT.1 )+ $ WRITE( NOUT, FMT = 9995 )J+*+ 120 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( CONJ )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, TRANS, N, K, RALPHA,+ $ LDA, RBETA, LDC+ ELSE+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, TRANS, N, K, ALPHA,+ $ LDA, BETA, LDC+ END IF+*+ 130 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(', 2( '''', A1, ''',' ), 2( I3, ',' ),+ $ F4.1, ', A,', I3, ',', F4.1, ', C,', I3, ') ',+ $ ' .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(', 2( '''', A1, ''',' ), 2( I3, ',' ),+ $ '(', F4.1, ',', F4.1, ') , A,', I3, ',(', F4.1, ',', F4.1,+ $ '), C,', I3, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of ZCHK4.+*+ END+ SUBROUTINE ZCHK5( SNAME, EPS, THRESH, NOUT, NTRA, TRACE, REWI,+ $ FATAL, NIDIM, IDIM, NALF, ALF, NBET, BET, NMAX,+ $ AB, AA, AS, BB, BS, C, CC, CS, CT, G, W )+*+* Tests ZHER2K and ZSYR2K.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ COMPLEX*16 ZERO, ONE+ PARAMETER ( ZERO = ( 0.0D0, 0.0D0 ),+ $ ONE = ( 1.0D0, 0.0D0 ) )+ DOUBLE PRECISION RONE, RZERO+ PARAMETER ( RONE = 1.0D0, RZERO = 0.0D0 )+* .. Scalar Arguments ..+ DOUBLE PRECISION EPS, THRESH+ INTEGER NALF, NBET, NIDIM, NMAX, NOUT, NTRA+ LOGICAL FATAL, REWI, TRACE+ CHARACTER*6 SNAME+* .. Array Arguments ..+ COMPLEX*16 AA( NMAX*NMAX ), AB( 2*NMAX*NMAX ),+ $ ALF( NALF ), AS( NMAX*NMAX ), BB( NMAX*NMAX ),+ $ BET( NBET ), BS( NMAX*NMAX ), C( NMAX, NMAX ),+ $ CC( NMAX*NMAX ), CS( NMAX*NMAX ), CT( NMAX ),+ $ W( 2*NMAX )+ DOUBLE PRECISION G( NMAX )+ INTEGER IDIM( NIDIM )+* .. Local Scalars ..+ COMPLEX*16 ALPHA, ALS, BETA, BETS+ DOUBLE PRECISION ERR, ERRMAX, RBETA, RBETS+ INTEGER I, IA, IB, ICT, ICU, IK, IN, J, JC, JJ, JJAB,+ $ K, KS, LAA, LBB, LCC, LDA, LDAS, LDB, LDBS,+ $ LDC, LDCS, LJ, MA, N, NA, NARGS, NC, NS+ LOGICAL CONJ, NULL, RESET, SAME, TRAN, UPPER+ CHARACTER*1 TRANS, TRANSS, TRANST, UPLO, UPLOS+ CHARACTER*2 ICHT, ICHU+* .. Local Arrays ..+ LOGICAL ISAME( 13 )+* .. External Functions ..+ LOGICAL LZE, LZERES+ EXTERNAL LZE, LZERES+* .. External Subroutines ..+ EXTERNAL ZHER2K, ZMAKE, ZMMCH, ZSYR2K+* .. Intrinsic Functions ..+ INTRINSIC DCMPLX, DCONJG, MAX, DBLE+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Data statements ..+ DATA ICHT/'NC'/, ICHU/'UL'/+* .. Executable Statements ..+ CONJ = SNAME( 2: 3 ).EQ.'HE'+*+ NARGS = 12+ NC = 0+ RESET = .TRUE.+ ERRMAX = RZERO+*+ DO 130 IN = 1, NIDIM+ N = IDIM( IN )+* Set LDC to 1 more than minimum value if room.+ LDC = N+ IF( LDC.LT.NMAX )+ $ LDC = LDC + 1+* Skip tests if not enough room.+ IF( LDC.GT.NMAX )+ $ GO TO 130+ LCC = LDC*N+*+ DO 120 IK = 1, NIDIM+ K = IDIM( IK )+*+ DO 110 ICT = 1, 2+ TRANS = ICHT( ICT: ICT )+ TRAN = TRANS.EQ.'C'+ IF( TRAN.AND..NOT.CONJ )+ $ TRANS = 'T'+ IF( TRAN )THEN+ MA = K+ NA = N+ ELSE+ MA = N+ NA = K+ END IF+* Set LDA to 1 more than minimum value if room.+ LDA = MA+ IF( LDA.LT.NMAX )+ $ LDA = LDA + 1+* Skip tests if not enough room.+ IF( LDA.GT.NMAX )+ $ GO TO 110+ LAA = LDA*NA+*+* Generate the matrix A.+*+ IF( TRAN )THEN+ CALL ZMAKE( 'GE', ' ', ' ', MA, NA, AB, 2*NMAX, AA,+ $ LDA, RESET, ZERO )+ ELSE+ CALL ZMAKE( 'GE', ' ', ' ', MA, NA, AB, NMAX, AA, LDA,+ $ RESET, ZERO )+ END IF+*+* Generate the matrix B.+*+ LDB = LDA+ LBB = LAA+ IF( TRAN )THEN+ CALL ZMAKE( 'GE', ' ', ' ', MA, NA, AB( K + 1 ),+ $ 2*NMAX, BB, LDB, RESET, ZERO )+ ELSE+ CALL ZMAKE( 'GE', ' ', ' ', MA, NA, AB( K*NMAX + 1 ),+ $ NMAX, BB, LDB, RESET, ZERO )+ END IF+*+ DO 100 ICU = 1, 2+ UPLO = ICHU( ICU: ICU )+ UPPER = UPLO.EQ.'U'+*+ DO 90 IA = 1, NALF+ ALPHA = ALF( IA )+*+ DO 80 IB = 1, NBET+ BETA = BET( IB )+ IF( CONJ )THEN+ RBETA = DBLE( BETA )+ BETA = DCMPLX( RBETA, RZERO )+ END IF+ NULL = N.LE.0+ IF( CONJ )+ $ NULL = NULL.OR.( ( K.LE.0.OR.ALPHA.EQ.+ $ ZERO ).AND.RBETA.EQ.RONE )+*+* Generate the matrix C.+*+ CALL ZMAKE( SNAME( 2: 3 ), UPLO, ' ', N, N, C,+ $ NMAX, CC, LDC, RESET, ZERO )+*+ NC = NC + 1+*+* Save every datum before calling the subroutine.+*+ UPLOS = UPLO+ TRANSS = TRANS+ NS = N+ KS = K+ ALS = ALPHA+ DO 10 I = 1, LAA+ AS( I ) = AA( I )+ 10 CONTINUE+ LDAS = LDA+ DO 20 I = 1, LBB+ BS( I ) = BB( I )+ 20 CONTINUE+ LDBS = LDB+ IF( CONJ )THEN+ RBETS = RBETA+ ELSE+ BETS = BETA+ END IF+ DO 30 I = 1, LCC+ CS( I ) = CC( I )+ 30 CONTINUE+ LDCS = LDC+*+* Call the subroutine.+*+ IF( CONJ )THEN+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9994 )NC, SNAME, UPLO,+ $ TRANS, N, K, ALPHA, LDA, LDB, RBETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL ZHER2K( UPLO, TRANS, N, K, ALPHA, AA,+ $ LDA, BB, LDB, RBETA, CC, LDC )+ ELSE+ IF( TRACE )+ $ WRITE( NTRA, FMT = 9993 )NC, SNAME, UPLO,+ $ TRANS, N, K, ALPHA, LDA, LDB, BETA, LDC+ IF( REWI )+ $ REWIND NTRA+ CALL ZSYR2K( UPLO, TRANS, N, K, ALPHA, AA,+ $ LDA, BB, LDB, BETA, CC, LDC )+ END IF+*+* Check if error-exit was taken incorrectly.+*+ IF( .NOT.OK )THEN+ WRITE( NOUT, FMT = 9992 )+ FATAL = .TRUE.+ GO TO 150+ END IF+*+* See what data changed inside subroutines.+*+ ISAME( 1 ) = UPLOS.EQ.UPLO+ ISAME( 2 ) = TRANSS.EQ.TRANS+ ISAME( 3 ) = NS.EQ.N+ ISAME( 4 ) = KS.EQ.K+ ISAME( 5 ) = ALS.EQ.ALPHA+ ISAME( 6 ) = LZE( AS, AA, LAA )+ ISAME( 7 ) = LDAS.EQ.LDA+ ISAME( 8 ) = LZE( BS, BB, LBB )+ ISAME( 9 ) = LDBS.EQ.LDB+ IF( CONJ )THEN+ ISAME( 10 ) = RBETS.EQ.RBETA+ ELSE+ ISAME( 10 ) = BETS.EQ.BETA+ END IF+ IF( NULL )THEN+ ISAME( 11 ) = LZE( CS, CC, LCC )+ ELSE+ ISAME( 11 ) = LZERES( 'HE', UPLO, N, N, CS,+ $ CC, LDC )+ END IF+ ISAME( 12 ) = LDCS.EQ.LDC+*+* If data was incorrectly changed, report and+* return.+*+ SAME = .TRUE.+ DO 40 I = 1, NARGS+ SAME = SAME.AND.ISAME( I )+ IF( .NOT.ISAME( I ) )+ $ WRITE( NOUT, FMT = 9998 )I+ 40 CONTINUE+ IF( .NOT.SAME )THEN+ FATAL = .TRUE.+ GO TO 150+ END IF+*+ IF( .NOT.NULL )THEN+*+* Check the result column by column.+*+ IF( CONJ )THEN+ TRANST = 'C'+ ELSE+ TRANST = 'T'+ END IF+ JJAB = 1+ JC = 1+ DO 70 J = 1, N+ IF( UPPER )THEN+ JJ = 1+ LJ = J+ ELSE+ JJ = J+ LJ = N - J + 1+ END IF+ IF( TRAN )THEN+ DO 50 I = 1, K+ W( I ) = ALPHA*AB( ( J - 1 )*2*+ $ NMAX + K + I )+ IF( CONJ )THEN+ W( K + I ) = DCONJG( ALPHA )*+ $ AB( ( J - 1 )*2*+ $ NMAX + I )+ ELSE+ W( K + I ) = ALPHA*+ $ AB( ( J - 1 )*2*+ $ NMAX + I )+ END IF+ 50 CONTINUE+ CALL ZMMCH( TRANST, 'N', LJ, 1, 2*K,+ $ ONE, AB( JJAB ), 2*NMAX, W,+ $ 2*NMAX, BETA, C( JJ, J ),+ $ NMAX, CT, G, CC( JC ), LDC,+ $ EPS, ERR, FATAL, NOUT,+ $ .TRUE. )+ ELSE+ DO 60 I = 1, K+ IF( CONJ )THEN+ W( I ) = ALPHA*DCONJG( AB( ( K ++ $ I - 1 )*NMAX + J ) )+ W( K + I ) = DCONJG( ALPHA*+ $ AB( ( I - 1 )*NMAX ++ $ J ) )+ ELSE+ W( I ) = ALPHA*AB( ( K + I - 1 )*+ $ NMAX + J )+ W( K + I ) = ALPHA*+ $ AB( ( I - 1 )*NMAX ++ $ J )+ END IF+ 60 CONTINUE+ CALL ZMMCH( 'N', 'N', LJ, 1, 2*K, ONE,+ $ AB( JJ ), NMAX, W, 2*NMAX,+ $ BETA, C( JJ, J ), NMAX, CT,+ $ G, CC( JC ), LDC, EPS, ERR,+ $ FATAL, NOUT, .TRUE. )+ END IF+ IF( UPPER )THEN+ JC = JC + LDC+ ELSE+ JC = JC + LDC + 1+ IF( TRAN )+ $ JJAB = JJAB + 2*NMAX+ END IF+ ERRMAX = MAX( ERRMAX, ERR )+* If got really bad answer, report and+* return.+ IF( FATAL )+ $ GO TO 140+ 70 CONTINUE+ END IF+*+ 80 CONTINUE+*+ 90 CONTINUE+*+ 100 CONTINUE+*+ 110 CONTINUE+*+ 120 CONTINUE+*+ 130 CONTINUE+*+* Report result.+*+ IF( ERRMAX.LT.THRESH )THEN+ WRITE( NOUT, FMT = 9999 )SNAME, NC+ ELSE+ WRITE( NOUT, FMT = 9997 )SNAME, NC, ERRMAX+ END IF+ GO TO 160+*+ 140 CONTINUE+ IF( N.GT.1 )+ $ WRITE( NOUT, FMT = 9995 )J+*+ 150 CONTINUE+ WRITE( NOUT, FMT = 9996 )SNAME+ IF( CONJ )THEN+ WRITE( NOUT, FMT = 9994 )NC, SNAME, UPLO, TRANS, N, K, ALPHA,+ $ LDA, LDB, RBETA, LDC+ ELSE+ WRITE( NOUT, FMT = 9993 )NC, SNAME, UPLO, TRANS, N, K, ALPHA,+ $ LDA, LDB, BETA, LDC+ END IF+*+ 160 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE COMPUTATIONAL TESTS (', I6, ' CALL',+ $ 'S)' )+ 9998 FORMAT( ' ******* FATAL ERROR - PARAMETER NUMBER ', I2, ' WAS CH',+ $ 'ANGED INCORRECTLY *******' )+ 9997 FORMAT( ' ', A6, ' COMPLETED THE COMPUTATIONAL TESTS (', I6, ' C',+ $ 'ALLS)', /' ******* BUT WITH MAXIMUM TEST RATIO', F8.2,+ $ ' - SUSPECT *******' )+ 9996 FORMAT( ' ******* ', A6, ' FAILED ON CALL NUMBER:' )+ 9995 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+ 9994 FORMAT( 1X, I6, ': ', A6, '(', 2( '''', A1, ''',' ), 2( I3, ',' ),+ $ '(', F4.1, ',', F4.1, '), A,', I3, ', B,', I3, ',', F4.1,+ $ ', C,', I3, ') .' )+ 9993 FORMAT( 1X, I6, ': ', A6, '(', 2( '''', A1, ''',' ), 2( I3, ',' ),+ $ '(', F4.1, ',', F4.1, '), A,', I3, ', B,', I3, ',(', F4.1,+ $ ',', F4.1, '), C,', I3, ') .' )+ 9992 FORMAT( ' ******* FATAL ERROR - ERROR-EXIT TAKEN ON VALID CALL *',+ $ '******' )+*+* End of ZCHK5.+*+ END+ SUBROUTINE ZCHKE( ISNUM, SRNAMT, NOUT )+*+* Tests the error exits from the Level 3 Blas.+* Requires a special version of the error-handling routine XERBLA.+* ALPHA, RALPHA, BETA, RBETA, A, B and C should not need to be defined.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER ISNUM, NOUT+ CHARACTER*6 SRNAMT+* .. Scalars in Common ..+ INTEGER INFOT, NOUTC+ LOGICAL LERR, OK+* .. Local Scalars ..+ COMPLEX*16 ALPHA, BETA+ DOUBLE PRECISION RALPHA, RBETA+* .. Local Arrays ..+ COMPLEX*16 A( 2, 1 ), B( 2, 1 ), C( 2, 1 )+* .. External Subroutines ..+ EXTERNAL ZGEMM, ZHEMM, ZHER2K, ZHERK, CHKXER, ZSYMM,+ $ ZSYR2K, ZSYRK, ZTRMM, ZTRSM+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUTC, OK, LERR+* .. Executable Statements ..+* OK is set to .FALSE. by the special version of XERBLA or by CHKXER+* if anything is wrong.+ OK = .TRUE.+* LERR is set to .TRUE. by the special version of XERBLA each time+* it is called, and is then tested and re-set by CHKXER.+ LERR = .FALSE.+ GO TO ( 10, 20, 30, 40, 50, 60, 70, 80,+ $ 90 )ISNUM+ 10 INFOT = 1+ CALL ZGEMM( '/', 'N', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 1+ CALL ZGEMM( '/', 'C', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 1+ CALL ZGEMM( '/', 'T', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZGEMM( 'N', '/', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZGEMM( 'C', '/', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZGEMM( 'T', '/', 0, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZGEMM( 'N', 'N', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZGEMM( 'N', 'C', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZGEMM( 'N', 'T', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZGEMM( 'C', 'N', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZGEMM( 'C', 'C', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZGEMM( 'C', 'T', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZGEMM( 'T', 'N', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZGEMM( 'T', 'C', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZGEMM( 'T', 'T', -1, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZGEMM( 'N', 'N', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZGEMM( 'N', 'C', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZGEMM( 'N', 'T', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZGEMM( 'C', 'N', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZGEMM( 'C', 'C', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZGEMM( 'C', 'T', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZGEMM( 'T', 'N', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZGEMM( 'T', 'C', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZGEMM( 'T', 'T', 0, -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZGEMM( 'N', 'N', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZGEMM( 'N', 'C', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZGEMM( 'N', 'T', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZGEMM( 'C', 'N', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZGEMM( 'C', 'C', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZGEMM( 'C', 'T', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZGEMM( 'T', 'N', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZGEMM( 'T', 'C', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZGEMM( 'T', 'T', 0, 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL ZGEMM( 'N', 'N', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL ZGEMM( 'N', 'C', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL ZGEMM( 'N', 'T', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL ZGEMM( 'C', 'N', 0, 0, 2, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL ZGEMM( 'C', 'C', 0, 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL ZGEMM( 'C', 'T', 0, 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL ZGEMM( 'T', 'N', 0, 0, 2, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL ZGEMM( 'T', 'C', 0, 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 8+ CALL ZGEMM( 'T', 'T', 0, 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZGEMM( 'N', 'N', 0, 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZGEMM( 'C', 'N', 0, 0, 2, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZGEMM( 'T', 'N', 0, 0, 2, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZGEMM( 'N', 'C', 0, 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZGEMM( 'C', 'C', 0, 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZGEMM( 'T', 'C', 0, 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZGEMM( 'N', 'T', 0, 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZGEMM( 'C', 'T', 0, 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZGEMM( 'T', 'T', 0, 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL ZGEMM( 'N', 'N', 2, 0, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL ZGEMM( 'N', 'C', 2, 0, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL ZGEMM( 'N', 'T', 2, 0, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL ZGEMM( 'C', 'N', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL ZGEMM( 'C', 'C', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL ZGEMM( 'C', 'T', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL ZGEMM( 'T', 'N', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL ZGEMM( 'T', 'C', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 13+ CALL ZGEMM( 'T', 'T', 2, 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 100+ 20 INFOT = 1+ CALL ZHEMM( '/', 'U', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZHEMM( 'L', '/', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZHEMM( 'L', 'U', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZHEMM( 'R', 'U', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZHEMM( 'L', 'L', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZHEMM( 'R', 'L', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZHEMM( 'L', 'U', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZHEMM( 'R', 'U', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZHEMM( 'L', 'L', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZHEMM( 'R', 'L', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZHEMM( 'L', 'U', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZHEMM( 'R', 'U', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZHEMM( 'L', 'L', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZHEMM( 'R', 'L', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZHEMM( 'L', 'U', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZHEMM( 'R', 'U', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZHEMM( 'L', 'L', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZHEMM( 'R', 'L', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL ZHEMM( 'L', 'U', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL ZHEMM( 'R', 'U', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL ZHEMM( 'L', 'L', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL ZHEMM( 'R', 'L', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 100+ 30 INFOT = 1+ CALL ZSYMM( '/', 'U', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZSYMM( 'L', '/', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZSYMM( 'L', 'U', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZSYMM( 'R', 'U', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZSYMM( 'L', 'L', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZSYMM( 'R', 'L', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZSYMM( 'L', 'U', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZSYMM( 'R', 'U', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZSYMM( 'L', 'L', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZSYMM( 'R', 'L', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZSYMM( 'L', 'U', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZSYMM( 'R', 'U', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZSYMM( 'L', 'L', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZSYMM( 'R', 'L', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZSYMM( 'L', 'U', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZSYMM( 'R', 'U', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZSYMM( 'L', 'L', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZSYMM( 'R', 'L', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL ZSYMM( 'L', 'U', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL ZSYMM( 'R', 'U', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL ZSYMM( 'L', 'L', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL ZSYMM( 'R', 'L', 2, 0, ALPHA, A, 1, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 100+ 40 INFOT = 1+ CALL ZTRMM( '/', 'U', 'N', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZTRMM( 'L', '/', 'N', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZTRMM( 'L', 'U', '/', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZTRMM( 'L', 'U', 'N', '/', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRMM( 'L', 'U', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRMM( 'L', 'U', 'C', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRMM( 'L', 'U', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRMM( 'R', 'U', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRMM( 'R', 'U', 'C', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRMM( 'R', 'U', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRMM( 'L', 'L', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRMM( 'L', 'L', 'C', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRMM( 'L', 'L', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRMM( 'R', 'L', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRMM( 'R', 'L', 'C', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRMM( 'R', 'L', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRMM( 'L', 'U', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRMM( 'L', 'U', 'C', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRMM( 'L', 'U', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRMM( 'R', 'U', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRMM( 'R', 'U', 'C', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRMM( 'R', 'U', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRMM( 'L', 'L', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRMM( 'L', 'L', 'C', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRMM( 'L', 'L', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRMM( 'R', 'L', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRMM( 'R', 'L', 'C', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRMM( 'R', 'L', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRMM( 'L', 'U', 'N', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRMM( 'L', 'U', 'C', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRMM( 'L', 'U', 'T', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRMM( 'R', 'U', 'N', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRMM( 'R', 'U', 'C', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRMM( 'R', 'U', 'T', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRMM( 'L', 'L', 'N', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRMM( 'L', 'L', 'C', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRMM( 'L', 'L', 'T', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRMM( 'R', 'L', 'N', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRMM( 'R', 'L', 'C', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRMM( 'R', 'L', 'T', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRMM( 'L', 'U', 'N', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRMM( 'L', 'U', 'C', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRMM( 'L', 'U', 'T', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRMM( 'R', 'U', 'N', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRMM( 'R', 'U', 'C', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRMM( 'R', 'U', 'T', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRMM( 'L', 'L', 'N', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRMM( 'L', 'L', 'C', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRMM( 'L', 'L', 'T', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRMM( 'R', 'L', 'N', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRMM( 'R', 'L', 'C', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRMM( 'R', 'L', 'T', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 100+ 50 INFOT = 1+ CALL ZTRSM( '/', 'U', 'N', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZTRSM( 'L', '/', 'N', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZTRSM( 'L', 'U', '/', 'N', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZTRSM( 'L', 'U', 'N', '/', 0, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRSM( 'L', 'U', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRSM( 'L', 'U', 'C', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRSM( 'L', 'U', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRSM( 'R', 'U', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRSM( 'R', 'U', 'C', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRSM( 'R', 'U', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRSM( 'L', 'L', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRSM( 'L', 'L', 'C', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRSM( 'L', 'L', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRSM( 'R', 'L', 'N', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRSM( 'R', 'L', 'C', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 5+ CALL ZTRSM( 'R', 'L', 'T', 'N', -1, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRSM( 'L', 'U', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRSM( 'L', 'U', 'C', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRSM( 'L', 'U', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRSM( 'R', 'U', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRSM( 'R', 'U', 'C', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRSM( 'R', 'U', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRSM( 'L', 'L', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRSM( 'L', 'L', 'C', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRSM( 'L', 'L', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRSM( 'R', 'L', 'N', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRSM( 'R', 'L', 'C', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 6+ CALL ZTRSM( 'R', 'L', 'T', 'N', 0, -1, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRSM( 'L', 'U', 'N', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRSM( 'L', 'U', 'C', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRSM( 'L', 'U', 'T', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRSM( 'R', 'U', 'N', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRSM( 'R', 'U', 'C', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRSM( 'R', 'U', 'T', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRSM( 'L', 'L', 'N', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRSM( 'L', 'L', 'C', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRSM( 'L', 'L', 'T', 'N', 2, 0, ALPHA, A, 1, B, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRSM( 'R', 'L', 'N', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRSM( 'R', 'L', 'C', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZTRSM( 'R', 'L', 'T', 'N', 0, 2, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRSM( 'L', 'U', 'N', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRSM( 'L', 'U', 'C', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRSM( 'L', 'U', 'T', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRSM( 'R', 'U', 'N', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRSM( 'R', 'U', 'C', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRSM( 'R', 'U', 'T', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRSM( 'L', 'L', 'N', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRSM( 'L', 'L', 'C', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRSM( 'L', 'L', 'T', 'N', 2, 0, ALPHA, A, 2, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRSM( 'R', 'L', 'N', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRSM( 'R', 'L', 'C', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 11+ CALL ZTRSM( 'R', 'L', 'T', 'N', 2, 0, ALPHA, A, 1, B, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 100+ 60 INFOT = 1+ CALL ZHERK( '/', 'N', 0, 0, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZHERK( 'U', 'T', 0, 0, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZHERK( 'U', 'N', -1, 0, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZHERK( 'U', 'C', -1, 0, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZHERK( 'L', 'N', -1, 0, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZHERK( 'L', 'C', -1, 0, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZHERK( 'U', 'N', 0, -1, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZHERK( 'U', 'C', 0, -1, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZHERK( 'L', 'N', 0, -1, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZHERK( 'L', 'C', 0, -1, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZHERK( 'U', 'N', 2, 0, RALPHA, A, 1, RBETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZHERK( 'U', 'C', 0, 2, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZHERK( 'L', 'N', 2, 0, RALPHA, A, 1, RBETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZHERK( 'L', 'C', 0, 2, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZHERK( 'U', 'N', 2, 0, RALPHA, A, 2, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZHERK( 'U', 'C', 2, 0, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZHERK( 'L', 'N', 2, 0, RALPHA, A, 2, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZHERK( 'L', 'C', 2, 0, RALPHA, A, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 100+ 70 INFOT = 1+ CALL ZSYRK( '/', 'N', 0, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZSYRK( 'U', 'C', 0, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZSYRK( 'U', 'N', -1, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZSYRK( 'U', 'T', -1, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZSYRK( 'L', 'N', -1, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZSYRK( 'L', 'T', -1, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZSYRK( 'U', 'N', 0, -1, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZSYRK( 'U', 'T', 0, -1, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZSYRK( 'L', 'N', 0, -1, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZSYRK( 'L', 'T', 0, -1, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZSYRK( 'U', 'N', 2, 0, ALPHA, A, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZSYRK( 'U', 'T', 0, 2, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZSYRK( 'L', 'N', 2, 0, ALPHA, A, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZSYRK( 'L', 'T', 0, 2, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZSYRK( 'U', 'N', 2, 0, ALPHA, A, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZSYRK( 'U', 'T', 2, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZSYRK( 'L', 'N', 2, 0, ALPHA, A, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 10+ CALL ZSYRK( 'L', 'T', 2, 0, ALPHA, A, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 100+ 80 INFOT = 1+ CALL ZHER2K( '/', 'N', 0, 0, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZHER2K( 'U', 'T', 0, 0, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZHER2K( 'U', 'N', -1, 0, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZHER2K( 'U', 'C', -1, 0, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZHER2K( 'L', 'N', -1, 0, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZHER2K( 'L', 'C', -1, 0, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZHER2K( 'U', 'N', 0, -1, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZHER2K( 'U', 'C', 0, -1, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZHER2K( 'L', 'N', 0, -1, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZHER2K( 'L', 'C', 0, -1, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZHER2K( 'U', 'N', 2, 0, ALPHA, A, 1, B, 1, RBETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZHER2K( 'U', 'C', 0, 2, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZHER2K( 'L', 'N', 2, 0, ALPHA, A, 1, B, 1, RBETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZHER2K( 'L', 'C', 0, 2, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZHER2K( 'U', 'N', 2, 0, ALPHA, A, 2, B, 1, RBETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZHER2K( 'U', 'C', 0, 2, ALPHA, A, 2, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZHER2K( 'L', 'N', 2, 0, ALPHA, A, 2, B, 1, RBETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZHER2K( 'L', 'C', 0, 2, ALPHA, A, 2, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL ZHER2K( 'U', 'N', 2, 0, ALPHA, A, 2, B, 2, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL ZHER2K( 'U', 'C', 2, 0, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL ZHER2K( 'L', 'N', 2, 0, ALPHA, A, 2, B, 2, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL ZHER2K( 'L', 'C', 2, 0, ALPHA, A, 1, B, 1, RBETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ GO TO 100+ 90 INFOT = 1+ CALL ZSYR2K( '/', 'N', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 2+ CALL ZSYR2K( 'U', 'C', 0, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZSYR2K( 'U', 'N', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZSYR2K( 'U', 'T', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZSYR2K( 'L', 'N', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 3+ CALL ZSYR2K( 'L', 'T', -1, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZSYR2K( 'U', 'N', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZSYR2K( 'U', 'T', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZSYR2K( 'L', 'N', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 4+ CALL ZSYR2K( 'L', 'T', 0, -1, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZSYR2K( 'U', 'N', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZSYR2K( 'U', 'T', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZSYR2K( 'L', 'N', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 7+ CALL ZSYR2K( 'L', 'T', 0, 2, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZSYR2K( 'U', 'N', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZSYR2K( 'U', 'T', 0, 2, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZSYR2K( 'L', 'N', 2, 0, ALPHA, A, 2, B, 1, BETA, C, 2 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 9+ CALL ZSYR2K( 'L', 'T', 0, 2, ALPHA, A, 2, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL ZSYR2K( 'U', 'N', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL ZSYR2K( 'U', 'T', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL ZSYR2K( 'L', 'N', 2, 0, ALPHA, A, 2, B, 2, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+ INFOT = 12+ CALL ZSYR2K( 'L', 'T', 2, 0, ALPHA, A, 1, B, 1, BETA, C, 1 )+ CALL CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+*+ 100 IF( OK )THEN+ WRITE( NOUT, FMT = 9999 )SRNAMT+ ELSE+ WRITE( NOUT, FMT = 9998 )SRNAMT+ END IF+ RETURN+*+ 9999 FORMAT( ' ', A6, ' PASSED THE TESTS OF ERROR-EXITS' )+ 9998 FORMAT( ' ******* ', A6, ' FAILED THE TESTS OF ERROR-EXITS *****',+ $ '**' )+*+* End of ZCHKE.+*+ END+ SUBROUTINE ZMAKE( TYPE, UPLO, DIAG, M, N, A, NMAX, AA, LDA, RESET,+ $ TRANSL )+*+* Generates values for an M by N matrix A.+* Stores the values in the array AA in the data structure required+* by the routine, with unwanted elements set to rogue value.+*+* TYPE is 'GE', 'HE', 'SY' or 'TR'.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ COMPLEX*16 ZERO, ONE+ PARAMETER ( ZERO = ( 0.0D0, 0.0D0 ),+ $ ONE = ( 1.0D0, 0.0D0 ) )+ COMPLEX*16 ROGUE+ PARAMETER ( ROGUE = ( -1.0D10, 1.0D10 ) )+ DOUBLE PRECISION RZERO+ PARAMETER ( RZERO = 0.0D0 )+ DOUBLE PRECISION RROGUE+ PARAMETER ( RROGUE = -1.0D10 )+* .. Scalar Arguments ..+ COMPLEX*16 TRANSL+ INTEGER LDA, M, N, NMAX+ LOGICAL RESET+ CHARACTER*1 DIAG, UPLO+ CHARACTER*2 TYPE+* .. Array Arguments ..+ COMPLEX*16 A( NMAX, * ), AA( * )+* .. Local Scalars ..+ INTEGER I, IBEG, IEND, J, JJ+ LOGICAL GEN, HER, LOWER, SYM, TRI, UNIT, UPPER+* .. External Functions ..+ COMPLEX*16 ZBEG+ EXTERNAL ZBEG+* .. Intrinsic Functions ..+ INTRINSIC DCMPLX, DCONJG, DBLE+* .. Executable Statements ..+ GEN = TYPE.EQ.'GE'+ HER = TYPE.EQ.'HE'+ SYM = TYPE.EQ.'SY'+ TRI = TYPE.EQ.'TR'+ UPPER = ( HER.OR.SYM.OR.TRI ).AND.UPLO.EQ.'U'+ LOWER = ( HER.OR.SYM.OR.TRI ).AND.UPLO.EQ.'L'+ UNIT = TRI.AND.DIAG.EQ.'U'+*+* Generate data in array A.+*+ DO 20 J = 1, N+ DO 10 I = 1, M+ IF( GEN.OR.( UPPER.AND.I.LE.J ).OR.( LOWER.AND.I.GE.J ) )+ $ THEN+ A( I, J ) = ZBEG( RESET ) + TRANSL+ IF( I.NE.J )THEN+* Set some elements to zero+ IF( N.GT.3.AND.J.EQ.N/2 )+ $ A( I, J ) = ZERO+ IF( HER )THEN+ A( J, I ) = DCONJG( A( I, J ) )+ ELSE IF( SYM )THEN+ A( J, I ) = A( I, J )+ ELSE IF( TRI )THEN+ A( J, I ) = ZERO+ END IF+ END IF+ END IF+ 10 CONTINUE+ IF( HER )+ $ A( J, J ) = DCMPLX( DBLE( A( J, J ) ), RZERO )+ IF( TRI )+ $ A( J, J ) = A( J, J ) + ONE+ IF( UNIT )+ $ A( J, J ) = ONE+ 20 CONTINUE+*+* Store elements in array AS in data structure required by routine.+*+ IF( TYPE.EQ.'GE' )THEN+ DO 50 J = 1, N+ DO 30 I = 1, M+ AA( I + ( J - 1 )*LDA ) = A( I, J )+ 30 CONTINUE+ DO 40 I = M + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 40 CONTINUE+ 50 CONTINUE+ ELSE IF( TYPE.EQ.'HE'.OR.TYPE.EQ.'SY'.OR.TYPE.EQ.'TR' )THEN+ DO 90 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IF( UNIT )THEN+ IEND = J - 1+ ELSE+ IEND = J+ END IF+ ELSE+ IF( UNIT )THEN+ IBEG = J + 1+ ELSE+ IBEG = J+ END IF+ IEND = N+ END IF+ DO 60 I = 1, IBEG - 1+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 60 CONTINUE+ DO 70 I = IBEG, IEND+ AA( I + ( J - 1 )*LDA ) = A( I, J )+ 70 CONTINUE+ DO 80 I = IEND + 1, LDA+ AA( I + ( J - 1 )*LDA ) = ROGUE+ 80 CONTINUE+ IF( HER )THEN+ JJ = J + ( J - 1 )*LDA+ AA( JJ ) = DCMPLX( DBLE( AA( JJ ) ), RROGUE )+ END IF+ 90 CONTINUE+ END IF+ RETURN+*+* End of ZMAKE.+*+ END+ SUBROUTINE ZMMCH( TRANSA, TRANSB, M, N, KK, ALPHA, A, LDA, B, LDB,+ $ BETA, C, LDC, CT, G, CC, LDCC, EPS, ERR, FATAL,+ $ NOUT, MV )+*+* Checks the results of the computational tests.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Parameters ..+ COMPLEX*16 ZERO+ PARAMETER ( ZERO = ( 0.0D0, 0.0D0 ) )+ DOUBLE PRECISION RZERO, RONE+ PARAMETER ( RZERO = 0.0D0, RONE = 1.0D0 )+* .. Scalar Arguments ..+ COMPLEX*16 ALPHA, BETA+ DOUBLE PRECISION EPS, ERR+ INTEGER KK, LDA, LDB, LDC, LDCC, M, N, NOUT+ LOGICAL FATAL, MV+ CHARACTER*1 TRANSA, TRANSB+* .. Array Arguments ..+ COMPLEX*16 A( LDA, * ), B( LDB, * ), C( LDC, * ),+ $ CC( LDCC, * ), CT( * )+ DOUBLE PRECISION G( * )+* .. Local Scalars ..+ COMPLEX*16 CL+ DOUBLE PRECISION ERRI+ INTEGER I, J, K+ LOGICAL CTRANA, CTRANB, TRANA, TRANB+* .. Intrinsic Functions ..+ INTRINSIC ABS, DIMAG, DCONJG, MAX, DBLE, SQRT+* .. Statement Functions ..+ DOUBLE PRECISION ABS1+* .. Statement Function definitions ..+ ABS1( CL ) = ABS( DBLE( CL ) ) + ABS( DIMAG( CL ) )+* .. Executable Statements ..+ TRANA = TRANSA.EQ.'T'.OR.TRANSA.EQ.'C'+ TRANB = TRANSB.EQ.'T'.OR.TRANSB.EQ.'C'+ CTRANA = TRANSA.EQ.'C'+ CTRANB = TRANSB.EQ.'C'+*+* Compute expected result, one column at a time, in CT using data+* in A, B and C.+* Compute gauges in G.+*+ DO 220 J = 1, N+*+ DO 10 I = 1, M+ CT( I ) = ZERO+ G( I ) = RZERO+ 10 CONTINUE+ IF( .NOT.TRANA.AND..NOT.TRANB )THEN+ DO 30 K = 1, KK+ DO 20 I = 1, M+ CT( I ) = CT( I ) + A( I, K )*B( K, J )+ G( I ) = G( I ) + ABS1( A( I, K ) )*ABS1( B( K, J ) )+ 20 CONTINUE+ 30 CONTINUE+ ELSE IF( TRANA.AND..NOT.TRANB )THEN+ IF( CTRANA )THEN+ DO 50 K = 1, KK+ DO 40 I = 1, M+ CT( I ) = CT( I ) + DCONJG( A( K, I ) )*B( K, J )+ G( I ) = G( I ) + ABS1( A( K, I ) )*+ $ ABS1( B( K, J ) )+ 40 CONTINUE+ 50 CONTINUE+ ELSE+ DO 70 K = 1, KK+ DO 60 I = 1, M+ CT( I ) = CT( I ) + A( K, I )*B( K, J )+ G( I ) = G( I ) + ABS1( A( K, I ) )*+ $ ABS1( B( K, J ) )+ 60 CONTINUE+ 70 CONTINUE+ END IF+ ELSE IF( .NOT.TRANA.AND.TRANB )THEN+ IF( CTRANB )THEN+ DO 90 K = 1, KK+ DO 80 I = 1, M+ CT( I ) = CT( I ) + A( I, K )*DCONJG( B( J, K ) )+ G( I ) = G( I ) + ABS1( A( I, K ) )*+ $ ABS1( B( J, K ) )+ 80 CONTINUE+ 90 CONTINUE+ ELSE+ DO 110 K = 1, KK+ DO 100 I = 1, M+ CT( I ) = CT( I ) + A( I, K )*B( J, K )+ G( I ) = G( I ) + ABS1( A( I, K ) )*+ $ ABS1( B( J, K ) )+ 100 CONTINUE+ 110 CONTINUE+ END IF+ ELSE IF( TRANA.AND.TRANB )THEN+ IF( CTRANA )THEN+ IF( CTRANB )THEN+ DO 130 K = 1, KK+ DO 120 I = 1, M+ CT( I ) = CT( I ) + DCONJG( A( K, I ) )*+ $ DCONJG( B( J, K ) )+ G( I ) = G( I ) + ABS1( A( K, I ) )*+ $ ABS1( B( J, K ) )+ 120 CONTINUE+ 130 CONTINUE+ ELSE+ DO 150 K = 1, KK+ DO 140 I = 1, M+ CT( I ) = CT( I ) + DCONJG( A( K, I ) )*+ $ B( J, K )+ G( I ) = G( I ) + ABS1( A( K, I ) )*+ $ ABS1( B( J, K ) )+ 140 CONTINUE+ 150 CONTINUE+ END IF+ ELSE+ IF( CTRANB )THEN+ DO 170 K = 1, KK+ DO 160 I = 1, M+ CT( I ) = CT( I ) + A( K, I )*+ $ DCONJG( B( J, K ) )+ G( I ) = G( I ) + ABS1( A( K, I ) )*+ $ ABS1( B( J, K ) )+ 160 CONTINUE+ 170 CONTINUE+ ELSE+ DO 190 K = 1, KK+ DO 180 I = 1, M+ CT( I ) = CT( I ) + A( K, I )*B( J, K )+ G( I ) = G( I ) + ABS1( A( K, I ) )*+ $ ABS1( B( J, K ) )+ 180 CONTINUE+ 190 CONTINUE+ END IF+ END IF+ END IF+ DO 200 I = 1, M+ CT( I ) = ALPHA*CT( I ) + BETA*C( I, J )+ G( I ) = ABS1( ALPHA )*G( I ) ++ $ ABS1( BETA )*ABS1( C( I, J ) )+ 200 CONTINUE+*+* Compute the error ratio for this result.+*+ ERR = ZERO+ DO 210 I = 1, M+ ERRI = ABS1( CT( I ) - CC( I, J ) )/EPS+ IF( G( I ).NE.RZERO )+ $ ERRI = ERRI/G( I )+ ERR = MAX( ERR, ERRI )+ IF( ERR*SQRT( EPS ).GE.RONE )+ $ GO TO 230+ 210 CONTINUE+*+ 220 CONTINUE+*+* If the loop completes, all results are at least half accurate.+ GO TO 250+*+* Report fatal error.+*+ 230 FATAL = .TRUE.+ WRITE( NOUT, FMT = 9999 )+ DO 240 I = 1, M+ IF( MV )THEN+ WRITE( NOUT, FMT = 9998 )I, CT( I ), CC( I, J )+ ELSE+ WRITE( NOUT, FMT = 9998 )I, CC( I, J ), CT( I )+ END IF+ 240 CONTINUE+ IF( N.GT.1 )+ $ WRITE( NOUT, FMT = 9997 )J+*+ 250 CONTINUE+ RETURN+*+ 9999 FORMAT( ' ******* FATAL ERROR - COMPUTED RESULT IS LESS THAN HAL',+ $ 'F ACCURATE *******', /' EXPECTED RE',+ $ 'SULT COMPUTED RESULT' )+ 9998 FORMAT( 1X, I7, 2( ' (', G15.6, ',', G15.6, ')' ) )+ 9997 FORMAT( ' THESE ARE THE RESULTS FOR COLUMN ', I3 )+*+* End of ZMMCH.+*+ END+ LOGICAL FUNCTION LZE( RI, RJ, LR )+*+* Tests if two arrays are identical.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER LR+* .. Array Arguments ..+ COMPLEX*16 RI( * ), RJ( * )+* .. Local Scalars ..+ INTEGER I+* .. Executable Statements ..+ DO 10 I = 1, LR+ IF( RI( I ).NE.RJ( I ) )+ $ GO TO 20+ 10 CONTINUE+ LZE = .TRUE.+ GO TO 30+ 20 CONTINUE+ LZE = .FALSE.+ 30 RETURN+*+* End of LZE.+*+ END+ LOGICAL FUNCTION LZERES( TYPE, UPLO, M, N, AA, AS, LDA )+*+* Tests if selected elements in two arrays are equal.+*+* TYPE is 'GE' or 'HE' or 'SY'.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER LDA, M, N+ CHARACTER*1 UPLO+ CHARACTER*2 TYPE+* .. Array Arguments ..+ COMPLEX*16 AA( LDA, * ), AS( LDA, * )+* .. Local Scalars ..+ INTEGER I, IBEG, IEND, J+ LOGICAL UPPER+* .. Executable Statements ..+ UPPER = UPLO.EQ.'U'+ IF( TYPE.EQ.'GE' )THEN+ DO 20 J = 1, N+ DO 10 I = M + 1, LDA+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 10 CONTINUE+ 20 CONTINUE+ ELSE IF( TYPE.EQ.'HE'.OR.TYPE.EQ.'SY' )THEN+ DO 50 J = 1, N+ IF( UPPER )THEN+ IBEG = 1+ IEND = J+ ELSE+ IBEG = J+ IEND = N+ END IF+ DO 30 I = 1, IBEG - 1+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 30 CONTINUE+ DO 40 I = IEND + 1, LDA+ IF( AA( I, J ).NE.AS( I, J ) )+ $ GO TO 70+ 40 CONTINUE+ 50 CONTINUE+ END IF+*+ 60 CONTINUE+ LZERES = .TRUE.+ GO TO 80+ 70 CONTINUE+ LZERES = .FALSE.+ 80 RETURN+*+* End of LZERES.+*+ END+ COMPLEX*16 FUNCTION ZBEG( RESET )+*+* Generates complex numbers as pairs of random numbers uniformly+* distributed between -0.5 and 0.5.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ LOGICAL RESET+* .. Local Scalars ..+ INTEGER I, IC, J, MI, MJ+* .. Save statement ..+ SAVE I, IC, J, MI, MJ+* .. Intrinsic Functions ..+ INTRINSIC DCMPLX+* .. Executable Statements ..+ IF( RESET )THEN+* Initialize local variables.+ MI = 891+ MJ = 457+ I = 7+ J = 7+ IC = 0+ RESET = .FALSE.+ END IF+*+* The sequence of values of I or J is bounded between 1 and 999.+* If initial I or J = 1,2,3,6,7 or 9, the period will be 50.+* If initial I or J = 4 or 8, the period will be 25.+* If initial I or J = 5, the period will be 10.+* IC is used to break up the period by skipping 1 value of I or J+* in 6.+*+ IC = IC + 1+ 10 I = I*MI+ J = J*MJ+ I = I - 1000*( I/1000 )+ J = J - 1000*( J/1000 )+ IF( IC.GE.5 )THEN+ IC = 0+ GO TO 10+ END IF+ ZBEG = DCMPLX( ( I - 500 )/1001.0D0, ( J - 500 )/1001.0D0 )+ RETURN+*+* End of ZBEG.+*+ END+ DOUBLE PRECISION FUNCTION DDIFF( X, Y )+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ DOUBLE PRECISION X, Y+* .. Executable Statements ..+ DDIFF = X - Y+ RETURN+*+* End of DDIFF.+*+ END+ SUBROUTINE CHKXER( SRNAMT, INFOT, NOUT, LERR, OK )+*+* Tests whether XERBLA has detected an error when it should.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER INFOT, NOUT+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Executable Statements ..+ IF( .NOT.LERR )THEN+ WRITE( NOUT, FMT = 9999 )INFOT, SRNAMT+ OK = .FALSE.+ END IF+ LERR = .FALSE.+ RETURN+*+ 9999 FORMAT( ' ***** ILLEGAL VALUE OF PARAMETER NUMBER ', I2, ' NOT D',+ $ 'ETECTED BY ', A6, ' *****' )+*+* End of CHKXER.+*+ END+ SUBROUTINE XERBLA( SRNAME, INFO )+*+* This is a special version of XERBLA to be used only as part of+* the test program for testing error exits from the Level 3 BLAS+* routines.+*+* XERBLA is an error handler for the Level 3 BLAS routines.+*+* It is called by the Level 3 BLAS routines if an input parameter is+* invalid.+*+* Auxiliary routine for test program for Level 3 Blas.+*+* -- Written on 8-February-1989.+* Jack Dongarra, Argonne National Laboratory.+* Iain Duff, AERE Harwell.+* Jeremy Du Croz, Numerical Algorithms Group Ltd.+* Sven Hammarling, Numerical Algorithms Group Ltd.+*+* .. Scalar Arguments ..+ INTEGER INFO+ CHARACTER*6 SRNAME+* .. Scalars in Common ..+ INTEGER INFOT, NOUT+ LOGICAL LERR, OK+ CHARACTER*6 SRNAMT+* .. Common blocks ..+ COMMON /INFOC/INFOT, NOUT, OK, LERR+ COMMON /SRNAMC/SRNAMT+* .. Executable Statements ..+ LERR = .TRUE.+ IF( INFO.NE.INFOT )THEN+ IF( INFOT.NE.0 )THEN+ WRITE( NOUT, FMT = 9999 )INFO, INFOT+ ELSE+ WRITE( NOUT, FMT = 9997 )INFO+ END IF+ OK = .FALSE.+ END IF+ IF( SRNAME.NE.SRNAMT )THEN+ WRITE( NOUT, FMT = 9998 )SRNAME, SRNAMT+ OK = .FALSE.+ END IF+ RETURN+*+ 9999 FORMAT( ' ******* XERBLA WAS CALLED WITH INFO = ', I6, ' INSTEAD',+ $ ' OF ', I2, ' *******' )+ 9998 FORMAT( ' ******* XERBLA WAS CALLED WITH SRNAME = ', A6, ' INSTE',+ $ 'AD OF ', A6, ' *******' )+ 9997 FORMAT( ' ******* XERBLA WAS CALLED WITH INFO = ', I6,+ $ ' *******' )+*+* End of XERBLA+*+ END+
+ eigen3/blas/xerbla.cpp view
@@ -0,0 +1,23 @@++#include <iostream>++#if (defined __GNUC__) && (!defined __MINGW32__) && (!defined __CYGWIN__)+#define EIGEN_WEAK_LINKING __attribute__ ((weak))+#else+#define EIGEN_WEAK_LINKING+#endif++#ifdef __cplusplus+extern "C"+{+#endif++EIGEN_WEAK_LINKING int xerbla_(const char * msg, int *info, int)+{+ std::cerr << "Eigen BLAS ERROR #" << *info << ": " << msg << "\n";+ return 0;+}++#ifdef __cplusplus+}+#endif
+ eigen3/blas/zhbmv.f view
@@ -0,0 +1,310 @@+ SUBROUTINE ZHBMV(UPLO,N,K,ALPHA,A,LDA,X,INCX,BETA,Y,INCY)+* .. Scalar Arguments ..+ DOUBLE COMPLEX ALPHA,BETA+ INTEGER INCX,INCY,K,LDA,N+ CHARACTER UPLO+* ..+* .. Array Arguments ..+ DOUBLE COMPLEX A(LDA,*),X(*),Y(*)+* ..+*+* Purpose+* =======+*+* ZHBMV performs the matrix-vector operation+*+* y := alpha*A*x + beta*y,+*+* where alpha and beta are scalars, x and y are n element vectors and+* A is an n by n hermitian band matrix, with k super-diagonals.+*+* Arguments+* ==========+*+* UPLO - CHARACTER*1.+* On entry, UPLO specifies whether the upper or lower+* triangular part of the band matrix A is being supplied as+* follows:+*+* UPLO = 'U' or 'u' The upper triangular part of A is+* being supplied.+*+* UPLO = 'L' or 'l' The lower triangular part of A is+* being supplied.+*+* Unchanged on exit.+*+* N - INTEGER.+* On entry, N specifies the order of the matrix A.+* N must be at least zero.+* Unchanged on exit.+*+* K - INTEGER.+* On entry, K specifies the number of super-diagonals of the+* matrix A. K must satisfy 0 .le. K.+* Unchanged on exit.+*+* ALPHA - COMPLEX*16 .+* On entry, ALPHA specifies the scalar alpha.+* Unchanged on exit.+*+* A - COMPLEX*16 array of DIMENSION ( LDA, n ).+* Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )+* by n part of the array A must contain the upper triangular+* band part of the hermitian matrix, supplied column by+* column, with the leading diagonal of the matrix in row+* ( k + 1 ) of the array, the first super-diagonal starting at+* position 2 in row k, and so on. The top left k by k triangle+* of the array A is not referenced.+* The following program segment will transfer the upper+* triangular part of a hermitian band matrix from conventional+* full matrix storage to band storage:+*+* DO 20, J = 1, N+* M = K + 1 - J+* DO 10, I = MAX( 1, J - K ), J+* A( M + I, J ) = matrix( I, J )+* 10 CONTINUE+* 20 CONTINUE+*+* Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )+* by n part of the array A must contain the lower triangular+* band part of the hermitian matrix, supplied column by+* column, with the leading diagonal of the matrix in row 1 of+* the array, the first sub-diagonal starting at position 1 in+* row 2, and so on. The bottom right k by k triangle of the+* array A is not referenced.+* The following program segment will transfer the lower+* triangular part of a hermitian band matrix from conventional+* full matrix storage to band storage:+*+* DO 20, J = 1, N+* M = 1 - J+* DO 10, I = J, MIN( N, J + K )+* A( M + I, J ) = matrix( I, J )+* 10 CONTINUE+* 20 CONTINUE+*+* Note that the imaginary parts of the diagonal elements need+* not be set and are assumed to be zero.+* Unchanged on exit.+*+* LDA - INTEGER.+* On entry, LDA specifies the first dimension of A as declared+* in the calling (sub) program. LDA must be at least+* ( k + 1 ).+* Unchanged on exit.+*+* X - COMPLEX*16 array of DIMENSION at least+* ( 1 + ( n - 1 )*abs( INCX ) ).+* Before entry, the incremented array X must contain the+* vector x.+* Unchanged on exit.+*+* INCX - INTEGER.+* On entry, INCX specifies the increment for the elements of+* X. INCX must not be zero.+* Unchanged on exit.+*+* BETA - COMPLEX*16 .+* On entry, BETA specifies the scalar beta.+* Unchanged on exit.+*+* Y - COMPLEX*16 array of DIMENSION at least+* ( 1 + ( n - 1 )*abs( INCY ) ).+* Before entry, the incremented array Y must contain the+* vector y. On exit, Y is overwritten by the updated vector y.+*+* INCY - INTEGER.+* On entry, INCY specifies the increment for the elements of+* Y. INCY must not be zero.+* Unchanged on exit.+*+* Further Details+* ===============+*+* Level 2 Blas routine.+*+* -- Written on 22-October-1986.+* Jack Dongarra, Argonne National Lab.+* Jeremy Du Croz, Nag Central Office.+* Sven Hammarling, Nag Central Office.+* Richard Hanson, Sandia National Labs.+*+* =====================================================================+*+* .. Parameters ..+ DOUBLE COMPLEX ONE+ PARAMETER (ONE= (1.0D+0,0.0D+0))+ DOUBLE COMPLEX ZERO+ PARAMETER (ZERO= (0.0D+0,0.0D+0))+* ..+* .. Local Scalars ..+ DOUBLE COMPLEX TEMP1,TEMP2+ INTEGER I,INFO,IX,IY,J,JX,JY,KPLUS1,KX,KY,L+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. External Subroutines ..+ EXTERNAL XERBLA+* ..+* .. Intrinsic Functions ..+ INTRINSIC DBLE,DCONJG,MAX,MIN+* ..+*+* Test the input parameters.+*+ INFO = 0+ IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN+ INFO = 1+ ELSE IF (N.LT.0) THEN+ INFO = 2+ ELSE IF (K.LT.0) THEN+ INFO = 3+ ELSE IF (LDA.LT. (K+1)) THEN+ INFO = 6+ ELSE IF (INCX.EQ.0) THEN+ INFO = 8+ ELSE IF (INCY.EQ.0) THEN+ INFO = 11+ END IF+ IF (INFO.NE.0) THEN+ CALL XERBLA('ZHBMV ',INFO)+ RETURN+ END IF+*+* Quick return if possible.+*+ IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN+*+* Set up the start points in X and Y.+*+ IF (INCX.GT.0) THEN+ KX = 1+ ELSE+ KX = 1 - (N-1)*INCX+ END IF+ IF (INCY.GT.0) THEN+ KY = 1+ ELSE+ KY = 1 - (N-1)*INCY+ END IF+*+* Start the operations. In this version the elements of the array A+* are accessed sequentially with one pass through A.+*+* First form y := beta*y.+*+ IF (BETA.NE.ONE) THEN+ IF (INCY.EQ.1) THEN+ IF (BETA.EQ.ZERO) THEN+ DO 10 I = 1,N+ Y(I) = ZERO+ 10 CONTINUE+ ELSE+ DO 20 I = 1,N+ Y(I) = BETA*Y(I)+ 20 CONTINUE+ END IF+ ELSE+ IY = KY+ IF (BETA.EQ.ZERO) THEN+ DO 30 I = 1,N+ Y(IY) = ZERO+ IY = IY + INCY+ 30 CONTINUE+ ELSE+ DO 40 I = 1,N+ Y(IY) = BETA*Y(IY)+ IY = IY + INCY+ 40 CONTINUE+ END IF+ END IF+ END IF+ IF (ALPHA.EQ.ZERO) RETURN+ IF (LSAME(UPLO,'U')) THEN+*+* Form y when upper triangle of A is stored.+*+ KPLUS1 = K + 1+ IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN+ DO 60 J = 1,N+ TEMP1 = ALPHA*X(J)+ TEMP2 = ZERO+ L = KPLUS1 - J+ DO 50 I = MAX(1,J-K),J - 1+ Y(I) = Y(I) + TEMP1*A(L+I,J)+ TEMP2 = TEMP2 + DCONJG(A(L+I,J))*X(I)+ 50 CONTINUE+ Y(J) = Y(J) + TEMP1*DBLE(A(KPLUS1,J)) + ALPHA*TEMP2+ 60 CONTINUE+ ELSE+ JX = KX+ JY = KY+ DO 80 J = 1,N+ TEMP1 = ALPHA*X(JX)+ TEMP2 = ZERO+ IX = KX+ IY = KY+ L = KPLUS1 - J+ DO 70 I = MAX(1,J-K),J - 1+ Y(IY) = Y(IY) + TEMP1*A(L+I,J)+ TEMP2 = TEMP2 + DCONJG(A(L+I,J))*X(IX)+ IX = IX + INCX+ IY = IY + INCY+ 70 CONTINUE+ Y(JY) = Y(JY) + TEMP1*DBLE(A(KPLUS1,J)) + ALPHA*TEMP2+ JX = JX + INCX+ JY = JY + INCY+ IF (J.GT.K) THEN+ KX = KX + INCX+ KY = KY + INCY+ END IF+ 80 CONTINUE+ END IF+ ELSE+*+* Form y when lower triangle of A is stored.+*+ IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN+ DO 100 J = 1,N+ TEMP1 = ALPHA*X(J)+ TEMP2 = ZERO+ Y(J) = Y(J) + TEMP1*DBLE(A(1,J))+ L = 1 - J+ DO 90 I = J + 1,MIN(N,J+K)+ Y(I) = Y(I) + TEMP1*A(L+I,J)+ TEMP2 = TEMP2 + DCONJG(A(L+I,J))*X(I)+ 90 CONTINUE+ Y(J) = Y(J) + ALPHA*TEMP2+ 100 CONTINUE+ ELSE+ JX = KX+ JY = KY+ DO 120 J = 1,N+ TEMP1 = ALPHA*X(JX)+ TEMP2 = ZERO+ Y(JY) = Y(JY) + TEMP1*DBLE(A(1,J))+ L = 1 - J+ IX = JX+ IY = JY+ DO 110 I = J + 1,MIN(N,J+K)+ IX = IX + INCX+ IY = IY + INCY+ Y(IY) = Y(IY) + TEMP1*A(L+I,J)+ TEMP2 = TEMP2 + DCONJG(A(L+I,J))*X(IX)+ 110 CONTINUE+ Y(JY) = Y(JY) + ALPHA*TEMP2+ JX = JX + INCX+ JY = JY + INCY+ 120 CONTINUE+ END IF+ END IF+*+ RETURN+*+* End of ZHBMV .+*+ END
+ eigen3/blas/zhpmv.f view
@@ -0,0 +1,272 @@+ SUBROUTINE ZHPMV(UPLO,N,ALPHA,AP,X,INCX,BETA,Y,INCY)+* .. Scalar Arguments ..+ DOUBLE COMPLEX ALPHA,BETA+ INTEGER INCX,INCY,N+ CHARACTER UPLO+* ..+* .. Array Arguments ..+ DOUBLE COMPLEX AP(*),X(*),Y(*)+* ..+*+* Purpose+* =======+*+* ZHPMV performs the matrix-vector operation+*+* y := alpha*A*x + beta*y,+*+* where alpha and beta are scalars, x and y are n element vectors and+* A is an n by n hermitian matrix, supplied in packed form.+*+* Arguments+* ==========+*+* UPLO - CHARACTER*1.+* On entry, UPLO specifies whether the upper or lower+* triangular part of the matrix A is supplied in the packed+* array AP as follows:+*+* UPLO = 'U' or 'u' The upper triangular part of A is+* supplied in AP.+*+* UPLO = 'L' or 'l' The lower triangular part of A is+* supplied in AP.+*+* Unchanged on exit.+*+* N - INTEGER.+* On entry, N specifies the order of the matrix A.+* N must be at least zero.+* Unchanged on exit.+*+* ALPHA - COMPLEX*16 .+* On entry, ALPHA specifies the scalar alpha.+* Unchanged on exit.+*+* AP - COMPLEX*16 array of DIMENSION at least+* ( ( n*( n + 1 ) )/2 ).+* Before entry with UPLO = 'U' or 'u', the array AP must+* contain the upper triangular part of the hermitian matrix+* packed sequentially, column by column, so that AP( 1 )+* contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 1, 2 )+* and a( 2, 2 ) respectively, and so on.+* Before entry with UPLO = 'L' or 'l', the array AP must+* contain the lower triangular part of the hermitian matrix+* packed sequentially, column by column, so that AP( 1 )+* contains a( 1, 1 ), AP( 2 ) and AP( 3 ) contain a( 2, 1 )+* and a( 3, 1 ) respectively, and so on.+* Note that the imaginary parts of the diagonal elements need+* not be set and are assumed to be zero.+* Unchanged on exit.+*+* X - COMPLEX*16 array of dimension at least+* ( 1 + ( n - 1 )*abs( INCX ) ).+* Before entry, the incremented array X must contain the n+* element vector x.+* Unchanged on exit.+*+* INCX - INTEGER.+* On entry, INCX specifies the increment for the elements of+* X. INCX must not be zero.+* Unchanged on exit.+*+* BETA - COMPLEX*16 .+* On entry, BETA specifies the scalar beta. When BETA is+* supplied as zero then Y need not be set on input.+* Unchanged on exit.+*+* Y - COMPLEX*16 array of dimension at least+* ( 1 + ( n - 1 )*abs( INCY ) ).+* Before entry, the incremented array Y must contain the n+* element vector y. On exit, Y is overwritten by the updated+* vector y.+*+* INCY - INTEGER.+* On entry, INCY specifies the increment for the elements of+* Y. INCY must not be zero.+* Unchanged on exit.+*+* Further Details+* ===============+*+* Level 2 Blas routine.+*+* -- Written on 22-October-1986.+* Jack Dongarra, Argonne National Lab.+* Jeremy Du Croz, Nag Central Office.+* Sven Hammarling, Nag Central Office.+* Richard Hanson, Sandia National Labs.+*+* =====================================================================+*+* .. Parameters ..+ DOUBLE COMPLEX ONE+ PARAMETER (ONE= (1.0D+0,0.0D+0))+ DOUBLE COMPLEX ZERO+ PARAMETER (ZERO= (0.0D+0,0.0D+0))+* ..+* .. Local Scalars ..+ DOUBLE COMPLEX TEMP1,TEMP2+ INTEGER I,INFO,IX,IY,J,JX,JY,K,KK,KX,KY+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. External Subroutines ..+ EXTERNAL XERBLA+* ..+* .. Intrinsic Functions ..+ INTRINSIC DBLE,DCONJG+* ..+*+* Test the input parameters.+*+ INFO = 0+ IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN+ INFO = 1+ ELSE IF (N.LT.0) THEN+ INFO = 2+ ELSE IF (INCX.EQ.0) THEN+ INFO = 6+ ELSE IF (INCY.EQ.0) THEN+ INFO = 9+ END IF+ IF (INFO.NE.0) THEN+ CALL XERBLA('ZHPMV ',INFO)+ RETURN+ END IF+*+* Quick return if possible.+*+ IF ((N.EQ.0) .OR. ((ALPHA.EQ.ZERO).AND. (BETA.EQ.ONE))) RETURN+*+* Set up the start points in X and Y.+*+ IF (INCX.GT.0) THEN+ KX = 1+ ELSE+ KX = 1 - (N-1)*INCX+ END IF+ IF (INCY.GT.0) THEN+ KY = 1+ ELSE+ KY = 1 - (N-1)*INCY+ END IF+*+* Start the operations. In this version the elements of the array AP+* are accessed sequentially with one pass through AP.+*+* First form y := beta*y.+*+ IF (BETA.NE.ONE) THEN+ IF (INCY.EQ.1) THEN+ IF (BETA.EQ.ZERO) THEN+ DO 10 I = 1,N+ Y(I) = ZERO+ 10 CONTINUE+ ELSE+ DO 20 I = 1,N+ Y(I) = BETA*Y(I)+ 20 CONTINUE+ END IF+ ELSE+ IY = KY+ IF (BETA.EQ.ZERO) THEN+ DO 30 I = 1,N+ Y(IY) = ZERO+ IY = IY + INCY+ 30 CONTINUE+ ELSE+ DO 40 I = 1,N+ Y(IY) = BETA*Y(IY)+ IY = IY + INCY+ 40 CONTINUE+ END IF+ END IF+ END IF+ IF (ALPHA.EQ.ZERO) RETURN+ KK = 1+ IF (LSAME(UPLO,'U')) THEN+*+* Form y when AP contains the upper triangle.+*+ IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN+ DO 60 J = 1,N+ TEMP1 = ALPHA*X(J)+ TEMP2 = ZERO+ K = KK+ DO 50 I = 1,J - 1+ Y(I) = Y(I) + TEMP1*AP(K)+ TEMP2 = TEMP2 + DCONJG(AP(K))*X(I)+ K = K + 1+ 50 CONTINUE+ Y(J) = Y(J) + TEMP1*DBLE(AP(KK+J-1)) + ALPHA*TEMP2+ KK = KK + J+ 60 CONTINUE+ ELSE+ JX = KX+ JY = KY+ DO 80 J = 1,N+ TEMP1 = ALPHA*X(JX)+ TEMP2 = ZERO+ IX = KX+ IY = KY+ DO 70 K = KK,KK + J - 2+ Y(IY) = Y(IY) + TEMP1*AP(K)+ TEMP2 = TEMP2 + DCONJG(AP(K))*X(IX)+ IX = IX + INCX+ IY = IY + INCY+ 70 CONTINUE+ Y(JY) = Y(JY) + TEMP1*DBLE(AP(KK+J-1)) + ALPHA*TEMP2+ JX = JX + INCX+ JY = JY + INCY+ KK = KK + J+ 80 CONTINUE+ END IF+ ELSE+*+* Form y when AP contains the lower triangle.+*+ IF ((INCX.EQ.1) .AND. (INCY.EQ.1)) THEN+ DO 100 J = 1,N+ TEMP1 = ALPHA*X(J)+ TEMP2 = ZERO+ Y(J) = Y(J) + TEMP1*DBLE(AP(KK))+ K = KK + 1+ DO 90 I = J + 1,N+ Y(I) = Y(I) + TEMP1*AP(K)+ TEMP2 = TEMP2 + DCONJG(AP(K))*X(I)+ K = K + 1+ 90 CONTINUE+ Y(J) = Y(J) + ALPHA*TEMP2+ KK = KK + (N-J+1)+ 100 CONTINUE+ ELSE+ JX = KX+ JY = KY+ DO 120 J = 1,N+ TEMP1 = ALPHA*X(JX)+ TEMP2 = ZERO+ Y(JY) = Y(JY) + TEMP1*DBLE(AP(KK))+ IX = JX+ IY = JY+ DO 110 K = KK + 1,KK + N - J+ IX = IX + INCX+ IY = IY + INCY+ Y(IY) = Y(IY) + TEMP1*AP(K)+ TEMP2 = TEMP2 + DCONJG(AP(K))*X(IX)+ 110 CONTINUE+ Y(JY) = Y(JY) + ALPHA*TEMP2+ JX = JX + INCX+ JY = JY + INCY+ KK = KK + (N-J+1)+ 120 CONTINUE+ END IF+ END IF+*+ RETURN+*+* End of ZHPMV .+*+ END
+ eigen3/blas/ztbmv.f view
@@ -0,0 +1,366 @@+ SUBROUTINE ZTBMV(UPLO,TRANS,DIAG,N,K,A,LDA,X,INCX)+* .. Scalar Arguments ..+ INTEGER INCX,K,LDA,N+ CHARACTER DIAG,TRANS,UPLO+* ..+* .. Array Arguments ..+ DOUBLE COMPLEX A(LDA,*),X(*)+* ..+*+* Purpose+* =======+*+* ZTBMV performs one of the matrix-vector operations+*+* x := A*x, or x := A'*x, or x := conjg( A' )*x,+*+* where x is an n element vector and A is an n by n unit, or non-unit,+* upper or lower triangular band matrix, with ( k + 1 ) diagonals.+*+* Arguments+* ==========+*+* UPLO - CHARACTER*1.+* On entry, UPLO specifies whether the matrix is an upper or+* lower triangular matrix as follows:+*+* UPLO = 'U' or 'u' A is an upper triangular matrix.+*+* UPLO = 'L' or 'l' A is a lower triangular matrix.+*+* Unchanged on exit.+*+* TRANS - CHARACTER*1.+* On entry, TRANS specifies the operation to be performed as+* follows:+*+* TRANS = 'N' or 'n' x := A*x.+*+* TRANS = 'T' or 't' x := A'*x.+*+* TRANS = 'C' or 'c' x := conjg( A' )*x.+*+* Unchanged on exit.+*+* DIAG - CHARACTER*1.+* On entry, DIAG specifies whether or not A is unit+* triangular as follows:+*+* DIAG = 'U' or 'u' A is assumed to be unit triangular.+*+* DIAG = 'N' or 'n' A is not assumed to be unit+* triangular.+*+* Unchanged on exit.+*+* N - INTEGER.+* On entry, N specifies the order of the matrix A.+* N must be at least zero.+* Unchanged on exit.+*+* K - INTEGER.+* On entry with UPLO = 'U' or 'u', K specifies the number of+* super-diagonals of the matrix A.+* On entry with UPLO = 'L' or 'l', K specifies the number of+* sub-diagonals of the matrix A.+* K must satisfy 0 .le. K.+* Unchanged on exit.+*+* A - COMPLEX*16 array of DIMENSION ( LDA, n ).+* Before entry with UPLO = 'U' or 'u', the leading ( k + 1 )+* by n part of the array A must contain the upper triangular+* band part of the matrix of coefficients, supplied column by+* column, with the leading diagonal of the matrix in row+* ( k + 1 ) of the array, the first super-diagonal starting at+* position 2 in row k, and so on. The top left k by k triangle+* of the array A is not referenced.+* The following program segment will transfer an upper+* triangular band matrix from conventional full matrix storage+* to band storage:+*+* DO 20, J = 1, N+* M = K + 1 - J+* DO 10, I = MAX( 1, J - K ), J+* A( M + I, J ) = matrix( I, J )+* 10 CONTINUE+* 20 CONTINUE+*+* Before entry with UPLO = 'L' or 'l', the leading ( k + 1 )+* by n part of the array A must contain the lower triangular+* band part of the matrix of coefficients, supplied column by+* column, with the leading diagonal of the matrix in row 1 of+* the array, the first sub-diagonal starting at position 1 in+* row 2, and so on. The bottom right k by k triangle of the+* array A is not referenced.+* The following program segment will transfer a lower+* triangular band matrix from conventional full matrix storage+* to band storage:+*+* DO 20, J = 1, N+* M = 1 - J+* DO 10, I = J, MIN( N, J + K )+* A( M + I, J ) = matrix( I, J )+* 10 CONTINUE+* 20 CONTINUE+*+* Note that when DIAG = 'U' or 'u' the elements of the array A+* corresponding to the diagonal elements of the matrix are not+* referenced, but are assumed to be unity.+* Unchanged on exit.+*+* LDA - INTEGER.+* On entry, LDA specifies the first dimension of A as declared+* in the calling (sub) program. LDA must be at least+* ( k + 1 ).+* Unchanged on exit.+*+* X - COMPLEX*16 array of dimension at least+* ( 1 + ( n - 1 )*abs( INCX ) ).+* Before entry, the incremented array X must contain the n+* element vector x. On exit, X is overwritten with the+* tranformed vector x.+*+* INCX - INTEGER.+* On entry, INCX specifies the increment for the elements of+* X. INCX must not be zero.+* Unchanged on exit.+*+* Further Details+* ===============+*+* Level 2 Blas routine.+*+* -- Written on 22-October-1986.+* Jack Dongarra, Argonne National Lab.+* Jeremy Du Croz, Nag Central Office.+* Sven Hammarling, Nag Central Office.+* Richard Hanson, Sandia National Labs.+*+* =====================================================================+*+* .. Parameters ..+ DOUBLE COMPLEX ZERO+ PARAMETER (ZERO= (0.0D+0,0.0D+0))+* ..+* .. Local Scalars ..+ DOUBLE COMPLEX TEMP+ INTEGER I,INFO,IX,J,JX,KPLUS1,KX,L+ LOGICAL NOCONJ,NOUNIT+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. External Subroutines ..+ EXTERNAL XERBLA+* ..+* .. Intrinsic Functions ..+ INTRINSIC DCONJG,MAX,MIN+* ..+*+* Test the input parameters.+*+ INFO = 0+ IF (.NOT.LSAME(UPLO,'U') .AND. .NOT.LSAME(UPLO,'L')) THEN+ INFO = 1+ ELSE IF (.NOT.LSAME(TRANS,'N') .AND. .NOT.LSAME(TRANS,'T') .AND.+ + .NOT.LSAME(TRANS,'C')) THEN+ INFO = 2+ ELSE IF (.NOT.LSAME(DIAG,'U') .AND. .NOT.LSAME(DIAG,'N')) THEN+ INFO = 3+ ELSE IF (N.LT.0) THEN+ INFO = 4+ ELSE IF (K.LT.0) THEN+ INFO = 5+ ELSE IF (LDA.LT. (K+1)) THEN+ INFO = 7+ ELSE IF (INCX.EQ.0) THEN+ INFO = 9+ END IF+ IF (INFO.NE.0) THEN+ CALL XERBLA('ZTBMV ',INFO)+ RETURN+ END IF+*+* Quick return if possible.+*+ IF (N.EQ.0) RETURN+*+ NOCONJ = LSAME(TRANS,'T')+ NOUNIT = LSAME(DIAG,'N')+*+* Set up the start point in X if the increment is not unity. This+* will be ( N - 1 )*INCX too small for descending loops.+*+ IF (INCX.LE.0) THEN+ KX = 1 - (N-1)*INCX+ ELSE IF (INCX.NE.1) THEN+ KX = 1+ END IF+*+* Start the operations. In this version the elements of A are+* accessed sequentially with one pass through A.+*+ IF (LSAME(TRANS,'N')) THEN+*+* Form x := A*x.+*+ IF (LSAME(UPLO,'U')) THEN+ KPLUS1 = K + 1+ IF (INCX.EQ.1) THEN+ DO 20 J = 1,N+ IF (X(J).NE.ZERO) THEN+ TEMP = X(J)+ L = KPLUS1 - J+ DO 10 I = MAX(1,J-K),J - 1+ X(I) = X(I) + TEMP*A(L+I,J)+ 10 CONTINUE+ IF (NOUNIT) X(J) = X(J)*A(KPLUS1,J)+ END IF+ 20 CONTINUE+ ELSE+ JX = KX+ DO 40 J = 1,N+ IF (X(JX).NE.ZERO) THEN+ TEMP = X(JX)+ IX = KX+ L = KPLUS1 - J+ DO 30 I = MAX(1,J-K),J - 1+ X(IX) = X(IX) + TEMP*A(L+I,J)+ IX = IX + INCX+ 30 CONTINUE+ IF (NOUNIT) X(JX) = X(JX)*A(KPLUS1,J)+ END IF+ JX = JX + INCX+ IF (J.GT.K) KX = KX + INCX+ 40 CONTINUE+ END IF+ ELSE+ IF (INCX.EQ.1) THEN+ DO 60 J = N,1,-1+ IF (X(J).NE.ZERO) THEN+ TEMP = X(J)+ L = 1 - J+ DO 50 I = MIN(N,J+K),J + 1,-1+ X(I) = X(I) + TEMP*A(L+I,J)+ 50 CONTINUE+ IF (NOUNIT) X(J) = X(J)*A(1,J)+ END IF+ 60 CONTINUE+ ELSE+ KX = KX + (N-1)*INCX+ JX = KX+ DO 80 J = N,1,-1+ IF (X(JX).NE.ZERO) THEN+ TEMP = X(JX)+ IX = KX+ L = 1 - J+ DO 70 I = MIN(N,J+K),J + 1,-1+ X(IX) = X(IX) + TEMP*A(L+I,J)+ IX = IX - INCX+ 70 CONTINUE+ IF (NOUNIT) X(JX) = X(JX)*A(1,J)+ END IF+ JX = JX - INCX+ IF ((N-J).GE.K) KX = KX - INCX+ 80 CONTINUE+ END IF+ END IF+ ELSE+*+* Form x := A'*x or x := conjg( A' )*x.+*+ IF (LSAME(UPLO,'U')) THEN+ KPLUS1 = K + 1+ IF (INCX.EQ.1) THEN+ DO 110 J = N,1,-1+ TEMP = X(J)+ L = KPLUS1 - J+ IF (NOCONJ) THEN+ IF (NOUNIT) TEMP = TEMP*A(KPLUS1,J)+ DO 90 I = J - 1,MAX(1,J-K),-1+ TEMP = TEMP + A(L+I,J)*X(I)+ 90 CONTINUE+ ELSE+ IF (NOUNIT) TEMP = TEMP*DCONJG(A(KPLUS1,J))+ DO 100 I = J - 1,MAX(1,J-K),-1+ TEMP = TEMP + DCONJG(A(L+I,J))*X(I)+ 100 CONTINUE+ END IF+ X(J) = TEMP+ 110 CONTINUE+ ELSE+ KX = KX + (N-1)*INCX+ JX = KX+ DO 140 J = N,1,-1+ TEMP = X(JX)+ KX = KX - INCX+ IX = KX+ L = KPLUS1 - J+ IF (NOCONJ) THEN+ IF (NOUNIT) TEMP = TEMP*A(KPLUS1,J)+ DO 120 I = J - 1,MAX(1,J-K),-1+ TEMP = TEMP + A(L+I,J)*X(IX)+ IX = IX - INCX+ 120 CONTINUE+ ELSE+ IF (NOUNIT) TEMP = TEMP*DCONJG(A(KPLUS1,J))+ DO 130 I = J - 1,MAX(1,J-K),-1+ TEMP = TEMP + DCONJG(A(L+I,J))*X(IX)+ IX = IX - INCX+ 130 CONTINUE+ END IF+ X(JX) = TEMP+ JX = JX - INCX+ 140 CONTINUE+ END IF+ ELSE+ IF (INCX.EQ.1) THEN+ DO 170 J = 1,N+ TEMP = X(J)+ L = 1 - J+ IF (NOCONJ) THEN+ IF (NOUNIT) TEMP = TEMP*A(1,J)+ DO 150 I = J + 1,MIN(N,J+K)+ TEMP = TEMP + A(L+I,J)*X(I)+ 150 CONTINUE+ ELSE+ IF (NOUNIT) TEMP = TEMP*DCONJG(A(1,J))+ DO 160 I = J + 1,MIN(N,J+K)+ TEMP = TEMP + DCONJG(A(L+I,J))*X(I)+ 160 CONTINUE+ END IF+ X(J) = TEMP+ 170 CONTINUE+ ELSE+ JX = KX+ DO 200 J = 1,N+ TEMP = X(JX)+ KX = KX + INCX+ IX = KX+ L = 1 - J+ IF (NOCONJ) THEN+ IF (NOUNIT) TEMP = TEMP*A(1,J)+ DO 180 I = J + 1,MIN(N,J+K)+ TEMP = TEMP + A(L+I,J)*X(IX)+ IX = IX + INCX+ 180 CONTINUE+ ELSE+ IF (NOUNIT) TEMP = TEMP*DCONJG(A(1,J))+ DO 190 I = J + 1,MIN(N,J+K)+ TEMP = TEMP + DCONJG(A(L+I,J))*X(IX)+ IX = IX + INCX+ 190 CONTINUE+ END IF+ X(JX) = TEMP+ JX = JX + INCX+ 200 CONTINUE+ END IF+ END IF+ END IF+*+ RETURN+*+* End of ZTBMV .+*+ END
+ eigen3/cmake/EigenConfigureTesting.cmake view
@@ -0,0 +1,81 @@+include(EigenTesting)+include(CheckCXXSourceCompiles)++# configure the "site" and "buildname" +ei_set_sitename()++# retrieve and store the build string+ei_set_build_string()++add_custom_target(buildtests)+add_custom_target(check COMMAND "ctest")+add_dependencies(check buildtests)++# check whether /bin/bash exists+find_file(EIGEN_BIN_BASH_EXISTS "/bin/bash" PATHS "/" NO_DEFAULT_PATH)++# CMake/Ctest does not allow us to change the build command,+# so we have to workaround by directly editing the generated DartConfiguration.tcl file+# save CMAKE_MAKE_PROGRAM+set(CMAKE_MAKE_PROGRAM_SAVE ${CMAKE_MAKE_PROGRAM})+# and set a fake one+set(CMAKE_MAKE_PROGRAM "@EIGEN_MAKECOMMAND_PLACEHOLDER@")++# This call activates testing and generates the DartConfiguration.tcl+include(CTest)++set(EIGEN_TEST_BUILD_FLAGS " " CACHE STRING "Options passed to the build command of unit tests")++# overwrite default DartConfiguration.tcl+# The worarounds are different for each version of the MSVC IDE+if(MSVC_IDE)+ if(CMAKE_MAKE_PROGRAM_SAVE MATCHES "devenv") # devenv+ set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} Eigen.sln /build \"Release\" /project buildtests ${EIGEN_TEST_BUILD_FLAGS} \n# ") + else() # msbuild+ set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} buildtests.vcxproj /p:Configuration=\${CTEST_CONFIGURATION_TYPE} ${EIGEN_TEST_BUILD_FLAGS}\n# ")+ endif()+else()+ # for make and nmake+ set(EIGEN_MAKECOMMAND_PLACEHOLDER "${CMAKE_MAKE_PROGRAM_SAVE} buildtests ${EIGEN_TEST_BUILD_FLAGS}")+endif()++# copy ctest properties, which currently+# o raise the warning levels+configure_file(${CMAKE_CURRENT_BINARY_DIR}/DartConfiguration.tcl ${CMAKE_BINARY_DIR}/DartConfiguration.tcl)++# restore default CMAKE_MAKE_PROGRAM+set(CMAKE_MAKE_PROGRAM ${CMAKE_MAKE_PROGRAM_SAVE})+# un-set temporary variables so that it is like they never existed. +# CMake 2.6.3 introduces the more logical unset() syntax for this.+set(CMAKE_MAKE_PROGRAM_SAVE) +set(EIGEN_MAKECOMMAND_PLACEHOLDER)++configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CTestCustom.cmake.in ${CMAKE_BINARY_DIR}/CTestCustom.cmake)++# some documentation of this function would be nice+ei_init_testing()++# configure Eigen related testing options+option(EIGEN_NO_ASSERTION_CHECKING "Disable checking of assertions using exceptions" OFF)+option(EIGEN_DEBUG_ASSERTS "Enable advanced debuging of assertions" OFF)++if(CMAKE_COMPILER_IS_GNUCXX)+ option(EIGEN_COVERAGE_TESTING "Enable/disable gcov" OFF)+ if(EIGEN_COVERAGE_TESTING)+ set(COVERAGE_FLAGS "-fprofile-arcs -ftest-coverage")+ set(CTEST_CUSTOM_COVERAGE_EXCLUDE "/test/")+ else(EIGEN_COVERAGE_TESTING)+ set(COVERAGE_FLAGS "")+ endif(EIGEN_COVERAGE_TESTING)+ if(EIGEN_TEST_C++0x)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++0x")+ endif(EIGEN_TEST_C++0x)+ if(CMAKE_SYSTEM_NAME MATCHES Linux)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_FLAGS} -g2")+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} ${COVERAGE_FLAGS} -O2 -g2")+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${COVERAGE_FLAGS} -fno-inline-functions")+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${COVERAGE_FLAGS} -O0 -g3")+ endif(CMAKE_SYSTEM_NAME MATCHES Linux)+elseif(MSVC)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_CRT_SECURE_NO_WARNINGS /D_SCL_SECURE_NO_WARNINGS")+endif(CMAKE_COMPILER_IS_GNUCXX)
+ eigen3/cmake/EigenDetermineOSVersion.cmake view
@@ -0,0 +1,46 @@+# The utility function DetermineOSVersion aims at providing an+# improved version of the CMake variable ${CMAKE_SYSTEM} on Windows+# machines.+#+# Usage:+# include(EigenDetermineOSVersion)+# DetermineOSVersion(OS_VERSION)+# message("OS: ${OS_VERSION}")++# - A little helper variable which should not be directly called+function(DetermineShortWindowsName WIN_VERSION win_num_version)+ if (${win_num_version} VERSION_EQUAL "6.1")+ set(_version "win7")+ elseif(${win_num_version} VERSION_EQUAL "6.0")+ set(_version "winVista")+ elseif(${win_num_version} VERSION_EQUAL "5.2")+ set(_version "winXpProf")+ elseif(${win_num_version} VERSION_EQUAL "5.1")+ set(_version "winXp")+ elseif(${win_num_version} VERSION_EQUAL "5.0")+ set(_version "win2000Prof")+ else()+ set(_version "unknownWin")+ endif()+ set(${WIN_VERSION} ${_version} PARENT_SCOPE)+endfunction()++function(DetermineOSVersion OS_VERSION)+ if (WIN32)+ file (TO_NATIVE_PATH "$ENV{COMSPEC}" SHELL)+ exec_program( ${SHELL} ARGS "/c" "ver" OUTPUT_VARIABLE ver_output)+ + string(REGEX MATCHALL "[0-9]+"+ ver_list "${ver_output}")+ list(GET ver_list 0 _major) + list(GET ver_list 1 _minor)+ + set(win_num_version ${_major}.${_minor})+ DetermineShortWindowsName(win_version "${win_num_version}")+ if(win_version)+ set(${OS_VERSION} ${win_version} PARENT_SCOPE)+ endif()+ else()+ set(${OS_VERSION} ${CMAKE_SYSTEM} PARENT_SCOPE)+ endif()+endfunction()
+ eigen3/cmake/EigenDetermineVSServicePack.cmake view
@@ -0,0 +1,27 @@+include(CMakeDetermineVSServicePack)++# The code is almost identical to the CMake version. The only difference is that we remove+# _DetermineVSServicePack_FastCheckVersionWithCompiler which lead to errors on some systems.+function(EigenDetermineVSServicePack _pack)+ if(NOT DETERMINED_VS_SERVICE_PACK OR NOT ${_pack})++ if(NOT DETERMINED_VS_SERVICE_PACK)+ _DetermineVSServicePack_CheckVersionWithTryCompile(DETERMINED_VS_SERVICE_PACK _cl_version)+ if(NOT DETERMINED_VS_SERVICE_PACK)+ _DetermineVSServicePack_CheckVersionWithTryRun(DETERMINED_VS_SERVICE_PACK _cl_version)+ endif()+ endif()++ if(DETERMINED_VS_SERVICE_PACK)++ if(_cl_version)+ # Call helper function to determine VS version+ _DetermineVSServicePackFromCompiler(_sp "${_cl_version}")+ if(_sp)+ set(${_pack} ${_sp} CACHE INTERNAL+ "The Visual Studio Release with Service Pack")+ endif()+ endif()+ endif()+ endif()+endfunction()
+ eigen3/cmake/EigenTesting.cmake view
@@ -0,0 +1,497 @@++macro(ei_add_property prop value)+ get_property(previous GLOBAL PROPERTY ${prop}) + if ((NOT previous) OR (previous STREQUAL ""))+ set_property(GLOBAL PROPERTY ${prop} "${value}")+ else()+ set_property(GLOBAL PROPERTY ${prop} "${previous} ${value}")+ endif() +endmacro(ei_add_property)++#internal. See documentation of ei_add_test for details.+macro(ei_add_test_internal testname testname_with_suffix)+ set(targetname ${testname_with_suffix})++ set(filename ${testname}.cpp)+ add_executable(${targetname} ${filename})+ if (targetname MATCHES "^eigen2_")+ add_dependencies(eigen2_buildtests ${targetname})+ else()+ add_dependencies(buildtests ${targetname})+ endif()++ if(EIGEN_NO_ASSERTION_CHECKING)+ ei_add_target_property(${targetname} COMPILE_FLAGS "-DEIGEN_NO_ASSERTION_CHECKING=1")+ else(EIGEN_NO_ASSERTION_CHECKING)+ if(EIGEN_DEBUG_ASSERTS)+ ei_add_target_property(${targetname} COMPILE_FLAGS "-DEIGEN_DEBUG_ASSERTS=1")+ endif(EIGEN_DEBUG_ASSERTS)+ endif(EIGEN_NO_ASSERTION_CHECKING)+ + ei_add_target_property(${targetname} COMPILE_FLAGS "-DEIGEN_TEST_MAX_SIZE=${EIGEN_TEST_MAX_SIZE}")++ ei_add_target_property(${targetname} COMPILE_FLAGS "-DEIGEN_TEST_FUNC=${testname}")+ + if(MSVC AND NOT EIGEN_SPLIT_LARGE_TESTS)+ ei_add_target_property(${targetname} COMPILE_FLAGS "/bigobj")+ endif() ++ # let the user pass flags.+ if(${ARGC} GREATER 2)+ ei_add_target_property(${targetname} COMPILE_FLAGS "${ARGV2}")+ endif(${ARGC} GREATER 2)+ + if(EIGEN_TEST_CUSTOM_CXX_FLAGS)+ ei_add_target_property(${targetname} COMPILE_FLAGS "${EIGEN_TEST_CUSTOM_CXX_FLAGS}")+ endif()++ if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)+ target_link_libraries(${targetname} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})+ endif()+ if(EXTERNAL_LIBS)+ target_link_libraries(${targetname} ${EXTERNAL_LIBS})+ endif()+ if(EIGEN_TEST_CUSTOM_LINKER_FLAGS)+ target_link_libraries(${targetname} ${EIGEN_TEST_CUSTOM_LINKER_FLAGS})+ endif()++ if(${ARGC} GREATER 3)+ set(libs_to_link ${ARGV3})+ # it could be that some cmake module provides a bad library string " " (just spaces),+ # and that severely breaks target_link_libraries ("can't link to -l-lstdc++" errors).+ # so we check for strings containing only spaces.+ string(STRIP "${libs_to_link}" libs_to_link_stripped)+ string(LENGTH "${libs_to_link_stripped}" libs_to_link_stripped_length)+ if(${libs_to_link_stripped_length} GREATER 0)+ # notice: no double quotes around ${libs_to_link} here. It may be a list.+ target_link_libraries(${targetname} ${libs_to_link})+ endif()+ endif() ++ if(EIGEN_BIN_BASH_EXISTS)+ add_test(${testname_with_suffix} "${Eigen_SOURCE_DIR}/test/runtest.sh" "${testname_with_suffix}")+ else()+ add_test(${testname_with_suffix} "${targetname}")+ endif()+ + # Specify target and test labels accoirding to EIGEN_CURRENT_SUBPROJECT+ get_property(current_subproject GLOBAL PROPERTY EIGEN_CURRENT_SUBPROJECT) + if ((current_subproject) AND (NOT (current_subproject STREQUAL "")))+ set_property(TARGET ${targetname} PROPERTY LABELS "Build${current_subproject}")+ add_dependencies("Build${current_subproject}" ${targetname})+ set_property(TEST ${testname_with_suffix} PROPERTY LABELS "${current_subproject}")+ endif()++endmacro(ei_add_test_internal)++# Macro to add a test+#+# the unique mandatory parameter testname must correspond to a file+# <testname>.cpp which follows this pattern:+#+# #include "main.h"+# void test_<testname>() { ... }+#+# Depending on the contents of that file, this macro can have 2 behaviors,+# see below.+#+# The optional 2nd parameter is libraries to link to.+#+# A. Default behavior+#+# this macro adds an executable <testname> as well as a ctest test+# named <testname> too.+#+# On platforms with bash simply run:+# "ctest -V" or "ctest -V -R <testname>"+# On other platform use ctest as usual+#+# B. Multi-part behavior+#+# If the source file matches the regexp+# CALL_SUBTEST_[0-9]+|EIGEN_TEST_PART_[0-9]++# then it is interpreted as a multi-part test. The behavior then depends on the+# CMake option EIGEN_SPLIT_LARGE_TESTS, which is ON by default.+#+# If EIGEN_SPLIT_LARGE_TESTS is OFF, the behavior is the same as in A (the multi-part+# aspect is ignored).+#+# If EIGEN_SPLIT_LARGE_TESTS is ON, the test is split into multiple executables+# test_<testname>_<N>+# where N runs from 1 to the greatest occurence found in the source file. Each of these+# executables is built passing -DEIGEN_TEST_PART_N. This allows to split large tests+# into smaller executables.+#+# Moreover, targets <testname> are still generated, they+# have the effect of building all the parts of the test.+#+# Again, ctest -R allows to run all matching tests.+macro(ei_add_test testname)+ get_property(EIGEN_TESTS_LIST GLOBAL PROPERTY EIGEN_TESTS_LIST)+ set(EIGEN_TESTS_LIST "${EIGEN_TESTS_LIST}${testname}\n")+ set_property(GLOBAL PROPERTY EIGEN_TESTS_LIST "${EIGEN_TESTS_LIST}")++ file(READ "${testname}.cpp" test_source)+ set(parts 0)+ string(REGEX MATCHALL "CALL_SUBTEST_[0-9]+|EIGEN_TEST_PART_[0-9]+|EIGEN_SUFFIXES(;[0-9]+)+"+ occurences "${test_source}")+ string(REGEX REPLACE "CALL_SUBTEST_|EIGEN_TEST_PART_|EIGEN_SUFFIXES" "" suffixes "${occurences}")+ list(REMOVE_DUPLICATES suffixes)+ if(EIGEN_SPLIT_LARGE_TESTS AND suffixes)+ add_custom_target(${testname})+ foreach(suffix ${suffixes})+ ei_add_test_internal(${testname} ${testname}_${suffix}+ "${ARGV1} -DEIGEN_TEST_PART_${suffix}=1" "${ARGV2}")+ add_dependencies(${testname} ${testname}_${suffix})+ endforeach(suffix)+ else(EIGEN_SPLIT_LARGE_TESTS AND suffixes)+ set(symbols_to_enable_all_parts "")+ foreach(suffix ${suffixes})+ set(symbols_to_enable_all_parts+ "${symbols_to_enable_all_parts} -DEIGEN_TEST_PART_${suffix}=1")+ endforeach(suffix)+ ei_add_test_internal(${testname} ${testname} "${ARGV1} ${symbols_to_enable_all_parts}" "${ARGV2}")+ endif(EIGEN_SPLIT_LARGE_TESTS AND suffixes)+endmacro(ei_add_test)+++# adds a failtest, i.e. a test that succeed if the program fails to compile+# note that the test runner for these is CMake itself, when passed -DEIGEN_FAILTEST=ON+# so here we're just running CMake commands immediately, we're not adding any targets.+macro(ei_add_failtest testname)+ get_property(EIGEN_FAILTEST_FAILURE_COUNT GLOBAL PROPERTY EIGEN_FAILTEST_FAILURE_COUNT)+ get_property(EIGEN_FAILTEST_COUNT GLOBAL PROPERTY EIGEN_FAILTEST_COUNT)++ message(STATUS "Checking failtest: ${testname}")+ set(filename "${testname}.cpp")+ file(READ "${filename}" test_source)++ try_compile(succeeds_when_it_should_fail+ "${CMAKE_CURRENT_BINARY_DIR}"+ "${CMAKE_CURRENT_SOURCE_DIR}/${filename}"+ COMPILE_DEFINITIONS "-DEIGEN_SHOULD_FAIL_TO_BUILD")+ if (succeeds_when_it_should_fail)+ message(STATUS "FAILED: ${testname} build succeeded when it should have failed")+ endif()++ try_compile(succeeds_when_it_should_succeed+ "${CMAKE_CURRENT_BINARY_DIR}"+ "${CMAKE_CURRENT_SOURCE_DIR}/${filename}"+ COMPILE_DEFINITIONS)+ if (NOT succeeds_when_it_should_succeed)+ message(STATUS "FAILED: ${testname} build failed when it should have succeeded")+ endif()++ if (succeeds_when_it_should_fail OR NOT succeeds_when_it_should_succeed)+ math(EXPR EIGEN_FAILTEST_FAILURE_COUNT ${EIGEN_FAILTEST_FAILURE_COUNT}+1)+ endif()++ math(EXPR EIGEN_FAILTEST_COUNT ${EIGEN_FAILTEST_COUNT}+1)++ set_property(GLOBAL PROPERTY EIGEN_FAILTEST_FAILURE_COUNT ${EIGEN_FAILTEST_FAILURE_COUNT})+ set_property(GLOBAL PROPERTY EIGEN_FAILTEST_COUNT ${EIGEN_FAILTEST_COUNT})+endmacro(ei_add_failtest)++# print a summary of the different options+macro(ei_testing_print_summary)+ message(STATUS "************************************************************")+ message(STATUS "*** Eigen's unit tests configuration summary ***")+ message(STATUS "************************************************************")+ message(STATUS "")+ message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")+ message(STATUS "Build site: ${SITE}")+ message(STATUS "Build string: ${BUILDNAME}")+ get_property(EIGEN_TESTING_SUMMARY GLOBAL PROPERTY EIGEN_TESTING_SUMMARY)+ get_property(EIGEN_TESTED_BACKENDS GLOBAL PROPERTY EIGEN_TESTED_BACKENDS)+ get_property(EIGEN_MISSING_BACKENDS GLOBAL PROPERTY EIGEN_MISSING_BACKENDS)+ message(STATUS "Enabled backends: ${EIGEN_TESTED_BACKENDS}")+ message(STATUS "Disabled backends: ${EIGEN_MISSING_BACKENDS}")++ if(EIGEN_DEFAULT_TO_ROW_MAJOR)+ message(STATUS "Default order: Row-major")+ else()+ message(STATUS "Default order: Column-major")+ endif()++ if(EIGEN_TEST_NO_EXPLICIT_ALIGNMENT)+ message(STATUS "Explicit alignment (hence vectorization) disabled")+ elseif(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)+ message(STATUS "Explicit vectorization disabled (alignment kept enabled)")+ else()+ + message(STATUS "Maximal matrix/vector size: ${EIGEN_TEST_MAX_SIZE}")++ if(EIGEN_TEST_SSE2)+ message(STATUS "SSE2: ON")+ else()+ message(STATUS "SSE2: Using architecture defaults")+ endif()++ if(EIGEN_TEST_SSE3)+ message(STATUS "SSE3: ON")+ else()+ message(STATUS "SSE3: Using architecture defaults")+ endif()++ if(EIGEN_TEST_SSSE3)+ message(STATUS "SSSE3: ON")+ else()+ message(STATUS "SSSE3: Using architecture defaults")+ endif()++ if(EIGEN_TEST_SSE4_1)+ message(STATUS "SSE4.1: ON")+ else()+ message(STATUS "SSE4.1: Using architecture defaults")+ endif()++ if(EIGEN_TEST_SSE4_2)+ message(STATUS "SSE4.2: ON")+ else()+ message(STATUS "SSE4.2: Using architecture defaults")+ endif()++ if(EIGEN_TEST_ALTIVEC)+ message(STATUS "Altivec: ON")+ else()+ message(STATUS "Altivec: Using architecture defaults")+ endif()++ if(EIGEN_TEST_NEON)+ message(STATUS "ARM NEON: ON")+ else()+ message(STATUS "ARM NEON: Using architecture defaults")+ endif()++ endif() # vectorization / alignment options++ message(STATUS "\n${EIGEN_TESTING_SUMMARY}")++ message(STATUS "************************************************************")+endmacro(ei_testing_print_summary)++macro(ei_init_testing)+ define_property(GLOBAL PROPERTY EIGEN_CURRENT_SUBPROJECT BRIEF_DOCS " " FULL_DOCS " ")+ define_property(GLOBAL PROPERTY EIGEN_TESTED_BACKENDS BRIEF_DOCS " " FULL_DOCS " ")+ define_property(GLOBAL PROPERTY EIGEN_MISSING_BACKENDS BRIEF_DOCS " " FULL_DOCS " ")+ define_property(GLOBAL PROPERTY EIGEN_TESTING_SUMMARY BRIEF_DOCS " " FULL_DOCS " ")+ define_property(GLOBAL PROPERTY EIGEN_TESTS_LIST BRIEF_DOCS " " FULL_DOCS " ")++ set_property(GLOBAL PROPERTY EIGEN_TESTED_BACKENDS "")+ set_property(GLOBAL PROPERTY EIGEN_MISSING_BACKENDS "")+ set_property(GLOBAL PROPERTY EIGEN_TESTING_SUMMARY "")+ set_property(GLOBAL PROPERTY EIGEN_TESTS_LIST "")++ define_property(GLOBAL PROPERTY EIGEN_FAILTEST_FAILURE_COUNT BRIEF_DOCS " " FULL_DOCS " ")+ define_property(GLOBAL PROPERTY EIGEN_FAILTEST_COUNT BRIEF_DOCS " " FULL_DOCS " ")++ set_property(GLOBAL PROPERTY EIGEN_FAILTEST_FAILURE_COUNT "0")+ set_property(GLOBAL PROPERTY EIGEN_FAILTEST_COUNT "0")+ + # uncomment anytime you change the ei_get_compilerver_from_cxx_version_string macro+ # ei_test_get_compilerver_from_cxx_version_string()+endmacro(ei_init_testing)++macro(ei_set_sitename)+ # if the sitename is not yet set, try to set it+ if(NOT ${SITE} OR ${SITE} STREQUAL "")+ set(eigen_computername $ENV{COMPUTERNAME})+ set(eigen_hostname $ENV{HOSTNAME})+ if(eigen_hostname)+ set(SITE ${eigen_hostname})+ elseif(eigen_computername)+ set(SITE ${eigen_computername})+ endif()+ endif()+ # in case it is already set, enforce lower case+ if(SITE)+ string(TOLOWER ${SITE} SITE)+ endif() +endmacro(ei_set_sitename)++macro(ei_get_compilerver VAR)+ if(MSVC)+ # on windows system, we use a modified CMake script + include(EigenDetermineVSServicePack)+ EigenDetermineVSServicePack( my_service_pack )++ if( my_service_pack )+ set(${VAR} ${my_service_pack})+ else()+ set(${VAR} "na")+ endif()+ else()+ # on all other system we rely on ${CMAKE_CXX_COMPILER}+ # supporting a "--version" or "/version" flag+ + if(WIN32 AND NOT CYGWIN)+ set(EIGEN_CXX_FLAG_VERSION "/version")+ else()+ set(EIGEN_CXX_FLAG_VERSION "--version")+ endif()+ + # check whether the head command exists+ find_program(HEAD_EXE head NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_PATH NO_CMAKE_SYSTEM_PATH)+ if(HEAD_EXE)+ execute_process(COMMAND ${CMAKE_CXX_COMPILER} ${EIGEN_CXX_FLAG_VERSION}+ COMMAND head -n 1+ OUTPUT_VARIABLE eigen_cxx_compiler_version_string OUTPUT_STRIP_TRAILING_WHITESPACE)+ else()+ execute_process(COMMAND ${CMAKE_CXX_COMPILER} ${EIGEN_CXX_FLAG_VERSION}+ OUTPUT_VARIABLE eigen_cxx_compiler_version_string OUTPUT_STRIP_TRAILING_WHITESPACE)+ string(REGEX REPLACE "[\n\r].*" "" eigen_cxx_compiler_version_string ${eigen_cxx_compiler_version_string})+ endif()+ + ei_get_compilerver_from_cxx_version_string("${eigen_cxx_compiler_version_string}" CNAME CVER)+ set(${VAR} "${CNAME}-${CVER}")+ + endif()+endmacro(ei_get_compilerver)++# Extract compiler name and version from a raw version string+# WARNING: if you edit thid macro, then please test it by uncommenting+# the testing macro call in ei_init_testing() of the EigenTesting.cmake file.+# See also the ei_test_get_compilerver_from_cxx_version_string macro at the end of the file+macro(ei_get_compilerver_from_cxx_version_string VERSTRING CNAME CVER)+ # extract possible compiler names + string(REGEX MATCH "g\\+\\+" ei_has_gpp ${VERSTRING})+ string(REGEX MATCH "llvm|LLVM" ei_has_llvm ${VERSTRING})+ string(REGEX MATCH "gcc|GCC" ei_has_gcc ${VERSTRING})+ string(REGEX MATCH "icpc|ICC" ei_has_icpc ${VERSTRING})+ string(REGEX MATCH "clang|CLANG" ei_has_clang ${VERSTRING})+ + # combine them+ if((ei_has_llvm) AND (ei_has_gpp OR ei_has_gcc))+ set(${CNAME} "llvm-g++")+ elseif((ei_has_llvm) AND (ei_has_clang))+ set(${CNAME} "llvm-clang++")+ elseif(ei_has_icpc)+ set(${CNAME} "icpc")+ elseif(ei_has_gpp OR ei_has_gcc)+ set(${CNAME} "g++")+ else()+ set(${CNAME} "_")+ endif()+ + # extract possible version numbers+ # first try to extract 3 isolated numbers:+ string(REGEX MATCH " [0-9]+\\.[0-9]+\\.[0-9]+" eicver ${VERSTRING})+ if(NOT eicver)+ # try to extract 2 isolated ones:+ string(REGEX MATCH " [0-9]+\\.[0-9]+" eicver ${VERSTRING})+ if(NOT eicver)+ # try to extract 3:+ string(REGEX MATCH "[^0-9][0-9]+\\.[0-9]+\\.[0-9]+" eicver ${VERSTRING})+ if(NOT eicver)+ # try to extract 2:+ string(REGEX MATCH "[^0-9][0-9]+\\.[0-9]+" eicver ${VERSTRING})+ else()+ set(eicver " _")+ endif()+ endif()+ endif()+ + string(REGEX REPLACE ".(.*)" "\\1" ${CVER} ${eicver})+ +endmacro(ei_get_compilerver_from_cxx_version_string)++macro(ei_get_cxxflags VAR)+ set(${VAR} "")+ ei_is_64bit_env(IS_64BIT_ENV)+ if(EIGEN_TEST_NEON)+ set(${VAR} NEON)+ elseif(EIGEN_TEST_ALTIVEC)+ set(${VAR} ALVEC)+ elseif(EIGEN_TEST_SSE4_2)+ set(${VAR} SSE42)+ elseif(EIGEN_TEST_SSE4_1)+ set(${VAR} SSE41)+ elseif(EIGEN_TEST_SSSE3)+ set(${VAR} SSSE3)+ elseif(EIGEN_TEST_SSE3)+ set(${VAR} SSE3)+ elseif(EIGEN_TEST_SSE2 OR IS_64BIT_ENV)+ set(${VAR} SSE2) + endif()++ if(EIGEN_TEST_OPENMP)+ if (${VAR} STREQUAL "")+ set(${VAR} OMP)+ else()+ set(${VAR} ${${VAR}}-OMP)+ endif()+ endif()+ + if(EIGEN_DEFAULT_TO_ROW_MAJOR)+ if (${VAR} STREQUAL "")+ set(${VAR} ROW)+ else()+ set(${VAR} ${${VAR}}-ROWMAJ)+ endif() + endif()+endmacro(ei_get_cxxflags)++macro(ei_set_build_string)+ ei_get_compilerver(LOCAL_COMPILER_VERSION)+ ei_get_cxxflags(LOCAL_COMPILER_FLAGS)+ + include(EigenDetermineOSVersion)+ DetermineOSVersion(OS_VERSION)++ set(TMP_BUILD_STRING ${OS_VERSION}-${LOCAL_COMPILER_VERSION})++ if (NOT ${LOCAL_COMPILER_FLAGS} STREQUAL "")+ set(TMP_BUILD_STRING ${TMP_BUILD_STRING}-${LOCAL_COMPILER_FLAGS})+ endif()++ ei_is_64bit_env(IS_64BIT_ENV)+ if(NOT IS_64BIT_ENV)+ set(TMP_BUILD_STRING ${TMP_BUILD_STRING}-32bit)+ else()+ set(TMP_BUILD_STRING ${TMP_BUILD_STRING}-64bit)+ endif()+ + if(EIGEN_BUILD_STRING_SUFFIX)+ set(TMP_BUILD_STRING ${TMP_BUILD_STRING}-${EIGEN_BUILD_STRING_SUFFIX})+ endif()++ string(TOLOWER ${TMP_BUILD_STRING} BUILDNAME)+endmacro(ei_set_build_string)++macro(ei_is_64bit_env VAR)+ if(CMAKE_SIZEOF_VOID_P EQUAL 8)+ set(${VAR} 1)+ elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)+ set(${VAR} 0)+ else()+ message(WARNING "Unsupported pointer size. Please contact the authors.")+ endif()+endmacro(ei_is_64bit_env)+++# helper macro for testing ei_get_compilerver_from_cxx_version_string+# STR: raw version string+# REFNAME: expected compiler name+# REFVER: expected compiler version+macro(ei_test1_get_compilerver_from_cxx_version_string STR REFNAME REFVER)+ ei_get_compilerver_from_cxx_version_string(${STR} CNAME CVER)+ if((NOT ${REFNAME} STREQUAL ${CNAME}) OR (NOT ${REFVER} STREQUAL ${CVER}))+ message("STATUS ei_get_compilerver_from_cxx_version_string error:")+ message("Expected \"${REFNAME}-${REFVER}\", got \"${CNAME}-${CVER}\"")+ endif()+endmacro(ei_test1_get_compilerver_from_cxx_version_string)++# macro for testing ei_get_compilerver_from_cxx_version_string+# feel free to add more version strings+macro(ei_test_get_compilerver_from_cxx_version_string)+ ei_test1_get_compilerver_from_cxx_version_string("g++ (SUSE Linux) 4.5.3 20110428 [gcc-4_5-branch revision 173117]" "g++" "4.5.3")+ ei_test1_get_compilerver_from_cxx_version_string("c++ (GCC) 4.5.1 20100924 (Red Hat 4.5.1-4)" "g++" "4.5.1")+ ei_test1_get_compilerver_from_cxx_version_string("icpc (ICC) 11.0 20081105" "icpc" "11.0")+ ei_test1_get_compilerver_from_cxx_version_string("g++-3.4 (GCC) 3.4.6" "g++" "3.4.6")+ ei_test1_get_compilerver_from_cxx_version_string("SUSE Linux clang version 3.0 (branches/release_30 145598) (based on LLVM 3.0)" "llvm-clang++" "3.0")+ ei_test1_get_compilerver_from_cxx_version_string("icpc (ICC) 12.0.5 20110719" "icpc" "12.0.5")+ ei_test1_get_compilerver_from_cxx_version_string("Apple clang version 2.1 (tags/Apple/clang-163.7.1) (based on LLVM 3.0svn)" "llvm-clang++" "2.1")+ ei_test1_get_compilerver_from_cxx_version_string("i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2335.15.00)" "llvm-g++" "4.2.1")+ ei_test1_get_compilerver_from_cxx_version_string("g++-mp-4.4 (GCC) 4.4.6" "g++" "4.4.6")+ ei_test1_get_compilerver_from_cxx_version_string("g++-mp-4.4 (GCC) 2011" "g++" "4.4")+endmacro(ei_test_get_compilerver_from_cxx_version_string)
+ eigen3/cmake/FindAdolc.cmake view
@@ -0,0 +1,20 @@++if (ADOLC_INCLUDES AND ADOLC_LIBRARIES)+ set(ADOLC_FIND_QUIETLY TRUE)+endif (ADOLC_INCLUDES AND ADOLC_LIBRARIES)++find_path(ADOLC_INCLUDES+ NAMES+ adolc/adouble.h+ PATHS+ $ENV{ADOLCDIR}+ ${INCLUDE_INSTALL_DIR}+)++find_library(ADOLC_LIBRARIES adolc PATHS $ENV{ADOLCDIR} ${LIB_INSTALL_DIR})++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(ADOLC DEFAULT_MSG+ ADOLC_INCLUDES ADOLC_LIBRARIES)++mark_as_advanced(ADOLC_INCLUDES ADOLC_LIBRARIES)
+ eigen3/cmake/FindBLAS.cmake view
@@ -0,0 +1,419 @@+# Find BLAS library+#+# This module finds an installed library that implements the BLAS+# linear-algebra interface (see http://www.netlib.org/blas/).+# The list of libraries searched for is mainly taken+# from the autoconf macro file, acx_blas.m4 (distributed at+# http://ac-archive.sourceforge.net/ac-archive/acx_blas.html).+#+# This module sets the following variables:+# BLAS_FOUND - set to true if a library implementing the BLAS interface+# is found+# BLAS_INCLUDE_DIR - Directories containing the BLAS header files+# BLAS_DEFINITIONS - Compilation options to use BLAS+# BLAS_LINKER_FLAGS - Linker flags to use BLAS (excluding -l+# and -L).+# BLAS_LIBRARIES_DIR - Directories containing the BLAS libraries.+# May be null if BLAS_LIBRARIES contains libraries name using full path.+# BLAS_LIBRARIES - List of libraries to link against BLAS interface.+# May be null if the compiler supports auto-link (e.g. VC++).+# BLAS_USE_FILE - The name of the cmake module to include to compile+# applications or libraries using BLAS.+#+# This module was modified by CGAL team:+# - find libraries for a C++ compiler, instead of Fortran+# - added BLAS_INCLUDE_DIR, BLAS_DEFINITIONS and BLAS_LIBRARIES_DIR+# - removed BLAS95_LIBRARIES++include(CheckFunctionExists)+++# This macro checks for the existence of the combination of fortran libraries+# given by _list. If the combination is found, this macro checks (using the+# check_function_exists macro) whether can link against that library+# combination using the name of a routine given by _name using the linker+# flags given by _flags. If the combination of libraries is found and passes+# the link test, LIBRARIES is set to the list of complete library paths that+# have been found and DEFINITIONS to the required definitions.+# Otherwise, LIBRARIES is set to FALSE.+# N.B. _prefix is the prefix applied to the names of all cached variables that+# are generated internally and marked advanced by this macro.+macro(check_fortran_libraries DEFINITIONS LIBRARIES _prefix _name _flags _list _path)+ #message("DEBUG: check_fortran_libraries(${_list} in ${_path})")++ # Check for the existence of the libraries given by _list+ set(_libraries_found TRUE)+ set(_libraries_work FALSE)+ set(${DEFINITIONS} "")+ set(${LIBRARIES} "")+ set(_combined_name)+ foreach(_library ${_list})+ set(_combined_name ${_combined_name}_${_library})++ if(_libraries_found)+ # search first in ${_path}+ find_library(${_prefix}_${_library}_LIBRARY+ NAMES ${_library}+ PATHS ${_path} NO_DEFAULT_PATH+ )+ # if not found, search in environment variables and system+ if ( WIN32 )+ find_library(${_prefix}_${_library}_LIBRARY+ NAMES ${_library}+ PATHS ENV LIB+ )+ elseif ( APPLE )+ find_library(${_prefix}_${_library}_LIBRARY+ NAMES ${_library}+ PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV DYLD_LIBRARY_PATH+ )+ else ()+ find_library(${_prefix}_${_library}_LIBRARY+ NAMES ${_library}+ PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH+ )+ endif()+ mark_as_advanced(${_prefix}_${_library}_LIBRARY)+ set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})+ set(_libraries_found ${${_prefix}_${_library}_LIBRARY})+ endif(_libraries_found)+ endforeach(_library ${_list})+ if(_libraries_found)+ set(_libraries_found ${${LIBRARIES}})+ endif()++ # Test this combination of libraries with the Fortran/f2c interface.+ # We test the Fortran interface first as it is well standardized.+ if(_libraries_found AND NOT _libraries_work)+ set(${DEFINITIONS} "-D${_prefix}_USE_F2C")+ set(${LIBRARIES} ${_libraries_found})+ # Some C++ linkers require the f2c library to link with Fortran libraries.+ # I do not know which ones, thus I just add the f2c library if it is available.+ find_package( F2C QUIET )+ if ( F2C_FOUND )+ set(${DEFINITIONS} ${${DEFINITIONS}} ${F2C_DEFINITIONS})+ set(${LIBRARIES} ${${LIBRARIES}} ${F2C_LIBRARIES})+ endif()+ set(CMAKE_REQUIRED_DEFINITIONS ${${DEFINITIONS}})+ set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}})+ #message("DEBUG: CMAKE_REQUIRED_DEFINITIONS = ${CMAKE_REQUIRED_DEFINITIONS}")+ #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")+ # Check if function exists with f2c calling convention (ie a trailing underscore)+ check_function_exists(${_name}_ ${_prefix}_${_name}_${_combined_name}_f2c_WORKS)+ set(CMAKE_REQUIRED_DEFINITIONS} "")+ set(CMAKE_REQUIRED_LIBRARIES "")+ mark_as_advanced(${_prefix}_${_name}_${_combined_name}_f2c_WORKS)+ set(_libraries_work ${${_prefix}_${_name}_${_combined_name}_f2c_WORKS})+ endif(_libraries_found AND NOT _libraries_work)++ # If not found, test this combination of libraries with a C interface.+ # A few implementations (ie ACML) provide a C interface. Unfortunately, there is no standard.+ if(_libraries_found AND NOT _libraries_work)+ set(${DEFINITIONS} "")+ set(${LIBRARIES} ${_libraries_found})+ set(CMAKE_REQUIRED_DEFINITIONS "")+ set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}})+ #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")+ check_function_exists(${_name} ${_prefix}_${_name}${_combined_name}_WORKS)+ set(CMAKE_REQUIRED_LIBRARIES "")+ mark_as_advanced(${_prefix}_${_name}${_combined_name}_WORKS)+ set(_libraries_work ${${_prefix}_${_name}${_combined_name}_WORKS})+ endif(_libraries_found AND NOT _libraries_work)++ # on failure+ if(NOT _libraries_work)+ set(${DEFINITIONS} "")+ set(${LIBRARIES} FALSE)+ endif()+ #message("DEBUG: ${DEFINITIONS} = ${${DEFINITIONS}}")+ #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}")+endmacro(check_fortran_libraries)+++#+# main+#++# Is it already configured?+if (BLAS_LIBRARIES_DIR OR BLAS_LIBRARIES)++ set(BLAS_FOUND TRUE)++else()++ # reset variables+ set( BLAS_INCLUDE_DIR "" )+ set( BLAS_DEFINITIONS "" )+ set( BLAS_LINKER_FLAGS "" )+ set( BLAS_LIBRARIES "" )+ set( BLAS_LIBRARIES_DIR "" )++ #+ # If Unix, search for BLAS function in possible libraries+ #++ # BLAS in ATLAS library? (http://math-atlas.sourceforge.net/)+ if(NOT BLAS_LIBRARIES)+ check_fortran_libraries(+ BLAS_DEFINITIONS+ BLAS_LIBRARIES+ BLAS+ sgemm+ ""+ "cblas;f77blas;atlas"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"+ )+ endif()++ # BLAS in PhiPACK libraries? (requires generic BLAS lib, too)+ if(NOT BLAS_LIBRARIES)+ check_fortran_libraries(+ BLAS_DEFINITIONS+ BLAS_LIBRARIES+ BLAS+ sgemm+ ""+ "sgemm;dgemm;blas"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"+ )+ endif()++ # BLAS in Alpha CXML library?+ if(NOT BLAS_LIBRARIES)+ check_fortran_libraries(+ BLAS_DEFINITIONS+ BLAS_LIBRARIES+ BLAS+ sgemm+ ""+ "cxml"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"+ )+ endif()++ # BLAS in Alpha DXML library? (now called CXML, see above)+ if(NOT BLAS_LIBRARIES)+ check_fortran_libraries(+ BLAS_DEFINITIONS+ BLAS_LIBRARIES+ BLAS+ sgemm+ ""+ "dxml"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"+ )+ endif()++ # BLAS in Sun Performance library?+ if(NOT BLAS_LIBRARIES)+ check_fortran_libraries(+ BLAS_DEFINITIONS+ BLAS_LIBRARIES+ BLAS+ sgemm+ "-xlic_lib=sunperf"+ "sunperf;sunmath"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"+ )+ if(BLAS_LIBRARIES)+ # Extra linker flag+ set(BLAS_LINKER_FLAGS "-xlic_lib=sunperf")+ endif()+ endif()++ # BLAS in SCSL library? (SGI/Cray Scientific Library)+ if(NOT BLAS_LIBRARIES)+ check_fortran_libraries(+ BLAS_DEFINITIONS+ BLAS_LIBRARIES+ BLAS+ sgemm+ ""+ "scsl"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"+ )+ endif()++ # BLAS in SGIMATH library?+ if(NOT BLAS_LIBRARIES)+ check_fortran_libraries(+ BLAS_DEFINITIONS+ BLAS_LIBRARIES+ BLAS+ sgemm+ ""+ "complib.sgimath"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"+ )+ endif()++ # BLAS in IBM ESSL library? (requires generic BLAS lib, too)+ if(NOT BLAS_LIBRARIES)+ check_fortran_libraries(+ BLAS_DEFINITIONS+ BLAS_LIBRARIES+ BLAS+ sgemm+ ""+ "essl;blas"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"+ )+ endif()++ #BLAS in intel mkl 10 library? (em64t 64bit)+ if(NOT BLAS_LIBRARIES)+ check_fortran_libraries(+ BLAS_DEFINITIONS+ BLAS_LIBRARIES+ BLAS+ sgemm+ ""+ "mkl_intel_lp64;mkl_intel_thread;mkl_core;guide;pthread"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"+ )+ endif()++ ### windows version of intel mkl 10?+ if(NOT BLAS_LIBRARIES)+ check_fortran_libraries(+ BLAS_DEFINITIONS+ BLAS_LIBRARIES+ BLAS+ SGEMM+ ""+ "mkl_c_dll;mkl_intel_thread_dll;mkl_core_dll;libguide40"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"+ )+ endif()++ #older versions of intel mkl libs++ # BLAS in intel mkl library? (shared)+ if(NOT BLAS_LIBRARIES)+ check_fortran_libraries(+ BLAS_DEFINITIONS+ BLAS_LIBRARIES+ BLAS+ sgemm+ ""+ "mkl;guide;pthread"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"+ )+ endif()++ #BLAS in intel mkl library? (static, 32bit)+ if(NOT BLAS_LIBRARIES)+ check_fortran_libraries(+ BLAS_DEFINITIONS+ BLAS_LIBRARIES+ BLAS+ sgemm+ ""+ "mkl_ia32;guide;pthread"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"+ )+ endif()++ #BLAS in intel mkl library? (static, em64t 64bit)+ if(NOT BLAS_LIBRARIES)+ check_fortran_libraries(+ BLAS_DEFINITIONS+ BLAS_LIBRARIES+ BLAS+ sgemm+ ""+ "mkl_em64t;guide;pthread"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"+ )+ endif()++ #BLAS in acml library?+ if(NOT BLAS_LIBRARIES)+ check_fortran_libraries(+ BLAS_DEFINITIONS+ BLAS_LIBRARIES+ BLAS+ sgemm+ ""+ "acml"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"+ )+ endif()++ # Apple BLAS library?+ if(NOT BLAS_LIBRARIES)+ check_fortran_libraries(+ BLAS_DEFINITIONS+ BLAS_LIBRARIES+ BLAS+ sgemm+ ""+ "Accelerate"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"+ )+ endif()++ if ( NOT BLAS_LIBRARIES )+ check_fortran_libraries(+ BLAS_DEFINITIONS+ BLAS_LIBRARIES+ BLAS+ sgemm+ ""+ "vecLib"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"+ )+ endif ( NOT BLAS_LIBRARIES )++ # Generic BLAS library?+ # This configuration *must* be the last try as this library is notably slow.+ if ( NOT BLAS_LIBRARIES )+ check_fortran_libraries(+ BLAS_DEFINITIONS+ BLAS_LIBRARIES+ BLAS+ sgemm+ ""+ "blas"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV BLAS_LIB_DIR"+ )+ endif()++ if(BLAS_LIBRARIES_DIR OR BLAS_LIBRARIES)+ set(BLAS_FOUND TRUE)+ else()+ set(BLAS_FOUND FALSE)+ endif()++ if(NOT BLAS_FIND_QUIETLY)+ if(BLAS_FOUND)+ message(STATUS "A library with BLAS API found.")+ else(BLAS_FOUND)+ if(BLAS_FIND_REQUIRED)+ message(FATAL_ERROR "A required library with BLAS API not found. Please specify library location.")+ else()+ message(STATUS "A library with BLAS API not found. Please specify library location.")+ endif()+ endif(BLAS_FOUND)+ endif(NOT BLAS_FIND_QUIETLY)++ # Add variables to cache+ set( BLAS_INCLUDE_DIR "${BLAS_INCLUDE_DIR}"+ CACHE PATH "Directories containing the BLAS header files" FORCE )+ set( BLAS_DEFINITIONS "${BLAS_DEFINITIONS}"+ CACHE STRING "Compilation options to use BLAS" FORCE )+ set( BLAS_LINKER_FLAGS "${BLAS_LINKER_FLAGS}"+ CACHE STRING "Linker flags to use BLAS" FORCE )+ set( BLAS_LIBRARIES "${BLAS_LIBRARIES}"+ CACHE FILEPATH "BLAS libraries name" FORCE )+ set( BLAS_LIBRARIES_DIR "${BLAS_LIBRARIES_DIR}"+ CACHE PATH "Directories containing the BLAS libraries" FORCE )++ #message("DEBUG: BLAS_INCLUDE_DIR = ${BLAS_INCLUDE_DIR}")+ #message("DEBUG: BLAS_DEFINITIONS = ${BLAS_DEFINITIONS}")+ #message("DEBUG: BLAS_LINKER_FLAGS = ${BLAS_LINKER_FLAGS}")+ #message("DEBUG: BLAS_LIBRARIES = ${BLAS_LIBRARIES}")+ #message("DEBUG: BLAS_LIBRARIES_DIR = ${BLAS_LIBRARIES_DIR}")+ #message("DEBUG: BLAS_FOUND = ${BLAS_FOUND}")++endif(BLAS_LIBRARIES_DIR OR BLAS_LIBRARIES)
+ eigen3/cmake/FindCholmod.cmake view
@@ -0,0 +1,89 @@+# Cholmod lib usually requires linking to a blas and lapack library.+# It is up to the user of this module to find a BLAS and link to it.++if (CHOLMOD_INCLUDES AND CHOLMOD_LIBRARIES)+ set(CHOLMOD_FIND_QUIETLY TRUE)+endif (CHOLMOD_INCLUDES AND CHOLMOD_LIBRARIES)++find_path(CHOLMOD_INCLUDES+ NAMES+ cholmod.h+ PATHS+ $ENV{CHOLMODDIR}+ ${INCLUDE_INSTALL_DIR}+ PATH_SUFFIXES+ suitesparse+ ufsparse+)++find_library(CHOLMOD_LIBRARIES cholmod PATHS $ENV{CHOLMODDIR} ${LIB_INSTALL_DIR})++if(CHOLMOD_LIBRARIES)++ get_filename_component(CHOLMOD_LIBDIR ${CHOLMOD_LIBRARIES} PATH)++ find_library(AMD_LIBRARY amd PATHS ${CHOLMOD_LIBDIR} $ENV{CHOLMODDIR} ${LIB_INSTALL_DIR})+ if (AMD_LIBRARY)+ set(CHOLMOD_LIBRARIES ${CHOLMOD_LIBRARIES} ${AMD_LIBRARY})+ else ()+ set(CHOLMOD_LIBRARIES FALSE)+ endif ()++endif(CHOLMOD_LIBRARIES)++if(CHOLMOD_LIBRARIES)++ find_library(COLAMD_LIBRARY colamd PATHS ${CHOLMOD_LIBDIR} $ENV{CHOLMODDIR} ${LIB_INSTALL_DIR})+ if (COLAMD_LIBRARY)+ set(CHOLMOD_LIBRARIES ${CHOLMOD_LIBRARIES} ${COLAMD_LIBRARY})+ else ()+ set(CHOLMOD_LIBRARIES FALSE)+ endif ()++endif(CHOLMOD_LIBRARIES)++if(CHOLMOD_LIBRARIES)++ find_library(CAMD_LIBRARY camd PATHS ${CHOLMOD_LIBDIR} $ENV{CHOLMODDIR} ${LIB_INSTALL_DIR})+ if (CAMD_LIBRARY)+ set(CHOLMOD_LIBRARIES ${CHOLMOD_LIBRARIES} ${CAMD_LIBRARY})+ else ()+ set(CHOLMOD_LIBRARIES FALSE)+ endif ()++endif(CHOLMOD_LIBRARIES)++if(CHOLMOD_LIBRARIES)++ find_library(CCOLAMD_LIBRARY ccolamd PATHS ${CHOLMOD_LIBDIR} $ENV{CHOLMODDIR} ${LIB_INSTALL_DIR})+ if (CCOLAMD_LIBRARY)+ set(CHOLMOD_LIBRARIES ${CHOLMOD_LIBRARIES} ${CCOLAMD_LIBRARY})+ else ()+ set(CHOLMOD_LIBRARIES FALSE)+ endif ()++endif(CHOLMOD_LIBRARIES)++if(CHOLMOD_LIBRARIES)++ find_library(CHOLMOD_METIS_LIBRARY metis PATHS ${CHOLMOD_LIBDIR} $ENV{CHOLMODDIR} ${LIB_INSTALL_DIR})+ if (CHOLMOD_METIS_LIBRARY)+ set(CHOLMOD_LIBRARIES ${CHOLMOD_LIBRARIES} ${CHOLMOD_METIS_LIBRARY})+ endif ()++endif(CHOLMOD_LIBRARIES)++if(CHOLMOD_LIBRARIES)++ find_library(SUITESPARSE_LIBRARY SuiteSparse PATHS ${CHOLMOD_LIBDIR} $ENV{CHOLMODDIR} ${LIB_INSTALL_DIR})+ if (SUITESPARSE_LIBRARY)+ set(CHOLMOD_LIBRARIES ${CHOLMOD_LIBRARIES} ${SUITESPARSE_LIBRARY})+ endif (SUITESPARSE_LIBRARY)+ +endif(CHOLMOD_LIBRARIES)++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(CHOLMOD DEFAULT_MSG+ CHOLMOD_INCLUDES CHOLMOD_LIBRARIES)++mark_as_advanced(CHOLMOD_INCLUDES CHOLMOD_LIBRARIES AMD_LIBRARY COLAMD_LIBRARY SUITESPARSE_LIBRARY CAMD_LIBRARY CCOLAMD_LIBRARY CHOLMOD_METIS_LIBRARY)
+ eigen3/cmake/FindEigen2.cmake view
@@ -0,0 +1,80 @@+# - Try to find Eigen2 lib+#+# This module supports requiring a minimum version, e.g. you can do+# find_package(Eigen2 2.0.3)+# to require version 2.0.3 to newer of Eigen2.+#+# Once done this will define+#+# EIGEN2_FOUND - system has eigen lib with correct version+# EIGEN2_INCLUDE_DIR - the eigen include directory+# EIGEN2_VERSION - eigen version++# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org>+# Copyright (c) 2008, 2009 Gael Guennebaud, <g.gael@free.fr>+# Redistribution and use is allowed according to the terms of the BSD license.++if(NOT Eigen2_FIND_VERSION)+ if(NOT Eigen2_FIND_VERSION_MAJOR)+ set(Eigen2_FIND_VERSION_MAJOR 2)+ endif(NOT Eigen2_FIND_VERSION_MAJOR)+ if(NOT Eigen2_FIND_VERSION_MINOR)+ set(Eigen2_FIND_VERSION_MINOR 0)+ endif(NOT Eigen2_FIND_VERSION_MINOR)+ if(NOT Eigen2_FIND_VERSION_PATCH)+ set(Eigen2_FIND_VERSION_PATCH 0)+ endif(NOT Eigen2_FIND_VERSION_PATCH)++ set(Eigen2_FIND_VERSION "${Eigen2_FIND_VERSION_MAJOR}.${Eigen2_FIND_VERSION_MINOR}.${Eigen2_FIND_VERSION_PATCH}")+endif(NOT Eigen2_FIND_VERSION)++macro(_eigen2_check_version)+ file(READ "${EIGEN2_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen2_version_header)++ string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen2_world_version_match "${_eigen2_version_header}")+ set(EIGEN2_WORLD_VERSION "${CMAKE_MATCH_1}")+ string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen2_major_version_match "${_eigen2_version_header}")+ set(EIGEN2_MAJOR_VERSION "${CMAKE_MATCH_1}")+ string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen2_minor_version_match "${_eigen2_version_header}")+ set(EIGEN2_MINOR_VERSION "${CMAKE_MATCH_1}")++ set(EIGEN2_VERSION ${EIGEN2_WORLD_VERSION}.${EIGEN2_MAJOR_VERSION}.${EIGEN2_MINOR_VERSION})+ if((${EIGEN2_WORLD_VERSION} NOTEQUAL 2) OR (${EIGEN2_MAJOR_VERSION} GREATER 10) OR (${EIGEN2_VERSION} VERSION_LESS ${Eigen2_FIND_VERSION}))+ set(EIGEN2_VERSION_OK FALSE)+ else()+ set(EIGEN2_VERSION_OK TRUE)+ endif()++ if(NOT EIGEN2_VERSION_OK)++ message(STATUS "Eigen2 version ${EIGEN2_VERSION} found in ${EIGEN2_INCLUDE_DIR}, "+ "but at least version ${Eigen2_FIND_VERSION} is required")+ endif(NOT EIGEN2_VERSION_OK)+endmacro(_eigen2_check_version)++if (EIGEN2_INCLUDE_DIR)++ # in cache already+ _eigen2_check_version()+ set(EIGEN2_FOUND ${EIGEN2_VERSION_OK})++else (EIGEN2_INCLUDE_DIR)++find_path(EIGEN2_INCLUDE_DIR NAMES Eigen/Core+ PATHS+ ${INCLUDE_INSTALL_DIR}+ ${KDE4_INCLUDE_DIR}+ PATH_SUFFIXES eigen2+ )++if(EIGEN2_INCLUDE_DIR)+ _eigen2_check_version()+endif(EIGEN2_INCLUDE_DIR)++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(Eigen2 DEFAULT_MSG EIGEN2_INCLUDE_DIR EIGEN2_VERSION_OK)++mark_as_advanced(EIGEN2_INCLUDE_DIR)++endif(EIGEN2_INCLUDE_DIR)+
+ eigen3/cmake/FindEigen3.cmake view
@@ -0,0 +1,81 @@+# - Try to find Eigen3 lib+#+# This module supports requiring a minimum version, e.g. you can do+# find_package(Eigen3 3.1.2)+# to require version 3.1.2 or newer of Eigen3.+#+# Once done this will define+#+# EIGEN3_FOUND - system has eigen lib with correct version+# EIGEN3_INCLUDE_DIR - the eigen include directory+# EIGEN3_VERSION - eigen version++# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org>+# Copyright (c) 2008, 2009 Gael Guennebaud, <g.gael@free.fr>+# Copyright (c) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+# Redistribution and use is allowed according to the terms of the 2-clause BSD license.++if(NOT Eigen3_FIND_VERSION)+ if(NOT Eigen3_FIND_VERSION_MAJOR)+ set(Eigen3_FIND_VERSION_MAJOR 2)+ endif(NOT Eigen3_FIND_VERSION_MAJOR)+ if(NOT Eigen3_FIND_VERSION_MINOR)+ set(Eigen3_FIND_VERSION_MINOR 91)+ endif(NOT Eigen3_FIND_VERSION_MINOR)+ if(NOT Eigen3_FIND_VERSION_PATCH)+ set(Eigen3_FIND_VERSION_PATCH 0)+ endif(NOT Eigen3_FIND_VERSION_PATCH)++ set(Eigen3_FIND_VERSION "${Eigen3_FIND_VERSION_MAJOR}.${Eigen3_FIND_VERSION_MINOR}.${Eigen3_FIND_VERSION_PATCH}")+endif(NOT Eigen3_FIND_VERSION)++macro(_eigen3_check_version)+ file(READ "${EIGEN3_INCLUDE_DIR}/Eigen/src/Core/util/Macros.h" _eigen3_version_header)++ string(REGEX MATCH "define[ \t]+EIGEN_WORLD_VERSION[ \t]+([0-9]+)" _eigen3_world_version_match "${_eigen3_version_header}")+ set(EIGEN3_WORLD_VERSION "${CMAKE_MATCH_1}")+ string(REGEX MATCH "define[ \t]+EIGEN_MAJOR_VERSION[ \t]+([0-9]+)" _eigen3_major_version_match "${_eigen3_version_header}")+ set(EIGEN3_MAJOR_VERSION "${CMAKE_MATCH_1}")+ string(REGEX MATCH "define[ \t]+EIGEN_MINOR_VERSION[ \t]+([0-9]+)" _eigen3_minor_version_match "${_eigen3_version_header}")+ set(EIGEN3_MINOR_VERSION "${CMAKE_MATCH_1}")++ set(EIGEN3_VERSION ${EIGEN3_WORLD_VERSION}.${EIGEN3_MAJOR_VERSION}.${EIGEN3_MINOR_VERSION})+ if(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})+ set(EIGEN3_VERSION_OK FALSE)+ else(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})+ set(EIGEN3_VERSION_OK TRUE)+ endif(${EIGEN3_VERSION} VERSION_LESS ${Eigen3_FIND_VERSION})++ if(NOT EIGEN3_VERSION_OK)++ message(STATUS "Eigen3 version ${EIGEN3_VERSION} found in ${EIGEN3_INCLUDE_DIR}, "+ "but at least version ${Eigen3_FIND_VERSION} is required")+ endif(NOT EIGEN3_VERSION_OK)+endmacro(_eigen3_check_version)++if (EIGEN3_INCLUDE_DIR)++ # in cache already+ _eigen3_check_version()+ set(EIGEN3_FOUND ${EIGEN3_VERSION_OK})++else (EIGEN3_INCLUDE_DIR)++ find_path(EIGEN3_INCLUDE_DIR NAMES signature_of_eigen3_matrix_library+ PATHS+ ${CMAKE_INSTALL_PREFIX}/include+ ${KDE4_INCLUDE_DIR}+ PATH_SUFFIXES eigen3 eigen+ )++ if(EIGEN3_INCLUDE_DIR)+ _eigen3_check_version()+ endif(EIGEN3_INCLUDE_DIR)++ include(FindPackageHandleStandardArgs)+ find_package_handle_standard_args(Eigen3 DEFAULT_MSG EIGEN3_INCLUDE_DIR EIGEN3_VERSION_OK)++ mark_as_advanced(EIGEN3_INCLUDE_DIR)++endif(EIGEN3_INCLUDE_DIR)+
+ eigen3/cmake/FindFFTW.cmake view
@@ -0,0 +1,119 @@+# - Find the FFTW library+#+# Usage:+# find_package(FFTW [REQUIRED] [QUIET] )+# +# It sets the following variables:+# FFTW_FOUND ... true if fftw is found on the system+# FFTW_LIBRARIES ... full path to fftw library+# FFTW_INCLUDES ... fftw include directory+#+# The following variables will be checked by the function+# FFTW_USE_STATIC_LIBS ... if true, only static libraries are found+# FFTW_ROOT ... if set, the libraries are exclusively searched+# under this path+# FFTW_LIBRARY ... fftw library to use+# FFTW_INCLUDE_DIR ... fftw include directory+#++#If environment variable FFTWDIR is specified, it has same effect as FFTW_ROOT+if( NOT FFTW_ROOT AND ENV{FFTWDIR} )+ set( FFTW_ROOT $ENV{FFTWDIR} )+endif()++# Check if we can use PkgConfig+find_package(PkgConfig)++#Determine from PKG+if( PKG_CONFIG_FOUND AND NOT FFTW_ROOT )+ pkg_check_modules( PKG_FFTW QUIET "fftw3" )+endif()++#Check whether to search static or dynamic libs+set( CMAKE_FIND_LIBRARY_SUFFIXES_SAV ${CMAKE_FIND_LIBRARY_SUFFIXES} )++if( ${FFTW_USE_STATIC_LIBS} )+ set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_STATIC_LIBRARY_SUFFIX} )+else()+ set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_SHARED_LIBRARY_SUFFIX} )+endif()++if( FFTW_ROOT )++ #find libs+ find_library(+ FFTW_LIB+ NAMES "fftw3"+ PATHS ${FFTW_ROOT}+ PATH_SUFFIXES "lib" "lib64"+ NO_DEFAULT_PATH+ )++ find_library(+ FFTWF_LIB+ NAMES "fftw3f"+ PATHS ${FFTW_ROOT}+ PATH_SUFFIXES "lib" "lib64"+ NO_DEFAULT_PATH+ )++ find_library(+ FFTWL_LIB+ NAMES "fftw3l"+ PATHS ${FFTW_ROOT}+ PATH_SUFFIXES "lib" "lib64"+ NO_DEFAULT_PATH+ )++ #find includes+ find_path(+ FFTW_INCLUDES+ NAMES "fftw3.h"+ PATHS ${FFTW_ROOT}+ PATH_SUFFIXES "include"+ NO_DEFAULT_PATH+ )++else()++ find_library(+ FFTW_LIB+ NAMES "fftw3"+ PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR}+ )++ find_library(+ FFTWF_LIB+ NAMES "fftw3f"+ PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR}+ )+++ find_library(+ FFTWL_LIB+ NAMES "fftw3l"+ PATHS ${PKG_FFTW_LIBRARY_DIRS} ${LIB_INSTALL_DIR}+ )++ find_path(+ FFTW_INCLUDES+ NAMES "fftw3.h"+ PATHS ${PKG_FFTW_INCLUDE_DIRS} ${INCLUDE_INSTALL_DIR}+ )++endif( FFTW_ROOT )++set(FFTW_LIBRARIES ${FFTW_LIB} ${FFTWF_LIB})++if(FFTWL_LIB)+ set(FFTW_LIBRARIES ${FFTW_LIBRARIES} ${FFTWL_LIB})+endif()++set( CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAV} )++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(FFTW DEFAULT_MSG+ FFTW_INCLUDES FFTW_LIBRARIES)++mark_as_advanced(FFTW_INCLUDES FFTW_LIBRARIES FFTW_LIB FFTWF_LIB FFTWL_LIB)+
+ eigen3/cmake/FindGLEW.cmake view
@@ -0,0 +1,105 @@+# Copyright (c) 2009 Boudewijn Rempt <boud@valdyas.org> +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. +# +# - try to find glew library and include files+# GLEW_INCLUDE_DIR, where to find GL/glew.h, etc.+# GLEW_LIBRARIES, the libraries to link against+# GLEW_FOUND, If false, do not try to use GLEW.+# Also defined, but not for general use are:+# GLEW_GLEW_LIBRARY = the full path to the glew library.++IF (WIN32)++ IF(CYGWIN)++ FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h)++ FIND_LIBRARY( GLEW_GLEW_LIBRARY glew32+ ${OPENGL_LIBRARY_DIR}+ /usr/lib/w32api+ /usr/X11R6/lib+ )+++ ELSE(CYGWIN)+ + FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h+ $ENV{GLEW_ROOT_PATH}/include+ )++ FIND_LIBRARY( GLEW_GLEW_LIBRARY+ NAMES glew glew32+ PATHS+ $ENV{GLEW_ROOT_PATH}/lib+ ${OPENGL_LIBRARY_DIR}+ )++ ENDIF(CYGWIN)++ELSE (WIN32)++ IF (APPLE)+# These values for Apple could probably do with improvement.+ FIND_PATH( GLEW_INCLUDE_DIR glew.h+ /System/Library/Frameworks/GLEW.framework/Versions/A/Headers+ ${OPENGL_LIBRARY_DIR}+ )+ SET(GLEW_GLEW_LIBRARY "-framework GLEW" CACHE STRING "GLEW library for OSX")+ SET(GLEW_cocoa_LIBRARY "-framework Cocoa" CACHE STRING "Cocoa framework for OSX")+ ELSE (APPLE)++ FIND_PATH( GLEW_INCLUDE_DIR GL/glew.h+ /usr/include/GL+ /usr/openwin/share/include+ /usr/openwin/include+ /usr/X11R6/include+ /usr/include/X11+ /opt/graphics/OpenGL/include+ /opt/graphics/OpenGL/contrib/libglew+ )++ FIND_LIBRARY( GLEW_GLEW_LIBRARY GLEW+ /usr/openwin/lib+ /usr/X11R6/lib+ )++ ENDIF (APPLE)++ENDIF (WIN32)++SET( GLEW_FOUND "NO" )+IF(GLEW_INCLUDE_DIR)+ IF(GLEW_GLEW_LIBRARY)+ # Is -lXi and -lXmu required on all platforms that have it?+ # If not, we need some way to figure out what platform we are on.+ SET( GLEW_LIBRARIES+ ${GLEW_GLEW_LIBRARY}+ ${GLEW_cocoa_LIBRARY}+ )+ SET( GLEW_FOUND "YES" )++#The following deprecated settings are for backwards compatibility with CMake1.4+ SET (GLEW_LIBRARY ${GLEW_LIBRARIES})+ SET (GLEW_INCLUDE_PATH ${GLEW_INCLUDE_DIR})++ ENDIF(GLEW_GLEW_LIBRARY)+ENDIF(GLEW_INCLUDE_DIR)++IF(GLEW_FOUND)+ IF(NOT GLEW_FIND_QUIETLY)+ MESSAGE(STATUS "Found Glew: ${GLEW_LIBRARIES}")+ ENDIF(NOT GLEW_FIND_QUIETLY)+ELSE(GLEW_FOUND)+ IF(GLEW_FIND_REQUIRED)+ MESSAGE(FATAL_ERROR "Could not find Glew")+ ENDIF(GLEW_FIND_REQUIRED)+ENDIF(GLEW_FOUND)++MARK_AS_ADVANCED(+ GLEW_INCLUDE_DIR+ GLEW_GLEW_LIBRARY+ GLEW_Xmu_LIBRARY+ GLEW_Xi_LIBRARY+)
+ eigen3/cmake/FindGMP.cmake view
@@ -0,0 +1,21 @@+# Try to find the GNU Multiple Precision Arithmetic Library (GMP)+# See http://gmplib.org/++if (GMP_INCLUDES AND GMP_LIBRARIES)+ set(GMP_FIND_QUIETLY TRUE)+endif (GMP_INCLUDES AND GMP_LIBRARIES)++find_path(GMP_INCLUDES+ NAMES+ gmp.h+ PATHS+ $ENV{GMPDIR}+ ${INCLUDE_INSTALL_DIR}+)++find_library(GMP_LIBRARIES gmp PATHS $ENV{GMPDIR} ${LIB_INSTALL_DIR})++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(GMP DEFAULT_MSG+ GMP_INCLUDES GMP_LIBRARIES)+mark_as_advanced(GMP_INCLUDES GMP_LIBRARIES)
+ eigen3/cmake/FindGSL.cmake view
@@ -0,0 +1,170 @@+# Try to find gnu scientific library GSL+# See +# http://www.gnu.org/software/gsl/ and+# http://gnuwin32.sourceforge.net/packages/gsl.htm+#+# Once run this will define: +# +# GSL_FOUND = system has GSL lib+#+# GSL_LIBRARIES = full path to the libraries+# on Unix/Linux with additional linker flags from "gsl-config --libs"+# +# CMAKE_GSL_CXX_FLAGS = Unix compiler flags for GSL, essentially "`gsl-config --cxxflags`"+#+# GSL_INCLUDE_DIR = where to find headers +#+# GSL_LINK_DIRECTORIES = link directories, useful for rpath on Unix+# GSL_EXE_LINKER_FLAGS = rpath on Unix+#+# Felix Woelk 07/2004+# Jan Woetzel+#+# www.mip.informatik.uni-kiel.de+# --------------------------------++IF(WIN32)+ # JW tested with gsl-1.8, Windows XP, MSVS 7.1+ SET(GSL_POSSIBLE_ROOT_DIRS+ ${GSL_ROOT_DIR}+ $ENV{GSL_ROOT_DIR}+ ${GSL_DIR}+ ${GSL_HOME} + $ENV{GSL_DIR}+ $ENV{GSL_HOME}+ $ENV{EXTRA}+ "C:/Program Files/GnuWin32"+ )+ FIND_PATH(GSL_INCLUDE_DIR+ NAMES gsl/gsl_cdf.h gsl/gsl_randist.h+ PATHS ${GSL_POSSIBLE_ROOT_DIRS}+ PATH_SUFFIXES include+ DOC "GSL header include dir"+ )+ + FIND_LIBRARY(GSL_GSL_LIBRARY+ NAMES libgsl.dll.a gsl libgsl+ PATHS ${GSL_POSSIBLE_ROOT_DIRS}+ PATH_SUFFIXES lib+ DOC "GSL library" )+ + if(NOT GSL_GSL_LIBRARY)+ FIND_FILE(GSL_GSL_LIBRARY+ NAMES libgsl.dll.a+ PATHS ${GSL_POSSIBLE_ROOT_DIRS}+ PATH_SUFFIXES lib+ DOC "GSL library")+ endif(NOT GSL_GSL_LIBRARY)+ + FIND_LIBRARY(GSL_GSLCBLAS_LIBRARY+ NAMES libgslcblas.dll.a gslcblas libgslcblas+ PATHS ${GSL_POSSIBLE_ROOT_DIRS}+ PATH_SUFFIXES lib+ DOC "GSL cblas library dir" )+ + if(NOT GSL_GSLCBLAS_LIBRARY)+ FIND_FILE(GSL_GSLCBLAS_LIBRARY+ NAMES libgslcblas.dll.a+ PATHS ${GSL_POSSIBLE_ROOT_DIRS}+ PATH_SUFFIXES lib+ DOC "GSL library")+ endif(NOT GSL_GSLCBLAS_LIBRARY)+ + SET(GSL_LIBRARIES ${GSL_GSL_LIBRARY})++ #MESSAGE("DBG\n"+ # "GSL_GSL_LIBRARY=${GSL_GSL_LIBRARY}\n"+ # "GSL_GSLCBLAS_LIBRARY=${GSL_GSLCBLAS_LIBRARY}\n"+ # "GSL_LIBRARIES=${GSL_LIBRARIES}")+++ELSE(WIN32)+ + IF(UNIX) + SET(GSL_CONFIG_PREFER_PATH + "$ENV{GSL_DIR}/bin"+ "$ENV{GSL_DIR}"+ "$ENV{GSL_HOME}/bin" + "$ENV{GSL_HOME}" + CACHE STRING "preferred path to GSL (gsl-config)")+ FIND_PROGRAM(GSL_CONFIG gsl-config+ ${GSL_CONFIG_PREFER_PATH}+ /usr/bin/+ )+ # MESSAGE("DBG GSL_CONFIG ${GSL_CONFIG}")+ + IF (GSL_CONFIG) + # set CXXFLAGS to be fed into CXX_FLAGS by the user:+ SET(GSL_CXX_FLAGS "`${GSL_CONFIG} --cflags`")+ + # set INCLUDE_DIRS to prefix+include+ EXEC_PROGRAM(${GSL_CONFIG}+ ARGS --prefix+ OUTPUT_VARIABLE GSL_PREFIX)+ SET(GSL_INCLUDE_DIR ${GSL_PREFIX}/include CACHE STRING INTERNAL)++ # set link libraries and link flags+ #SET(GSL_LIBRARIES "`${GSL_CONFIG} --libs`")+ EXEC_PROGRAM(${GSL_CONFIG}+ ARGS --libs+ OUTPUT_VARIABLE GSL_LIBRARIES )+ + # extract link dirs for rpath + EXEC_PROGRAM(${GSL_CONFIG}+ ARGS --libs+ OUTPUT_VARIABLE GSL_CONFIG_LIBS )+ + # extract version+ EXEC_PROGRAM(${GSL_CONFIG}+ ARGS --version+ OUTPUT_VARIABLE GSL_FULL_VERSION )+ + # split version as major/minor+ STRING(REGEX MATCH "(.)\\..*" GSL_VERSION_MAJOR_ "${GSL_FULL_VERSION}")+ SET(GSL_VERSION_MAJOR ${CMAKE_MATCH_1})+ STRING(REGEX MATCH ".\\.(.*)" GSL_VERSION_MINOR_ "${GSL_FULL_VERSION}")+ SET(GSL_VERSION_MINOR ${CMAKE_MATCH_1})++ # split off the link dirs (for rpath)+ # use regular expression to match wildcard equivalent "-L*<endchar>"+ # with <endchar> is a space or a semicolon+ STRING(REGEX MATCHALL "[-][L]([^ ;])+" + GSL_LINK_DIRECTORIES_WITH_PREFIX + "${GSL_CONFIG_LIBS}" )+ # MESSAGE("DBG GSL_LINK_DIRECTORIES_WITH_PREFIX=${GSL_LINK_DIRECTORIES_WITH_PREFIX}")++ # remove prefix -L because we need the pure directory for LINK_DIRECTORIES+ + IF (GSL_LINK_DIRECTORIES_WITH_PREFIX)+ STRING(REGEX REPLACE "[-][L]" "" GSL_LINK_DIRECTORIES ${GSL_LINK_DIRECTORIES_WITH_PREFIX} )+ ENDIF (GSL_LINK_DIRECTORIES_WITH_PREFIX)+ SET(GSL_EXE_LINKER_FLAGS "-Wl,-rpath,${GSL_LINK_DIRECTORIES}" CACHE STRING INTERNAL)+ # MESSAGE("DBG GSL_LINK_DIRECTORIES=${GSL_LINK_DIRECTORIES}")+ # MESSAGE("DBG GSL_EXE_LINKER_FLAGS=${GSL_EXE_LINKER_FLAGS}")++ # ADD_DEFINITIONS("-DHAVE_GSL")+ # SET(GSL_DEFINITIONS "-DHAVE_GSL")+ MARK_AS_ADVANCED(+ GSL_CXX_FLAGS+ GSL_INCLUDE_DIR+ GSL_LIBRARIES+ GSL_LINK_DIRECTORIES+ GSL_DEFINITIONS+ )+ MESSAGE(STATUS "Using GSL from ${GSL_PREFIX}")+ + ELSE(GSL_CONFIG)+ MESSAGE("FindGSL.cmake: gsl-config not found. Please set it manually. GSL_CONFIG=${GSL_CONFIG}")+ ENDIF(GSL_CONFIG)++ ENDIF(UNIX)+ENDIF(WIN32)+++IF(GSL_LIBRARIES)+ IF(GSL_INCLUDE_DIR OR GSL_CXX_FLAGS)++ SET(GSL_FOUND 1)+ + ENDIF(GSL_INCLUDE_DIR OR GSL_CXX_FLAGS)+ENDIF(GSL_LIBRARIES)
+ eigen3/cmake/FindGoogleHash.cmake view
@@ -0,0 +1,23 @@++if (GOOGLEHASH_INCLUDES AND GOOGLEHASH_LIBRARIES)+ set(GOOGLEHASH_FIND_QUIETLY TRUE)+endif (GOOGLEHASH_INCLUDES AND GOOGLEHASH_LIBRARIES)++find_path(GOOGLEHASH_INCLUDES+ NAMES+ google/dense_hash_map+ PATHS+ ${INCLUDE_INSTALL_DIR}+)++if(GOOGLEHASH_INCLUDES)+ # let's make sure it compiles with the current compiler+ file(WRITE ${CMAKE_BINARY_DIR}/googlehash_test.cpp+ "#include <google/sparse_hash_map>\n#include <google/dense_hash_map>\nint main(int argc, char** argv) { google::dense_hash_map<int,float> a; google::sparse_hash_map<int,float> b; return 0;}\n")+ try_compile(GOOGLEHASH_COMPILE ${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/googlehash_test.cpp OUTPUT_VARIABLE GOOGLEHASH_COMPILE_RESULT)+endif(GOOGLEHASH_INCLUDES)++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(GOOGLEHASH DEFAULT_MSG GOOGLEHASH_INCLUDES GOOGLEHASH_COMPILE)++mark_as_advanced(GOOGLEHASH_INCLUDES)
+ eigen3/cmake/FindLAPACK.cmake view
@@ -0,0 +1,273 @@+# Find LAPACK library+#+# This module finds an installed library that implements the LAPACK+# linear-algebra interface (see http://www.netlib.org/lapack/).+# The approach follows mostly that taken for the autoconf macro file, acx_lapack.m4+# (distributed at http://ac-archive.sourceforge.net/ac-archive/acx_lapack.html).+#+# This module sets the following variables:+# LAPACK_FOUND - set to true if a library implementing the LAPACK interface+# is found+# LAPACK_INCLUDE_DIR - Directories containing the LAPACK header files+# LAPACK_DEFINITIONS - Compilation options to use LAPACK+# LAPACK_LINKER_FLAGS - Linker flags to use LAPACK (excluding -l+# and -L).+# LAPACK_LIBRARIES_DIR - Directories containing the LAPACK libraries.+# May be null if LAPACK_LIBRARIES contains libraries name using full path.+# LAPACK_LIBRARIES - List of libraries to link against LAPACK interface.+# May be null if the compiler supports auto-link (e.g. VC++).+# LAPACK_USE_FILE - The name of the cmake module to include to compile+# applications or libraries using LAPACK.+#+# This module was modified by CGAL team:+# - find libraries for a C++ compiler, instead of Fortran+# - added LAPACK_INCLUDE_DIR, LAPACK_DEFINITIONS and LAPACK_LIBRARIES_DIR+# - removed LAPACK95_LIBRARIES+++include(CheckFunctionExists)++# This macro checks for the existence of the combination of fortran libraries+# given by _list. If the combination is found, this macro checks (using the+# check_function_exists macro) whether can link against that library+# combination using the name of a routine given by _name using the linker+# flags given by _flags. If the combination of libraries is found and passes+# the link test, LIBRARIES is set to the list of complete library paths that+# have been found and DEFINITIONS to the required definitions.+# Otherwise, LIBRARIES is set to FALSE.+# N.B. _prefix is the prefix applied to the names of all cached variables that+# are generated internally and marked advanced by this macro.+macro(check_lapack_libraries DEFINITIONS LIBRARIES _prefix _name _flags _list _blas _path)+ #message("DEBUG: check_lapack_libraries(${_list} in ${_path} with ${_blas})")++ # Check for the existence of the libraries given by _list+ set(_libraries_found TRUE)+ set(_libraries_work FALSE)+ set(${DEFINITIONS} "")+ set(${LIBRARIES} "")+ set(_combined_name)+ foreach(_library ${_list})+ set(_combined_name ${_combined_name}_${_library})++ if(_libraries_found)+ # search first in ${_path}+ find_library(${_prefix}_${_library}_LIBRARY+ NAMES ${_library}+ PATHS ${_path} NO_DEFAULT_PATH+ )+ # if not found, search in environment variables and system+ if ( WIN32 )+ find_library(${_prefix}_${_library}_LIBRARY+ NAMES ${_library}+ PATHS ENV LIB+ )+ elseif ( APPLE )+ find_library(${_prefix}_${_library}_LIBRARY+ NAMES ${_library}+ PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV DYLD_LIBRARY_PATH+ )+ else ()+ find_library(${_prefix}_${_library}_LIBRARY+ NAMES ${_library}+ PATHS /usr/local/lib /usr/lib /usr/local/lib64 /usr/lib64 ENV LD_LIBRARY_PATH+ )+ endif()+ mark_as_advanced(${_prefix}_${_library}_LIBRARY)+ set(${LIBRARIES} ${${LIBRARIES}} ${${_prefix}_${_library}_LIBRARY})+ set(_libraries_found ${${_prefix}_${_library}_LIBRARY})+ endif(_libraries_found)+ endforeach(_library ${_list})+ if(_libraries_found)+ set(_libraries_found ${${LIBRARIES}})+ endif()++ # Test this combination of libraries with the Fortran/f2c interface.+ # We test the Fortran interface first as it is well standardized.+ if(_libraries_found AND NOT _libraries_work)+ set(${DEFINITIONS} "-D${_prefix}_USE_F2C")+ set(${LIBRARIES} ${_libraries_found})+ # Some C++ linkers require the f2c library to link with Fortran libraries.+ # I do not know which ones, thus I just add the f2c library if it is available.+ find_package( F2C QUIET )+ if ( F2C_FOUND )+ set(${DEFINITIONS} ${${DEFINITIONS}} ${F2C_DEFINITIONS})+ set(${LIBRARIES} ${${LIBRARIES}} ${F2C_LIBRARIES})+ endif()+ set(CMAKE_REQUIRED_DEFINITIONS ${${DEFINITIONS}})+ set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas})+ #message("DEBUG: CMAKE_REQUIRED_DEFINITIONS = ${CMAKE_REQUIRED_DEFINITIONS}")+ #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")+ # Check if function exists with f2c calling convention (ie a trailing underscore)+ check_function_exists(${_name}_ ${_prefix}_${_name}_${_combined_name}_f2c_WORKS)+ set(CMAKE_REQUIRED_DEFINITIONS} "")+ set(CMAKE_REQUIRED_LIBRARIES "")+ mark_as_advanced(${_prefix}_${_name}_${_combined_name}_f2c_WORKS)+ set(_libraries_work ${${_prefix}_${_name}_${_combined_name}_f2c_WORKS})+ endif(_libraries_found AND NOT _libraries_work)++ # If not found, test this combination of libraries with a C interface.+ # A few implementations (ie ACML) provide a C interface. Unfortunately, there is no standard.+ if(_libraries_found AND NOT _libraries_work)+ set(${DEFINITIONS} "")+ set(${LIBRARIES} ${_libraries_found})+ set(CMAKE_REQUIRED_DEFINITIONS "")+ set(CMAKE_REQUIRED_LIBRARIES ${_flags} ${${LIBRARIES}} ${_blas})+ #message("DEBUG: CMAKE_REQUIRED_LIBRARIES = ${CMAKE_REQUIRED_LIBRARIES}")+ check_function_exists(${_name} ${_prefix}_${_name}${_combined_name}_WORKS)+ set(CMAKE_REQUIRED_LIBRARIES "")+ mark_as_advanced(${_prefix}_${_name}${_combined_name}_WORKS)+ set(_libraries_work ${${_prefix}_${_name}${_combined_name}_WORKS})+ endif(_libraries_found AND NOT _libraries_work)++ # on failure+ if(NOT _libraries_work)+ set(${DEFINITIONS} "")+ set(${LIBRARIES} FALSE)+ endif()+ #message("DEBUG: ${DEFINITIONS} = ${${DEFINITIONS}}")+ #message("DEBUG: ${LIBRARIES} = ${${LIBRARIES}}")+endmacro(check_lapack_libraries)+++#+# main+#++# LAPACK requires BLAS+if(LAPACK_FIND_QUIETLY OR NOT LAPACK_FIND_REQUIRED)+ find_package(BLAS)+else()+ find_package(BLAS REQUIRED)+endif()++if (NOT BLAS_FOUND)++ message(STATUS "LAPACK requires BLAS.")+ set(LAPACK_FOUND FALSE)++# Is it already configured?+elseif (LAPACK_LIBRARIES_DIR OR LAPACK_LIBRARIES)++ set(LAPACK_FOUND TRUE)++else()++ # reset variables+ set( LAPACK_INCLUDE_DIR "" )+ set( LAPACK_DEFINITIONS "" )+ set( LAPACK_LINKER_FLAGS "" ) # unused (yet)+ set( LAPACK_LIBRARIES "" )+ set( LAPACK_LIBRARIES_DIR "" )++ #+ # If Unix, search for LAPACK function in possible libraries+ #++ #intel mkl lapack?+ if(NOT LAPACK_LIBRARIES)+ check_lapack_libraries(+ LAPACK_DEFINITIONS+ LAPACK_LIBRARIES+ LAPACK+ cheev+ ""+ "mkl_lapack"+ "${BLAS_LIBRARIES}"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV LAPACK_LIB_DIR"+ )+ endif()++ #acml lapack?+ if(NOT LAPACK_LIBRARIES)+ check_lapack_libraries(+ LAPACK_DEFINITIONS+ LAPACK_LIBRARIES+ LAPACK+ cheev+ ""+ "acml"+ "${BLAS_LIBRARIES}"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV LAPACK_LIB_DIR"+ )+ endif()++ # Apple LAPACK library?+ if(NOT LAPACK_LIBRARIES)+ check_lapack_libraries(+ LAPACK_DEFINITIONS+ LAPACK_LIBRARIES+ LAPACK+ cheev+ ""+ "Accelerate"+ "${BLAS_LIBRARIES}"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV LAPACK_LIB_DIR"+ )+ endif()++ if ( NOT LAPACK_LIBRARIES )+ check_lapack_libraries(+ LAPACK_DEFINITIONS+ LAPACK_LIBRARIES+ LAPACK+ cheev+ ""+ "vecLib"+ "${BLAS_LIBRARIES}"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV LAPACK_LIB_DIR"+ )+ endif ( NOT LAPACK_LIBRARIES )++ # Generic LAPACK library?+ # This configuration *must* be the last try as this library is notably slow.+ if ( NOT LAPACK_LIBRARIES )+ check_lapack_libraries(+ LAPACK_DEFINITIONS+ LAPACK_LIBRARIES+ LAPACK+ cheev+ ""+ "lapack"+ "${BLAS_LIBRARIES}"+ "${CGAL_TAUCS_LIBRARIES_DIR} ENV LAPACK_LIB_DIR"+ )+ endif()++ if(LAPACK_LIBRARIES_DIR OR LAPACK_LIBRARIES)+ set(LAPACK_FOUND TRUE)+ else()+ set(LAPACK_FOUND FALSE)+ endif()++ if(NOT LAPACK_FIND_QUIETLY)+ if(LAPACK_FOUND)+ message(STATUS "A library with LAPACK API found.")+ else(LAPACK_FOUND)+ if(LAPACK_FIND_REQUIRED)+ message(FATAL_ERROR "A required library with LAPACK API not found. Please specify library location.")+ else()+ message(STATUS "A library with LAPACK API not found. Please specify library location.")+ endif()+ endif(LAPACK_FOUND)+ endif(NOT LAPACK_FIND_QUIETLY)++ # Add variables to cache+ set( LAPACK_INCLUDE_DIR "${LAPACK_INCLUDE_DIR}"+ CACHE PATH "Directories containing the LAPACK header files" FORCE )+ set( LAPACK_DEFINITIONS "${LAPACK_DEFINITIONS}"+ CACHE STRING "Compilation options to use LAPACK" FORCE )+ set( LAPACK_LINKER_FLAGS "${LAPACK_LINKER_FLAGS}"+ CACHE STRING "Linker flags to use LAPACK" FORCE )+ set( LAPACK_LIBRARIES "${LAPACK_LIBRARIES}"+ CACHE FILEPATH "LAPACK libraries name" FORCE )+ set( LAPACK_LIBRARIES_DIR "${LAPACK_LIBRARIES_DIR}"+ CACHE PATH "Directories containing the LAPACK libraries" FORCE )++ #message("DEBUG: LAPACK_INCLUDE_DIR = ${LAPACK_INCLUDE_DIR}")+ #message("DEBUG: LAPACK_DEFINITIONS = ${LAPACK_DEFINITIONS}")+ #message("DEBUG: LAPACK_LINKER_FLAGS = ${LAPACK_LINKER_FLAGS}")+ #message("DEBUG: LAPACK_LIBRARIES = ${LAPACK_LIBRARIES}")+ #message("DEBUG: LAPACK_LIBRARIES_DIR = ${LAPACK_LIBRARIES_DIR}")+ #message("DEBUG: LAPACK_FOUND = ${LAPACK_FOUND}")++endif(NOT BLAS_FOUND)
+ eigen3/cmake/FindMPFR.cmake view
@@ -0,0 +1,83 @@+# Try to find the MPFR library+# See http://www.mpfr.org/+#+# This module supports requiring a minimum version, e.g. you can do+# find_package(MPFR 2.3.0)+# to require version 2.3.0 to newer of MPFR.+#+# Once done this will define+#+# MPFR_FOUND - system has MPFR lib with correct version+# MPFR_INCLUDES - the MPFR include directory+# MPFR_LIBRARIES - the MPFR library+# MPFR_VERSION - MPFR version++# Copyright (c) 2006, 2007 Montel Laurent, <montel@kde.org>+# Copyright (c) 2008, 2009 Gael Guennebaud, <g.gael@free.fr>+# Copyright (c) 2010 Jitse Niesen, <jitse@maths.leeds.ac.uk>+# Redistribution and use is allowed according to the terms of the BSD license.++# Set MPFR_INCLUDES++find_path(MPFR_INCLUDES+ NAMES+ mpfr.h+ PATHS+ $ENV{GMPDIR}+ ${INCLUDE_INSTALL_DIR}+)++# Set MPFR_FIND_VERSION to 1.0.0 if no minimum version is specified++if(NOT MPFR_FIND_VERSION)+ if(NOT MPFR_FIND_VERSION_MAJOR)+ set(MPFR_FIND_VERSION_MAJOR 1)+ endif(NOT MPFR_FIND_VERSION_MAJOR)+ if(NOT MPFR_FIND_VERSION_MINOR)+ set(MPFR_FIND_VERSION_MINOR 0)+ endif(NOT MPFR_FIND_VERSION_MINOR)+ if(NOT MPFR_FIND_VERSION_PATCH)+ set(MPFR_FIND_VERSION_PATCH 0)+ endif(NOT MPFR_FIND_VERSION_PATCH)++ set(MPFR_FIND_VERSION "${MPFR_FIND_VERSION_MAJOR}.${MPFR_FIND_VERSION_MINOR}.${MPFR_FIND_VERSION_PATCH}")+endif(NOT MPFR_FIND_VERSION)+++if(MPFR_INCLUDES)++ # Set MPFR_VERSION+ + file(READ "${MPFR_INCLUDES}/mpfr.h" _mpfr_version_header)+ + string(REGEX MATCH "define[ \t]+MPFR_VERSION_MAJOR[ \t]+([0-9]+)" _mpfr_major_version_match "${_mpfr_version_header}")+ set(MPFR_MAJOR_VERSION "${CMAKE_MATCH_1}")+ string(REGEX MATCH "define[ \t]+MPFR_VERSION_MINOR[ \t]+([0-9]+)" _mpfr_minor_version_match "${_mpfr_version_header}")+ set(MPFR_MINOR_VERSION "${CMAKE_MATCH_1}")+ string(REGEX MATCH "define[ \t]+MPFR_VERSION_PATCHLEVEL[ \t]+([0-9]+)" _mpfr_patchlevel_version_match "${_mpfr_version_header}")+ set(MPFR_PATCHLEVEL_VERSION "${CMAKE_MATCH_1}")+ + set(MPFR_VERSION ${MPFR_MAJOR_VERSION}.${MPFR_MINOR_VERSION}.${MPFR_PATCHLEVEL_VERSION})+ + # Check whether found version exceeds minimum version+ + if(${MPFR_VERSION} VERSION_LESS ${MPFR_FIND_VERSION})+ set(MPFR_VERSION_OK FALSE)+ message(STATUS "MPFR version ${MPFR_VERSION} found in ${MPFR_INCLUDES}, "+ "but at least version ${MPFR_FIND_VERSION} is required")+ else(${MPFR_VERSION} VERSION_LESS ${MPFR_FIND_VERSION})+ set(MPFR_VERSION_OK TRUE)+ endif(${MPFR_VERSION} VERSION_LESS ${MPFR_FIND_VERSION})++endif(MPFR_INCLUDES)++# Set MPFR_LIBRARIES++find_library(MPFR_LIBRARIES mpfr PATHS $ENV{GMPDIR} ${LIB_INSTALL_DIR})++# Epilogue++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(MPFR DEFAULT_MSG+ MPFR_INCLUDES MPFR_LIBRARIES MPFR_VERSION_OK)+mark_as_advanced(MPFR_INCLUDES MPFR_LIBRARIES)
+ eigen3/cmake/FindMetis.cmake view
@@ -0,0 +1,59 @@+# Pastix requires METIS or METIS (partitioning and reordering tools)++if (METIS_INCLUDES AND METIS_LIBRARIES)+ set(METIS_FIND_QUIETLY TRUE)+endif (METIS_INCLUDES AND METIS_LIBRARIES)++find_path(METIS_INCLUDES + NAMES + metis.h + PATHS + $ENV{METISDIR} + ${INCLUDE_INSTALL_DIR} + PATH_SUFFIXES+ .+ metis+ include+)++macro(_metis_check_version)+ file(READ "${METIS_INCLUDES}/metis.h" _metis_version_header)++ string(REGEX MATCH "define[ \t]+METIS_VER_MAJOR[ \t]+([0-9]+)" _metis_major_version_match "${_metis_version_header}")+ set(METIS_MAJOR_VERSION "${CMAKE_MATCH_1}")+ string(REGEX MATCH "define[ \t]+METIS_VER_MINOR[ \t]+([0-9]+)" _metis_minor_version_match "${_metis_version_header}")+ set(METIS_MINOR_VERSION "${CMAKE_MATCH_1}")+ string(REGEX MATCH "define[ \t]+METIS_VER_SUBMINOR[ \t]+([0-9]+)" _metis_subminor_version_match "${_metis_version_header}")+ set(METIS_SUBMINOR_VERSION "${CMAKE_MATCH_1}")+ if(NOT METIS_MAJOR_VERSION)+ message(STATUS "Could not determine Metis version. Assuming version 4.0.0")+ set(METIS_VERSION 4.0.0)+ else()+ set(METIS_VERSION ${METIS_MAJOR_VERSION}.${METIS_MINOR_VERSION}.${METIS_SUBMINOR_VERSION})+ endif()+ if(${METIS_VERSION} VERSION_LESS ${Metis_FIND_VERSION})+ set(METIS_VERSION_OK FALSE)+ else()+ set(METIS_VERSION_OK TRUE)+ endif()++ if(NOT METIS_VERSION_OK)+ message(STATUS "Metis version ${METIS_VERSION} found in ${METIS_INCLUDES}, "+ "but at least version ${Metis_FIND_VERSION} is required")+ endif(NOT METIS_VERSION_OK)+endmacro(_metis_check_version)++ if(METIS_INCLUDES AND Metis_FIND_VERSION)+ _metis_check_version()+ else()+ set(METIS_VERSION_OK TRUE)+ endif()+++find_library(METIS_LIBRARIES metis PATHS $ENV{METISDIR} ${LIB_INSTALL_DIR} PATH_SUFFIXES lib)++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(METIS DEFAULT_MSG+ METIS_INCLUDES METIS_LIBRARIES METIS_VERSION_OK)++mark_as_advanced(METIS_INCLUDES METIS_LIBRARIES)
+ eigen3/cmake/FindPastix.cmake view
@@ -0,0 +1,25 @@+# Pastix lib requires linking to a blas library.+# It is up to the user of this module to find a BLAS and link to it.+# Pastix requires SCOTCH or METIS (partitioning and reordering tools) as well++if (PASTIX_INCLUDES AND PASTIX_LIBRARIES)+ set(PASTIX_FIND_QUIETLY TRUE)+endif (PASTIX_INCLUDES AND PASTIX_LIBRARIES)++find_path(PASTIX_INCLUDES+ NAMES+ pastix_nompi.h+ PATHS+ $ENV{PASTIXDIR}+ ${INCLUDE_INSTALL_DIR}+)++find_library(PASTIX_LIBRARIES pastix PATHS $ENV{PASTIXDIR} ${LIB_INSTALL_DIR})++++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(PASTIX DEFAULT_MSG+ PASTIX_INCLUDES PASTIX_LIBRARIES)++mark_as_advanced(PASTIX_INCLUDES PASTIX_LIBRARIES)
+ eigen3/cmake/FindSPQR.cmake view
@@ -0,0 +1,36 @@+# SPQR lib usually requires linking to a blas and lapack library.+# It is up to the user of this module to find a BLAS and link to it.++# SPQR lib requires Cholmod, colamd and amd as well. +# FindCholmod.cmake can be used to find those packages before finding spqr++if (SPQR_INCLUDES AND SPQR_LIBRARIES)+ set(SPQR_FIND_QUIETLY TRUE)+endif (SPQR_INCLUDES AND SPQR_LIBRARIES)++find_path(SPQR_INCLUDES+ NAMES+ SuiteSparseQR.hpp+ PATHS+ $ENV{SPQRDIR}+ ${INCLUDE_INSTALL_DIR}+ PATH_SUFFIXES+ suitesparse+ ufsparse+)++find_library(SPQR_LIBRARIES spqr $ENV{SPQRDIR} ${LIB_INSTALL_DIR})++if(SPQR_LIBRARIES)++ find_library(SUITESPARSE_LIBRARY SuiteSparse PATHS $ENV{SPQRDIR} ${LIB_INSTALL_DIR})+ if (SUITESPARSE_LIBRARY)+ set(SPQR_LIBRARIES ${SPQR_LIBRARIES} ${SUITESPARSE_LIBRARY})+ endif (SUITESPARSE_LIBRARY)+ +endif(SPQR_LIBRARIES)++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(SPQR DEFAULT_MSG SPQR_INCLUDES SPQR_LIBRARIES)++mark_as_advanced(SPQR_INCLUDES SPQR_LIBRARIES)
+ eigen3/cmake/FindScotch.cmake view
@@ -0,0 +1,24 @@+# Pastix requires SCOTCH or METIS (partitioning and reordering tools)++if (SCOTCH_INCLUDES AND SCOTCH_LIBRARIES)+ set(SCOTCH_FIND_QUIETLY TRUE)+endif (SCOTCH_INCLUDES AND SCOTCH_LIBRARIES)++find_path(SCOTCH_INCLUDES + NAMES + scotch.h + PATHS + $ENV{SCOTCHDIR} + ${INCLUDE_INSTALL_DIR} + PATH_SUFFIXES + scotch+)+++find_library(SCOTCH_LIBRARIES scotch PATHS $ENV{SCOTCHDIR} ${LIB_INSTALL_DIR})++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(SCOTCH DEFAULT_MSG+ SCOTCH_INCLUDES SCOTCH_LIBRARIES)++mark_as_advanced(SCOTCH_INCLUDES SCOTCH_LIBRARIES)
+ eigen3/cmake/FindStandardMathLibrary.cmake view
@@ -0,0 +1,64 @@+# - Try to find how to link to the standard math library, if anything at all is needed to do.+# On most platforms this is automatic, but for example it's not automatic on QNX.+#+# Once done this will define+#+# STANDARD_MATH_LIBRARY_FOUND - we found how to successfully link to the standard math library+# STANDARD_MATH_LIBRARY - the name of the standard library that one has to link to.+# -- this will be left empty if it's automatic (most platforms).+# -- this will be set to "m" on platforms where one must explicitly+# pass the "-lm" linker flag.+#+# Copyright (c) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>+# Redistribution and use is allowed according to the terms of the 2-clause BSD license.+++include(CheckCXXSourceCompiles)++# a little test program for c++ math functions.+# notice the std:: is required on some platforms such as QNX++set(find_standard_math_library_test_program+"#include<cmath>+int main() { std::sin(0.0); std::log(0.0f); }")++# first try compiling/linking the test program without any linker flags++set(CMAKE_REQUIRED_FLAGS "")+set(CMAKE_REQUIRED_LIBRARIES "")+CHECK_CXX_SOURCE_COMPILES(+ "${find_standard_math_library_test_program}"+ standard_math_library_linked_to_automatically+)++if(standard_math_library_linked_to_automatically)++ # the test program linked successfully without any linker flag.+ set(STANDARD_MATH_LIBRARY "")+ set(STANDARD_MATH_LIBRARY_FOUND TRUE)++else()++ # the test program did not link successfully without any linker flag.+ # This is a very uncommon case that so far we only saw on QNX. The next try is the+ # standard name 'm' for the standard math library.++ set(CMAKE_REQUIRED_LIBRARIES "m")+ CHECK_CXX_SOURCE_COMPILES(+ "${find_standard_math_library_test_program}"+ standard_math_library_linked_to_as_m)++ if(standard_math_library_linked_to_as_m)++ # the test program linked successfully when linking to the 'm' library+ set(STANDARD_MATH_LIBRARY "m")+ set(STANDARD_MATH_LIBRARY_FOUND TRUE)++ else()++ # the test program still doesn't link successfully+ set(STANDARD_MATH_LIBRARY_FOUND FALSE)++ endif()++endif()
+ eigen3/cmake/FindSuperLU.cmake view
@@ -0,0 +1,26 @@++# Umfpack lib usually requires linking to a blas library.+# It is up to the user of this module to find a BLAS and link to it.++if (SUPERLU_INCLUDES AND SUPERLU_LIBRARIES)+ set(SUPERLU_FIND_QUIETLY TRUE)+endif (SUPERLU_INCLUDES AND SUPERLU_LIBRARIES)++find_path(SUPERLU_INCLUDES+ NAMES+ supermatrix.h+ PATHS+ $ENV{SUPERLUDIR}+ ${INCLUDE_INSTALL_DIR}+ PATH_SUFFIXES+ superlu+ SRC+)++find_library(SUPERLU_LIBRARIES superlu PATHS $ENV{SUPERLUDIR} ${LIB_INSTALL_DIR} PATH_SUFFIXES lib)+ +include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(SUPERLU DEFAULT_MSG+ SUPERLU_INCLUDES SUPERLU_LIBRARIES)++mark_as_advanced(SUPERLU_INCLUDES SUPERLU_LIBRARIES)
+ eigen3/cmake/FindUmfpack.cmake view
@@ -0,0 +1,48 @@+# Umfpack lib usually requires linking to a blas library.+# It is up to the user of this module to find a BLAS and link to it.++if (UMFPACK_INCLUDES AND UMFPACK_LIBRARIES)+ set(UMFPACK_FIND_QUIETLY TRUE)+endif (UMFPACK_INCLUDES AND UMFPACK_LIBRARIES)++find_path(UMFPACK_INCLUDES+ NAMES+ umfpack.h+ PATHS+ $ENV{UMFPACKDIR}+ ${INCLUDE_INSTALL_DIR}+ PATH_SUFFIXES+ suitesparse+ ufsparse+)++find_library(UMFPACK_LIBRARIES umfpack PATHS $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR})++if(UMFPACK_LIBRARIES)++ if (NOT UMFPACK_LIBDIR)+ get_filename_component(UMFPACK_LIBDIR ${UMFPACK_LIBRARIES} PATH)+ endif(NOT UMFPACK_LIBDIR)++ find_library(COLAMD_LIBRARY colamd PATHS ${UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR})+ if (COLAMD_LIBRARY)+ set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${COLAMD_LIBRARY})+ endif (COLAMD_LIBRARY)+ + find_library(AMD_LIBRARY amd PATHS ${UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR})+ if (AMD_LIBRARY)+ set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${AMD_LIBRARY})+ endif (AMD_LIBRARY)++ find_library(SUITESPARSE_LIBRARY SuiteSparse PATHS ${UMFPACK_LIBDIR} $ENV{UMFPACKDIR} ${LIB_INSTALL_DIR})+ if (SUITESPARSE_LIBRARY)+ set(UMFPACK_LIBRARIES ${UMFPACK_LIBRARIES} ${SUITESPARSE_LIBRARY})+ endif (SUITESPARSE_LIBRARY)++endif(UMFPACK_LIBRARIES)++include(FindPackageHandleStandardArgs)+find_package_handle_standard_args(UMFPACK DEFAULT_MSG+ UMFPACK_INCLUDES UMFPACK_LIBRARIES)++mark_as_advanced(UMFPACK_INCLUDES UMFPACK_LIBRARIES AMD_LIBRARY COLAMD_LIBRARY SUITESPARSE_LIBRARY)
+ eigen3/cmake/RegexUtils.cmake view
@@ -0,0 +1,19 @@+function(escape_string_as_regex _str_out _str_in)+ STRING(REGEX REPLACE "\\\\" "\\\\\\\\" FILETEST2 "${_str_in}")+ STRING(REGEX REPLACE "([.$+*?|-])" "\\\\\\1" FILETEST2 "${FILETEST2}")+ STRING(REGEX REPLACE "\\^" "\\\\^" FILETEST2 "${FILETEST2}")+ STRING(REGEX REPLACE "\\(" "\\\\(" FILETEST2 "${FILETEST2}")+ STRING(REGEX REPLACE "\\)" "\\\\)" FILETEST2 "${FILETEST2}")+ STRING(REGEX REPLACE "\\[" "\\\\[" FILETEST2 "${FILETEST2}")+ STRING(REGEX REPLACE "\\]" "\\\\]" FILETEST2 "${FILETEST2}")+ SET(${_str_out} "${FILETEST2}" PARENT_SCOPE)+endfunction()++function(test_escape_string_as_regex)+ SET(test1 "\\.^$-+*()[]?|")+ escape_string_as_regex(test2 "${test1}")+ SET(testRef "\\\\\\.\\^\\$\\-\\+\\*\\(\\)\\[\\]\\?\\|")+ if(NOT test2 STREQUAL testRef)+ message("Error in the escape_string_for_regex function : \n ${test1} was escaped as ${test2}, should be ${testRef}")+ endif(NOT test2 STREQUAL testRef)+endfunction()
+ eigen3/cmake/language_support.cmake view
@@ -0,0 +1,66 @@+# cmake/modules/language_support.cmake+#+# Temporary additional general language support is contained within this+# file. ++# This additional function definition is needed to provide a workaround for+# CMake bug 9220.++# On debian testing (cmake 2.6.2), I get return code zero when calling +# cmake the first time, but cmake crashes when running a second time+# as follows:+#+# -- The Fortran compiler identification is unknown+# CMake Error at /usr/share/cmake-2.6/Modules/CMakeFortranInformation.cmake:7 (GET_FILENAME_COMPONENT):+# get_filename_component called with incorrect number of arguments+# Call Stack (most recent call first):+# CMakeLists.txt:3 (enable_language)+#+# My workaround is to invoke cmake twice. If both return codes are zero, +# it is safe to invoke ENABLE_LANGUAGE(Fortran OPTIONAL)++function(workaround_9220 language language_works)+ #message("DEBUG: language = ${language}")+ set(text+ "project(test NONE)+ cmake_minimum_required(VERSION 2.8.0)+ set (CMAKE_Fortran_FLAGS \"${CMAKE_Fortran_FLAGS}\")+ set (CMAKE_EXE_LINKER_FLAGS \"${CMAKE_EXE_LINKER_FLAGS}\")+ enable_language(${language} OPTIONAL)+ ")+ file(REMOVE_RECURSE ${CMAKE_BINARY_DIR}/language_tests/${language})+ file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/language_tests/${language})+ file(WRITE ${CMAKE_BINARY_DIR}/language_tests/${language}/CMakeLists.txt+ ${text})+ execute_process(+ COMMAND ${CMAKE_COMMAND} . -G "${CMAKE_GENERATOR}"+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/language_tests/${language}+ RESULT_VARIABLE return_code+ OUTPUT_QUIET+ ERROR_QUIET+ )++ if(return_code EQUAL 0)+ # Second run+ execute_process (+ COMMAND ${CMAKE_COMMAND} .+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/language_tests/${language}+ RESULT_VARIABLE return_code+ OUTPUT_QUIET+ ERROR_QUIET+ )+ if(return_code EQUAL 0)+ set(${language_works} ON PARENT_SCOPE)+ else(return_code EQUAL 0)+ set(${language_works} OFF PARENT_SCOPE)+ endif(return_code EQUAL 0)+ else(return_code EQUAL 0)+ set(${language_works} OFF PARENT_SCOPE)+ endif(return_code EQUAL 0)+endfunction(workaround_9220)++# Temporary tests of the above function.+#workaround_9220(CXX CXX_language_works)+#message("CXX_language_works = ${CXX_language_works}")+#workaround_9220(CXXp CXXp_language_works)+#message("CXXp_language_works = ${CXXp_language_works}")
+ eigen3/debug/gdb/__init__.py view
@@ -0,0 +1,1 @@+# Intentionally empty
+ eigen3/debug/gdb/printers.py view
@@ -0,0 +1,208 @@+# -*- coding: utf-8 -*-+# This file is part of Eigen, a lightweight C++ template library+# for linear algebra.+#+# Copyright (C) 2009 Benjamin Schindler <bschindler@inf.ethz.ch>+#+# This Source Code Form is subject to the terms of the Mozilla Public+# License, v. 2.0. If a copy of the MPL was not distributed with this+# file, You can obtain one at http://mozilla.org/MPL/2.0/.++# Pretty printers for Eigen::Matrix+# This is still pretty basic as the python extension to gdb is still pretty basic. +# It cannot handle complex eigen types and it doesn't support any of the other eigen types+# Such as quaternion or some other type. +# This code supports fixed size as well as dynamic size matrices++# To use it:+#+# * Create a directory and put the file as well as an empty __init__.py in +# that directory.+# * Create a ~/.gdbinit file, that contains the following:+# python+# import sys+# sys.path.insert(0, '/path/to/eigen/printer/directory')+# from printers import register_eigen_printers+# register_eigen_printers (None)+# end++import gdb+import re+import itertools+++class EigenMatrixPrinter:+ "Print Eigen Matrix or Array of some kind"++ def __init__(self, variety, val):+ "Extract all the necessary information"+ + # Save the variety (presumably "Matrix" or "Array") for later usage+ self.variety = variety+ + # The gdb extension does not support value template arguments - need to extract them by hand+ type = val.type+ if type.code == gdb.TYPE_CODE_REF:+ type = type.target()+ self.type = type.unqualified().strip_typedefs()+ tag = self.type.tag+ regex = re.compile('\<.*\>')+ m = regex.findall(tag)[0][1:-1]+ template_params = m.split(',')+ template_params = map(lambda x:x.replace(" ", ""), template_params)+ + if template_params[1] == '-0x00000000000000001' or template_params[1] == '-0x000000001' or template_params[1] == '-1':+ self.rows = val['m_storage']['m_rows']+ else:+ self.rows = int(template_params[1])+ + if template_params[2] == '-0x00000000000000001' or template_params[2] == '-0x000000001' or template_params[2] == '-1':+ self.cols = val['m_storage']['m_cols']+ else:+ self.cols = int(template_params[2])+ + self.options = 0 # default value+ if len(template_params) > 3:+ self.options = template_params[3];+ + self.rowMajor = (int(self.options) & 0x1)+ + self.innerType = self.type.template_argument(0)+ + self.val = val+ + # Fixed size matrices have a struct as their storage, so we need to walk through this+ self.data = self.val['m_storage']['m_data']+ if self.data.type.code == gdb.TYPE_CODE_STRUCT:+ self.data = self.data['array']+ self.data = self.data.cast(self.innerType.pointer())+ + class _iterator:+ def __init__ (self, rows, cols, dataPtr, rowMajor):+ self.rows = rows+ self.cols = cols+ self.dataPtr = dataPtr+ self.currentRow = 0+ self.currentCol = 0+ self.rowMajor = rowMajor+ + def __iter__ (self):+ return self+ + def next(self):+ + row = self.currentRow+ col = self.currentCol+ if self.rowMajor == 0:+ if self.currentCol >= self.cols:+ raise StopIteration+ + self.currentRow = self.currentRow + 1+ if self.currentRow >= self.rows:+ self.currentRow = 0+ self.currentCol = self.currentCol + 1+ else:+ if self.currentRow >= self.rows:+ raise StopIteration+ + self.currentCol = self.currentCol + 1+ if self.currentCol >= self.cols:+ self.currentCol = 0+ self.currentRow = self.currentRow + 1+ + + item = self.dataPtr.dereference()+ self.dataPtr = self.dataPtr + 1+ if (self.cols == 1): #if it's a column vector+ return ('[%d]' % (row,), item)+ elif (self.rows == 1): #if it's a row vector+ return ('[%d]' % (col,), item)+ return ('[%d,%d]' % (row, col), item)+ + def children(self):+ + return self._iterator(self.rows, self.cols, self.data, self.rowMajor)+ + def to_string(self):+ return "Eigen::%s<%s,%d,%d,%s> (data ptr: %s)" % (self.variety, self.innerType, self.rows, self.cols, "RowMajor" if self.rowMajor else "ColMajor", self.data)++class EigenQuaternionPrinter:+ "Print an Eigen Quaternion"+ + def __init__(self, val):+ "Extract all the necessary information"+ # The gdb extension does not support value template arguments - need to extract them by hand+ type = val.type+ if type.code == gdb.TYPE_CODE_REF:+ type = type.target()+ self.type = type.unqualified().strip_typedefs()+ self.innerType = self.type.template_argument(0)+ self.val = val+ + # Quaternions have a struct as their storage, so we need to walk through this+ self.data = self.val['m_coeffs']['m_storage']['m_data']['array']+ self.data = self.data.cast(self.innerType.pointer())+ + class _iterator:+ def __init__ (self, dataPtr):+ self.dataPtr = dataPtr+ self.currentElement = 0+ self.elementNames = ['x', 'y', 'z', 'w']+ + def __iter__ (self):+ return self+ + def next(self):+ element = self.currentElement+ + if self.currentElement >= 4: #there are 4 elements in a quanternion+ raise StopIteration+ + self.currentElement = self.currentElement + 1+ + item = self.dataPtr.dereference()+ self.dataPtr = self.dataPtr + 1+ return ('[%s]' % (self.elementNames[element],), item)+ + def children(self):+ + return self._iterator(self.data)+ + def to_string(self):+ return "Eigen::Quaternion<%s> (data ptr: %s)" % (self.innerType, self.data)++def build_eigen_dictionary ():+ pretty_printers_dict[re.compile('^Eigen::Quaternion<.*>$')] = lambda val: EigenQuaternionPrinter(val)+ pretty_printers_dict[re.compile('^Eigen::Matrix<.*>$')] = lambda val: EigenMatrixPrinter("Matrix", val)+ pretty_printers_dict[re.compile('^Eigen::Array<.*>$')] = lambda val: EigenMatrixPrinter("Array", val)++def register_eigen_printers(obj):+ "Register eigen pretty-printers with objfile Obj"++ if obj == None:+ obj = gdb+ obj.pretty_printers.append(lookup_function)++def lookup_function(val):+ "Look-up and return a pretty-printer that can print va."+ + type = val.type+ + if type.code == gdb.TYPE_CODE_REF:+ type = type.target()+ + type = type.unqualified().strip_typedefs()+ + typename = type.tag+ if typename == None:+ return None+ + for function in pretty_printers_dict:+ if function.search(typename):+ return pretty_printers_dict[function](val)+ + return None++pretty_printers_dict = {}++build_eigen_dictionary ()
+ eigen3/debug/msvc/eigen.natvis view
@@ -0,0 +1,235 @@+<?xml version="1.0" encoding="utf-8"?> + +<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> + + <!-- Fixed x Fixed Matrix --> + <Type Name="Eigen::Matrix<*,*,*,*,*,*>"> + <AlternativeType Name="Eigen::Array<*,-1,-1,*,*,*>"/> + <DisplayString>[{$T2}, {$T3}] (fixed matrix)</DisplayString> + <Expand> + <ArrayItems Condition="Flags%2"> <!-- row major layout --> + <Rank>2</Rank> + <Size>$i==0 ? $T2 : $T3</Size> + <ValuePointer>m_storage.m_data.array</ValuePointer> + </ArrayItems> + <ArrayItems Condition="!(Flags%2)"> <!-- column major layout --> + <Direction>Backward</Direction> + <Rank>2</Rank> + <Size>$i==0 ? $T2 : $T3</Size> + <ValuePointer>m_storage.m_data.array</ValuePointer> + </ArrayItems> + </Expand> + </Type> + + <!-- 2 x 2 Matrix --> + <Type Name="Eigen::Matrix<*,2,2,*,*,*>"> + <AlternativeType Name="Eigen::Array<*,2,2,*,*,*>"/> + <DisplayString>[2, 2] (fixed matrix)</DisplayString> + <Expand> + <Synthetic Name="[row 0]" Condition="Flags%2"> + <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]})</DisplayString> + </Synthetic> + <Synthetic Name="[row 0]" Condition="!(Flags%2)"> + <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[2]})</DisplayString> + </Synthetic> + <Synthetic Name="[row 1]" Condition="Flags%2"> + <DisplayString>({m_storage.m_data.array[2]}, {m_storage.m_data.array[3]})</DisplayString> + </Synthetic> + <Synthetic Name="[row 1]" Condition="!(Flags%2)"> + <DisplayString>({m_storage.m_data.array[1]}, {m_storage.m_data.array[3]})</DisplayString> + </Synthetic> + </Expand> + </Type> + + <!-- 3 x 3 Matrix --> + <Type Name="Eigen::Matrix<*,3,3,*,*,*>"> + <AlternativeType Name="Eigen::Array<*,3,3,*,*,*>"/> + <DisplayString>[3, 3] (fixed matrix)</DisplayString> + <Expand> + <Synthetic Name="[row 0]" Condition="Flags%2"> + <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]}, {m_storage.m_data.array[2]})</DisplayString> + </Synthetic> + <Synthetic Name="[row 0]" Condition="!(Flags%2)"> + <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[3]}, {m_storage.m_data.array[6]})</DisplayString> + </Synthetic> + <Synthetic Name="[row 1]" Condition="Flags%2"> + <DisplayString>({m_storage.m_data.array[3]}, {m_storage.m_data.array[4]}, {m_storage.m_data.array[5]})</DisplayString> + </Synthetic> + <Synthetic Name="[row 1]" Condition="!(Flags%2)"> + <DisplayString>({m_storage.m_data.array[1]}, {m_storage.m_data.array[4]}, {m_storage.m_data.array[7]})</DisplayString> + </Synthetic> + <Synthetic Name="[row 2]" Condition="Flags%2"> + <DisplayString>({m_storage.m_data.array[6]}, {m_storage.m_data.array[7]}, {m_storage.m_data.array[8]})</DisplayString> + </Synthetic> + <Synthetic Name="[row 2]" Condition="!(Flags%2)"> + <DisplayString>({m_storage.m_data.array[2]}, {m_storage.m_data.array[5]}, {m_storage.m_data.array[8]})</DisplayString> + </Synthetic> + </Expand> + </Type> + + <!-- 4 x 4 Matrix --> + <Type Name="Eigen::Matrix<*,4,4,*,*,*>"> + <AlternativeType Name="Eigen::Array<*,4,4,*,*,*>"/> + <DisplayString>[4, 4] (fixed matrix)</DisplayString> + <Expand> + <Synthetic Name="[row 0]" Condition="Flags%2"> + <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]}, {m_storage.m_data.array[2]}, {m_storage.m_data.array[3]})</DisplayString> + </Synthetic> + <Synthetic Name="[row 0]" Condition="!(Flags%2)"> + <DisplayString>({m_storage.m_data.array[0]}, {m_storage.m_data.array[4]}, {m_storage.m_data.array[8]}, {m_storage.m_data.array[12]})</DisplayString> + </Synthetic> + <Synthetic Name="[row 1]" Condition="Flags%2"> + <DisplayString>({m_storage.m_data.array[4]}, {m_storage.m_data.array[5]}, {m_storage.m_data.array[6]}, {m_storage.m_data.array[7]})</DisplayString> + </Synthetic> + <Synthetic Name="[row 1]" Condition="!(Flags%2)"> + <DisplayString>({m_storage.m_data.array[1]}, {m_storage.m_data.array[5]}, {m_storage.m_data.array[9]}, {m_storage.m_data.array[13]})</DisplayString> + </Synthetic> + <Synthetic Name="[row 2]" Condition="Flags%2"> + <DisplayString>({m_storage.m_data.array[8]}, {m_storage.m_data.array[9]}, {m_storage.m_data.array[10]}, {m_storage.m_data.array[11]})</DisplayString> + </Synthetic> + <Synthetic Name="[row 2]" Condition="!(Flags%2)"> + <DisplayString>({m_storage.m_data.array[2]}, {m_storage.m_data.array[6]}, {m_storage.m_data.array[10]}, {m_storage.m_data.array[14]})</DisplayString> + </Synthetic> + <Synthetic Name="[row 3]" Condition="Flags%2"> + <DisplayString>({m_storage.m_data.array[12]}, {m_storage.m_data.array[13]}, {m_storage.m_data.array[14]}, {m_storage.m_data.array[15]})</DisplayString> + </Synthetic> + <Synthetic Name="[row 3]" Condition="!(Flags%2)"> + <DisplayString>({m_storage.m_data.array[3]}, {m_storage.m_data.array[7]}, {m_storage.m_data.array[11]}, {m_storage.m_data.array[15]})</DisplayString> + </Synthetic> + </Expand> + </Type> + + <!-- Dynamic x Dynamic Matrix --> + <Type Name="Eigen::Matrix<*,-1,-1,*,*,*>"> + <AlternativeType Name="Eigen::Array<*,-1,-1,*,*,*>"/> + <DisplayString Condition="m_storage.m_data == 0">empty</DisplayString> + <DisplayString Condition="m_storage.m_data != 0">[{m_storage.m_rows}, {m_storage.m_cols}] (dynamic matrix)</DisplayString> + <Expand> + <ArrayItems Condition="Flags%2"> <!-- row major layout --> + <Rank>2</Rank> + <Size>$i==0 ? m_storage.m_rows : m_storage.m_cols</Size> + <ValuePointer>m_storage.m_data</ValuePointer> + </ArrayItems> + <ArrayItems Condition="!(Flags%2)"> <!-- column major layout --> + <Direction>Backward</Direction> + <Rank>2</Rank> + <Size>$i==0 ? m_storage.m_rows : m_storage.m_cols</Size> + <ValuePointer>m_storage.m_data</ValuePointer> + </ArrayItems> + </Expand> + </Type> + + <!-- Fixed x Dynamic Matrix --> + <Type Name="Eigen::Matrix<*,*,-1,*,*,*>"> + <AlternativeType Name="Eigen::Array<*,*,-1,*,*,*>"/> + <DisplayString Condition="m_storage.m_data == 0">empty</DisplayString> + <DisplayString Condition="m_storage.m_data != 0">[{$T2}, {m_storage.m_cols}] (dynamic column matrix)</DisplayString> + <Expand> + <ArrayItems Condition="Flags%2"> <!-- row major layout --> + <Rank>2</Rank> + <Size>$i==0 ? $T2 : m_storage.m_cols</Size> + <ValuePointer>m_storage.m_data</ValuePointer> + </ArrayItems> + <ArrayItems Condition="!(Flags%2)"> <!-- column major layout --> + <Direction>Backward</Direction> + <Rank>2</Rank> + <Size>$i==0 ? $T2 : m_storage.m_cols</Size> + <ValuePointer>m_storage.m_data</ValuePointer> + </ArrayItems> + </Expand> + </Type> + + <!-- Dynamic x Fixed Matrix --> + <Type Name="Eigen::Matrix<*,-1,*,*,*,*>"> + <AlternativeType Name="Eigen::Array<*,-1,*,*,*,*>"/> + <DisplayString Condition="m_storage.m_data == 0">empty</DisplayString> + <DisplayString Condition="m_storage.m_data != 0">[{m_storage.m_rows}, {$T2}] (dynamic row matrix)</DisplayString> + <Expand> + <ArrayItems Condition="Flags%2"> <!-- row major layout --> + <Rank>2</Rank> + <Size>$i==0 ? m_storage.m_rows : $T2</Size> + <ValuePointer>m_storage.m_data</ValuePointer> + </ArrayItems> + <ArrayItems Condition="!(Flags%2)"> <!-- column major layout --> + <Direction>Backward</Direction> + <Rank>2</Rank> + <Size>$i==0 ? m_storage.m_rows : $T2</Size> + <ValuePointer>m_storage.m_data</ValuePointer> + </ArrayItems> + </Expand> + </Type> + + <!-- Dynamic Column Vector --> + <Type Name="Eigen::Matrix<*,1,-1,*,*,*>"> + <AlternativeType Name="Eigen::Array<*,1,-1,*,*,*>"/> + <DisplayString Condition="m_storage.m_data == 0">empty</DisplayString> + <DisplayString Condition="m_storage.m_data != 0">[{m_storage.m_cols}] (dynamic column vector)</DisplayString> + <Expand> + <Item Name="[size]">m_storage.m_cols</Item> + <ArrayItems> + <Size>m_storage.m_cols</Size> + <ValuePointer>m_storage.m_data</ValuePointer> + </ArrayItems> + </Expand> + </Type> + + <!-- Dynamic Row Vector --> + <Type Name="Eigen::Matrix<*,-1,1,*,*,*>"> + <AlternativeType Name="Eigen::Array<*,-1,1,*,*,*>"/> + <DisplayString Condition="m_storage.m_data == 0">empty</DisplayString> + <DisplayString Condition="m_storage.m_data != 0">[{m_storage.m_rows}] (dynamic row vector)</DisplayString> + <Expand> + <Item Name="[size]">m_storage.m_rows</Item> + <ArrayItems> + <Size>m_storage.m_rows</Size> + <ValuePointer>m_storage.m_data</ValuePointer> + </ArrayItems> + </Expand> + </Type> + + <!-- Fixed Vector --> + <Type Name="Eigen::Matrix<*,1,1,*,*,*>"> + <AlternativeType Name="Eigen::Array<*,1,1,*,*,*>"/> + <DisplayString>[1] ({m_storage.m_data.array[0]})</DisplayString> + <Expand> + <Item Name="[x]">m_storage.m_data.array[0]</Item> + </Expand> + </Type> + + <Type Name="Eigen::Matrix<*,2,1,*,*,*>"> + <AlternativeType Name="Eigen::Matrix<*,1,2,*,*,*>"/> + <AlternativeType Name="Eigen::Array<*,2,1,*,*,*>"/> + <AlternativeType Name="Eigen::Array<*,1,2,*,*,*>"/> + <DisplayString>[2] ({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]})</DisplayString> + <Expand> + <Item Name="[x]">m_storage.m_data.array[0]</Item> + <Item Name="[y]">m_storage.m_data.array[1]</Item> + </Expand> + </Type> + + <Type Name="Eigen::Matrix<*,3,1,*,*,*>"> + <AlternativeType Name="Eigen::Matrix<*,1,3,*,*,*>"/> + <AlternativeType Name="Eigen::Array<*,3,1,*,*,*>"/> + <AlternativeType Name="Eigen::Array<*,1,3,*,*,*>"/> + <DisplayString>[3] ({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]}, {m_storage.m_data.array[2]})</DisplayString> + <Expand> + <Item Name="[x]">m_storage.m_data.array[0]</Item> + <Item Name="[y]">m_storage.m_data.array[1]</Item> + <Item Name="[z]">m_storage.m_data.array[2]</Item> + </Expand> + </Type> + + <Type Name="Eigen::Matrix<*,4,1,*,*,*>"> + <AlternativeType Name="Eigen::Matrix<*,1,4,*,*,*>"/> + <AlternativeType Name="Eigen::Array<*,4,1,*,*,*>"/> + <AlternativeType Name="Eigen::Array<*,1,4,*,*,*>"/> + <DisplayString>[4] ({m_storage.m_data.array[0]}, {m_storage.m_data.array[1]}, {m_storage.m_data.array[2]}, {m_storage.m_data.array[3]})</DisplayString> + <Expand> + <Item Name="[x]">m_storage.m_data.array[0]</Item> + <Item Name="[y]">m_storage.m_data.array[1]</Item> + <Item Name="[z]">m_storage.m_data.array[2]</Item> + <Item Name="[w]">m_storage.m_data.array[3]</Item> + </Expand> + </Type> + +</AutoVisualizer>
+ eigen3/debug/msvc/eigen_autoexp_part.dat view
@@ -0,0 +1,295 @@+; *************************************************************** +; * Eigen Visualizer +; * +; * Author: Hauke Heibel <hauke.heibel@gmail.com> +; * +; * Support the enhanced debugging of the following Eigen +; * types (*: any, +:fixed dimension) : +; * +; * - Eigen::Matrix<*,4,1,*,*,*> and Eigen::Matrix<*,1,4,*,*,*> +; * - Eigen::Matrix<*,3,1,*,*,*> and Eigen::Matrix<*,1,3,*,*,*> +; * - Eigen::Matrix<*,2,1,*,*,*> and Eigen::Matrix<*,1,2,*,*,*> +; * - Eigen::Matrix<*,-1,-1,*,*,*> +; * - Eigen::Matrix<*,+,-1,*,*,*> +; * - Eigen::Matrix<*,-1,+,*,*,*> +; * - Eigen::Matrix<*,+,+,*,*,*> +; * +; * Matrices are displayed properly independantly of the memory +; * alignment (RowMajor vs. ColMajor). +; * +; * This file is distributed WITHOUT ANY WARRANTY. Please ensure +; * that your original autoexp.dat file is copied to a safe +; * place before proceeding with its modification. +; *************************************************************** + +[Visualizer] + +; Fixed size 4-vectors +Eigen::Matrix<*,4,1,*,*,*>|Eigen::Matrix<*,1,4,*,*,*>{ + children + ( + #( + [internals]: [$c,!], + x : ($c.m_storage.m_data.array)[0], + y : ($c.m_storage.m_data.array)[1], + z : ($c.m_storage.m_data.array)[2], + w : ($c.m_storage.m_data.array)[3] + ) + ) + + preview + ( + #( + "[", + 4, + "](", + #array(expr: $e.m_storage.m_data.array[$i], size: 4), + ")" + ) + ) +} + +; Fixed size 3-vectors +Eigen::Matrix<*,3,1,*,*,*>|Eigen::Matrix<*,1,3,*,*,*>{ + children + ( + #( + [internals]: [$c,!], + x : ($c.m_storage.m_data.array)[0], + y : ($c.m_storage.m_data.array)[1], + z : ($c.m_storage.m_data.array)[2] + ) + ) + + preview + ( + #( + "[", + 3, + "](", + #array(expr: $e.m_storage.m_data.array[$i], size: 3), + ")" + ) + ) +} + +; Fixed size 2-vectors +Eigen::Matrix<*,2,1,*,*,*>|Eigen::Matrix<*,1,2,*,*,*>{ + children + ( + #( + [internals]: [$c,!], + x : ($c.m_storage.m_data.array)[0], + y : ($c.m_storage.m_data.array)[1] + ) + ) + + preview + ( + #( + "[", + 2, + "](", + #array(expr: $e.m_storage.m_data.array[$i], size: 2), + ")" + ) + ) +} + +; Fixed size 1-vectors +Eigen::Matrix<*,1,1,*,*,*>|Eigen::Matrix<*,1,1,*,*,*>{ + children + ( + #( + [internals]: [$c,!], + x : ($c.m_storage.m_data.array)[0] + ) + ) + + preview + ( + #( + "[", + 1, + "](", + #array(expr: $e.m_storage.m_data.array[$i], size: 1), + ")" + ) + ) +} + +; Dynamic matrices (ColMajor and RowMajor support) +Eigen::Matrix<*,-1,-1,*,*,*>{ + children + ( + #( + [internals]: [$c,!], + rows: $c.m_storage.m_rows, + cols: $c.m_storage.m_cols, + ; Check for RowMajorBit + #if ($c.Flags & 0x1) ( + #array( + rank: 2, + base: 0, + expr: ($c.m_storage.m_data)[($i % $c.m_storage.m_rows)*$c.m_storage.m_cols + (($i- $i % $c.m_storage.m_rows)/$c.m_storage.m_rows)], + size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.m_storage.m_cols + ) + ) #else ( + #array( + rank: 2, + base: 0, + expr: ($c.m_storage.m_data)[$i], + size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.m_storage.m_cols + ) + ) + ) + ) + + preview + ( + #( + "[", + $c.m_storage.m_rows, + ",", + $c.m_storage.m_cols, + "](", + #array( + expr : [($c.m_storage.m_data)[$i],g], + size : $c.m_storage.m_rows*$c.m_storage.m_cols + ), + ")" + ) + ) +} + +; Fixed rows, dynamic columns matrix (ColMajor and RowMajor support) +Eigen::Matrix<*,*,-1,*,*,*>{ + children + ( + #( + [internals]: [$c,!], + rows: $c.RowsAtCompileTime, + cols: $c.m_storage.m_cols, + ; Check for RowMajorBit + #if ($c.Flags & 0x1) ( + #array( + rank: 2, + base: 0, + expr: ($c.m_storage.m_data)[($i % $c.RowsAtCompileTime)*$c.m_storage.m_cols + (($i- $i % $c.RowsAtCompileTime)/$c.RowsAtCompileTime)], + size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.m_storage.m_cols + ) + ) #else ( + #array( + rank: 2, + base: 0, + expr: ($c.m_storage.m_data)[$i], + size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.m_storage.m_cols + ) + ) + ) + ) + + preview + ( + #( + "[", + $c.RowsAtCompileTime, + ",", + $c.m_storage.m_cols, + "](", + #array( + expr : [($c.m_storage.m_data)[$i],g], + size : $c.RowsAtCompileTime*$c.m_storage.m_cols + ), + ")" + ) + ) +} + +; Dynamic rows, fixed columns matrix (ColMajor and RowMajor support) +Eigen::Matrix<*,-1,*,*,*,*>{ + children + ( + #( + [internals]: [$c,!], + rows: $c.m_storage.m_rows, + cols: $c.ColsAtCompileTime, + ; Check for RowMajorBit + #if ($c.Flags & 0x1) ( + #array( + rank: 2, + base: 0, + expr: ($c.m_storage.m_data)[($i % $c.m_storage.m_rows)*$c.ColsAtCompileTime + (($i- $i % $c.m_storage.m_rows)/$c.m_storage.m_rows)], + size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.ColsAtCompileTime + ) + ) #else ( + #array( + rank: 2, + base: 0, + expr: ($c.m_storage.m_data)[$i], + size: ($r==1)*$c.m_storage.m_rows+($r==0)*$c.ColsAtCompileTime + ) + ) + ) + ) + + preview + ( + #( + "[", + $c.m_storage.m_rows, + ",", + $c.ColsAtCompileTime, + "](", + #array( + expr : [($c.m_storage.m_data)[$i],g], + size : $c.m_storage.m_rows*$c.ColsAtCompileTime + ), + ")" + ) + ) +} + +; Fixed size matrix (ColMajor and RowMajor support) +Eigen::Matrix<*,*,*,*,*,*>{ + children + ( + #( + [internals]: [$c,!], + rows: $c.RowsAtCompileTime, + cols: $c.ColsAtCompileTime, + ; Check for RowMajorBit + #if ($c.Flags & 0x1) ( + #array( + rank: 2, + base: 0, + expr: ($c.m_storage.m_data.array)[($i % $c.RowsAtCompileTime)*$c.ColsAtCompileTime + (($i- $i % $c.RowsAtCompileTime)/$c.RowsAtCompileTime)], + size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.ColsAtCompileTime + ) + ) #else ( + #array( + rank: 2, + base: 0, + expr: ($c.m_storage.m_data.array)[$i], + size: ($r==1)*$c.RowsAtCompileTime+($r==0)*$c.ColsAtCompileTime + ) + ) + ) + ) + + preview + ( + #( + "[", + $c.RowsAtCompileTime, + ",", + $c.ColsAtCompileTime, + "](", + #array( + expr : [($c.m_storage.m_data.array)[$i],g], + size : $c.RowsAtCompileTime*$c.ColsAtCompileTime + ), + ")" + ) + ) +}
+ eigen3/demos/CMakeLists.txt view
@@ -0,0 +1,13 @@+project(EigenDemos)++add_custom_target(demos)++if(NOT EIGEN_TEST_NOQT)+ find_package(Qt4)+ if(QT4_FOUND)+ add_subdirectory(mandelbrot)+ add_subdirectory(opengl)+ else(QT4_FOUND)+ message(STATUS "Qt4 not found, so disabling the mandelbrot and opengl demos")+ endif(QT4_FOUND)+endif()
+ eigen3/demos/mandelbrot/CMakeLists.txt view
@@ -0,0 +1,21 @@+find_package(Qt4 REQUIRED)++set(CMAKE_INCLUDE_CURRENT_DIR ON)++if (CMAKE_COMPILER_IS_GNUCXX)+ set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2")+ add_definitions ( "-DNDEBUG" )+endif (CMAKE_COMPILER_IS_GNUCXX)++include_directories( ${QT_INCLUDE_DIR} )++set(mandelbrot_SRCS+ mandelbrot.cpp+)++qt4_automoc(${mandelbrot_SRCS})++add_executable(mandelbrot ${mandelbrot_SRCS})+add_dependencies(demos mandelbrot)++target_link_libraries(mandelbrot ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY})
+ eigen3/demos/mandelbrot/README view
@@ -0,0 +1,10 @@+*** Mandelbrot demo ***++Controls:+* Left mouse button to center view at a point.+* Drag vertically with left mouse button to zoom in and out.++Be sure to enable SSE2 or AltiVec to improve performance.++The number of iterations, and the choice between single and double precision, are+determined at runtime depending on the zoom level.
+ eigen3/demos/mandelbrot/mandelbrot.cpp view
@@ -0,0 +1,213 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "mandelbrot.h"+#include <iostream>+#include<QtGui/QPainter>+#include<QtGui/QImage>+#include<QtGui/QMouseEvent>+#include<QtCore/QTime>++void MandelbrotWidget::resizeEvent(QResizeEvent *)+{+ if(size < width() * height())+ {+ std::cout << "reallocate buffer" << std::endl;+ size = width() * height();+ if(buffer) delete[]buffer;+ buffer = new unsigned char[4*size];+ }+}++template<typename T> struct iters_before_test { enum { ret = 8 }; };+template<> struct iters_before_test<double> { enum { ret = 16 }; };++template<typename Real> void MandelbrotThread::render(int img_width, int img_height)+{+ enum { packetSize = Eigen::internal::packet_traits<Real>::size }; // number of reals in a Packet+ typedef Eigen::Array<Real, packetSize, 1> Packet; // wrap a Packet as a vector++ enum { iters_before_test = iters_before_test<Real>::ret };+ max_iter = (max_iter / iters_before_test) * iters_before_test;+ const int alignedWidth = (img_width/packetSize)*packetSize;+ unsigned char *const buffer = widget->buffer;+ const double xradius = widget->xradius;+ const double yradius = xradius * img_height / img_width;+ const int threadcount = widget->threadcount;+ typedef Eigen::Array<Real, 2, 1> Vector2;+ Vector2 start(widget->center.x() - widget->xradius, widget->center.y() - yradius);+ Vector2 step(2*widget->xradius/img_width, 2*yradius/img_height);+ total_iter = 0;++ for(int y = id; y < img_height; y += threadcount)+ {+ int pix = y * img_width;++ // for each pixel, we're going to do the iteration z := z^2 + c where z and c are complex numbers, + // starting with z = c = complex coord of the pixel. pzi and pzr denote the real and imaginary parts of z.+ // pci and pcr denote the real and imaginary parts of c.++ Packet pzi_start, pci_start;+ for(int i = 0; i < packetSize; i++) pzi_start[i] = pci_start[i] = start.y() + y * step.y();++ for(int x = 0; x < alignedWidth; x += packetSize, pix += packetSize)+ {+ Packet pcr, pci = pci_start, pzr, pzi = pzi_start, pzr_buf;+ for(int i = 0; i < packetSize; i++) pzr[i] = pcr[i] = start.x() + (x+i) * step.x();++ // do the iterations. Every iters_before_test iterations we check for divergence,+ // in which case we can stop iterating.+ int j = 0;+ typedef Eigen::Matrix<int, packetSize, 1> Packeti;+ Packeti pix_iter = Packeti::Zero(), // number of iteration per pixel in the packet+ pix_dont_diverge; // whether or not each pixel has already diverged+ do+ {+ for(int i = 0; i < iters_before_test/4; i++) // peel the inner loop by 4+ {+# define ITERATE \+ pzr_buf = pzr; \+ pzr = pzr.square(); \+ pzr -= pzi.square(); \+ pzr += pcr; \+ pzi = (2*pzr_buf)*pzi; \+ pzi += pci;+ ITERATE ITERATE ITERATE ITERATE+ }+ pix_dont_diverge = ((pzr.square() + pzi.square())+ .eval() // temporary fix as what follows is not yet vectorized by Eigen+ <= Packet::Constant(4))+ // the 4 here is not a magic value, it's a math fact that if+ // the square modulus is >4 then divergence is inevitable.+ .template cast<int>();+ pix_iter += iters_before_test * pix_dont_diverge;+ j++;+ total_iter += iters_before_test * packetSize;+ }+ while(j < max_iter/iters_before_test && pix_dont_diverge.any()); // any() is not yet vectorized by Eigen++ // compute pixel colors+ for(int i = 0; i < packetSize; i++)+ {+ buffer[4*(pix+i)] = 255*pix_iter[i]/max_iter;+ buffer[4*(pix+i)+1] = 0;+ buffer[4*(pix+i)+2] = 0;+ }+ }++ // if the width is not a multiple of packetSize, fill the remainder in black+ for(int x = alignedWidth; x < img_width; x++, pix++)+ buffer[4*pix] = buffer[4*pix+1] = buffer[4*pix+2] = 0;+ }+ return;+}++void MandelbrotThread::run()+{+ setTerminationEnabled(true);+ double resolution = widget->xradius*2/widget->width();+ max_iter = 128;+ if(resolution < 1e-4f) max_iter += 128 * ( - 4 - std::log10(resolution));+ int img_width = widget->width()/widget->draft;+ int img_height = widget->height()/widget->draft;+ single_precision = resolution > 1e-7f;++ if(single_precision)+ render<float>(img_width, img_height);+ else+ render<double>(img_width, img_height);+}++void MandelbrotWidget::paintEvent(QPaintEvent *)+{+ static float max_speed = 0;+ long long total_iter = 0;++ QTime time;+ time.start();+ for(int th = 0; th < threadcount; th++)+ threads[th]->start(QThread::LowPriority);+ for(int th = 0; th < threadcount; th++)+ {+ threads[th]->wait();+ total_iter += threads[th]->total_iter;+ }+ int elapsed = time.elapsed();++ if(draft == 1)+ {+ float speed = elapsed ? float(total_iter)*1000/elapsed : 0;+ max_speed = std::max(max_speed, speed);+ std::cout << threadcount << " threads, "+ << elapsed << " ms, "+ << speed << " iters/s (max " << max_speed << ")" << std::endl;+ int packetSize = threads[0]->single_precision+ ? int(Eigen::internal::packet_traits<float>::size)+ : int(Eigen::internal::packet_traits<double>::size);+ setWindowTitle(QString("resolution ")+QString::number(xradius*2/width(), 'e', 2)+ +QString(", %1 iterations per pixel, ").arg(threads[0]->max_iter)+ +(threads[0]->single_precision ? QString("single ") : QString("double "))+ +QString("precision, ")+ +(packetSize==1 ? QString("no vectorization")+ : QString("vectorized (%1 per packet)").arg(packetSize)));+ }+ + QImage image(buffer, width()/draft, height()/draft, QImage::Format_RGB32);+ QPainter painter(this);+ painter.drawImage(QPoint(0, 0), image.scaled(width(), height()));++ if(draft>1)+ {+ draft /= 2;+ setWindowTitle(QString("recomputing at 1/%1 resolution...").arg(draft));+ update();+ }+}++void MandelbrotWidget::mousePressEvent(QMouseEvent *event)+{+ if( event->buttons() & Qt::LeftButton )+ {+ lastpos = event->pos();+ double yradius = xradius * height() / width();+ center = Eigen::Vector2d(center.x() + (event->pos().x() - width()/2) * xradius * 2 / width(),+ center.y() + (event->pos().y() - height()/2) * yradius * 2 / height());+ draft = 16;+ for(int th = 0; th < threadcount; th++)+ threads[th]->terminate();+ update();+ }+}++void MandelbrotWidget::mouseMoveEvent(QMouseEvent *event)+{+ QPoint delta = event->pos() - lastpos;+ lastpos = event->pos();+ if( event->buttons() & Qt::LeftButton )+ {+ double t = 1 + 5 * double(delta.y()) / height();+ if(t < 0.5) t = 0.5;+ if(t > 2) t = 2;+ xradius *= t;+ draft = 16;+ for(int th = 0; th < threadcount; th++)+ threads[th]->terminate();+ update();+ }+}++int main(int argc, char *argv[])+{+ QApplication app(argc, argv);+ MandelbrotWidget w;+ w.show();+ return app.exec();+}++#include "mandelbrot.moc"
+ eigen3/demos/mandelbrot/mandelbrot.h view
@@ -0,0 +1,71 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef MANDELBROT_H+#define MANDELBROT_H++#include <Eigen/Core>+#include <QtGui/QApplication>+#include <QtGui/QWidget>+#include <QtCore/QThread>++class MandelbrotWidget;++class MandelbrotThread : public QThread+{+ friend class MandelbrotWidget;+ MandelbrotWidget *widget;+ long long total_iter;+ int id, max_iter;+ bool single_precision;++ public:+ MandelbrotThread(MandelbrotWidget *w, int i) : widget(w), id(i) {}+ void run();+ template<typename Real> void render(int img_width, int img_height);+};++class MandelbrotWidget : public QWidget+{+ Q_OBJECT++ friend class MandelbrotThread;+ Eigen::Vector2d center;+ double xradius;+ int size;+ unsigned char *buffer;+ QPoint lastpos;+ int draft;+ MandelbrotThread **threads;+ int threadcount;++ protected:+ void resizeEvent(QResizeEvent *);+ void paintEvent(QPaintEvent *);+ void mousePressEvent(QMouseEvent *event);+ void mouseMoveEvent(QMouseEvent *event);++ public:+ MandelbrotWidget() : QWidget(), center(0,0), xradius(2),+ size(0), buffer(0), draft(16)+ {+ setAutoFillBackground(false);+ threadcount = QThread::idealThreadCount();+ threads = new MandelbrotThread*[threadcount];+ for(int th = 0; th < threadcount; th++) threads[th] = new MandelbrotThread(this, th);+ }+ ~MandelbrotWidget()+ {+ if(buffer) delete[]buffer;+ for(int th = 0; th < threadcount; th++) delete threads[th];+ delete[] threads;+ }+};++#endif // MANDELBROT_H
+ eigen3/demos/mix_eigen_and_c/README view
@@ -0,0 +1,9 @@+This is an example of how one can wrap some of Eigen into a C library.++To try this with GCC, do:++ g++ -c binary_library.cpp -O2 -msse2 -I ../..+ gcc example.c binary_library.o -o example -lstdc+++ ./example++TODO: add CMakeLists, add more explanations here
+ eigen3/demos/mix_eigen_and_c/binary_library.cpp view
@@ -0,0 +1,185 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++// This C++ file compiles to binary code that can be linked to by your C program,+// thanks to the extern "C" syntax used in the declarations in binary_library.h.++#include "binary_library.h"++#include <Eigen/Core>++using namespace Eigen;++/************************* pointer conversion methods **********************************************/++////// class MatrixXd //////++inline MatrixXd& c_to_eigen(C_MatrixXd* ptr)+{+ return *reinterpret_cast<MatrixXd*>(ptr);+}++inline const MatrixXd& c_to_eigen(const C_MatrixXd* ptr)+{+ return *reinterpret_cast<const MatrixXd*>(ptr);+}++inline C_MatrixXd* eigen_to_c(MatrixXd& ref)+{+ return reinterpret_cast<C_MatrixXd*>(&ref);+}++inline const C_MatrixXd* eigen_to_c(const MatrixXd& ref)+{+ return reinterpret_cast<const C_MatrixXd*>(&ref);+}++////// class Map<MatrixXd> //////++inline Map<MatrixXd>& c_to_eigen(C_Map_MatrixXd* ptr)+{+ return *reinterpret_cast<Map<MatrixXd>*>(ptr);+}++inline const Map<MatrixXd>& c_to_eigen(const C_Map_MatrixXd* ptr)+{+ return *reinterpret_cast<const Map<MatrixXd>*>(ptr);+}++inline C_Map_MatrixXd* eigen_to_c(Map<MatrixXd>& ref)+{+ return reinterpret_cast<C_Map_MatrixXd*>(&ref);+}++inline const C_Map_MatrixXd* eigen_to_c(const Map<MatrixXd>& ref)+{+ return reinterpret_cast<const C_Map_MatrixXd*>(&ref);+}+++/************************* implementation of classes **********************************************/+++////// class MatrixXd //////+++C_MatrixXd* MatrixXd_new(int rows, int cols)+{+ return eigen_to_c(*new MatrixXd(rows,cols));+}++void MatrixXd_delete(C_MatrixXd *m)+{+ delete &c_to_eigen(m);+}++double* MatrixXd_data(C_MatrixXd *m)+{+ return c_to_eigen(m).data();+}++void MatrixXd_set_zero(C_MatrixXd *m)+{+ c_to_eigen(m).setZero();+}++void MatrixXd_resize(C_MatrixXd *m, int rows, int cols)+{+ c_to_eigen(m).resize(rows,cols);+}++void MatrixXd_copy(C_MatrixXd *dst, const C_MatrixXd *src)+{+ c_to_eigen(dst) = c_to_eigen(src);+}++void MatrixXd_copy_map(C_MatrixXd *dst, const C_Map_MatrixXd *src)+{+ c_to_eigen(dst) = c_to_eigen(src);+}++void MatrixXd_set_coeff(C_MatrixXd *m, int i, int j, double coeff)+{+ c_to_eigen(m)(i,j) = coeff;+}++double MatrixXd_get_coeff(const C_MatrixXd *m, int i, int j)+{+ return c_to_eigen(m)(i,j);+}++void MatrixXd_print(const C_MatrixXd *m)+{+ std::cout << c_to_eigen(m) << std::endl;+}++void MatrixXd_multiply(const C_MatrixXd *m1, const C_MatrixXd *m2, C_MatrixXd *result)+{+ c_to_eigen(result) = c_to_eigen(m1) * c_to_eigen(m2);+}++void MatrixXd_add(const C_MatrixXd *m1, const C_MatrixXd *m2, C_MatrixXd *result)+{+ c_to_eigen(result) = c_to_eigen(m1) + c_to_eigen(m2);+}++++////// class Map_MatrixXd //////+++C_Map_MatrixXd* Map_MatrixXd_new(double *array, int rows, int cols)+{+ return eigen_to_c(*new Map<MatrixXd>(array,rows,cols));+}++void Map_MatrixXd_delete(C_Map_MatrixXd *m)+{+ delete &c_to_eigen(m);+}++void Map_MatrixXd_set_zero(C_Map_MatrixXd *m)+{+ c_to_eigen(m).setZero();+}++void Map_MatrixXd_copy(C_Map_MatrixXd *dst, const C_Map_MatrixXd *src)+{+ c_to_eigen(dst) = c_to_eigen(src);+}++void Map_MatrixXd_copy_matrix(C_Map_MatrixXd *dst, const C_MatrixXd *src)+{+ c_to_eigen(dst) = c_to_eigen(src);+}++void Map_MatrixXd_set_coeff(C_Map_MatrixXd *m, int i, int j, double coeff)+{+ c_to_eigen(m)(i,j) = coeff;+}++double Map_MatrixXd_get_coeff(const C_Map_MatrixXd *m, int i, int j)+{+ return c_to_eigen(m)(i,j);+}++void Map_MatrixXd_print(const C_Map_MatrixXd *m)+{+ std::cout << c_to_eigen(m) << std::endl;+}++void Map_MatrixXd_multiply(const C_Map_MatrixXd *m1, const C_Map_MatrixXd *m2, C_Map_MatrixXd *result)+{+ c_to_eigen(result) = c_to_eigen(m1) * c_to_eigen(m2);+}++void Map_MatrixXd_add(const C_Map_MatrixXd *m1, const C_Map_MatrixXd *m2, C_Map_MatrixXd *result)+{+ c_to_eigen(result) = c_to_eigen(m1) + c_to_eigen(m2);+}
+ eigen3/demos/mix_eigen_and_c/binary_library.h view
@@ -0,0 +1,71 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++// This is a pure C header, no C++ here.+// The functions declared here will be implemented in C++ but+// we don't have to know, because thanks to the extern "C" syntax,+// they will be compiled to C object code.++#ifdef __cplusplus+extern "C"+{+#endif++ // just dummy empty structs to give different pointer types,+ // instead of using void* which would be type unsafe+ struct C_MatrixXd {};+ struct C_Map_MatrixXd {};++ // the C_MatrixXd class, wraps some of the functionality+ // of Eigen::MatrixXd.+ struct C_MatrixXd* MatrixXd_new(int rows, int cols);+ void MatrixXd_delete (struct C_MatrixXd *m);+ double* MatrixXd_data (struct C_MatrixXd *m);+ void MatrixXd_set_zero (struct C_MatrixXd *m);+ void MatrixXd_resize (struct C_MatrixXd *m, int rows, int cols);+ void MatrixXd_copy (struct C_MatrixXd *dst,+ const struct C_MatrixXd *src);+ void MatrixXd_copy_map (struct C_MatrixXd *dst,+ const struct C_Map_MatrixXd *src); + void MatrixXd_set_coeff (struct C_MatrixXd *m,+ int i, int j, double coeff);+ double MatrixXd_get_coeff (const struct C_MatrixXd *m,+ int i, int j);+ void MatrixXd_print (const struct C_MatrixXd *m);+ void MatrixXd_add (const struct C_MatrixXd *m1,+ const struct C_MatrixXd *m2,+ struct C_MatrixXd *result); + void MatrixXd_multiply (const struct C_MatrixXd *m1,+ const struct C_MatrixXd *m2,+ struct C_MatrixXd *result);+ + // the C_Map_MatrixXd class, wraps some of the functionality+ // of Eigen::Map<MatrixXd>+ struct C_Map_MatrixXd* Map_MatrixXd_new(double *array, int rows, int cols);+ void Map_MatrixXd_delete (struct C_Map_MatrixXd *m);+ void Map_MatrixXd_set_zero (struct C_Map_MatrixXd *m);+ void Map_MatrixXd_copy (struct C_Map_MatrixXd *dst,+ const struct C_Map_MatrixXd *src);+ void Map_MatrixXd_copy_matrix(struct C_Map_MatrixXd *dst,+ const struct C_MatrixXd *src); + void Map_MatrixXd_set_coeff (struct C_Map_MatrixXd *m,+ int i, int j, double coeff);+ double Map_MatrixXd_get_coeff (const struct C_Map_MatrixXd *m,+ int i, int j);+ void Map_MatrixXd_print (const struct C_Map_MatrixXd *m);+ void Map_MatrixXd_add (const struct C_Map_MatrixXd *m1,+ const struct C_Map_MatrixXd *m2,+ struct C_Map_MatrixXd *result); + void Map_MatrixXd_multiply (const struct C_Map_MatrixXd *m1,+ const struct C_Map_MatrixXd *m2,+ struct C_Map_MatrixXd *result);++#ifdef __cplusplus+} // end extern "C"+#endif
+ eigen3/demos/mix_eigen_and_c/example.c view
@@ -0,0 +1,65 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "binary_library.h"+#include "stdio.h"++void demo_MatrixXd()+{+ struct C_MatrixXd *matrix1, *matrix2, *result;+ printf("*** demo_MatrixXd ***\n");+ + matrix1 = MatrixXd_new(3, 3);+ MatrixXd_set_zero(matrix1);+ MatrixXd_set_coeff(matrix1, 0, 1, 2.5);+ MatrixXd_set_coeff(matrix1, 1, 0, 1.4);+ printf("Here is matrix1:\n");+ MatrixXd_print(matrix1);++ matrix2 = MatrixXd_new(3, 3);+ MatrixXd_multiply(matrix1, matrix1, matrix2);+ printf("Here is matrix1*matrix1:\n");+ MatrixXd_print(matrix2);++ MatrixXd_delete(matrix1);+ MatrixXd_delete(matrix2);+}++// this helper function takes a plain C array and prints it in one line+void print_array(double *array, int n)+{+ struct C_Map_MatrixXd *m = Map_MatrixXd_new(array, 1, n);+ Map_MatrixXd_print(m);+ Map_MatrixXd_delete(m);+}++void demo_Map_MatrixXd()+{+ struct C_Map_MatrixXd *map;+ double array[5];+ int i;+ printf("*** demo_Map_MatrixXd ***\n");+ + for(i = 0; i < 5; ++i) array[i] = i;+ printf("Initially, the array is:\n");+ print_array(array, 5);+ + map = Map_MatrixXd_new(array, 5, 1);+ Map_MatrixXd_add(map, map, map);+ Map_MatrixXd_delete(map);++ printf("Now the array is:\n");+ print_array(array, 5);+}++int main()+{+ demo_MatrixXd();+ demo_Map_MatrixXd();+}
+ eigen3/demos/opengl/CMakeLists.txt view
@@ -0,0 +1,28 @@+find_package(Qt4)+find_package(OpenGL)++if(QT4_FOUND AND OPENGL_FOUND)++ set(QT_USE_QTOPENGL TRUE)+ include(${QT_USE_FILE})++ set(CMAKE_INCLUDE_CURRENT_DIR ON)++ include_directories( ${QT_INCLUDE_DIR} )++ set(quaternion_demo_SRCS gpuhelper.cpp icosphere.cpp camera.cpp trackball.cpp quaternion_demo.cpp)++ qt4_automoc(${quaternion_demo_SRCS})++ add_executable(quaternion_demo ${quaternion_demo_SRCS})+ add_dependencies(demos quaternion_demo)++ target_link_libraries(quaternion_demo+ ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY}+ ${QT_QTOPENGL_LIBRARY} ${OPENGL_LIBRARIES} )++else()++ message(STATUS "OpenGL demo disabled because Qt4 and/or OpenGL have not been found.")++endif()
+ eigen3/demos/opengl/README view
@@ -0,0 +1,13 @@++Navigation:+ left button: rotate around the target+ middle button: zoom+ left button + ctrl quake rotate (rotate around camera position)+ middle button + ctrl walk (progress along camera's z direction)+ left button: pan (translate in the XY camera's plane)++R : move the camera to initial position+A : start/stop animation+C : clear the animation+G : add a key frame+
+ eigen3/demos/opengl/camera.cpp view
@@ -0,0 +1,264 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "camera.h"++#include "gpuhelper.h"+#include <GL/glu.h>++#include "Eigen/LU"+using namespace Eigen;++Camera::Camera()+ : mViewIsUptodate(false), mProjIsUptodate(false)+{+ mViewMatrix.setIdentity();+ + mFovY = M_PI/3.;+ mNearDist = 1.;+ mFarDist = 50000.;+ + mVpX = 0;+ mVpY = 0;++ setPosition(Vector3f::Constant(100.));+ setTarget(Vector3f::Zero());+}++Camera& Camera::operator=(const Camera& other)+{+ mViewIsUptodate = false;+ mProjIsUptodate = false;+ + mVpX = other.mVpX;+ mVpY = other.mVpY;+ mVpWidth = other.mVpWidth;+ mVpHeight = other.mVpHeight;++ mTarget = other.mTarget;+ mFovY = other.mFovY;+ mNearDist = other.mNearDist;+ mFarDist = other.mFarDist;+ + mViewMatrix = other.mViewMatrix;+ mProjectionMatrix = other.mProjectionMatrix;++ return *this;+}++Camera::Camera(const Camera& other)+{+ *this = other;+}++Camera::~Camera()+{+}+++void Camera::setViewport(uint offsetx, uint offsety, uint width, uint height)+{+ mVpX = offsetx;+ mVpY = offsety;+ mVpWidth = width;+ mVpHeight = height;+ + mProjIsUptodate = false;+}++void Camera::setViewport(uint width, uint height)+{+ mVpWidth = width;+ mVpHeight = height;+ + mProjIsUptodate = false;+}++void Camera::setFovY(float value)+{+ mFovY = value;+ mProjIsUptodate = false;+}++Vector3f Camera::direction(void) const+{+ return - (orientation() * Vector3f::UnitZ());+}+Vector3f Camera::up(void) const+{+ return orientation() * Vector3f::UnitY();+}+Vector3f Camera::right(void) const+{+ return orientation() * Vector3f::UnitX();+}++void Camera::setDirection(const Vector3f& newDirection)+{+ // TODO implement it computing the rotation between newDirection and current dir ?+ Vector3f up = this->up();+ + Matrix3f camAxes;++ camAxes.col(2) = (-newDirection).normalized();+ camAxes.col(0) = up.cross( camAxes.col(2) ).normalized();+ camAxes.col(1) = camAxes.col(2).cross( camAxes.col(0) ).normalized();+ setOrientation(Quaternionf(camAxes));+ + mViewIsUptodate = false;+}++void Camera::setTarget(const Vector3f& target)+{+ mTarget = target;+ if (!mTarget.isApprox(position()))+ {+ Vector3f newDirection = mTarget - position();+ setDirection(newDirection.normalized());+ }+}++void Camera::setPosition(const Vector3f& p)+{+ mFrame.position = p;+ mViewIsUptodate = false;+}++void Camera::setOrientation(const Quaternionf& q)+{+ mFrame.orientation = q;+ mViewIsUptodate = false;+}++void Camera::setFrame(const Frame& f)+{+ mFrame = f;+ mViewIsUptodate = false;+}++void Camera::rotateAroundTarget(const Quaternionf& q)+{+ Matrix4f mrot, mt, mtm;+ + // update the transform matrix+ updateViewMatrix();+ Vector3f t = mViewMatrix * mTarget;++ mViewMatrix = Translation3f(t)+ * q+ * Translation3f(-t)+ * mViewMatrix;+ + Quaternionf qa(mViewMatrix.linear());+ qa = qa.conjugate();+ setOrientation(qa);+ setPosition(- (qa * mViewMatrix.translation()) );++ mViewIsUptodate = true;+}++void Camera::localRotate(const Quaternionf& q)+{+ float dist = (position() - mTarget).norm();+ setOrientation(orientation() * q);+ mTarget = position() + dist * direction();+ mViewIsUptodate = false;+}++void Camera::zoom(float d)+{+ float dist = (position() - mTarget).norm();+ if(dist > d)+ {+ setPosition(position() + direction() * d);+ mViewIsUptodate = false;+ }+}++void Camera::localTranslate(const Vector3f& t)+{+ Vector3f trans = orientation() * t;+ setPosition( position() + trans );+ setTarget( mTarget + trans );++ mViewIsUptodate = false;+}++void Camera::updateViewMatrix(void) const+{+ if(!mViewIsUptodate)+ {+ Quaternionf q = orientation().conjugate();+ mViewMatrix.linear() = q.toRotationMatrix();+ mViewMatrix.translation() = - (mViewMatrix.linear() * position());++ mViewIsUptodate = true;+ }+}++const Affine3f& Camera::viewMatrix(void) const+{+ updateViewMatrix();+ return mViewMatrix;+}++void Camera::updateProjectionMatrix(void) const+{+ if(!mProjIsUptodate)+ {+ mProjectionMatrix.setIdentity();+ float aspect = float(mVpWidth)/float(mVpHeight);+ float theta = mFovY*0.5;+ float range = mFarDist - mNearDist;+ float invtan = 1./tan(theta);++ mProjectionMatrix(0,0) = invtan / aspect;+ mProjectionMatrix(1,1) = invtan;+ mProjectionMatrix(2,2) = -(mNearDist + mFarDist) / range;+ mProjectionMatrix(3,2) = -1;+ mProjectionMatrix(2,3) = -2 * mNearDist * mFarDist / range;+ mProjectionMatrix(3,3) = 0;+ + mProjIsUptodate = true;+ }+}++const Matrix4f& Camera::projectionMatrix(void) const+{+ updateProjectionMatrix();+ return mProjectionMatrix;+}++void Camera::activateGL(void)+{+ glViewport(vpX(), vpY(), vpWidth(), vpHeight());+ gpu.loadMatrix(projectionMatrix(),GL_PROJECTION);+ gpu.loadMatrix(viewMatrix().matrix(),GL_MODELVIEW);+}+++Vector3f Camera::unProject(const Vector2f& uv, float depth) const+{+ Matrix4f inv = mViewMatrix.inverse().matrix();+ return unProject(uv, depth, inv);+}++Vector3f Camera::unProject(const Vector2f& uv, float depth, const Matrix4f& invModelview) const+{+ updateViewMatrix();+ updateProjectionMatrix();+ + Vector3f a(2.*uv.x()/float(mVpWidth)-1., 2.*uv.y()/float(mVpHeight)-1., 1.);+ a.x() *= depth/mProjectionMatrix(0,0);+ a.y() *= depth/mProjectionMatrix(1,1);+ a.z() = -depth;+ // FIXME /\/|+ Vector4f b = invModelview * Vector4f(a.x(), a.y(), a.z(), 1.);+ return Vector3f(b.x(), b.y(), b.z());+}
+ eigen3/demos/opengl/camera.h view
@@ -0,0 +1,118 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_CAMERA_H+#define EIGEN_CAMERA_H++#include <Eigen/Geometry>+#include <QObject>+// #include <frame.h>++class Frame+{+ public:+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW+ + inline Frame(const Eigen::Vector3f& pos = Eigen::Vector3f::Zero(),+ const Eigen::Quaternionf& o = Eigen::Quaternionf())+ : orientation(o), position(pos)+ {}+ Frame lerp(float alpha, const Frame& other) const+ {+ return Frame((1.f-alpha)*position + alpha * other.position,+ orientation.slerp(alpha,other.orientation));+ }++ Eigen::Quaternionf orientation;+ Eigen::Vector3f position;+};++class Camera+{+ public:+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW++ Camera(void);+ + Camera(const Camera& other);+ + virtual ~Camera();+ + Camera& operator=(const Camera& other);+ + void setViewport(uint offsetx, uint offsety, uint width, uint height);+ void setViewport(uint width, uint height);+ + inline uint vpX(void) const { return mVpX; }+ inline uint vpY(void) const { return mVpY; }+ inline uint vpWidth(void) const { return mVpWidth; }+ inline uint vpHeight(void) const { return mVpHeight; }++ inline float fovY(void) const { return mFovY; }+ void setFovY(float value);+ + void setPosition(const Eigen::Vector3f& pos);+ inline const Eigen::Vector3f& position(void) const { return mFrame.position; }++ void setOrientation(const Eigen::Quaternionf& q);+ inline const Eigen::Quaternionf& orientation(void) const { return mFrame.orientation; }++ void setFrame(const Frame& f);+ const Frame& frame(void) const { return mFrame; }+ + void setDirection(const Eigen::Vector3f& newDirection);+ Eigen::Vector3f direction(void) const;+ void setUp(const Eigen::Vector3f& vectorUp);+ Eigen::Vector3f up(void) const;+ Eigen::Vector3f right(void) const;+ + void setTarget(const Eigen::Vector3f& target);+ inline const Eigen::Vector3f& target(void) { return mTarget; }+ + const Eigen::Affine3f& viewMatrix(void) const;+ const Eigen::Matrix4f& projectionMatrix(void) const;+ + void rotateAroundTarget(const Eigen::Quaternionf& q);+ void localRotate(const Eigen::Quaternionf& q);+ void zoom(float d);+ + void localTranslate(const Eigen::Vector3f& t);+ + /** Setup OpenGL matrices and viewport */+ void activateGL(void);+ + Eigen::Vector3f unProject(const Eigen::Vector2f& uv, float depth, const Eigen::Matrix4f& invModelview) const;+ Eigen::Vector3f unProject(const Eigen::Vector2f& uv, float depth) const;+ + protected:+ void updateViewMatrix(void) const;+ void updateProjectionMatrix(void) const;++ protected:++ uint mVpX, mVpY;+ uint mVpWidth, mVpHeight;++ Frame mFrame;+ + mutable Eigen::Affine3f mViewMatrix;+ mutable Eigen::Matrix4f mProjectionMatrix;++ mutable bool mViewIsUptodate;+ mutable bool mProjIsUptodate;++ // used by rotateAroundTarget+ Eigen::Vector3f mTarget;+ + float mFovY;+ float mNearDist;+ float mFarDist;+};++#endif // EIGEN_CAMERA_H
+ eigen3/demos/opengl/gpuhelper.cpp view
@@ -0,0 +1,126 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "gpuhelper.h"+#include "icosphere.h"+#include <GL/glu.h>+// PLEASE don't look at this old code... ;)++#include <fstream>+#include <algorithm>++GpuHelper gpu;++GpuHelper::GpuHelper()+{+ mVpWidth = mVpHeight = 0;+ mCurrentMatrixTarget = 0;+ mInitialized = false;+}++GpuHelper::~GpuHelper()+{+}++void GpuHelper::pushProjectionMode2D(ProjectionMode2D pm)+{+ // switch to 2D projection+ pushMatrix(Matrix4f::Identity(),GL_PROJECTION);++ if(pm==PM_Normalized)+ {+ //glOrtho(-1., 1., -1., 1., 0., 1.);+ }+ else if(pm==PM_Viewport)+ {+ GLint vp[4];+ glGetIntegerv(GL_VIEWPORT, vp);+ glOrtho(0., vp[2], 0., vp[3], -1., 1.);+ }++ pushMatrix(Matrix4f::Identity(),GL_MODELVIEW);+}++void GpuHelper::popProjectionMode2D(void)+{+ popMatrix(GL_PROJECTION);+ popMatrix(GL_MODELVIEW);+}++void GpuHelper::drawVector(const Vector3f& position, const Vector3f& vec, const Color& color, float aspect /* = 50.*/)+{+ static GLUquadricObj *cylindre = gluNewQuadric();+ glColor4fv(color.data());+ float length = vec.norm();+ pushMatrix(GL_MODELVIEW);+ glTranslatef(position.x(), position.y(), position.z());+ Vector3f ax = Matrix3f::Identity().col(2).cross(vec);+ ax.normalize();+ Vector3f tmp = vec;+ tmp.normalize();+ float angle = 180.f/M_PI * acos(tmp.z());+ if (angle>1e-3)+ glRotatef(angle, ax.x(), ax.y(), ax.z());+ gluCylinder(cylindre, length/aspect, length/aspect, 0.8*length, 10, 10);+ glTranslatef(0.0,0.0,0.8*length);+ gluCylinder(cylindre, 2.0*length/aspect, 0.0, 0.2*length, 10, 10);++ popMatrix(GL_MODELVIEW);+}++void GpuHelper::drawVectorBox(const Vector3f& position, const Vector3f& vec, const Color& color, float aspect)+{+ static GLUquadricObj *cylindre = gluNewQuadric();+ glColor4fv(color.data());+ float length = vec.norm();+ pushMatrix(GL_MODELVIEW);+ glTranslatef(position.x(), position.y(), position.z());+ Vector3f ax = Matrix3f::Identity().col(2).cross(vec);+ ax.normalize();+ Vector3f tmp = vec;+ tmp.normalize();+ float angle = 180.f/M_PI * acos(tmp.z());+ if (angle>1e-3)+ glRotatef(angle, ax.x(), ax.y(), ax.z());+ gluCylinder(cylindre, length/aspect, length/aspect, 0.8*length, 10, 10);+ glTranslatef(0.0,0.0,0.8*length);+ glScalef(4.0*length/aspect,4.0*length/aspect,4.0*length/aspect);+ drawUnitCube();+ popMatrix(GL_MODELVIEW);+}++void GpuHelper::drawUnitCube(void)+{+ static float vertices[][3] = {+ {-0.5,-0.5,-0.5},+ { 0.5,-0.5,-0.5},+ {-0.5, 0.5,-0.5},+ { 0.5, 0.5,-0.5},+ {-0.5,-0.5, 0.5},+ { 0.5,-0.5, 0.5},+ {-0.5, 0.5, 0.5},+ { 0.5, 0.5, 0.5}};++ glBegin(GL_QUADS);+ glNormal3f(0,0,-1); glVertex3fv(vertices[0]); glVertex3fv(vertices[2]); glVertex3fv(vertices[3]); glVertex3fv(vertices[1]);+ glNormal3f(0,0, 1); glVertex3fv(vertices[4]); glVertex3fv(vertices[5]); glVertex3fv(vertices[7]); glVertex3fv(vertices[6]);+ glNormal3f(0,-1,0); glVertex3fv(vertices[0]); glVertex3fv(vertices[1]); glVertex3fv(vertices[5]); glVertex3fv(vertices[4]);+ glNormal3f(0, 1,0); glVertex3fv(vertices[2]); glVertex3fv(vertices[6]); glVertex3fv(vertices[7]); glVertex3fv(vertices[3]);+ glNormal3f(-1,0,0); glVertex3fv(vertices[0]); glVertex3fv(vertices[4]); glVertex3fv(vertices[6]); glVertex3fv(vertices[2]);+ glNormal3f( 1,0,0); glVertex3fv(vertices[1]); glVertex3fv(vertices[3]); glVertex3fv(vertices[7]); glVertex3fv(vertices[5]);+ glEnd();+}++void GpuHelper::drawUnitSphere(int level)+{+ static IcoSphere sphere;+ sphere.draw(level);+}++
+ eigen3/demos/opengl/gpuhelper.h view
@@ -0,0 +1,207 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_GPUHELPER_H+#define EIGEN_GPUHELPER_H++#include <Eigen/Geometry>+#include <GL/gl.h>+#include <vector>++using namespace Eigen;++typedef Vector4f Color;++class GpuHelper+{+ public:++ GpuHelper();++ ~GpuHelper();++ enum ProjectionMode2D { PM_Normalized = 1, PM_Viewport = 2 };+ void pushProjectionMode2D(ProjectionMode2D pm);+ void popProjectionMode2D();++ /** Multiply the OpenGL matrix \a matrixTarget by the matrix \a mat.+ Essentially, this helper function automatically calls glMatrixMode(matrixTarget) if required+ and does a proper call to the right glMultMatrix*() function according to the scalar type+ and storage order.+ \warning glMatrixMode() must never be called directly. If your're unsure, use forceMatrixMode().+ \sa Matrix, loadMatrix(), forceMatrixMode()+ */+ template<typename Scalar, int _Flags>+ void multMatrix(const Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget);++ /** Load the matrix \a mat to the OpenGL matrix \a matrixTarget.+ Essentially, this helper function automatically calls glMatrixMode(matrixTarget) if required+ and does a proper call to the right glLoadMatrix*() or glLoadIdentity() function according to the scalar type+ and storage order.+ \warning glMatrixMode() must never be called directly. If your're unsure, use forceMatrixMode().+ \sa Matrix, multMatrix(), forceMatrixMode()+ */+ template<typename Scalar, int _Flags>+ void loadMatrix(const Eigen::Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget);++ template<typename Scalar, typename Derived>+ void loadMatrix(+ const Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<Scalar>,Derived>&,+ GLenum matrixTarget);++ /** Make the matrix \a matrixTarget the current OpenGL matrix target.+ Call this function before loadMatrix() or multMatrix() if you cannot guarantee that glMatrixMode()+ has never been called after the last loadMatrix() or multMatrix() calls.+ \todo provides a debug mode checking the sanity of the cached matrix mode.+ */+ inline void forceMatrixTarget(GLenum matrixTarget) {glMatrixMode(mCurrentMatrixTarget=matrixTarget);}++ inline void setMatrixTarget(GLenum matrixTarget);++ /** Push the OpenGL matrix \a matrixTarget and load \a mat.+ */+ template<typename Scalar, int _Flags>+ inline void pushMatrix(const Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget);++ template<typename Scalar, typename Derived>+ void pushMatrix(+ const Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<Scalar>,Derived>&,+ GLenum matrixTarget);++ /** Push and clone the OpenGL matrix \a matrixTarget+ */+ inline void pushMatrix(GLenum matrixTarget);++ /** Pop the OpenGL matrix \a matrixTarget+ */+ inline void popMatrix(GLenum matrixTarget);++ void drawVector(const Vector3f& position, const Vector3f& vec, const Color& color, float aspect = 50.);+ void drawVectorBox(const Vector3f& position, const Vector3f& vec, const Color& color, float aspect = 50.);+ void drawUnitCube(void);+ void drawUnitSphere(int level=0);++ /// draw the \a nofElement first elements+ inline void draw(GLenum mode, uint nofElement);++ /// draw a range of elements+ inline void draw(GLenum mode, uint start, uint end);++ /// draw an indexed subset+ inline void draw(GLenum mode, const std::vector<uint>* pIndexes);++protected:++ void update(void);++ GLuint mColorBufferId;+ int mVpWidth, mVpHeight;+ GLenum mCurrentMatrixTarget;+ bool mInitialized;+};++/** Singleton shortcut+*/+extern GpuHelper gpu;+++/** \internal+*/+template<bool RowMajor, int _Flags> struct GlMatrixHelper;++template<int _Flags> struct GlMatrixHelper<false,_Flags>+{+ static void loadMatrix(const Matrix<float, 4,4, _Flags, 4,4>& mat) { glLoadMatrixf(mat.data()); }+ static void loadMatrix(const Matrix<double,4,4, _Flags, 4,4>& mat) { glLoadMatrixd(mat.data()); }+ static void multMatrix(const Matrix<float, 4,4, _Flags, 4,4>& mat) { glMultMatrixf(mat.data()); }+ static void multMatrix(const Matrix<double,4,4, _Flags, 4,4>& mat) { glMultMatrixd(mat.data()); }+};++template<int _Flags> struct GlMatrixHelper<true,_Flags>+{+ static void loadMatrix(const Matrix<float, 4,4, _Flags, 4,4>& mat) { glLoadMatrixf(mat.transpose().eval().data()); }+ static void loadMatrix(const Matrix<double,4,4, _Flags, 4,4>& mat) { glLoadMatrixd(mat.transpose().eval().data()); }+ static void multMatrix(const Matrix<float, 4,4, _Flags, 4,4>& mat) { glMultMatrixf(mat.transpose().eval().data()); }+ static void multMatrix(const Matrix<double,4,4, _Flags, 4,4>& mat) { glMultMatrixd(mat.transpose().eval().data()); }+};++inline void GpuHelper::setMatrixTarget(GLenum matrixTarget)+{+ if (matrixTarget != mCurrentMatrixTarget)+ glMatrixMode(mCurrentMatrixTarget=matrixTarget);+}++template<typename Scalar, int _Flags>+void GpuHelper::multMatrix(const Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget)+{+ setMatrixTarget(matrixTarget);+ GlMatrixHelper<_Flags&Eigen::RowMajorBit, _Flags>::multMatrix(mat);+}++template<typename Scalar, typename Derived>+void GpuHelper::loadMatrix(+ const Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<Scalar>,Derived>&,+ GLenum matrixTarget)+{+ setMatrixTarget(matrixTarget);+ glLoadIdentity();+}++template<typename Scalar, int _Flags>+void GpuHelper::loadMatrix(const Eigen::Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget)+{+ setMatrixTarget(matrixTarget);+ GlMatrixHelper<(_Flags&Eigen::RowMajorBit)!=0, _Flags>::loadMatrix(mat);+}++inline void GpuHelper::pushMatrix(GLenum matrixTarget)+{+ setMatrixTarget(matrixTarget);+ glPushMatrix();+}++template<typename Scalar, int _Flags>+inline void GpuHelper::pushMatrix(const Matrix<Scalar,4,4, _Flags, 4,4>& mat, GLenum matrixTarget)+{+ pushMatrix(matrixTarget);+ GlMatrixHelper<_Flags&Eigen::RowMajorBit,_Flags>::loadMatrix(mat);+}++template<typename Scalar, typename Derived>+void GpuHelper::pushMatrix(+ const Eigen::CwiseNullaryOp<Eigen::internal::scalar_identity_op<Scalar>,Derived>&,+ GLenum matrixTarget)+{+ pushMatrix(matrixTarget);+ glLoadIdentity();+}++inline void GpuHelper::popMatrix(GLenum matrixTarget)+{+ setMatrixTarget(matrixTarget);+ glPopMatrix();+}++inline void GpuHelper::draw(GLenum mode, uint nofElement)+{+ glDrawArrays(mode, 0, nofElement);+}+++inline void GpuHelper::draw(GLenum mode, const std::vector<uint>* pIndexes)+{+ glDrawElements(mode, pIndexes->size(), GL_UNSIGNED_INT, &(pIndexes->front()));+}++inline void GpuHelper::draw(GLenum mode, uint start, uint end)+{+ glDrawArrays(mode, start, end-start);+}++#endif // EIGEN_GPUHELPER_H
+ eigen3/demos/opengl/icosphere.cpp view
@@ -0,0 +1,120 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "icosphere.h"++#include <GL/gl.h>+#include <map>++using namespace Eigen;++//--------------------------------------------------------------------------------+// icosahedron data+//--------------------------------------------------------------------------------+#define X .525731112119133606+#define Z .850650808352039932++static GLfloat vdata[12][3] = {+ {-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z},+ {0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X},+ {Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0}+};++static GLint tindices[20][3] = {+ {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},+ {8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},+ {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},+ {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} };+//--------------------------------------------------------------------------------++IcoSphere::IcoSphere(unsigned int levels)+{+ // init with an icosahedron+ for (int i = 0; i < 12; i++)+ mVertices.push_back(Map<Vector3f>(vdata[i]));+ mIndices.push_back(new std::vector<int>);+ std::vector<int>& indices = *mIndices.back();+ for (int i = 0; i < 20; i++)+ {+ for (int k = 0; k < 3; k++)+ indices.push_back(tindices[i][k]);+ }+ mListIds.push_back(0);++ while(mIndices.size()<levels)+ _subdivide();+}++const std::vector<int>& IcoSphere::indices(int level) const+{+ while (level>=int(mIndices.size()))+ const_cast<IcoSphere*>(this)->_subdivide();+ return *mIndices[level];+}++void IcoSphere::_subdivide(void)+{+ typedef unsigned long long Key;+ std::map<Key,int> edgeMap;+ const std::vector<int>& indices = *mIndices.back();+ mIndices.push_back(new std::vector<int>);+ std::vector<int>& refinedIndices = *mIndices.back();+ int end = indices.size();+ for (int i=0; i<end; i+=3)+ {+ int ids0[3], // indices of outer vertices+ ids1[3]; // indices of edge vertices+ for (int k=0; k<3; ++k)+ {+ int k1 = (k+1)%3;+ int e0 = indices[i+k];+ int e1 = indices[i+k1];+ ids0[k] = e0;+ if (e1>e0)+ std::swap(e0,e1);+ Key edgeKey = Key(e0) | (Key(e1)<<32);+ std::map<Key,int>::iterator it = edgeMap.find(edgeKey);+ if (it==edgeMap.end())+ {+ ids1[k] = mVertices.size();+ edgeMap[edgeKey] = ids1[k];+ mVertices.push_back( (mVertices[e0]+mVertices[e1]).normalized() );+ }+ else+ ids1[k] = it->second;+ }+ refinedIndices.push_back(ids0[0]); refinedIndices.push_back(ids1[0]); refinedIndices.push_back(ids1[2]);+ refinedIndices.push_back(ids0[1]); refinedIndices.push_back(ids1[1]); refinedIndices.push_back(ids1[0]);+ refinedIndices.push_back(ids0[2]); refinedIndices.push_back(ids1[2]); refinedIndices.push_back(ids1[1]);+ refinedIndices.push_back(ids1[0]); refinedIndices.push_back(ids1[1]); refinedIndices.push_back(ids1[2]);+ }+ mListIds.push_back(0);+}++void IcoSphere::draw(int level)+{+ while (level>=int(mIndices.size()))+ const_cast<IcoSphere*>(this)->_subdivide();+ if (mListIds[level]==0)+ {+ mListIds[level] = glGenLists(1);+ glNewList(mListIds[level], GL_COMPILE);+ glVertexPointer(3, GL_FLOAT, 0, mVertices[0].data());+ glNormalPointer(GL_FLOAT, 0, mVertices[0].data());+ glEnableClientState(GL_VERTEX_ARRAY);+ glEnableClientState(GL_NORMAL_ARRAY);+ glDrawElements(GL_TRIANGLES, mIndices[level]->size(), GL_UNSIGNED_INT, &(mIndices[level]->at(0)));+ glDisableClientState(GL_VERTEX_ARRAY);+ glDisableClientState(GL_NORMAL_ARRAY);+ glEndList();+ }+ glCallList(mListIds[level]);+}++
+ eigen3/demos/opengl/icosphere.h view
@@ -0,0 +1,30 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_ICOSPHERE_H+#define EIGEN_ICOSPHERE_H++#include <Eigen/Core>+#include <vector>++class IcoSphere+{+ public:+ IcoSphere(unsigned int levels=1);+ const std::vector<Eigen::Vector3f>& vertices() const { return mVertices; }+ const std::vector<int>& indices(int level) const;+ void draw(int level);+ protected:+ void _subdivide();+ std::vector<Eigen::Vector3f> mVertices;+ std::vector<std::vector<int>*> mIndices;+ std::vector<int> mListIds;+};++#endif // EIGEN_ICOSPHERE_H
+ eigen3/demos/opengl/quaternion_demo.cpp view
@@ -0,0 +1,656 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "quaternion_demo.h"+#include "icosphere.h"++#include <Eigen/Geometry>+#include <Eigen/QR>+#include <Eigen/LU>++#include <iostream>+#include <QEvent>+#include <QMouseEvent>+#include <QInputDialog>+#include <QGridLayout>+#include <QButtonGroup>+#include <QRadioButton>+#include <QDockWidget>+#include <QPushButton>+#include <QGroupBox>++using namespace Eigen;++class FancySpheres+{+ public:+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW+ + FancySpheres()+ {+ const int levels = 4;+ const float scale = 0.33;+ float radius = 100;+ std::vector<int> parents;++ // leval 0+ mCenters.push_back(Vector3f::Zero());+ parents.push_back(-1);+ mRadii.push_back(radius);++ // generate level 1 using icosphere vertices+ radius *= 0.45;+ {+ float dist = mRadii[0]*0.9;+ for (int i=0; i<12; ++i)+ {+ mCenters.push_back(mIcoSphere.vertices()[i] * dist);+ mRadii.push_back(radius);+ parents.push_back(0);+ }+ }++ static const float angles [10] = {+ 0, 0,+ M_PI, 0.*M_PI,+ M_PI, 0.5*M_PI,+ M_PI, 1.*M_PI,+ M_PI, 1.5*M_PI+ };++ // generate other levels+ int start = 1;+ for (int l=1; l<levels; l++)+ {+ radius *= scale;+ int end = mCenters.size();+ for (int i=start; i<end; ++i)+ {+ Vector3f c = mCenters[i];+ Vector3f ax0 = (c - mCenters[parents[i]]).normalized();+ Vector3f ax1 = ax0.unitOrthogonal();+ Quaternionf q;+ q.setFromTwoVectors(Vector3f::UnitZ(), ax0);+ Affine3f t = Translation3f(c) * q * Scaling(mRadii[i]+radius);+ for (int j=0; j<5; ++j)+ {+ Vector3f newC = c + ( (AngleAxisf(angles[j*2+1], ax0)+ * AngleAxisf(angles[j*2+0] * (l==1 ? 0.35 : 0.5), ax1)) * ax0)+ * (mRadii[i] + radius*0.8);+ mCenters.push_back(newC);+ mRadii.push_back(radius);+ parents.push_back(i);+ }+ }+ start = end;+ }+ }++ void draw()+ {+ int end = mCenters.size();+ glEnable(GL_NORMALIZE);+ for (int i=0; i<end; ++i)+ {+ Affine3f t = Translation3f(mCenters[i]) * Scaling(mRadii[i]);+ gpu.pushMatrix(GL_MODELVIEW);+ gpu.multMatrix(t.matrix(),GL_MODELVIEW);+ mIcoSphere.draw(2);+ gpu.popMatrix(GL_MODELVIEW);+ }+ glDisable(GL_NORMALIZE);+ }+ protected:+ std::vector<Vector3f> mCenters;+ std::vector<float> mRadii;+ IcoSphere mIcoSphere;+};+++// generic linear interpolation method+template<typename T> T lerp(float t, const T& a, const T& b)+{+ return a*(1-t) + b*t;+}++// quaternion slerp+template<> Quaternionf lerp(float t, const Quaternionf& a, const Quaternionf& b)+{ return a.slerp(t,b); }++// linear interpolation of a frame using the type OrientationType+// to perform the interpolation of the orientations+template<typename OrientationType>+inline static Frame lerpFrame(float alpha, const Frame& a, const Frame& b)+{+ return Frame(lerp(alpha,a.position,b.position),+ Quaternionf(lerp(alpha,OrientationType(a.orientation),OrientationType(b.orientation))));+}++template<typename _Scalar> class EulerAngles+{+public:+ enum { Dim = 3 };+ typedef _Scalar Scalar;+ typedef Matrix<Scalar,3,3> Matrix3;+ typedef Matrix<Scalar,3,1> Vector3;+ typedef Quaternion<Scalar> QuaternionType;++protected:++ Vector3 m_angles;++public:++ EulerAngles() {}+ inline EulerAngles(Scalar a0, Scalar a1, Scalar a2) : m_angles(a0, a1, a2) {}+ inline EulerAngles(const QuaternionType& q) { *this = q; }++ const Vector3& coeffs() const { return m_angles; }+ Vector3& coeffs() { return m_angles; }++ EulerAngles& operator=(const QuaternionType& q)+ {+ Matrix3 m = q.toRotationMatrix();+ return *this = m;+ }++ EulerAngles& operator=(const Matrix3& m)+ {+ // mat = cy*cz -cy*sz sy+ // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx+ // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy+ m_angles.coeffRef(1) = std::asin(m.coeff(0,2));+ m_angles.coeffRef(0) = std::atan2(-m.coeff(1,2),m.coeff(2,2));+ m_angles.coeffRef(2) = std::atan2(-m.coeff(0,1),m.coeff(0,0));+ return *this;+ }++ Matrix3 toRotationMatrix(void) const+ {+ Vector3 c = m_angles.array().cos();+ Vector3 s = m_angles.array().sin();+ Matrix3 res;+ res << c.y()*c.z(), -c.y()*s.z(), s.y(),+ c.z()*s.x()*s.y()+c.x()*s.z(), c.x()*c.z()-s.x()*s.y()*s.z(), -c.y()*s.x(),+ -c.x()*c.z()*s.y()+s.x()*s.z(), c.z()*s.x()+c.x()*s.y()*s.z(), c.x()*c.y();+ return res;+ }++ operator QuaternionType() { return QuaternionType(toRotationMatrix()); }+};++// Euler angles slerp+template<> EulerAngles<float> lerp(float t, const EulerAngles<float>& a, const EulerAngles<float>& b)+{+ EulerAngles<float> res;+ res.coeffs() = lerp(t, a.coeffs(), b.coeffs());+ return res;+}+++RenderingWidget::RenderingWidget()+{+ mAnimate = false;+ mCurrentTrackingMode = TM_NO_TRACK;+ mNavMode = NavTurnAround;+ mLerpMode = LerpQuaternion;+ mRotationMode = RotationStable;+ mTrackball.setCamera(&mCamera);++ // required to capture key press events+ setFocusPolicy(Qt::ClickFocus);+}++void RenderingWidget::grabFrame(void)+{+ // ask user for a time+ bool ok = false;+ double t = 0;+ if (!m_timeline.empty())+ t = (--m_timeline.end())->first + 1.;+ t = QInputDialog::getDouble(this, "Eigen's RenderingWidget", "time value: ",+ t, 0, 1e3, 1, &ok);+ if (ok)+ {+ Frame aux;+ aux.orientation = mCamera.viewMatrix().linear();+ aux.position = mCamera.viewMatrix().translation();+ m_timeline[t] = aux;+ }+}++void RenderingWidget::drawScene()+{+ static FancySpheres sFancySpheres;+ float length = 50;+ gpu.drawVector(Vector3f::Zero(), length*Vector3f::UnitX(), Color(1,0,0,1));+ gpu.drawVector(Vector3f::Zero(), length*Vector3f::UnitY(), Color(0,1,0,1));+ gpu.drawVector(Vector3f::Zero(), length*Vector3f::UnitZ(), Color(0,0,1,1));++ // draw the fractal object+ float sqrt3 = internal::sqrt(3.);+ glLightfv(GL_LIGHT0, GL_AMBIENT, Vector4f(0.5,0.5,0.5,1).data());+ glLightfv(GL_LIGHT0, GL_DIFFUSE, Vector4f(0.5,1,0.5,1).data());+ glLightfv(GL_LIGHT0, GL_SPECULAR, Vector4f(1,1,1,1).data());+ glLightfv(GL_LIGHT0, GL_POSITION, Vector4f(-sqrt3,-sqrt3,sqrt3,0).data());++ glLightfv(GL_LIGHT1, GL_AMBIENT, Vector4f(0,0,0,1).data());+ glLightfv(GL_LIGHT1, GL_DIFFUSE, Vector4f(1,0.5,0.5,1).data());+ glLightfv(GL_LIGHT1, GL_SPECULAR, Vector4f(1,1,1,1).data());+ glLightfv(GL_LIGHT1, GL_POSITION, Vector4f(-sqrt3,sqrt3,-sqrt3,0).data());++ glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, Vector4f(0.7, 0.7, 0.7, 1).data());+ glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, Vector4f(0.8, 0.75, 0.6, 1).data());+ glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, Vector4f(1, 1, 1, 1).data());+ glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 64);++ glEnable(GL_LIGHTING);+ glEnable(GL_LIGHT0);+ glEnable(GL_LIGHT1);++ sFancySpheres.draw();+ glVertexPointer(3, GL_FLOAT, 0, mVertices[0].data());+ glNormalPointer(GL_FLOAT, 0, mNormals[0].data());+ glEnableClientState(GL_VERTEX_ARRAY);+ glEnableClientState(GL_NORMAL_ARRAY);+ glDrawArrays(GL_TRIANGLES, 0, mVertices.size());+ glDisableClientState(GL_VERTEX_ARRAY);+ glDisableClientState(GL_NORMAL_ARRAY);++ glDisable(GL_LIGHTING);+}++void RenderingWidget::animate()+{+ m_alpha += double(m_timer.interval()) * 1e-3;++ TimeLine::const_iterator hi = m_timeline.upper_bound(m_alpha);+ TimeLine::const_iterator lo = hi;+ --lo;++ Frame currentFrame;++ if(hi==m_timeline.end())+ {+ // end+ currentFrame = lo->second;+ stopAnimation();+ }+ else if(hi==m_timeline.begin())+ {+ // start+ currentFrame = hi->second;+ }+ else+ {+ float s = (m_alpha - lo->first)/(hi->first - lo->first);+ if (mLerpMode==LerpEulerAngles)+ currentFrame = ::lerpFrame<EulerAngles<float> >(s, lo->second, hi->second);+ else if (mLerpMode==LerpQuaternion)+ currentFrame = ::lerpFrame<Eigen::Quaternionf>(s, lo->second, hi->second);+ else+ {+ std::cerr << "Invalid rotation interpolation mode (abort)\n";+ exit(2);+ }+ currentFrame.orientation.coeffs().normalize();+ }++ currentFrame.orientation = currentFrame.orientation.inverse();+ currentFrame.position = - (currentFrame.orientation * currentFrame.position);+ mCamera.setFrame(currentFrame);++ updateGL();+}++void RenderingWidget::keyPressEvent(QKeyEvent * e)+{+ switch(e->key())+ {+ case Qt::Key_Up:+ mCamera.zoom(2);+ break;+ case Qt::Key_Down:+ mCamera.zoom(-2);+ break;+ // add a frame+ case Qt::Key_G:+ grabFrame();+ break;+ // clear the time line+ case Qt::Key_C:+ m_timeline.clear();+ break;+ // move the camera to initial pos+ case Qt::Key_R:+ resetCamera();+ break;+ // start/stop the animation+ case Qt::Key_A:+ if (mAnimate)+ {+ stopAnimation();+ }+ else+ {+ m_alpha = 0;+ connect(&m_timer, SIGNAL(timeout()), this, SLOT(animate()));+ m_timer.start(1000/30);+ mAnimate = true;+ }+ break;+ default:+ break;+ }++ updateGL();+}++void RenderingWidget::stopAnimation()+{+ disconnect(&m_timer, SIGNAL(timeout()), this, SLOT(animate()));+ m_timer.stop();+ mAnimate = false;+ m_alpha = 0;+}++void RenderingWidget::mousePressEvent(QMouseEvent* e)+{+ mMouseCoords = Vector2i(e->pos().x(), e->pos().y());+ bool fly = (mNavMode==NavFly) || (e->modifiers()&Qt::ControlModifier);+ switch(e->button())+ {+ case Qt::LeftButton:+ if(fly)+ {+ mCurrentTrackingMode = TM_LOCAL_ROTATE;+ mTrackball.start(Trackball::Local);+ }+ else+ {+ mCurrentTrackingMode = TM_ROTATE_AROUND;+ mTrackball.start(Trackball::Around);+ }+ mTrackball.track(mMouseCoords);+ break;+ case Qt::MidButton:+ if(fly)+ mCurrentTrackingMode = TM_FLY_Z;+ else+ mCurrentTrackingMode = TM_ZOOM;+ break;+ case Qt::RightButton:+ mCurrentTrackingMode = TM_FLY_PAN;+ break;+ default:+ break;+ }+}+void RenderingWidget::mouseReleaseEvent(QMouseEvent*)+{+ mCurrentTrackingMode = TM_NO_TRACK;+ updateGL();+}++void RenderingWidget::mouseMoveEvent(QMouseEvent* e)+{+ // tracking+ if(mCurrentTrackingMode != TM_NO_TRACK)+ {+ float dx = float(e->x() - mMouseCoords.x()) / float(mCamera.vpWidth());+ float dy = - float(e->y() - mMouseCoords.y()) / float(mCamera.vpHeight());++ // speedup the transformations+ if(e->modifiers() & Qt::ShiftModifier)+ {+ dx *= 10.;+ dy *= 10.;+ }++ switch(mCurrentTrackingMode)+ {+ case TM_ROTATE_AROUND:+ case TM_LOCAL_ROTATE:+ if (mRotationMode==RotationStable)+ {+ // use the stable trackball implementation mapping+ // the 2D coordinates to 3D points on a sphere.+ mTrackball.track(Vector2i(e->pos().x(), e->pos().y()));+ }+ else+ {+ // standard approach mapping the x and y displacements as rotations+ // around the camera's X and Y axes.+ Quaternionf q = AngleAxisf( dx*M_PI, Vector3f::UnitY())+ * AngleAxisf(-dy*M_PI, Vector3f::UnitX());+ if (mCurrentTrackingMode==TM_LOCAL_ROTATE)+ mCamera.localRotate(q);+ else+ mCamera.rotateAroundTarget(q);+ }+ break;+ case TM_ZOOM :+ mCamera.zoom(dy*100);+ break;+ case TM_FLY_Z :+ mCamera.localTranslate(Vector3f(0, 0, -dy*200));+ break;+ case TM_FLY_PAN :+ mCamera.localTranslate(Vector3f(dx*200, dy*200, 0));+ break;+ default:+ break;+ }++ updateGL();+ }++ mMouseCoords = Vector2i(e->pos().x(), e->pos().y());+}++void RenderingWidget::paintGL()+{+ glEnable(GL_DEPTH_TEST);+ glDisable(GL_CULL_FACE);+ glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);+ glDisable(GL_COLOR_MATERIAL);+ glDisable(GL_BLEND);+ glDisable(GL_ALPHA_TEST);+ glDisable(GL_TEXTURE_1D);+ glDisable(GL_TEXTURE_2D);+ glDisable(GL_TEXTURE_3D);++ // Clear buffers+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);++ mCamera.activateGL();++ drawScene();+}++void RenderingWidget::initializeGL()+{+ glClearColor(1., 1., 1., 0.);+ glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, 1);+ glDepthMask(GL_TRUE);+ glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);++ mCamera.setPosition(Vector3f(-200, -200, -200));+ mCamera.setTarget(Vector3f(0, 0, 0));+ mInitFrame.orientation = mCamera.orientation().inverse();+ mInitFrame.position = mCamera.viewMatrix().translation();+}++void RenderingWidget::resizeGL(int width, int height)+{+ mCamera.setViewport(width,height);+}++void RenderingWidget::setNavMode(int m)+{+ mNavMode = NavMode(m);+}++void RenderingWidget::setLerpMode(int m)+{+ mLerpMode = LerpMode(m);+}++void RenderingWidget::setRotationMode(int m)+{+ mRotationMode = RotationMode(m);+}++void RenderingWidget::resetCamera()+{+ if (mAnimate)+ stopAnimation();+ m_timeline.clear();+ Frame aux0 = mCamera.frame();+ aux0.orientation = aux0.orientation.inverse();+ aux0.position = mCamera.viewMatrix().translation();+ m_timeline[0] = aux0;++ Vector3f currentTarget = mCamera.target();+ mCamera.setTarget(Vector3f::Zero());++ // compute the rotation duration to move the camera to the target+ Frame aux1 = mCamera.frame();+ aux1.orientation = aux1.orientation.inverse();+ aux1.position = mCamera.viewMatrix().translation();+ float duration = aux0.orientation.angularDistance(aux1.orientation) * 0.9;+ if (duration<0.1) duration = 0.1;++ // put the camera at that time step:+ aux1 = aux0.lerp(duration/2,mInitFrame);+ // and make it look at the target again+ aux1.orientation = aux1.orientation.inverse();+ aux1.position = - (aux1.orientation * aux1.position);+ mCamera.setFrame(aux1);+ mCamera.setTarget(Vector3f::Zero());++ // add this camera keyframe+ aux1.orientation = aux1.orientation.inverse();+ aux1.position = mCamera.viewMatrix().translation();+ m_timeline[duration] = aux1;++ m_timeline[2] = mInitFrame;+ m_alpha = 0;+ animate();+ connect(&m_timer, SIGNAL(timeout()), this, SLOT(animate()));+ m_timer.start(1000/30);+ mAnimate = true;+}++QWidget* RenderingWidget::createNavigationControlWidget()+{+ QWidget* panel = new QWidget();+ QVBoxLayout* layout = new QVBoxLayout();++ {+ QPushButton* but = new QPushButton("reset");+ but->setToolTip("move the camera to initial position (with animation)");+ layout->addWidget(but);+ connect(but, SIGNAL(clicked()), this, SLOT(resetCamera()));+ }+ {+ // navigation mode+ QGroupBox* box = new QGroupBox("navigation mode");+ QVBoxLayout* boxLayout = new QVBoxLayout;+ QButtonGroup* group = new QButtonGroup(panel);+ QRadioButton* but;+ but = new QRadioButton("turn around");+ but->setToolTip("look around an object");+ group->addButton(but, NavTurnAround);+ boxLayout->addWidget(but);+ but = new QRadioButton("fly");+ but->setToolTip("free navigation like a spaceship\n(this mode can also be enabled pressing the \"shift\" key)");+ group->addButton(but, NavFly);+ boxLayout->addWidget(but);+ group->button(mNavMode)->setChecked(true);+ connect(group, SIGNAL(buttonClicked(int)), this, SLOT(setNavMode(int)));+ box->setLayout(boxLayout);+ layout->addWidget(box);+ }+ {+ // track ball, rotation mode+ QGroupBox* box = new QGroupBox("rotation mode");+ QVBoxLayout* boxLayout = new QVBoxLayout;+ QButtonGroup* group = new QButtonGroup(panel);+ QRadioButton* but;+ but = new QRadioButton("stable trackball");+ group->addButton(but, RotationStable);+ boxLayout->addWidget(but);+ but->setToolTip("use the stable trackball implementation mapping\nthe 2D coordinates to 3D points on a sphere");+ but = new QRadioButton("standard rotation");+ group->addButton(but, RotationStandard);+ boxLayout->addWidget(but);+ but->setToolTip("standard approach mapping the x and y displacements\nas rotations around the camera's X and Y axes");+ group->button(mRotationMode)->setChecked(true);+ connect(group, SIGNAL(buttonClicked(int)), this, SLOT(setRotationMode(int)));+ box->setLayout(boxLayout);+ layout->addWidget(box);+ }+ {+ // interpolation mode+ QGroupBox* box = new QGroupBox("spherical interpolation");+ QVBoxLayout* boxLayout = new QVBoxLayout;+ QButtonGroup* group = new QButtonGroup(panel);+ QRadioButton* but;+ but = new QRadioButton("quaternion slerp");+ group->addButton(but, LerpQuaternion);+ boxLayout->addWidget(but);+ but->setToolTip("use quaternion spherical interpolation\nto interpolate orientations");+ but = new QRadioButton("euler angles");+ group->addButton(but, LerpEulerAngles);+ boxLayout->addWidget(but);+ but->setToolTip("use Euler angles to interpolate orientations");+ group->button(mNavMode)->setChecked(true);+ connect(group, SIGNAL(buttonClicked(int)), this, SLOT(setLerpMode(int)));+ box->setLayout(boxLayout);+ layout->addWidget(box);+ }+ layout->addItem(new QSpacerItem(0,0,QSizePolicy::Minimum,QSizePolicy::Expanding));+ panel->setLayout(layout);+ return panel;+}++QuaternionDemo::QuaternionDemo()+{+ mRenderingWidget = new RenderingWidget();+ setCentralWidget(mRenderingWidget);++ QDockWidget* panel = new QDockWidget("navigation", this);+ panel->setAllowedAreas((QFlags<Qt::DockWidgetArea>)(Qt::RightDockWidgetArea | Qt::LeftDockWidgetArea));+ addDockWidget(Qt::RightDockWidgetArea, panel);+ panel->setWidget(mRenderingWidget->createNavigationControlWidget());+}++int main(int argc, char *argv[])+{+ std::cout << "Navigation:\n";+ std::cout << " left button: rotate around the target\n";+ std::cout << " middle button: zoom\n";+ std::cout << " left button + ctrl quake rotate (rotate around camera position)\n";+ std::cout << " middle button + ctrl walk (progress along camera's z direction)\n";+ std::cout << " left button: pan (translate in the XY camera's plane)\n\n";+ std::cout << "R : move the camera to initial position\n";+ std::cout << "A : start/stop animation\n";+ std::cout << "C : clear the animation\n";+ std::cout << "G : add a key frame\n";++ QApplication app(argc, argv);+ QuaternionDemo demo;+ demo.resize(600,500);+ demo.show();+ return app.exec();+}++#include "quaternion_demo.moc"+
+ eigen3/demos/opengl/quaternion_demo.h view
@@ -0,0 +1,114 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_QUATERNION_DEMO_H+#define EIGEN_QUATERNION_DEMO_H++#include "gpuhelper.h"+#include "camera.h"+#include "trackball.h"+#include <map>+#include <QTimer>+#include <QtGui/QApplication>+#include <QtOpenGL/QGLWidget>+#include <QtGui/QMainWindow>++class RenderingWidget : public QGLWidget+{+ Q_OBJECT++ typedef std::map<float,Frame> TimeLine;+ TimeLine m_timeline;+ Frame lerpFrame(float t);++ Frame mInitFrame;+ bool mAnimate;+ float m_alpha;++ enum TrackMode {+ TM_NO_TRACK=0, TM_ROTATE_AROUND, TM_ZOOM,+ TM_LOCAL_ROTATE, TM_FLY_Z, TM_FLY_PAN+ };++ enum NavMode {+ NavTurnAround,+ NavFly+ };++ enum LerpMode {+ LerpQuaternion,+ LerpEulerAngles+ };++ enum RotationMode {+ RotationStable,+ RotationStandard+ };++ Camera mCamera;+ TrackMode mCurrentTrackingMode;+ NavMode mNavMode;+ LerpMode mLerpMode;+ RotationMode mRotationMode;+ Vector2i mMouseCoords;+ Trackball mTrackball;++ QTimer m_timer;++ void setupCamera();++ std::vector<Vector3f> mVertices;+ std::vector<Vector3f> mNormals;+ std::vector<int> mIndices;++ protected slots:++ virtual void animate(void);+ virtual void drawScene(void);++ virtual void grabFrame(void);+ virtual void stopAnimation();++ virtual void setNavMode(int);+ virtual void setLerpMode(int);+ virtual void setRotationMode(int);+ virtual void resetCamera();++ protected:++ virtual void initializeGL();+ virtual void resizeGL(int width, int height);+ virtual void paintGL();+ + //--------------------------------------------------------------------------------+ virtual void mousePressEvent(QMouseEvent * e);+ virtual void mouseReleaseEvent(QMouseEvent * e);+ virtual void mouseMoveEvent(QMouseEvent * e);+ virtual void keyPressEvent(QKeyEvent * e);+ //--------------------------------------------------------------------------------++ public: + EIGEN_MAKE_ALIGNED_OPERATOR_NEW+ + RenderingWidget();+ ~RenderingWidget() { }++ QWidget* createNavigationControlWidget();+};++class QuaternionDemo : public QMainWindow+{+ Q_OBJECT+ public:+ QuaternionDemo();+ protected:+ RenderingWidget* mRenderingWidget;+};++#endif // EIGEN_QUATERNION_DEMO_H
+ eigen3/demos/opengl/trackball.cpp view
@@ -0,0 +1,59 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "trackball.h"+#include "camera.h"++using namespace Eigen;++void Trackball::track(const Vector2i& point2D)+{+ if (mpCamera==0)+ return;+ Vector3f newPoint3D;+ bool newPointOk = mapToSphere(point2D, newPoint3D);++ if (mLastPointOk && newPointOk)+ {+ Vector3f axis = mLastPoint3D.cross(newPoint3D).normalized();+ float cos_angle = mLastPoint3D.dot(newPoint3D);+ if ( internal::abs(cos_angle) < 1.0 )+ {+ float angle = 2. * acos(cos_angle);+ if (mMode==Around)+ mpCamera->rotateAroundTarget(Quaternionf(AngleAxisf(angle, axis)));+ else+ mpCamera->localRotate(Quaternionf(AngleAxisf(-angle, axis)));+ }+ }++ mLastPoint3D = newPoint3D;+ mLastPointOk = newPointOk;+}++bool Trackball::mapToSphere(const Vector2i& p2, Vector3f& v3)+{+ if ((p2.x() >= 0) && (p2.x() <= int(mpCamera->vpWidth())) &&+ (p2.y() >= 0) && (p2.y() <= int(mpCamera->vpHeight())) )+ {+ double x = (double)(p2.x() - 0.5*mpCamera->vpWidth()) / (double)mpCamera->vpWidth();+ double y = (double)(0.5*mpCamera->vpHeight() - p2.y()) / (double)mpCamera->vpHeight();+ double sinx = sin(M_PI * x * 0.5);+ double siny = sin(M_PI * y * 0.5);+ double sinx2siny2 = sinx * sinx + siny * siny;++ v3.x() = sinx;+ v3.y() = siny;+ v3.z() = sinx2siny2 < 1.0 ? sqrt(1.0 - sinx2siny2) : 0.0;++ return true;+ }+ else+ return false;+}
+ eigen3/demos/opengl/trackball.h view
@@ -0,0 +1,42 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_TRACKBALL_H+#define EIGEN_TRACKBALL_H++#include <Eigen/Geometry>++class Camera;++class Trackball+{+ public:++ enum Mode {Around, Local};++ Trackball() : mpCamera(0) {}++ void start(Mode m = Around) { mMode = m; mLastPointOk = false; }++ void setCamera(Camera* pCam) { mpCamera = pCam; }++ void track(const Eigen::Vector2i& newPoint2D);++ protected:++ bool mapToSphere( const Eigen::Vector2i& p2, Eigen::Vector3f& v3);++ Camera* mpCamera;+ Eigen::Vector3f mLastPoint3D;+ Mode mMode;+ bool mLastPointOk;++};++#endif // EIGEN_TRACKBALL_H
+ eigen3/doc/A05_PortingFrom2To3.dox view
@@ -0,0 +1,304 @@+namespace Eigen {++/** \page Eigen2ToEigen3 Porting from Eigen2 to Eigen3++<div class="bigwarning">Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3.</div>++This page lists the most important API changes between Eigen2 and Eigen3,+and gives tips to help porting your application from Eigen2 to Eigen3.++\eigenAutoToc++\section CompatibilitySupport Eigen2 compatibility support++In order to ease the switch from Eigen2 to Eigen3, Eigen3 features \subpage Eigen2SupportModes "Eigen2 support modes".++The quick way to enable this is to define the \c EIGEN2_SUPPORT preprocessor token \b before including any Eigen header (typically it should be set in your project options).++A more powerful, \em staged migration path is also provided, which may be useful to migrate larger projects from Eigen2 to Eigen3. This is explained in the \ref Eigen2SupportModes "Eigen 2 support modes" page. ++\section Using The USING_PART_OF_NAMESPACE_EIGEN macro++The USING_PART_OF_NAMESPACE_EIGEN macro has been removed. In Eigen 3, just do:+\code+using namespace Eigen;+\endcode++\section ComplexDot Dot products over complex numbers++This is the single trickiest change between Eigen 2 and Eigen 3. It only affects code using \c std::complex numbers as scalar type.++Eigen 2's dot product was linear in the first variable. Eigen 3's dot product is linear in the second variable. In other words, the Eigen 2 code \code x.dot(y) \endcode is equivalent to the Eigen 3 code \code y.dot(x) \endcode In yet other words, dot products are complex-conjugated in Eigen 3 compared to Eigen 2. The switch to the new convention was commanded by common usage, especially with the notation \f$ x^Ty \f$ for dot products of column-vectors.++\section VectorBlocks Vector blocks++<table class="manual">+<tr><th>Eigen 2</th><th>Eigen 3</th></th>+<tr><td>\code+vector.start(length)+vector.start<length>()+vector.end(length)+vector.end<length>()+\endcode</td><td>\code+vector.head(length)+vector.head<length>()+vector.tail(length)+vector.tail<length>()+\endcode</td></tr>+</table>+++\section Corners Matrix Corners++<table class="manual">+<tr><th>Eigen 2</th><th>Eigen 3</th></th>+<tr><td>\code+matrix.corner(TopLeft,r,c)+matrix.corner(TopRight,r,c)+matrix.corner(BottomLeft,r,c)+matrix.corner(BottomRight,r,c)+matrix.corner<r,c>(TopLeft)+matrix.corner<r,c>(TopRight)+matrix.corner<r,c>(BottomLeft)+matrix.corner<r,c>(BottomRight)+\endcode</td><td>\code+matrix.topLeftCorner(r,c)+matrix.topRightCorner(r,c)+matrix.bottomLeftCorner(r,c)+matrix.bottomRightCorner(r,c)+matrix.topLeftCorner<r,c>()+matrix.topRightCorner<r,c>()+matrix.bottomLeftCorner<r,c>()+matrix.bottomRightCorner<r,c>()+\endcode</td>+</tr>+</table>++Notice that Eigen3 also provides these new convenience methods: topRows(), bottomRows(), leftCols(), rightCols(). See in class DenseBase.++\section CoefficientWiseOperations Coefficient wise operations++In Eigen2, coefficient wise operations which have no proper mathematical definition (as a coefficient wise product)+were achieved using the .cwise() prefix, e.g.:+\code a.cwise() * b \endcode+In Eigen3 this .cwise() prefix has been superseded by a new kind of matrix type called+Array for which all operations are performed coefficient wise. You can easily view a matrix as an array and vice versa using+the MatrixBase::array() and ArrayBase::matrix() functions respectively. Here is an example:+\code+Vector4f a, b, c;+c = a.array() * b.array();+\endcode+Note that the .array() function is not at all a synonym of the deprecated .cwise() prefix.+While the .cwise() prefix changed the behavior of the following operator, the array() function performs+a permanent conversion to the array world. Therefore, for binary operations such as the coefficient wise product,+both sides must be converted to an \em array as in the above example. On the other hand, when you+concatenate multiple coefficient wise operations you only have to do the conversion once, e.g.:+\code+Vector4f a, b, c;+c = a.array().abs().pow(3) * b.array().abs().sin();+\endcode+With Eigen2 you would have written:+\code+c = (a.cwise().abs().cwise().pow(3)).cwise() * (b.cwise().abs().cwise().sin());+\endcode++\section PartAndExtract Triangular and self-adjoint matrices++In Eigen 2 you had to play with the part, extract, and marked functions to deal with triangular and selfadjoint matrices. In Eigen 3, all these functions have been removed in favor of the concept of \em views:++<table class="manual">+<tr><th>Eigen 2</th><th>Eigen 3</th></tr>+<tr><td>\code+A.part<UpperTriangular>();+A.part<StrictlyLowerTriangular>(); \endcode</td>+<td>\code+A.triangularView<Upper>()+A.triangularView<StrictlyLower>()\endcode</td></tr>+<tr><td>\code+A.extract<UpperTriangular>();+A.extract<StrictlyLowerTriangular>();\endcode</td>+<td>\code+A.triangularView<Upper>()+A.triangularView<StrictlyLower>()\endcode</td></tr>+<tr><td>\code+A.marked<UpperTriangular>();+A.marked<StrictlyLowerTriangular>();\endcode</td>+<td>\code+A.triangularView<Upper>()+A.triangularView<StrictlyLower>()\endcode</td></tr>+<tr><td colspan="2"></td></tr>+<tr><td>\code+A.part<SelfAdfjoint|UpperTriangular>();+A.extract<SelfAdfjoint|LowerTriangular>();\endcode</td>+<td>\code+A.selfadjointView<Upper>()+A.selfadjointView<Lower>()\endcode</td></tr>+<tr><td colspan="2"></td></tr>+<tr><td>\code+UpperTriangular+LowerTriangular+UnitUpperTriangular+UnitLowerTriangular+StrictlyUpperTriangular+StrictlyLowerTriangular+\endcode</td><td>\code+Upper+Lower+UnitUpper+UnitLower+StrictlyUpper+StrictlyLower+\endcode</td>+</tr>+</table>++\sa class TriangularView, class SelfAdjointView++\section TriangularSolveInPlace Triangular in-place solving++<table class="manual">+<tr><th>Eigen 2</th><th>Eigen 3</th></tr>+<tr><td>\code A.triangularSolveInPlace<XxxTriangular>(Y);\endcode</td><td>\code A.triangularView<Xxx>().solveInPlace(Y);\endcode</td></tr>+</table>+++\section Decompositions Matrix decompositions++Some of Eigen 2's matrix decompositions have been renamed in Eigen 3, while some others have been removed and are replaced by other decompositions in Eigen 3.++<table class="manual">+ <tr>+ <th>Eigen 2</th>+ <th>Eigen 3</th>+ <th>Notes</th>+ </tr>+ <tr>+ <td>LU</td>+ <td>FullPivLU</td>+ <td class="alt">See also the new PartialPivLU, it's much faster</td>+ </tr>+ <tr>+ <td>QR</td>+ <td>HouseholderQR</td>+ <td class="alt">See also the new ColPivHouseholderQR, it's more reliable</td>+ </tr>+ <tr>+ <td>SVD</td>+ <td>JacobiSVD</td>+ <td class="alt">We currently don't have a bidiagonalizing SVD; of course this is planned.</td>+ </tr>+ <tr>+ <td>EigenSolver and friends</td>+ <td>\code #include<Eigen/Eigenvalues> \endcode </td>+ <td class="alt">Moved to separate module</td>+ </tr>+</table>++\section LinearSolvers Linear solvers++<table class="manual">+<tr><th>Eigen 2</th><th>Eigen 3</th><th>Notes</th></tr>+<tr><td>\code A.lu();\endcode</td>+<td>\code A.fullPivLu();\endcode</td>+<td class="alt">Now A.lu() returns a PartialPivLU</td></tr>+<tr><td>\code A.lu().solve(B,&X);\endcode</td>+<td>\code X = A.lu().solve(B);+ X = A.fullPivLu().solve(B);\endcode</td>+<td class="alt">The returned by value is fully optimized</td></tr>+<tr><td>\code A.llt().solve(B,&X);\endcode</td>+<td>\code X = A.llt().solve(B);+ X = A.selfadjointView<Lower>.llt().solve(B);+ X = A.selfadjointView<Upper>.llt().solve(B);\endcode</td>+<td class="alt">The returned by value is fully optimized and \n+the selfadjointView API allows you to select the \n+triangular part to work on (default is lower part)</td></tr>+<tr><td>\code A.llt().solveInPlace(B);\endcode</td>+<td>\code B = A.llt().solve(B);+ B = A.selfadjointView<Lower>.llt().solve(B);+ B = A.selfadjointView<Upper>.llt().solve(B);\endcode</td>+<td class="alt">In place solving</td></tr>+<tr><td>\code A.ldlt().solve(B,&X);\endcode</td>+<td>\code X = A.ldlt().solve(B);+ X = A.selfadjointView<Lower>.ldlt().solve(B);+ X = A.selfadjointView<Upper>.ldlt().solve(B);\endcode</td>+<td class="alt">The returned by value is fully optimized and \n+the selfadjointView API allows you to select the \n+triangular part to work on</td></tr>+</table>++\section GeometryModule Changes in the Geometry module++The Geometry module is the one that changed the most. If you rely heavily on it, it's probably a good idea to use the \ref Eigen2SupportModes "Eigen 2 support modes" to perform your migration.++\section Transform The Transform class++In Eigen 2, the Transform class didn't really know whether it was a projective or affine transformation. In Eigen 3, it takes a new \a Mode template parameter, which indicates whether it's \a Projective or \a Affine transform. There is no default value.++The Transform3f (etc) typedefs are no more. In Eigen 3, the Transform typedefs explicitly refer to the \a Projective and \a Affine modes:++<table class="manual">+<tr><th>Eigen 2</th><th>Eigen 3</th><th>Notes</th></tr>+<tr>+ <td> Transform3f </td>+ <td> Affine3f or Projective3f </td>+ <td> Of course 3f is just an example here </td>+</tr>+</table>+++\section LazyVsNoalias Lazy evaluation and noalias++In Eigen all operations are performed in a lazy fashion except the matrix products which are always evaluated into a temporary by default.+In Eigen2, lazy evaluation could be enforced by tagging a product using the .lazy() function. However, in complex expressions it was not+easy to determine where to put the lazy() function. In Eigen3, the lazy() feature has been superseded by the MatrixBase::noalias() function+which can be used on the left hand side of an assignment when no aliasing can occur. Here is an example:+\code+MatrixXf a, b, c;+...+c.noalias() += 2 * a.transpose() * b;+\endcode+However, the noalias mechanism does not cover all the features of the old .lazy(). Indeed, in some extremely rare cases,+it might be useful to explicit request for a lay product, i.e., for a product which will be evaluated one coefficient at once, on request,+just like any other expressions. To this end you can use the MatrixBase::lazyProduct() function, however we strongly discourage you to+use it unless you are sure of what you are doing, i.e., you have rigourosly measured a speed improvement.++\section AlignMacros Alignment-related macros++The EIGEN_ALIGN_128 macro has been renamed to EIGEN_ALIGN16. Don't be surprised, it's just that we switched to counting in bytes ;-)++The EIGEN_DONT_ALIGN option still exists in Eigen 3, but it has a new cousin: EIGEN_DONT_ALIGN_STATICALLY. It allows to get rid of all static alignment issues while keeping alignment of dynamic-size heap-allocated arrays, thus keeping vectorization for dynamic-size objects.++\section AlignedMap Aligned Map objects++A common issue with Eigen 2 was that when mapping an array with Map, there was no way to tell Eigen that your array was aligned. There was a ForceAligned option but it didn't mean that; it was just confusing and has been removed.++New in Eigen3 is the #Aligned option. See the documentation of class Map. Use it like this:+\code+Map<Vector4f, Aligned> myMappedVector(some_aligned_array);+\endcode+There also are related convenience static methods, which actually are the preferred way as they take care of such things as constness:+\code+result = Vector4f::MapAligned(some_aligned_array);+\endcode++\section StdContainers STL Containers++In Eigen2, <tt>#include<Eigen/StdVector></tt> tweaked std::vector to automatically align elements. The problem was that that was quite invasive. In Eigen3, we only override standard behavior if you use Eigen::aligned_allocator<T> as your allocator type. So for example, if you use std::vector<Matrix4f>, you need to do the following change (note that aligned_allocator is under namespace Eigen):++<table class="manual">+<tr><th>Eigen 2</th><th>Eigen 3</th></tr>+<tr>+ <td> \code std::vector<Matrix4f> \endcode </td>+ <td> \code std::vector<Matrix4f, aligned_allocator<Matrix4f> > \endcode </td>+</tr>+</table>++\section eiPrefix Internal ei_ prefix++In Eigen2, global internal functions and structures were prefixed by \c ei_. In Eigen3, they all have been moved into the more explicit \c internal namespace. So, e.g., \c ei_sqrt(x) now becomes \c internal::sqrt(x). Of course it is not recommended to rely on Eigen's internal features.++++*/++}
+ eigen3/doc/A10_Eigen2SupportModes.dox view
@@ -0,0 +1,95 @@+namespace Eigen {++/** \page Eigen2SupportModes Eigen 2 support modes++<div class="bigwarning">Eigen2 support is deprecated in Eigen 3.2.x and it will be removed in Eigen 3.3.</div>++This page documents the Eigen2 support modes, a powerful tool to help migrating your project from Eigen 2 to Eigen 3.+Don't miss our page on \ref Eigen2ToEigen3 "API changes" between Eigen 2 and Eigen 3.++\eigenAutoToc++\section EIGEN2_SUPPORT_Macro The quick way: define EIGEN2_SUPPORT++By defining EIGEN2_SUPPORT before including any Eigen 3 header, you get back a large part of the Eigen 2 API, while keeping the Eigen 3 API and ABI unchanged.++This defaults to the \ref Stage30 "stage 30" described below.++The rest of this page describes an optional, more powerful \em staged migration path.++\section StagedMigrationPathOverview Overview of the staged migration path++The primary reason why EIGEN2_SUPPORT alone may not be enough to migrate a large project from Eigen 2 to Eigen 3 is that some of the Eigen 2 API is inherently incompatible with the Eigen 3 API. This happens when the same identifier is used in Eigen 2 and in Eigen 3 with different meanings. To help migrate projects that rely on such API, we provide a staged migration path allowing to perform the migration \em incrementally.++It goes as follows:+\li Step 0: start with a project using Eigen 2.+\li Step 1: build your project against Eigen 3 with \ref Stage10 "Eigen 2 support stage 10". This mode enables maximum compatibility with the Eigen 2 API, with just a few exceptions.+\li Step 2: build your project against Eigen 3 with \ref Stage20 "Eigen 2 support stage 20". This mode forces you to add eigen2_ prefixes to the Eigen2 identifiers that conflict with Eigen 3 API.+\li Step 3: build your project against Eigen 3 with \ref Stage30 "Eigen 2 support stage 30". This mode enables the full Eigen 3 API.+\li Step 4: build your project against Eigen 3 with \ref Stage40 "Eigen 2 support stage 40". This mode enables the full Eigen 3 strictness on matters, such as const-correctness, where Eigen 2 was looser.+\li Step 5: build your project against Eigen 3 without any Eigen 2 support mode.++\section Stage10 Stage 10: define EIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API++Enable this mode by defining the EIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API preprocessor macro before including any Eigen 3 header.++This mode maximizes support for the Eigen 2 API. As a result, it does not offer the full Eigen 3 API. Also, it doesn't offer quite 100% of the Eigen 2 API.++The part of the Eigen 3 API that is not present in this mode, is Eigen 3's Geometry module. Indeed, this mode completely replaces it by a copy of Eigen 2's Geometry module.++The parts of the API that are still not 100% Eigen 2 compatible in this mode are:+\li Dot products over complex numbers. Eigen 2's dot product was linear in the first variable. Eigen 3's dot product is linear in the second variable. In other words, the Eigen 2 code \code x.dot(y) \endcode is equivalent to the Eigen 3 code \code y.dot(x) \endcode In yet other words, dot products are complex-conjugated in Eigen 3 compared to Eigen 2. The switch to the new convention was commanded by common usage, especially with the notation \f$ x^Ty \f$ for dot products of column-vectors.+\li The Sparse module.+\li Certain fine details of linear algebraic decompositions. For example, LDLT decomposition is now pivoting in Eigen 3 whereas it wasn't in Eigen 2, so code that was relying on its underlying matrix structure will break.+\li Usage of Eigen types in STL containers, \ref Eigen2ToEigen3 "as explained on this page".++\section Stage20 Stage 20: define EIGEN2_SUPPORT_STAGE20_RESOLVE_API_CONFLICTS++Enable this mode by defining the EIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API preprocessor macro before including any Eigen 3 header.++This mode removes the Eigen 2 API that is directly conflicting with Eigen 3 API. Instead, these bits of Eigen 2 API remain available with eigen2_ prefixes. The main examples of such API are:+\li the whole Geometry module. For example, replace \c Quaternion by \c eigen2_Quaternion, replace \c Transform3f by \c eigen2_Transform3f, etc.+\li the lu() method to obtain a LU decomposition. Replace by eigen2_lu().++There is also one more eigen2_-prefixed identifier that you should know about, even though its use is not checked at compile time by this mode: the dot() method. As was discussed above, over complex numbers, its meaning is different between Eigen 2 and Eigen 3. You can use eigen2_dot() to get the Eigen 2 behavior.++\section Stage30 Stage 30: define EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API++Enable this mode by defining the EIGEN2_SUPPORT_STAGE30_FULL_EIGEN3_API preprocessor macro before including any Eigen 3 header. Also, this mode is what you get by default when you just define EIGEN2_SUPPORT.++This mode gives you the full unaltered Eigen 3 API, while still keeping as much support as possible for the Eigen 2 API.++The eigen2_-prefixed identifiers are still available, but at this stage you should now replace them by Eigen 3 identifiers. Have a look at our page on \ref Eigen2ToEigen3 "API changes" between Eigen 2 and Eigen 3.++\section Stage40 Stage 40: define EIGEN2_SUPPORT_STAGE40_FULL_EIGEN3_STRICTNESS++Enable this mode by defining the EIGEN2_SUPPORT_STAGE40_FULL_EIGEN3_STRICTNESS preprocessor macro before including any Eigen 3 header.++This mode tightens the last bits of strictness, especially const-correctness, that had to be loosened to support what Eigen 2 allowed. For example, this code compiled in Eigen 2:+\code+const float array[4];+x = Map<Vector4f>(array);+\endcode+That allowed to circumvent constness. This is no longer allowed in Eigen 3. If you have to map const data in Eigen 3, map it as a const-qualified type. However, rather than explictly constructing Map objects, we strongly encourage you to use the static Map methods instead, as they take care of all of this for you:+\code+const float array[4];+x = Vector4f::Map(array);+\endcode+This lets Eigen do the right thing for you and works equally well in Eigen 2 and in Eigen 3.++\section FinallyDropAllEigen2Support Finally drop all Eigen 2 support++Stage 40 is the first where it's "comfortable" to stay for a little longer period, since it preserves 100% Eigen 3 compatibility. However, we still encourage you to complete your migration as quickly as possible. While we do run the Eigen 2 test suite against Eigen 3's stage 10 support mode, we can't guarantee the same level of support and quality assurance for Eigen 2 support as we do for Eigen 3 itself, especially not in the long term. \ref Eigen2ToEigen3 "This page" describes a large part of the changes that you may need to perform.++\section ABICompatibility What about ABI compatibility?++It goes as follows:+\li Stage 10 already is ABI compatible with Eigen 3 for the basic (Matrix, Array, SparseMatrix...) types. However, since this stage uses a copy of Eigen 2's Geometry module instead of Eigen 3's own Geometry module, the ABI in the Geometry module is not Eigen 3 compatible.+\li Stage 20 removes the Eigen 3-incompatible Eigen 2 Geometry module (it remains available with eigen2_ prefix). So at this stage, all the identifiers that exist in Eigen 3 have the Eigen 3 ABI (and API).+\li Stage 30 introduces the remaining Eigen 3 identifiers. So at this stage, you have the full Eigen 3 ABI.+\li Stage 40 is no different than Stage 30 in these matters.+++*/++}
+ eigen3/doc/AsciiQuickReference.txt view
@@ -0,0 +1,207 @@+// A simple quickref for Eigen. Add anything that's missing.+// Main author: Keir Mierle++#include <Eigen/Dense>++Matrix<double, 3, 3> A; // Fixed rows and cols. Same as Matrix3d.+Matrix<double, 3, Dynamic> B; // Fixed rows, dynamic cols.+Matrix<double, Dynamic, Dynamic> C; // Full dynamic. Same as MatrixXd.+Matrix<double, 3, 3, RowMajor> E; // Row major; default is column-major.+Matrix3f P, Q, R; // 3x3 float matrix.+Vector3f x, y, z; // 3x1 float matrix.+RowVector3f a, b, c; // 1x3 float matrix.+VectorXd v; // Dynamic column vector of doubles+double s; ++// Basic usage+// Eigen // Matlab // comments+x.size() // length(x) // vector size+C.rows() // size(C,1) // number of rows+C.cols() // size(C,2) // number of columns+x(i) // x(i+1) // Matlab is 1-based+C(i,j) // C(i+1,j+1) //++A.resize(4, 4); // Runtime error if assertions are on.+B.resize(4, 9); // Runtime error if assertions are on.+A.resize(3, 3); // Ok; size didn't change.+B.resize(3, 9); // Ok; only dynamic cols changed.+ +A << 1, 2, 3, // Initialize A. The elements can also be+ 4, 5, 6, // matrices, which are stacked along cols+ 7, 8, 9; // and then the rows are stacked.+B << A, A, A; // B is three horizontally stacked A's.+A.fill(10); // Fill A with all 10's.++// Eigen // Matlab+MatrixXd::Identity(rows,cols) // eye(rows,cols)+C.setIdentity(rows,cols) // C = eye(rows,cols)+MatrixXd::Zero(rows,cols) // zeros(rows,cols)+C.setZero(rows,cols) // C = ones(rows,cols)+MatrixXd::Ones(rows,cols) // ones(rows,cols)+C.setOnes(rows,cols) // C = ones(rows,cols)+MatrixXd::Random(rows,cols) // rand(rows,cols)*2-1 // MatrixXd::Random returns uniform random numbers in (-1, 1).+C.setRandom(rows,cols) // C = rand(rows,cols)*2-1+VectorXd::LinSpaced(size,low,high) // linspace(low,high,size)'+v.setLinSpaced(size,low,high) // v = linspace(low,high,size)'+++// Matrix slicing and blocks. All expressions listed here are read/write.+// Templated size versions are faster. Note that Matlab is 1-based (a size N+// vector is x(1)...x(N)).+// Eigen // Matlab+x.head(n) // x(1:n)+x.head<n>() // x(1:n)+x.tail(n) // x(end - n + 1: end)+x.tail<n>() // x(end - n + 1: end)+x.segment(i, n) // x(i+1 : i+n)+x.segment<n>(i) // x(i+1 : i+n)+P.block(i, j, rows, cols) // P(i+1 : i+rows, j+1 : j+cols)+P.block<rows, cols>(i, j) // P(i+1 : i+rows, j+1 : j+cols)+P.row(i) // P(i+1, :)+P.col(j) // P(:, j+1)+P.leftCols<cols>() // P(:, 1:cols)+P.leftCols(cols) // P(:, 1:cols)+P.middleCols<cols>(j) // P(:, j+1:j+cols)+P.middleCols(j, cols) // P(:, j+1:j+cols)+P.rightCols<cols>() // P(:, end-cols+1:end)+P.rightCols(cols) // P(:, end-cols+1:end)+P.topRows<rows>() // P(1:rows, :)+P.topRows(rows) // P(1:rows, :)+P.middleRows<rows>(i) // P(i+1:i+rows, :)+P.middleRows(i, rows) // P(i+1:i+rows, :)+P.bottomRows<rows>() // P(end-rows+1:end, :)+P.bottomRows(rows) // P(end-rows+1:end, :)+P.topLeftCorner(rows, cols) // P(1:rows, 1:cols)+P.topRightCorner(rows, cols) // P(1:rows, end-cols+1:end)+P.bottomLeftCorner(rows, cols) // P(end-rows+1:end, 1:cols)+P.bottomRightCorner(rows, cols) // P(end-rows+1:end, end-cols+1:end)+P.topLeftCorner<rows,cols>() // P(1:rows, 1:cols)+P.topRightCorner<rows,cols>() // P(1:rows, end-cols+1:end)+P.bottomLeftCorner<rows,cols>() // P(end-rows+1:end, 1:cols)+P.bottomRightCorner<rows,cols>() // P(end-rows+1:end, end-cols+1:end)++// Of particular note is Eigen's swap function which is highly optimized.+// Eigen // Matlab+R.row(i) = P.col(j); // R(i, :) = P(:, i)+R.col(j1).swap(mat1.col(j2)); // R(:, [j1 j2]) = R(:, [j2, j1])++// Views, transpose, etc; all read-write except for .adjoint().+// Eigen // Matlab+R.adjoint() // R'+R.transpose() // R.' or conj(R')+R.diagonal() // diag(R)+x.asDiagonal() // diag(x)+R.transpose().colwise().reverse(); // rot90(R)+R.conjugate() // conj(R)++// All the same as Matlab, but matlab doesn't have *= style operators.+// Matrix-vector. Matrix-matrix. Matrix-scalar.+y = M*x; R = P*Q; R = P*s;+a = b*M; R = P - Q; R = s*P;+a *= M; R = P + Q; R = P/s;+ R *= Q; R = s*P;+ R += Q; R *= s;+ R -= Q; R /= s;++// Vectorized operations on each element independently+// Eigen // Matlab+R = P.cwiseProduct(Q); // R = P .* Q+R = P.array() * s.array();// R = P .* s+R = P.cwiseQuotient(Q); // R = P ./ Q+R = P.array() / Q.array();// R = P ./ Q+R = P.array() + s.array();// R = P + s+R = P.array() - s.array();// R = P - s+R.array() += s; // R = R + s+R.array() -= s; // R = R - s+R.array() < Q.array(); // R < Q+R.array() <= Q.array(); // R <= Q+R.cwiseInverse(); // 1 ./ P+R.array().inverse(); // 1 ./ P+R.array().sin() // sin(P)+R.array().cos() // cos(P)+R.array().pow(s) // P .^ s+R.array().square() // P .^ 2+R.array().cube() // P .^ 3+R.cwiseSqrt() // sqrt(P)+R.array().sqrt() // sqrt(P)+R.array().exp() // exp(P)+R.array().log() // log(P)+R.cwiseMax(P) // max(R, P)+R.array().max(P.array()) // max(R, P)+R.cwiseMin(P) // min(R, P)+R.array().min(P.array()) // min(R, P)+R.cwiseAbs() // abs(P)+R.array().abs() // abs(P)+R.cwiseAbs2() // abs(P.^2)+R.array().abs2() // abs(P.^2)+(R.array() < s).select(P,Q); // (R < s ? P : Q)++// Reductions.+int r, c;+// Eigen // Matlab+R.minCoeff() // min(R(:))+R.maxCoeff() // max(R(:))+s = R.minCoeff(&r, &c) // [s, i] = min(R(:)); [r, c] = ind2sub(size(R), i);+s = R.maxCoeff(&r, &c) // [s, i] = max(R(:)); [r, c] = ind2sub(size(R), i);+R.sum() // sum(R(:))+R.colwise().sum() // sum(R)+R.rowwise().sum() // sum(R, 2) or sum(R')'+R.prod() // prod(R(:))+R.colwise().prod() // prod(R)+R.rowwise().prod() // prod(R, 2) or prod(R')'+R.trace() // trace(R)+R.all() // all(R(:))+R.colwise().all() // all(R)+R.rowwise().all() // all(R, 2)+R.any() // any(R(:))+R.colwise().any() // any(R)+R.rowwise().any() // any(R, 2)++// Dot products, norms, etc.+// Eigen // Matlab+x.norm() // norm(x). Note that norm(R) doesn't work in Eigen.+x.squaredNorm() // dot(x, x) Note the equivalence is not true for complex+x.dot(y) // dot(x, y)+x.cross(y) // cross(x, y) Requires #include <Eigen/Geometry>++//// Type conversion+// Eigen // Matlab+A.cast<double>(); // double(A)+A.cast<float>(); // single(A)+A.cast<int>(); // int32(A)+A.real(); // real(A)+A.imag(); // imag(A)+// if the original type equals destination type, no work is done++// Note that for most operations Eigen requires all operands to have the same type:+MatrixXf F = MatrixXf::Zero(3,3);+A += F; // illegal in Eigen. In Matlab A = A+F is allowed+A += F.cast<double>(); // F converted to double and then added (generally, conversion happens on-the-fly)++// Eigen can map existing memory into Eigen matrices.+float array[3];+Vector3f::Map(array).fill(10); // create a temporary Map over array and sets entries to 10+int data[4] = {1, 2, 3, 4};+Matrix2i mat2x2(data); // copies data into mat2x2+Matrix2i::Map(data) = 2*mat2x2; // overwrite elements of data with 2*mat2x2+MatrixXi::Map(data, 2, 2) += mat2x2; // adds mat2x2 to elements of data (alternative syntax if size is not know at compile time)++// Solve Ax = b. Result stored in x. Matlab: x = A \ b.+x = A.ldlt().solve(b)); // A sym. p.s.d. #include <Eigen/Cholesky>+x = A.llt() .solve(b)); // A sym. p.d. #include <Eigen/Cholesky>+x = A.lu() .solve(b)); // Stable and fast. #include <Eigen/LU>+x = A.qr() .solve(b)); // No pivoting. #include <Eigen/QR>+x = A.svd() .solve(b)); // Stable, slowest. #include <Eigen/SVD>+// .ldlt() -> .matrixL() and .matrixD()+// .llt() -> .matrixL()+// .lu() -> .matrixL() and .matrixU()+// .qr() -> .matrixQ() and .matrixR()+// .svd() -> .matrixU(), .singularValues(), and .matrixV()++// Eigenvalue problems+// Eigen // Matlab+A.eigenvalues(); // eig(A);+EigenSolver<Matrix3d> eig(A); // [vec val] = eig(A)+eig.eigenvalues(); // diag(val)+eig.eigenvectors(); // vec+// For self-adjoint matrices use SelfAdjointEigenSolver<>
+ eigen3/doc/B01_Experimental.dox view
@@ -0,0 +1,52 @@+namespace Eigen {++/** \page Experimental Experimental parts of Eigen++\eigenAutoToc++\section summary Summary++With the 2.0 release, Eigen's API is, to a large extent, stable. However, we wish to retain the freedom to make API incompatible changes. To that effect, we call many parts of Eigen "experimental" which means that they are not subject to API stability guarantee.++Our goal is that for the 2.1 release (expected in July 2009) most of these parts become API-stable too.++We are aware that API stability is a major concern for our users. That's why it's a priority for us to reach it, but at the same time we're being serious about not calling Eigen API-stable too early.++Experimental features may at any time:+\li be removed;+\li be subject to an API incompatible change;+\li introduce API or ABI incompatible changes in your own code if you let them affect your API or ABI.++\section modules Experimental modules++The following modules are considered entirely experimental, and we make no firm API stability guarantee about them for the time being:+\li SVD+\li QR+\li Cholesky+\li Sparse+\li Geometry (this one should be mostly stable, but it's a little too early to make a formal guarantee)++\section core Experimental parts of the Core module++In the Core module, the only classes subject to ABI stability guarantee (meaning that you can use it for data members in your public ABI) is:+\li Matrix+\li Map++All other classes offer no ABI guarantee, e.g. the layout of their data can be changed.++The only classes subject to (even partial) API stability guarantee (meaning that you can safely construct and use objects) are:+\li MatrixBase : partial API stability (see below)+\li Matrix : full API stability (except for experimental stuff inherited from MatrixBase)+\li Map : full API stability (except for experimental stuff inherited from MatrixBase)++All other classes offer no direct API guarantee, e.g. their methods can be changed; however notice that most classes inherit MatrixBase and that this is where most of their API comes from -- so in practice most of the API is stable.++A few MatrixBase methods are considered experimental, hence not part of any API stability guarantee:+\li all methods documented as internal+\li all methods hidden in the Doxygen documentation+\li all methods marked as experimental+\li all methods defined in experimental modules++*/++}
+ eigen3/doc/CMakeLists.txt view
@@ -0,0 +1,99 @@+project(EigenDoc)++set_directory_properties(PROPERTIES EXCLUDE_FROM_ALL TRUE)++project(EigenDoc)++if(CMAKE_COMPILER_IS_GNUCXX)+ if(CMAKE_SYSTEM_NAME MATCHES Linux)+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O1 -g1")+ endif(CMAKE_SYSTEM_NAME MATCHES Linux)+endif(CMAKE_COMPILER_IS_GNUCXX)++# Set some Doxygen flags+set(EIGEN_DOXY_PROJECT_NAME "Eigen")+set(EIGEN_DOXY_OUTPUT_DIRECTORY_SUFFIX "")+set(EIGEN_DOXY_INPUT "\"${Eigen_SOURCE_DIR}/Eigen\" \"${Eigen_SOURCE_DIR}/doc\"")+set(EIGEN_DOXY_HTML_COLORSTYLE_HUE "220")+set(EIGEN_DOXY_TAGFILES "")++configure_file(+ ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in+ ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile+)++set(EIGEN_DOXY_PROJECT_NAME "Eigen-unsupported")+set(EIGEN_DOXY_OUTPUT_DIRECTORY_SUFFIX "/unsupported")+set(EIGEN_DOXY_INPUT "\"${Eigen_SOURCE_DIR}/unsupported/Eigen\" \"${Eigen_SOURCE_DIR}/unsupported/doc\"")+set(EIGEN_DOXY_HTML_COLORSTYLE_HUE "0")+# set(EIGEN_DOXY_TAGFILES "\"${Eigen_BINARY_DIR}/doc/eigen.doxytags =../\"")+set(EIGEN_DOXY_TAGFILES "")++configure_file(+ ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in+ ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile-unsupported+)++configure_file(+ ${CMAKE_CURRENT_SOURCE_DIR}/eigendoxy_header.html.in+ ${CMAKE_CURRENT_BINARY_DIR}/eigendoxy_header.html+)++configure_file(+ ${CMAKE_CURRENT_SOURCE_DIR}/eigendoxy_footer.html.in+ ${CMAKE_CURRENT_BINARY_DIR}/eigendoxy_footer.html+)++configure_file(+ ${CMAKE_CURRENT_SOURCE_DIR}/eigendoxy_layout.xml.in+ ${CMAKE_CURRENT_BINARY_DIR}/eigendoxy_layout.xml+)++configure_file(+ ${Eigen_SOURCE_DIR}/unsupported/doc/eigendoxy_layout.xml.in+ ${Eigen_BINARY_DIR}/doc/unsupported/eigendoxy_layout.xml+)++set(examples_targets "")+set(snippets_targets "")++add_definitions("-DEIGEN_MAKING_DOCS")+add_custom_target(all_examples)++add_subdirectory(examples)+add_subdirectory(special_examples)+add_subdirectory(snippets)++add_custom_target(+ doc-eigen-prerequisites+ ALL+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/html/+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/eigen_navtree_hacks.js ${CMAKE_CURRENT_BINARY_DIR}/html/+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/Eigen_Silly_Professor_64x64.png ${CMAKE_CURRENT_BINARY_DIR}/html/+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/AsciiQuickReference.txt ${CMAKE_CURRENT_BINARY_DIR}/html/+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}+)++add_custom_target(+ doc-unsupported-prerequisites+ ALL+ COMMAND ${CMAKE_COMMAND} -E make_directory ${Eigen_BINARY_DIR}/doc/html/unsupported+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/eigen_navtree_hacks.js ${CMAKE_CURRENT_BINARY_DIR}/html/unsupported/+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/Eigen_Silly_Professor_64x64.png ${CMAKE_CURRENT_BINARY_DIR}/html/unsupported/+ WORKING_DIRECTORY ${Eigen_BINARY_DIR}/doc+)++add_dependencies(doc-eigen-prerequisites all_snippets all_examples)+add_dependencies(doc-unsupported-prerequisites unsupported_snippets unsupported_examples)++add_custom_target(doc ALL+ COMMAND doxygen+ COMMAND doxygen Doxyfile-unsupported+ COMMAND ${CMAKE_COMMAND} -E rename html eigen-doc+ COMMAND ${CMAKE_COMMAND} -E remove eigen-doc/eigen-doc.tgz+ COMMAND ${CMAKE_COMMAND} -E tar cfz eigen-doc.tgz eigen-doc+ COMMAND ${CMAKE_COMMAND} -E rename eigen-doc.tgz eigen-doc/eigen-doc.tgz+ COMMAND ${CMAKE_COMMAND} -E rename eigen-doc html+ WORKING_DIRECTORY ${Eigen_BINARY_DIR}/doc)++add_dependencies(doc doc-eigen-prerequisites doc-unsupported-prerequisites)
+ eigen3/doc/ClassHierarchy.dox view
@@ -0,0 +1,129 @@+namespace Eigen {++/** \page TopicClassHierarchy The class hierarchy++This page explains the design of the core classes in Eigen's class hierarchy and how they fit together. Casual+users probably need not concern themselves with these details, but it may be useful for both advanced users+and Eigen developers.++\eigenAutoToc+++\section TopicClassHierarchyPrinciples Principles++Eigen's class hierarchy is designed so that virtual functions are avoided where their overhead would+significantly impair performance. Instead, Eigen achieves polymorphism with the Curiously Recurring Template+Pattern (CRTP). In this pattern, the base class (for instance, \c MatrixBase) is in fact a template class, and+the derived class (for instance, \c Matrix) inherits the base class with the derived class itself as a+template argument (in this case, \c Matrix inherits from \c MatrixBase<Matrix>). This allows Eigen to+resolve the polymorphic function calls at compile time.++In addition, the design avoids multiple inheritance. One reason for this is that in our experience, some+compilers (like MSVC) fail to perform empty base class optimization, which is crucial for our fixed-size+types.+++\section TopicClassHierarchyCoreClasses The core classes++These are the classes that you need to know about if you want to write functions that accept or return Eigen+objects.++ - Matrix means plain dense matrix. If \c m is a \c %Matrix, then, for instance, \c m+m is no longer a + \c %Matrix, it is a "matrix expression".+ - MatrixBase means dense matrix expression. This means that a \c %MatrixBase is something that can be+ added, matrix-multiplied, LU-decomposed, QR-decomposed... All matrix expression classes, including + \c %Matrix itself, inherit \c %MatrixBase.+ - Array means plain dense array. If \c x is an \c %Array, then, for instance, \c x+x is no longer an + \c %Array, it is an "array expression".+ - ArrayBase means dense array expression. This means that an \c %ArrayBase is something that can be+ added, array-multiplied, and on which you can perform all sorts of array operations... All array+ expression classes, including \c %Array itself, inherit \c %ArrayBase.+ - DenseBase means dense (matrix or array) expression. Both \c %ArrayBase and \c %MatrixBase inherit+ \c %DenseBase. \c %DenseBase is where all the methods go that apply to dense expressions regardless of+ whether they are matrix or array expressions. For example, the \link DenseBase::block() block(...) \endlink+ methods are in \c %DenseBase.++\section TopicClassHierarchyBaseClasses Base classes++These classes serve as base classes for the five core classes mentioned above. They are more internal and so+less interesting for users of the Eigen library.++ - PlainObjectBase means dense (matrix or array) plain object, i.e. something that stores its own dense+ array of coefficients. This is where, for instance, the \link PlainObjectBase::resize() resize() \endlink+ methods go. \c %PlainObjectBase is inherited by \c %Matrix and by \c %Array. But above, we said that + \c %Matrix inherits \c %MatrixBase and \c %Array inherits \c %ArrayBase. So does that mean multiple+ inheritance? No, because \c %PlainObjectBase \e itself inherits \c %MatrixBase or \c %ArrayBase depending+ on whether we are in the matrix or array case. When we said above that \c %Matrix inherited + \c %MatrixBase, we omitted to say it does so indirectly via \c %PlainObjectBase. Same for \c %Array.+ - DenseCoeffsBase means something that has dense coefficient accessors. It is a base class for+ \c %DenseBase. The reason for \c %DenseCoeffsBase to exist is that the set of available coefficient+ accessors is very different depending on whether a dense expression has direct memory access or not (the+ \c DirectAccessBit flag). For example, if \c x is a plain matrix, then \c x has direct access, and + \c x.transpose() and \c x.block(...) also have direct access, because their coefficients can be read right+ off memory, but for example, \c x+x does not have direct memory access, because obtaining any of its+ coefficients requires a computation (an addition), it can't be just read off memory.+ - EigenBase means anything that can be evaluated into a plain dense matrix or array (even if that would+ be a bad idea). \c %EigenBase is really the absolute base class for anything that remotely looks like a+ matrix or array. It is a base class for \c %DenseCoeffsBase, so it sits below all our dense class+ hierarchy, but it is not limited to dense expressions. For example, \c %EigenBase is also inherited by+ diagonal matrices, sparse matrices, etc...+++\section TopicClassHierarchyInheritanceDiagrams Inheritance diagrams++The inheritance diagram for Matrix looks as follows:++<pre>+EigenBase<%Matrix>+ <-- DenseCoeffsBase<%Matrix> (direct access case)+ <-- DenseBase<%Matrix>+ <-- MatrixBase<%Matrix>+ <-- PlainObjectBase<%Matrix> (matrix case)+ <-- Matrix+</pre>++The inheritance diagram for Array looks as follows:++<pre>+EigenBase<%Array>+ <-- DenseCoeffsBase<%Array> (direct access case)+ <-- DenseBase<%Array>+ <-- ArrayBase<%Array>+ <-- PlainObjectBase<%Array> (array case)+ <-- Array+</pre>++The inheritance diagram for some other matrix expression class, here denoted by \c SomeMatrixXpr, looks as+follows:++<pre>+EigenBase<SomeMatrixXpr>+ <-- DenseCoeffsBase<SomeMatrixXpr> (direct access or no direct access case)+ <-- DenseBase<SomeMatrixXpr>+ <-- MatrixBase<SomeMatrixXpr>+ <-- SomeMatrixXpr+</pre>++The inheritance diagram for some other array expression class, here denoted by \c SomeArrayXpr, looks as+follows:++<pre>+EigenBase<SomeArrayXpr>+ <-- DenseCoeffsBase<SomeArrayXpr> (direct access or no direct access case)+ <-- DenseBase<SomeArrayXpr>+ <-- ArrayBase<SomeArrayXpr>+ <-- SomeArrayXpr+</pre>++Finally, consider an example of something that is not a dense expression, for instance a diagonal matrix. The+corresponding inheritance diagram is:++<pre>+EigenBase<%DiagonalMatrix>+ <-- DiagonalBase<%DiagonalMatrix>+ <-- DiagonalMatrix+</pre>+++*/+}
+ eigen3/doc/CustomizingEigen.dox view
@@ -0,0 +1,188 @@+namespace Eigen {++/** \page TopicCustomizingEigen Customizing/Extending Eigen++Eigen can be extended in several ways, for instance, by defining global methods, \ref ExtendingMatrixBase "by adding custom methods to MatrixBase", adding support to \ref CustomScalarType "custom types" etc.++\eigenAutoToc++\section ExtendingMatrixBase Extending MatrixBase (and other classes)++In this section we will see how to add custom methods to MatrixBase. Since all expressions and matrix types inherit MatrixBase, adding a method to MatrixBase make it immediately available to all expressions ! A typical use case is, for instance, to make Eigen compatible with another API.++You certainly know that in C++ it is not possible to add methods to an existing class. So how that's possible ? Here the trick is to include in the declaration of MatrixBase a file defined by the preprocessor token \c EIGEN_MATRIXBASE_PLUGIN:+\code+class MatrixBase {+ // ...+ #ifdef EIGEN_MATRIXBASE_PLUGIN+ #include EIGEN_MATRIXBASE_PLUGIN+ #endif+};+\endcode+Therefore to extend MatrixBase with your own methods you just have to create a file with your method declaration and define EIGEN_MATRIXBASE_PLUGIN before you include any Eigen's header file.++You can extend many of the other classes used in Eigen by defining similarly named preprocessor symbols. For instance, define \c EIGEN_ARRAYBASE_PLUGIN if you want to extend the ArrayBase class. A full list of classes that can be extended in this way and the corresponding preprocessor symbols can be found on our page \ref TopicPreprocessorDirectives.++Here is an example of an extension file for adding methods to MatrixBase: \n+\b MatrixBaseAddons.h+\code+inline Scalar at(uint i, uint j) const { return this->operator()(i,j); }+inline Scalar& at(uint i, uint j) { return this->operator()(i,j); }+inline Scalar at(uint i) const { return this->operator[](i); }+inline Scalar& at(uint i) { return this->operator[](i); }++inline RealScalar squaredLength() const { return squaredNorm(); }+inline RealScalar length() const { return norm(); }+inline RealScalar invLength(void) const { return fast_inv_sqrt(squaredNorm()); }++template<typename OtherDerived>+inline Scalar squaredDistanceTo(const MatrixBase<OtherDerived>& other) const+{ return (derived() - other.derived()).squaredNorm(); }++template<typename OtherDerived>+inline RealScalar distanceTo(const MatrixBase<OtherDerived>& other) const+{ return internal::sqrt(derived().squaredDistanceTo(other)); }++inline void scaleTo(RealScalar l) { RealScalar vl = norm(); if (vl>1e-9) derived() *= (l/vl); }++inline Transpose<Derived> transposed() {return this->transpose();}+inline const Transpose<Derived> transposed() const {return this->transpose();}++inline uint minComponentId(void) const { int i; this->minCoeff(&i); return i; }+inline uint maxComponentId(void) const { int i; this->maxCoeff(&i); return i; }++template<typename OtherDerived>+void makeFloor(const MatrixBase<OtherDerived>& other) { derived() = derived().cwiseMin(other.derived()); }+template<typename OtherDerived>+void makeCeil(const MatrixBase<OtherDerived>& other) { derived() = derived().cwiseMax(other.derived()); }++const CwiseUnaryOp<internal::scalar_add_op<Scalar>, Derived>+operator+(const Scalar& scalar) const+{ return CwiseUnaryOp<internal::scalar_add_op<Scalar>, Derived>(derived(), internal::scalar_add_op<Scalar>(scalar)); }++friend const CwiseUnaryOp<internal::scalar_add_op<Scalar>, Derived>+operator+(const Scalar& scalar, const MatrixBase<Derived>& mat)+{ return CwiseUnaryOp<internal::scalar_add_op<Scalar>, Derived>(mat.derived(), internal::scalar_add_op<Scalar>(scalar)); }+\endcode++Then one can the following declaration in the config.h or whatever prerequisites header file of his project:+\code+#define EIGEN_MATRIXBASE_PLUGIN "MatrixBaseAddons.h"+\endcode++\section InheritingFromMatrix Inheriting from Matrix++Before inheriting from Matrix, be really, i mean REALLY sure that using+EIGEN_MATRIX_PLUGIN is not what you really want (see previous section).+If you just need to add few members to Matrix, this is the way to go.++An example of when you actually need to inherit Matrix, is when you have+several layers of heritage such as MyVerySpecificVector1,MyVerySpecificVector1 -> MyVector1 -> Matrix and.+MyVerySpecificVector3,MyVerySpecificVector4 -> MyVector2 -> Matrix.++In order for your object to work within the %Eigen framework, you need to+define a few members in your inherited class.++Here is a minimalistic example:\n+\code+class MyVectorType : public Eigen::VectorXd+{+public:+ MyVectorType(void):Eigen::VectorXd() {}++ typedef Eigen::VectorXd Base;++ // This constructor allows you to construct MyVectorType from Eigen expressions+ template<typename OtherDerived>+ MyVectorType(const Eigen::MatrixBase<OtherDerived>& other)+ : Eigen::Vector3d(other)+ { }++ // This method allows you to assign Eigen expressions to MyVectorType+ template<typename OtherDerived>+ MyVectorType & operator= (const Eigen::MatrixBase <OtherDerived>& other)+ {+ this->Base::operator=(other);+ return *this;+ }+};+\endcode++This is the kind of error you can get if you don't provide those methods+\code+error: no match for ‘operator=’ in ‘delta =+(((Eigen::MatrixBase<Eigen::Matrix<std::complex<float>, 10000, 1, 2, 10000,+1> >*)(& delta)) + 8u)->Eigen::MatrixBase<Derived>::cwise [with Derived =+Eigen::Matrix<std::complex<float>, 10000, 1, 2, 10000,+1>]().Eigen::Cwise<ExpressionType>::operator* [with OtherDerived =+Eigen::Matrix<std::complex<float>, 10000, 1, 2, 10000, 1>, ExpressionType =+Eigen::Matrix<std::complex<float>, 10000, 1, 2, 10000, 1>](((const+Eigen::MatrixBase<Eigen::Matrix<std::complex<float>, 10000, 1, 2, 10000, 1>+>&)(((const Eigen::MatrixBase<Eigen::Matrix<std::complex<float>, 10000, 1,+>2, 10000, 1> >*)((const spectral1d*)where)) + 8u)))’ +\endcode++\anchor user_defined_scalars \section CustomScalarType Using custom scalar types++By default, Eigen currently supports standard floating-point types (\c float, \c double, \c std::complex<float>, \c std::complex<double>, \c long \c double), as well as all native integer types (e.g., \c int, \c unsigned \c int, \c short, etc.), and \c bool.+On x86-64 systems, \c long \c double permits to locally enforces the use of x87 registers with extended accuracy (in comparison to SSE).++In order to add support for a custom type \c T you need:+-# make sure the common operator (+,-,*,/,etc.) are supported by the type \c T+-# add a specialization of struct Eigen::NumTraits<T> (see \ref NumTraits)+-# define the math functions that makes sense for your type. This includes standard ones like sqrt, pow, sin, tan, conj, real, imag, etc, as well as abs2 which is Eigen specific.+ (see the file Eigen/src/Core/MathFunctions.h)++The math function should be defined in the same namespace than \c T, or in the \c std namespace though that second approach is not recommended.++Here is a concrete example adding support for the Adolc's \c adouble type. <a href="https://projects.coin-or.org/ADOL-C">Adolc</a> is an automatic differentiation library. The type \c adouble is basically a real value tracking the values of any number of partial derivatives.++\code+#ifndef ADOLCSUPPORT_H+#define ADOLCSUPPORT_H++#define ADOLC_TAPELESS+#include <adolc/adouble.h>+#include <Eigen/Core>++namespace Eigen {++template<> struct NumTraits<adtl::adouble>+ : NumTraits<double> // permits to get the epsilon, dummy_precision, lowest, highest functions+{+ typedef adtl::adouble Real;+ typedef adtl::adouble NonInteger;+ typedef adtl::adouble Nested;++ enum {+ IsComplex = 0,+ IsInteger = 0,+ IsSigned = 1,+ RequireInitialization = 1,+ ReadCost = 1,+ AddCost = 3,+ MulCost = 3+ };+};++}++namespace adtl {++inline const adouble& conj(const adouble& x) { return x; }+inline const adouble& real(const adouble& x) { return x; }+inline adouble imag(const adouble&) { return 0.; }+inline adouble abs(const adouble& x) { return fabs(x); }+inline adouble abs2(const adouble& x) { return x*x; }++}++#endif // ADOLCSUPPORT_H+\endcode+++\sa \ref TopicPreprocessorDirectives++*/++}
+ eigen3/doc/Doxyfile.in view
@@ -0,0 +1,1875 @@+# Doxyfile 1.8.1.1++# This file describes the settings to be used by the documentation system+# doxygen (www.doxygen.org) for a project.+#+# All text after a hash (#) is considered a comment and will be ignored.+# The format is:+# TAG = value [value, ...]+# For lists items can also be appended using:+# TAG += value [value, ...]+# Values that contain spaces should be placed between quotes (" ").++#---------------------------------------------------------------------------+# Project related configuration options+#---------------------------------------------------------------------------++# This tag specifies the encoding used for all characters in the config file+# that follow. The default is UTF-8 which is also the encoding used for all+# text before the first occurrence of this tag. Doxygen uses libiconv (or the+# iconv built into libc) for the transcoding. See+# http://www.gnu.org/software/libiconv for the list of possible encodings.++DOXYFILE_ENCODING = UTF-8++# The PROJECT_NAME tag is a single word (or sequence of words) that should+# identify the project. Note that if you do not use Doxywizard you need+# to put quotes around the project name if it contains spaces.++PROJECT_NAME = ${EIGEN_DOXY_PROJECT_NAME}++# The PROJECT_NUMBER tag can be used to enter a project or revision number.+# This could be handy for archiving the generated documentation or+# if some version control system is used.++# EIGEN_VERSION is set in the root CMakeLists.txt++PROJECT_NUMBER = "${EIGEN_VERSION}"++# Using the PROJECT_BRIEF tag one can provide an optional one line description+# for a project that appears at the top of each page and should give viewer+# a quick idea about the purpose of the project. Keep the description short.++PROJECT_BRIEF =++# With the PROJECT_LOGO tag one can specify an logo or icon that is+# included in the documentation. The maximum height of the logo should not+# exceed 55 pixels and the maximum width should not exceed 200 pixels.+# Doxygen will copy the logo to the output directory.++PROJECT_LOGO = "${Eigen_SOURCE_DIR}/doc/Eigen_Silly_Professor_64x64.png"++# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)+# base path where the generated documentation will be put.+# If a relative path is entered, it will be relative to the location+# where doxygen was started. If left blank the current directory will be used.++OUTPUT_DIRECTORY = "${Eigen_BINARY_DIR}/doc${EIGEN_DOXY_OUTPUT_DIRECTORY_SUFFIX}"++# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create+# 4096 sub-directories (in 2 levels) under the output directory of each output+# format and will distribute the generated files over these directories.+# Enabling this option can be useful when feeding doxygen a huge amount of+# source files, where putting all generated files in the same directory would+# otherwise cause performance problems for the file system.++CREATE_SUBDIRS = NO++# The OUTPUT_LANGUAGE tag is used to specify the language in which all+# documentation generated by doxygen is written. Doxygen will use this+# information to generate all constant output in the proper language.+# The default language is English, other supported languages are:+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,+# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German,+# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English+# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian,+# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak,+# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese.++OUTPUT_LANGUAGE = English++# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will+# include brief member descriptions after the members that are listed in+# the file and class documentation (similar to JavaDoc).+# Set to NO to disable this.++BRIEF_MEMBER_DESC = YES++# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend+# the brief description of a member or function before the detailed description.+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the+# brief descriptions will be completely suppressed.++REPEAT_BRIEF = YES++# This tag implements a quasi-intelligent brief description abbreviator+# that is used to form the text in various listings. Each string+# in this list, if found as the leading text of the brief description, will be+# stripped from the text and the result after processing the whole list, is+# used as the annotated text. Otherwise, the brief description is used as-is.+# If left blank, the following values are used ("$name" is automatically+# replaced with the name of the entity): "The $name class" "The $name widget"+# "The $name file" "is" "provides" "specifies" "contains"+# "represents" "a" "an" "the"++ABBREVIATE_BRIEF = "The $name class" \+ "The $name widget" \+ "The $name file" \+ is \+ provides \+ specifies \+ contains \+ represents \+ a \+ an \+ the++# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then+# Doxygen will generate a detailed section even if there is only a brief+# description.++ALWAYS_DETAILED_SEC = NO++# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all+# inherited members of a class in the documentation of that class as if those+# members were ordinary class members. Constructors, destructors and assignment+# operators of the base classes will not be shown.++INLINE_INHERITED_MEMB = YES++# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full+# path before files name in the file list and in the header files. If set+# to NO the shortest path that makes the file name unique will be used.++FULL_PATH_NAMES = NO++# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag+# can be used to strip a user-defined part of the path. Stripping is+# only done if one of the specified strings matches the left-hand part of+# the path. The tag can be used to show relative paths in the file list.+# If left blank the directory from which doxygen is run is used as the+# path to strip.++STRIP_FROM_PATH =++# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of+# the path mentioned in the documentation of a class, which tells+# the reader which header file to include in order to use a class.+# If left blank only the name of the header file containing the class+# definition is used. Otherwise one should specify the include paths that+# are normally passed to the compiler using the -I flag.++STRIP_FROM_INC_PATH =++# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter+# (but less readable) file names. This can be useful if your file system+# doesn't support long names like on DOS, Mac, or CD-ROM.++SHORT_NAMES = NO++# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen+# will interpret the first line (until the first dot) of a JavaDoc-style+# comment as the brief description. If set to NO, the JavaDoc+# comments will behave just like regular Qt-style comments+# (thus requiring an explicit @brief command for a brief description.)++JAVADOC_AUTOBRIEF = NO++# If the QT_AUTOBRIEF tag is set to YES then Doxygen will+# interpret the first line (until the first dot) of a Qt-style+# comment as the brief description. If set to NO, the comments+# will behave just like regular Qt-style comments (thus requiring+# an explicit \brief command for a brief description.)++QT_AUTOBRIEF = NO++# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen+# treat a multi-line C++ special comment block (i.e. a block of //! or ///+# comments) as a brief description. This used to be the default behaviour.+# The new default is to treat a multi-line C++ comment block as a detailed+# description. Set this tag to YES if you prefer the old behaviour instead.++MULTILINE_CPP_IS_BRIEF = NO++# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented+# member inherits the documentation from any documented member that it+# re-implements.++INHERIT_DOCS = YES++# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce+# a new page for each member. If set to NO, the documentation of a member will+# be part of the file/class/namespace that contains it.++SEPARATE_MEMBER_PAGES = NO++# The TAB_SIZE tag can be used to set the number of spaces in a tab.+# Doxygen uses this value to replace tabs by spaces in code fragments.++TAB_SIZE = 8++# This tag can be used to specify a number of aliases that acts+# as commands in the documentation. An alias has the form "name=value".+# For example adding "sideeffect=\par Side Effects:\n" will allow you to+# put the command \sideeffect (or @sideeffect) in the documentation, which+# will result in a user-defined paragraph with heading "Side Effects:".+# You can put \n's in the value part of an alias to insert newlines.++ALIASES = "only_for_vectors=This is only for vectors (either row-vectors or column-vectors), i.e. matrices which are known at compile-time to have either one row or one column." \+ "array_module=This is defined in the %Array module. \code #include <Eigen/Array> \endcode" \+ "cholesky_module=This is defined in the %Cholesky module. \code #include <Eigen/Cholesky> \endcode" \+ "eigenvalues_module=This is defined in the %Eigenvalues module. \code #include <Eigen/Eigenvalues> \endcode" \+ "geometry_module=This is defined in the %Geometry module. \code #include <Eigen/Geometry> \endcode" \+ "householder_module=This is defined in the %Householder module. \code #include <Eigen/Householder> \endcode" \+ "jacobi_module=This is defined in the %Jacobi module. \code #include <Eigen/Jacobi> \endcode" \+ "lu_module=This is defined in the %LU module. \code #include <Eigen/LU> \endcode" \+ "qr_module=This is defined in the %QR module. \code #include <Eigen/QR> \endcode" \+ "svd_module=This is defined in the %SVD module. \code #include <Eigen/SVD> \endcode" \+ "label=\bug" \+ "matrixworld=<a href='#matrixonly' style='color:green;text-decoration: none;'>*</a>" \+ "arrayworld=<a href='#arrayonly' style='color:blue;text-decoration: none;'>*</a>" \+ "note_about_arbitrary_choice_of_solution=If there exists more than one solution, this method will arbitrarily choose one." \+ "note_about_using_kernel_to_study_multiple_solutions=If you need a complete analysis of the space of solutions, take the one solution obtained by this method and add to it elements of the kernel, as determined by kernel()." \+ "note_about_checking_solutions=This method just tries to find as good a solution as possible. If you want to check whether a solution exists or if it is accurate, just call this function to get a result and then compute the error of this result, or use MatrixBase::isApprox() directly, for instance like this: \code bool a_solution_exists = (A*result).isApprox(b, precision); \endcode This method avoids dividing by zero, so that the non-existence of a solution doesn't by itself mean that you'll get \c inf or \c nan values." \+ "note_try_to_help_rvo=This function returns the result by value. In order to make that efficient, it is implemented as just a return statement using a special constructor, hopefully allowing the compiler to perform a RVO (return value optimization)." \+ "nonstableyet=\warning This is not considered to be part of the stable public API yet. Changes may happen in future releases. See \ref Experimental \"Experimental parts of Eigen\""++ALIASES += "eigenAutoToc= "+ALIASES += "eigenManualPage=\defgroup"++# This tag can be used to specify a number of word-keyword mappings (TCL only).+# A mapping has the form "name=value". For example adding+# "class=itcl::class" will allow you to use the command class in the+# itcl::class meaning.++TCL_SUBST =++# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C+# sources only. Doxygen will then generate output that is more tailored for C.+# For instance, some of the names that are used will be different. The list+# of all members will be omitted, etc.++OPTIMIZE_OUTPUT_FOR_C = NO++# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java+# sources only. Doxygen will then generate output that is more tailored for+# Java. For instance, namespaces will be presented as packages, qualified+# scopes will look different, etc.++OPTIMIZE_OUTPUT_JAVA = NO++# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran+# sources only. Doxygen will then generate output that is more tailored for+# Fortran.++OPTIMIZE_FOR_FORTRAN = NO++# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL+# sources. Doxygen will then generate output that is tailored for+# VHDL.++OPTIMIZE_OUTPUT_VHDL = NO++# Doxygen selects the parser to use depending on the extension of the files it+# parses. With this tag you can assign which parser to use for a given extension.+# Doxygen has a built-in mapping, but you can override or extend it using this+# tag. The format is ext=language, where ext is a file extension, and language+# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C,+# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make+# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C+# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions+# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen.++EXTENSION_MAPPING =++# If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all+# comments according to the Markdown format, which allows for more readable+# documentation. See http://daringfireball.net/projects/markdown/ for details.+# The output of markdown processing is further processed by doxygen, so you+# can mix doxygen, HTML, and XML commands with Markdown formatting.+# Disable only in case of backward compatibilities issues.++MARKDOWN_SUPPORT = YES++# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want+# to include (a tag file for) the STL sources as input, then you should+# set this tag to YES in order to let doxygen match functions declarations and+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.+# func(std::string) {}). This also makes the inheritance and collaboration+# diagrams that involve STL classes more complete and accurate.++BUILTIN_STL_SUPPORT = NO++# If you use Microsoft's C++/CLI language, you should set this option to YES to+# enable parsing support.++CPP_CLI_SUPPORT = NO++# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.+# Doxygen will parse them like normal C++ but will assume all classes use public+# instead of private inheritance when no explicit protection keyword is present.++SIP_SUPPORT = NO++# For Microsoft's IDL there are propget and propput attributes to indicate getter+# and setter methods for a property. Setting this option to YES (the default)+# will make doxygen replace the get and set methods by a property in the+# documentation. This will only work if the methods are indeed getting or+# setting a simple type. If this is not the case, or you want to show the+# methods anyway, you should set this option to NO.++IDL_PROPERTY_SUPPORT = YES++# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC+# tag is set to YES, then doxygen will reuse the documentation of the first+# member in the group (if any) for the other members of the group. By default+# all members of a group must be documented explicitly.++DISTRIBUTE_GROUP_DOC = YES++# Set the SUBGROUPING tag to YES (the default) to allow class member groups of+# the same type (for instance a group of public functions) to be put as a+# subgroup of that type (e.g. under the Public Functions section). Set it to+# NO to prevent subgrouping. Alternatively, this can be done per class using+# the \nosubgrouping command.++SUBGROUPING = YES++# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and+# unions are shown inside the group in which they are included (e.g. using+# @ingroup) instead of on a separate page (for HTML and Man pages) or+# section (for LaTeX and RTF).++INLINE_GROUPED_CLASSES = NO++# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and+# unions with only public data fields will be shown inline in the documentation+# of the scope in which they are defined (i.e. file, namespace, or group+# documentation), provided this scope is documented. If set to NO (the default),+# structs, classes, and unions are shown on a separate page (for HTML and Man+# pages) or section (for LaTeX and RTF).++INLINE_SIMPLE_STRUCTS = NO++# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum+# is documented as struct, union, or enum with the name of the typedef. So+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct+# with name TypeT. When disabled the typedef will appear as a member of a file,+# namespace, or class. And the struct will be named TypeS. This can typically+# be useful for C code in case the coding convention dictates that all compound+# types are typedef'ed and only the typedef is referenced, never the tag name.++TYPEDEF_HIDES_STRUCT = NO++# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to+# determine which symbols to keep in memory and which to flush to disk.+# When the cache is full, less often used symbols will be written to disk.+# For small to medium size projects (<1000 input files) the default value is+# probably good enough. For larger projects a too small cache size can cause+# doxygen to be busy swapping symbols to and from disk most of the time+# causing a significant performance penalty.+# If the system has enough physical memory increasing the cache will improve the+# performance by keeping more symbols in memory. Note that the value works on+# a logarithmic scale so increasing the size by one will roughly double the+# memory usage. The cache size is given by this formula:+# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0,+# corresponding to a cache size of 2^16 = 65536 symbols.++# SYMBOL_CACHE_SIZE = 0++# Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be+# set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given+# their name and scope. Since this can be an expensive process and often the+# same symbol appear multiple times in the code, doxygen keeps a cache of+# pre-resolved symbols. If the cache is too small doxygen will become slower.+# If the cache is too large, memory is wasted. The cache size is given by this+# formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0,+# corresponding to a cache size of 2^16 = 65536 symbols.++LOOKUP_CACHE_SIZE = 0++#---------------------------------------------------------------------------+# Build related configuration options+#---------------------------------------------------------------------------++# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in+# documentation are documented, even if no documentation was available.+# Private class members and static file members will be hidden unless+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES++EXTRACT_ALL = NO++# If the EXTRACT_PRIVATE tag is set to YES all private members of a class+# will be included in the documentation.++EXTRACT_PRIVATE = NO++# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal scope will be included in the documentation.++EXTRACT_PACKAGE = NO++# If the EXTRACT_STATIC tag is set to YES all static members of a file+# will be included in the documentation.++EXTRACT_STATIC = NO++# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)+# defined locally in source files will be included in the documentation.+# If set to NO only classes defined in header files are included.++EXTRACT_LOCAL_CLASSES = NO++# This flag is only useful for Objective-C code. When set to YES local+# methods, which are defined in the implementation section but not in+# the interface are included in the documentation.+# If set to NO (the default) only methods in the interface are included.++EXTRACT_LOCAL_METHODS = NO++# If this flag is set to YES, the members of anonymous namespaces will be+# extracted and appear in the documentation as a namespace called+# 'anonymous_namespace{file}', where file will be replaced with the base+# name of the file that contains the anonymous namespace. By default+# anonymous namespaces are hidden.++EXTRACT_ANON_NSPACES = NO++# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all+# undocumented members of documented classes, files or namespaces.+# If set to NO (the default) these members will be included in the+# various overviews, but no documentation section is generated.+# This option has no effect if EXTRACT_ALL is enabled.++HIDE_UNDOC_MEMBERS = YES++# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all+# undocumented classes that are normally visible in the class hierarchy.+# If set to NO (the default) these classes will be included in the various+# overviews. This option has no effect if EXTRACT_ALL is enabled.++HIDE_UNDOC_CLASSES = YES++# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all+# friend (class|struct|union) declarations.+# If set to NO (the default) these declarations will be included in the+# documentation.++HIDE_FRIEND_COMPOUNDS = YES++# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any+# documentation blocks found inside the body of a function.+# If set to NO (the default) these blocks will be appended to the+# function's detailed documentation block.++HIDE_IN_BODY_DOCS = NO++# The INTERNAL_DOCS tag determines if documentation+# that is typed after a \internal command is included. If the tag is set+# to NO (the default) then the documentation will be excluded.+# Set it to YES to include the internal documentation.++INTERNAL_DOCS = NO++# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate+# file names in lower-case letters. If set to YES upper-case letters are also+# allowed. This is useful if you have classes or files whose names only differ+# in case and if your file system supports case sensitive file names. Windows+# and Mac users are advised to set this option to NO.++CASE_SENSE_NAMES = YES++# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen+# will show members with their full class and namespace scopes in the+# documentation. If set to YES the scope will be hidden.++HIDE_SCOPE_NAMES = YES++# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen+# will put a list of the files that are included by a file in the documentation+# of that file.++SHOW_INCLUDE_FILES = NO++# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen+# will list include files with double quotes in the documentation+# rather than with sharp brackets.++FORCE_LOCAL_INCLUDES = NO++# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]+# is inserted in the documentation for inline members.++INLINE_INFO = YES++# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen+# will sort the (detailed) documentation of file and class members+# alphabetically by member name. If set to NO the members will appear in+# declaration order.++SORT_MEMBER_DOCS = YES++# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the+# brief documentation of file, namespace and class members alphabetically+# by member name. If set to NO (the default) the members will appear in+# declaration order.++SORT_BRIEF_DOCS = YES++# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen+# will sort the (brief and detailed) documentation of class members so that+# constructors and destructors are listed first. If set to NO (the default)+# the constructors will appear in the respective orders defined by+# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS.+# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO+# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO.++SORT_MEMBERS_CTORS_1ST = NO++# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the+# hierarchy of group names into alphabetical order. If set to NO (the default)+# the group names will appear in their defined order.++SORT_GROUP_NAMES = NO++# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be+# sorted by fully-qualified names, including namespaces. If set to+# NO (the default), the class list will be sorted only by class name,+# not including the namespace part.+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.+# Note: This option applies only to the class list, not to the+# alphabetical list.++SORT_BY_SCOPE_NAME = NO++# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to+# do proper type resolution of all parameters of a function it will reject a+# match between the prototype and the implementation of a member function even+# if there is only one candidate or it is obvious which candidate to choose+# by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen+# will still accept a match between prototype and implementation in such cases.++STRICT_PROTO_MATCHING = NO++# The GENERATE_TODOLIST tag can be used to enable (YES) or+# disable (NO) the todo list. This list is created by putting \todo+# commands in the documentation.++GENERATE_TODOLIST = NO++# The GENERATE_TESTLIST tag can be used to enable (YES) or+# disable (NO) the test list. This list is created by putting \test+# commands in the documentation.++GENERATE_TESTLIST = NO++# The GENERATE_BUGLIST tag can be used to enable (YES) or+# disable (NO) the bug list. This list is created by putting \bug+# commands in the documentation.++GENERATE_BUGLIST = NO++# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or+# disable (NO) the deprecated list. This list is created by putting+# \deprecated commands in the documentation.++GENERATE_DEPRECATEDLIST= YES++# The ENABLED_SECTIONS tag can be used to enable conditional+# documentation sections, marked by \if sectionname ... \endif.++ENABLED_SECTIONS =++# The MAX_INITIALIZER_LINES tag determines the maximum number of lines+# the initial value of a variable or macro consists of for it to appear in+# the documentation. If the initializer consists of more lines than specified+# here it will be hidden. Use a value of 0 to hide initializers completely.+# The appearance of the initializer of individual variables and macros in the+# documentation can be controlled using \showinitializer or \hideinitializer+# command in the documentation regardless of this setting.++MAX_INITIALIZER_LINES = 0++# Set the SHOW_USED_FILES tag to NO to disable the list of files generated+# at the bottom of the documentation of classes and structs. If set to YES the+# list will mention the files that were used to generate the documentation.++SHOW_USED_FILES = YES++# Set the SHOW_FILES tag to NO to disable the generation of the Files page.+# This will remove the Files entry from the Quick Index and from the+# Folder Tree View (if specified). The default is YES.++SHOW_FILES = YES++# Set the SHOW_NAMESPACES tag to NO to disable the generation of the+# Namespaces page.+# This will remove the Namespaces entry from the Quick Index+# and from the Folder Tree View (if specified). The default is YES.++SHOW_NAMESPACES = NO++# The FILE_VERSION_FILTER tag can be used to specify a program or script that+# doxygen should invoke to get the current version for each file (typically from+# the version control system). Doxygen will invoke the program by executing (via+# popen()) the command <command> <input-file>, where <command> is the value of+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file+# provided by doxygen. Whatever the program writes to standard output+# is used as the file version. See the manual for examples.++FILE_VERSION_FILTER =++# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed+# by doxygen. The layout file controls the global structure of the generated+# output files in an output format independent way. To create the layout file+# that represents doxygen's defaults, run doxygen with the -l option.+# You can optionally specify a file name after the option, if omitted+# DoxygenLayout.xml will be used as the name of the layout file.++LAYOUT_FILE = "${Eigen_BINARY_DIR}/doc${EIGEN_DOXY_OUTPUT_DIRECTORY_SUFFIX}/eigendoxy_layout.xml"++# The CITE_BIB_FILES tag can be used to specify one or more bib files+# containing the references data. This must be a list of .bib files. The+# .bib extension is automatically appended if omitted. Using this command+# requires the bibtex tool to be installed. See also+# http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style+# of the bibliography can be controlled using LATEX_BIB_STYLE. To use this+# feature you need bibtex and perl available in the search path.++CITE_BIB_FILES =++#---------------------------------------------------------------------------+# configuration options related to warning and progress messages+#---------------------------------------------------------------------------++# The QUIET tag can be used to turn on/off the messages that are generated+# by doxygen. Possible values are YES and NO. If left blank NO is used.++QUIET = NO++# The WARNINGS tag can be used to turn on/off the warning messages that are+# generated by doxygen. Possible values are YES and NO. If left blank+# NO is used.++WARNINGS = YES++# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will+# automatically be disabled.++WARN_IF_UNDOCUMENTED = NO++# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for+# potential errors in the documentation, such as not documenting some+# parameters in a documented function, or documenting parameters that+# don't exist or using markup commands wrongly.++WARN_IF_DOC_ERROR = YES++# The WARN_NO_PARAMDOC option can be enabled to get warnings for+# functions that are documented, but have no documentation for their parameters+# or return value. If set to NO (the default) doxygen will only warn about+# wrong or incomplete parameter documentation, but not about the absence of+# documentation.++WARN_NO_PARAMDOC = NO++# The WARN_FORMAT tag determines the format of the warning messages that+# doxygen can produce. The string should contain the $file, $line, and $text+# tags, which will be replaced by the file and line number from which the+# warning originated and the warning text. Optionally the format may contain+# $version, which will be replaced by the version of the file (if it could+# be obtained via FILE_VERSION_FILTER)++WARN_FORMAT = "$file:$line: $text"++# The WARN_LOGFILE tag can be used to specify a file to which warning+# and error messages should be written. If left blank the output is written+# to stderr.++WARN_LOGFILE =++#---------------------------------------------------------------------------+# configuration options related to the input files+#---------------------------------------------------------------------------++# The INPUT tag can be used to specify the files and/or directories that contain+# documented source files. You may enter file names like "myfile.cpp" or+# directories like "/usr/src/myproject". Separate the files or directories+# with spaces.++INPUT = ${EIGEN_DOXY_INPUT}++# This tag can be used to specify the character encoding of the source files+# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is+# also the default input encoding. Doxygen uses libiconv (or the iconv built+# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for+# the list of possible encodings.++INPUT_ENCODING = UTF-8++# If the value of the INPUT tag contains directories, you can use the+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp+# and *.h) to filter out the source-files in the directories. If left+# blank the following patterns are tested:+# *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh+# *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py+# *.f90 *.f *.for *.vhd *.vhdl++FILE_PATTERNS = *++# The RECURSIVE tag can be used to turn specify whether or not subdirectories+# should be searched for input files as well. Possible values are YES and NO.+# If left blank NO is used.++RECURSIVE = YES++# The EXCLUDE tag can be used to specify files and/or directories that should be+# excluded from the INPUT source files. This way you can easily exclude a+# subdirectory from a directory tree whose root is specified with the INPUT tag.+# Note that relative paths are relative to the directory from which doxygen is+# run.++EXCLUDE = "${Eigen_SOURCE_DIR}/Eigen/Eigen2Support" \+ "${Eigen_SOURCE_DIR}/Eigen/src/Eigen2Support" \+ "${Eigen_SOURCE_DIR}/doc/examples" \+ "${Eigen_SOURCE_DIR}/doc/special_examples" \+ "${Eigen_SOURCE_DIR}/doc/snippets" \+ "${Eigen_SOURCE_DIR}/unsupported/doc/examples" \+ "${Eigen_SOURCE_DIR}/unsupported/doc/snippets"++# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or+# directories that are symbolic links (a Unix file system feature) are excluded+# from the input.++EXCLUDE_SYMLINKS = NO++# If the value of the INPUT tag contains directories, you can use the+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude+# certain files from those directories. Note that the wildcards are matched+# against the file with absolute path, so to exclude all test directories+# for example use the pattern */test/*++EXCLUDE_PATTERNS = CMake* \+ *.txt \+ *.sh \+ *.orig \+ *.diff \+ diff \+ *~ \+ *. \+ *.sln \+ *.sdf \+ *.tmp \+ *.vcxproj \+ *.filters \+ *.user \+ *.suo++# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names+# (namespaces, classes, functions, etc.) that should be excluded from the+# output. The symbol name can be a fully qualified name, a word, or if the+# wildcard * is used, a substring. Examples: ANamespace, AClass,+# AClass::ANamespace, ANamespace::*Test++EXCLUDE_SYMBOLS = internal::* \+ Flagged* \+ *InnerIterator* \+ DenseStorage<* \+ ++# The EXAMPLE_PATH tag can be used to specify one or more files or+# directories that contain example code fragments that are included (see+# the \include command).++EXAMPLE_PATH = "${Eigen_SOURCE_DIR}/doc/snippets" \+ "${Eigen_BINARY_DIR}/doc/snippets" \+ "${Eigen_SOURCE_DIR}/doc/examples" \+ "${Eigen_BINARY_DIR}/doc/examples" \+ "${Eigen_SOURCE_DIR}/doc/special_examples" \+ "${Eigen_BINARY_DIR}/doc/special_examples" \+ "${Eigen_SOURCE_DIR}/unsupported/doc/snippets" \+ "${Eigen_BINARY_DIR}/unsupported/doc/snippets" \+ "${Eigen_SOURCE_DIR}/unsupported/doc/examples" \+ "${Eigen_BINARY_DIR}/unsupported/doc/examples"++# If the value of the EXAMPLE_PATH tag contains directories, you can use the+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp+# and *.h) to filter out the source-files in the directories. If left+# blank all files are included.++EXAMPLE_PATTERNS = *++# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be+# searched for input files to be used with the \include or \dontinclude+# commands irrespective of the value of the RECURSIVE tag.+# Possible values are YES and NO. If left blank NO is used.++EXAMPLE_RECURSIVE = NO++# The IMAGE_PATH tag can be used to specify one or more files or+# directories that contain image that are included in the documentation (see+# the \image command).++IMAGE_PATH =++# The INPUT_FILTER tag can be used to specify a program that doxygen should+# invoke to filter for each input file. Doxygen will invoke the filter program+# by executing (via popen()) the command <filter> <input-file>, where <filter>+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an+# input file. Doxygen will then use the output that the filter program writes+# to standard output.+# If FILTER_PATTERNS is specified, this tag will be+# ignored.++INPUT_FILTER =++# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern+# basis.+# Doxygen will compare the file name with each pattern and apply the+# filter if there is a match.+# The filters are a list of the form:+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further+# info on how filters are used. If FILTER_PATTERNS is empty or if+# non of the patterns match the file name, INPUT_FILTER is applied.++FILTER_PATTERNS =++# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using+# INPUT_FILTER) will be used to filter the input files when producing source+# files to browse (i.e. when SOURCE_BROWSER is set to YES).++FILTER_SOURCE_FILES = NO++# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file+# pattern. A pattern will override the setting for FILTER_PATTERN (if any)+# and it is also possible to disable source filtering for a specific pattern+# using *.ext= (so without naming a filter). This option only has effect when+# FILTER_SOURCE_FILES is enabled.++FILTER_SOURCE_PATTERNS =++#---------------------------------------------------------------------------+# configuration options related to source browsing+#---------------------------------------------------------------------------++# If the SOURCE_BROWSER tag is set to YES then a list of source files will+# be generated. Documented entities will be cross-referenced with these sources.+# Note: To get rid of all source code in the generated output, make sure also+# VERBATIM_HEADERS is set to NO.++SOURCE_BROWSER = NO++# Setting the INLINE_SOURCES tag to YES will include the body+# of functions and classes directly in the documentation.++INLINE_SOURCES = NO++# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct+# doxygen to hide any special comment blocks from generated source code+# fragments. Normal C, C++ and Fortran comments will always remain visible.++STRIP_CODE_COMMENTS = YES++# If the REFERENCED_BY_RELATION tag is set to YES+# then for each documented function all documented+# functions referencing it will be listed.++REFERENCED_BY_RELATION = YES++# If the REFERENCES_RELATION tag is set to YES+# then for each documented function all documented entities+# called/used by that function will be listed.++REFERENCES_RELATION = YES++# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will+# link to the source code.+# Otherwise they will link to the documentation.++REFERENCES_LINK_SOURCE = YES++# If the USE_HTAGS tag is set to YES then the references to source code+# will point to the HTML generated by the htags(1) tool instead of doxygen+# built-in source browser. The htags tool is part of GNU's global source+# tagging system (see http://www.gnu.org/software/global/global.html). You+# will need version 4.8.6 or higher.++USE_HTAGS = NO++# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen+# will generate a verbatim copy of the header file for each class for+# which an include is specified. Set to NO to disable this.++VERBATIM_HEADERS = YES++#---------------------------------------------------------------------------+# configuration options related to the alphabetical class index+#---------------------------------------------------------------------------++# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index+# of all compounds will be generated. Enable this if the project+# contains a lot of classes, structs, unions or interfaces.++ALPHABETICAL_INDEX = NO++# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns+# in which this list will be split (can be a number in the range [1..20])++COLS_IN_ALPHA_INDEX = 5++# In case all classes in a project start with a common prefix, all+# classes will be put under the same header in the alphabetical index.+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that+# should be ignored while generating the index headers.++IGNORE_PREFIX =++#---------------------------------------------------------------------------+# configuration options related to the HTML output+#---------------------------------------------------------------------------++# If the GENERATE_HTML tag is set to YES (the default) Doxygen will+# generate HTML output.++GENERATE_HTML = YES++# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.+# If a relative path is entered the value of OUTPUT_DIRECTORY will be+# put in front of it. If left blank `html' will be used as the default path.++HTML_OUTPUT = "${Eigen_BINARY_DIR}/doc/html${EIGEN_DOXY_OUTPUT_DIRECTORY_SUFFIX}"++# The HTML_FILE_EXTENSION tag can be used to specify the file extension for+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank+# doxygen will generate files with .html extension.++HTML_FILE_EXTENSION = .html++# The HTML_HEADER tag can be used to specify a personal HTML header for+# each generated HTML page. If it is left blank doxygen will generate a+# standard header. Note that when using a custom header you are responsible+# for the proper inclusion of any scripts and style sheets that doxygen+# needs, which is dependent on the configuration options used.+# It is advised to generate a default header using "doxygen -w html+# header.html footer.html stylesheet.css YourConfigFile" and then modify+# that header. Note that the header is subject to change so you typically+# have to redo this when upgrading to a newer version of doxygen or when+# changing the value of configuration settings such as GENERATE_TREEVIEW!++HTML_HEADER = "${Eigen_BINARY_DIR}/doc/eigendoxy_header.html"++# The HTML_FOOTER tag can be used to specify a personal HTML footer for+# each generated HTML page. If it is left blank doxygen will generate a+# standard footer.++HTML_FOOTER = "${Eigen_BINARY_DIR}/doc/eigendoxy_footer.html"++# The HTML_STYLESHEET tag can be used to specify a user-defined cascading+# style sheet that is used by each HTML page. It can be used to+# fine-tune the look of the HTML output. If the tag is left blank doxygen+# will generate a default style sheet. Note that doxygen will try to copy+# the style sheet file to the HTML output directory, so don't put your own+# style sheet in the HTML output directory as well, or it will be erased!++HTML_STYLESHEET = ++# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or+# other source files which should be copied to the HTML output directory. Note+# that these files will be copied to the base HTML output directory. Use the+# $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these+# files. In the HTML_STYLESHEET file, use the file name only. Also note that+# the files will be copied as-is; there are no commands or markers available.++HTML_EXTRA_FILES = "${Eigen_SOURCE_DIR}/doc/eigendoxy.css"++# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output.+# Doxygen will adjust the colors in the style sheet and background images+# according to this color. Hue is specified as an angle on a colorwheel,+# see http://en.wikipedia.org/wiki/Hue for more information.+# For instance the value 0 represents red, 60 is yellow, 120 is green,+# 180 is cyan, 240 is blue, 300 purple, and 360 is red again.+# The allowed range is 0 to 359.+# The default is 220.++HTML_COLORSTYLE_HUE = ${EIGEN_DOXY_HTML_COLORSTYLE_HUE}++# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of+# the colors in the HTML output. For a value of 0 the output will use+# grayscales only. A value of 255 will produce the most vivid colors.++HTML_COLORSTYLE_SAT = 100++# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to+# the luminance component of the colors in the HTML output. Values below+# 100 gradually make the output lighter, whereas values above 100 make+# the output darker. The value divided by 100 is the actual gamma applied,+# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2,+# and 100 does not change the gamma.++HTML_COLORSTYLE_GAMMA = 80++# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML+# page will contain the date and time when the page was generated. Setting+# this to NO can help when comparing the output of multiple runs.++HTML_TIMESTAMP = YES++# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML+# documentation will contain sections that can be hidden and shown after the+# page has loaded.++HTML_DYNAMIC_SECTIONS = YES++# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of+# entries shown in the various tree structured indices initially; the user+# can expand and collapse entries dynamically later on. Doxygen will expand+# the tree to such a level that at most the specified number of entries are+# visible (unless a fully collapsed tree already exceeds this amount).+# So setting the number of entries 1 will produce a full collapsed tree by+# default. 0 is a special value representing an infinite number of entries+# and will result in a full expanded tree by default.++HTML_INDEX_NUM_ENTRIES = 100++# If the GENERATE_DOCSET tag is set to YES, additional index files+# will be generated that can be used as input for Apple's Xcode 3+# integrated development environment, introduced with OSX 10.5 (Leopard).+# To create a documentation set, doxygen will generate a Makefile in the+# HTML output directory. Running make will produce the docset in that+# directory and running "make install" will install the docset in+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find+# it at startup.+# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html+# for more information.++GENERATE_DOCSET = NO++# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the+# feed. A documentation feed provides an umbrella under which multiple+# documentation sets from a single provider (such as a company or product suite)+# can be grouped.++DOCSET_FEEDNAME = "Doxygen generated docs"++# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that+# should uniquely identify the documentation set bundle. This should be a+# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen+# will append .docset to the name.++DOCSET_BUNDLE_ID = org.doxygen.Project++# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify+# the documentation publisher. This should be a reverse domain-name style+# string, e.g. com.mycompany.MyDocSet.documentation.++DOCSET_PUBLISHER_ID = org.doxygen.Publisher++# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher.++DOCSET_PUBLISHER_NAME = Publisher++# If the GENERATE_HTMLHELP tag is set to YES, additional index files+# will be generated that can be used as input for tools like the+# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)+# of the generated HTML documentation.++GENERATE_HTMLHELP = NO++# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can+# be used to specify the file name of the resulting .chm file. You+# can add a path in front of the file if the result should not be+# written to the html output directory.++CHM_FILE =++# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can+# be used to specify the location (absolute path including file name) of+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run+# the HTML help compiler on the generated index.hhp.++HHC_LOCATION =++# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag+# controls if a separate .chi index file is generated (YES) or that+# it should be included in the master .chm file (NO).++GENERATE_CHI = NO++# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING+# is used to encode HtmlHelp index (hhk), content (hhc) and project file+# content.++CHM_INDEX_ENCODING =++# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag+# controls whether a binary table of contents is generated (YES) or a+# normal table of contents (NO) in the .chm file.++BINARY_TOC = NO++# The TOC_EXPAND flag can be set to YES to add extra items for group members+# to the contents of the HTML help documentation and to the tree view.++TOC_EXPAND = NO++# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated+# that can be used as input for Qt's qhelpgenerator to generate a+# Qt Compressed Help (.qch) of the generated HTML documentation.++GENERATE_QHP = NO++# If the QHG_LOCATION tag is specified, the QCH_FILE tag can+# be used to specify the file name of the resulting .qch file.+# The path specified is relative to the HTML output folder.++QCH_FILE =++# The QHP_NAMESPACE tag specifies the namespace to use when generating+# Qt Help Project output. For more information please see+# http://doc.trolltech.com/qthelpproject.html#namespace++QHP_NAMESPACE = org.doxygen.Project++# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating+# Qt Help Project output. For more information please see+# http://doc.trolltech.com/qthelpproject.html#virtual-folders++QHP_VIRTUAL_FOLDER = doc++# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to+# add. For more information please see+# http://doc.trolltech.com/qthelpproject.html#custom-filters++QHP_CUST_FILTER_NAME =++# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the+# custom filter to add. For more information please see+# <a href="http://doc.trolltech.com/qthelpproject.html#custom-filters">+# Qt Help Project / Custom Filters</a>.++QHP_CUST_FILTER_ATTRS =++# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this+# project's+# filter section matches.+# <a href="http://doc.trolltech.com/qthelpproject.html#filter-attributes">+# Qt Help Project / Filter Attributes</a>.++QHP_SECT_FILTER_ATTRS =++# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can+# be used to specify the location of Qt's qhelpgenerator.+# If non-empty doxygen will try to run qhelpgenerator on the generated+# .qhp file.++QHG_LOCATION =++# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files+# will be generated, which together with the HTML files, form an Eclipse help+# plugin. To install this plugin and make it available under the help contents+# menu in Eclipse, the contents of the directory containing the HTML and XML+# files needs to be copied into the plugins directory of eclipse. The name of+# the directory within the plugins directory should be the same as+# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before+# the help appears.++GENERATE_ECLIPSEHELP = NO++# A unique identifier for the eclipse help plugin. When installing the plugin+# the directory name containing the HTML and XML files should also have+# this name.++ECLIPSE_DOC_ID = org.doxygen.Project++# The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs)+# at top of each HTML page. The value NO (the default) enables the index and+# the value YES disables it. Since the tabs have the same information as the+# navigation tree you can set this option to NO if you already set+# GENERATE_TREEVIEW to YES.++DISABLE_INDEX = YES++# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index+# structure should be generated to display hierarchical information.+# If the tag value is set to YES, a side panel will be generated+# containing a tree-like index structure (just like the one that+# is generated for HTML Help). For this to work a browser that supports+# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser).+# Windows users are probably better off using the HTML help feature.+# Since the tree basically has the same information as the tab index you+# could consider to set DISABLE_INDEX to NO when enabling this option.++GENERATE_TREEVIEW = YES++# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values+# (range [0,1..20]) that doxygen will group on one line in the generated HTML+# documentation. Note that a value of 0 will completely suppress the enum+# values from appearing in the overview section.++ENUM_VALUES_PER_LINE = 1++# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be+# used to set the initial width (in pixels) of the frame in which the tree+# is shown.++TREEVIEW_WIDTH = 250++# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open+# links to external symbols imported via tag files in a separate window.++EXT_LINKS_IN_WINDOW = NO++# Use this tag to change the font size of Latex formulas included+# as images in the HTML documentation. The default is 10. Note that+# when you change the font size after a successful doxygen run you need+# to manually remove any form_*.png images from the HTML output directory+# to force them to be regenerated.++FORMULA_FONTSIZE = 12++# Use the FORMULA_TRANPARENT tag to determine whether or not the images+# generated for formulas are transparent PNGs. Transparent PNGs are+# not supported properly for IE 6.0, but are supported on all modern browsers.+# Note that when changing this option you need to delete any form_*.png files+# in the HTML output before the changes have effect.++FORMULA_TRANSPARENT = YES++# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax+# (see http://www.mathjax.org) which uses client side Javascript for the+# rendering instead of using prerendered bitmaps. Use this if you do not+# have LaTeX installed or if you want to formulas look prettier in the HTML+# output. When enabled you may also need to install MathJax separately and+# configure the path to it using the MATHJAX_RELPATH option.++USE_MATHJAX = NO++# When MathJax is enabled you need to specify the location relative to the+# HTML output directory using the MATHJAX_RELPATH option. The destination+# directory should contain the MathJax.js script. For instance, if the mathjax+# directory is located at the same level as the HTML output directory, then+# MATHJAX_RELPATH should be ../mathjax. The default value points to+# the MathJax Content Delivery Network so you can quickly see the result without+# installing MathJax.+# However, it is strongly recommended to install a local+# copy of MathJax from http://www.mathjax.org before deployment.++MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest++# The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension+# names that should be enabled during MathJax rendering.++MATHJAX_EXTENSIONS =++# When the SEARCHENGINE tag is enabled doxygen will generate a search box+# for the HTML output. The underlying search engine uses javascript+# and DHTML and should work on any modern browser. Note that when using+# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets+# (GENERATE_DOCSET) there is already a search function so this one should+# typically be disabled. For large projects the javascript based search engine+# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution.++SEARCHENGINE = YES++# When the SERVER_BASED_SEARCH tag is enabled the search engine will be+# implemented using a PHP enabled web server instead of at the web client+# using Javascript. Doxygen will generate the search PHP script and index+# file to put on the web server. The advantage of the server+# based approach is that it scales better to large projects and allows+# full text search. The disadvantages are that it is more difficult to setup+# and does not have live searching capabilities.++SERVER_BASED_SEARCH = NO++#---------------------------------------------------------------------------+# configuration options related to the LaTeX output+#---------------------------------------------------------------------------++# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will+# generate Latex output.++GENERATE_LATEX = NO++# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.+# If a relative path is entered the value of OUTPUT_DIRECTORY will be+# put in front of it. If left blank `latex' will be used as the default path.++LATEX_OUTPUT = latex++# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be+# invoked. If left blank `latex' will be used as the default command name.+# Note that when enabling USE_PDFLATEX this option is only used for+# generating bitmaps for formulas in the HTML output, but not in the+# Makefile that is written to the output directory.++LATEX_CMD_NAME = latex++# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to+# generate index for LaTeX. If left blank `makeindex' will be used as the+# default command name.++MAKEINDEX_CMD_NAME = makeindex++# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact+# LaTeX documents. This may be useful for small projects and may help to+# save some trees in general.++COMPACT_LATEX = NO++# The PAPER_TYPE tag can be used to set the paper type that is used+# by the printer. Possible values are: a4, letter, legal and+# executive. If left blank a4wide will be used.++PAPER_TYPE = a4wide++# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX+# packages that should be included in the LaTeX output.++EXTRA_PACKAGES = amssymb \+ amsmath++# The LATEX_HEADER tag can be used to specify a personal LaTeX header for+# the generated latex document. The header should contain everything until+# the first chapter. If it is left blank doxygen will generate a+# standard header. Notice: only use this tag if you know what you are doing!++LATEX_HEADER =++# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for+# the generated latex document. The footer should contain everything after+# the last chapter. If it is left blank doxygen will generate a+# standard footer. Notice: only use this tag if you know what you are doing!++LATEX_FOOTER =++# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated+# is prepared for conversion to pdf (using ps2pdf). The pdf file will+# contain links (just like the HTML output) instead of page references+# This makes the output suitable for online browsing using a pdf viewer.++PDF_HYPERLINKS = NO++# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of+# plain latex in the generated Makefile. Set this option to YES to get a+# higher quality PDF documentation.++USE_PDFLATEX = NO++# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.+# command to the generated LaTeX files. This will instruct LaTeX to keep+# running if errors occur, instead of asking the user for help.+# This option is also used when generating formulas in HTML.++LATEX_BATCHMODE = NO++# If LATEX_HIDE_INDICES is set to YES then doxygen will not+# include the index chapters (such as File Index, Compound Index, etc.)+# in the output.++LATEX_HIDE_INDICES = NO++# If LATEX_SOURCE_CODE is set to YES then doxygen will include+# source code with syntax highlighting in the LaTeX output.+# Note that which sources are shown also depends on other settings+# such as SOURCE_BROWSER.++LATEX_SOURCE_CODE = NO++# The LATEX_BIB_STYLE tag can be used to specify the style to use for the+# bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See+# http://en.wikipedia.org/wiki/BibTeX for more info.++LATEX_BIB_STYLE = plain++#---------------------------------------------------------------------------+# configuration options related to the RTF output+#---------------------------------------------------------------------------++# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output+# The RTF output is optimized for Word 97 and may not look very pretty with+# other RTF readers or editors.++GENERATE_RTF = NO++# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.+# If a relative path is entered the value of OUTPUT_DIRECTORY will be+# put in front of it. If left blank `rtf' will be used as the default path.++RTF_OUTPUT = rtf++# If the COMPACT_RTF tag is set to YES Doxygen generates more compact+# RTF documents. This may be useful for small projects and may help to+# save some trees in general.++COMPACT_RTF = NO++# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated+# will contain hyperlink fields. The RTF file will+# contain links (just like the HTML output) instead of page references.+# This makes the output suitable for online browsing using WORD or other+# programs which support those fields.+# Note: wordpad (write) and others do not support links.++RTF_HYPERLINKS = NO++# Load style sheet definitions from file. Syntax is similar to doxygen's+# config file, i.e. a series of assignments. You only have to provide+# replacements, missing definitions are set to their default value.++RTF_STYLESHEET_FILE =++# Set optional variables used in the generation of an rtf document.+# Syntax is similar to doxygen's config file.++RTF_EXTENSIONS_FILE =++#---------------------------------------------------------------------------+# configuration options related to the man page output+#---------------------------------------------------------------------------++# If the GENERATE_MAN tag is set to YES (the default) Doxygen will+# generate man pages++GENERATE_MAN = NO++# The MAN_OUTPUT tag is used to specify where the man pages will be put.+# If a relative path is entered the value of OUTPUT_DIRECTORY will be+# put in front of it. If left blank `man' will be used as the default path.++MAN_OUTPUT = man++# The MAN_EXTENSION tag determines the extension that is added to+# the generated man pages (default is the subroutine's section .3)++MAN_EXTENSION = .3++# If the MAN_LINKS tag is set to YES and Doxygen generates man output,+# then it will generate one additional man file for each entity+# documented in the real man page(s). These additional files+# only source the real man page, but without them the man command+# would be unable to find the correct page. The default is NO.++MAN_LINKS = NO++#---------------------------------------------------------------------------+# configuration options related to the XML output+#---------------------------------------------------------------------------++# If the GENERATE_XML tag is set to YES Doxygen will+# generate an XML file that captures the structure of+# the code including all documentation.++GENERATE_XML = NO++# The XML_OUTPUT tag is used to specify where the XML pages will be put.+# If a relative path is entered the value of OUTPUT_DIRECTORY will be+# put in front of it. If left blank `xml' will be used as the default path.++XML_OUTPUT = xml++# The XML_SCHEMA tag can be used to specify an XML schema,+# which can be used by a validating XML parser to check the+# syntax of the XML files.++# XML_SCHEMA =++# The XML_DTD tag can be used to specify an XML DTD,+# which can be used by a validating XML parser to check the+# syntax of the XML files.++# XML_DTD =++# If the XML_PROGRAMLISTING tag is set to YES Doxygen will+# dump the program listings (including syntax highlighting+# and cross-referencing information) to the XML output. Note that+# enabling this will significantly increase the size of the XML output.++XML_PROGRAMLISTING = YES++#---------------------------------------------------------------------------+# configuration options for the AutoGen Definitions output+#---------------------------------------------------------------------------++# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will+# generate an AutoGen Definitions (see autogen.sf.net) file+# that captures the structure of the code including all+# documentation. Note that this feature is still experimental+# and incomplete at the moment.++GENERATE_AUTOGEN_DEF = NO++#---------------------------------------------------------------------------+# configuration options related to the Perl module output+#---------------------------------------------------------------------------++# If the GENERATE_PERLMOD tag is set to YES Doxygen will+# generate a Perl module file that captures the structure of+# the code including all documentation. Note that this+# feature is still experimental and incomplete at the+# moment.++GENERATE_PERLMOD = NO++# If the PERLMOD_LATEX tag is set to YES Doxygen will generate+# the necessary Makefile rules, Perl scripts and LaTeX code to be able+# to generate PDF and DVI output from the Perl module output.++PERLMOD_LATEX = NO++# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be+# nicely formatted so it can be parsed by a human reader.+# This is useful+# if you want to understand what is going on.+# On the other hand, if this+# tag is set to NO the size of the Perl module output will be much smaller+# and Perl will parse it just the same.++PERLMOD_PRETTY = YES++# The names of the make variables in the generated doxyrules.make file+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.+# This is useful so different doxyrules.make files included by the same+# Makefile don't overwrite each other's variables.++PERLMOD_MAKEVAR_PREFIX =++#---------------------------------------------------------------------------+# Configuration options related to the preprocessor+#---------------------------------------------------------------------------++# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will+# evaluate all C-preprocessor directives found in the sources and include+# files.++ENABLE_PREPROCESSING = YES++# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro+# names in the source code. If set to NO (the default) only conditional+# compilation will be performed. Macro expansion can be done in a controlled+# way by setting EXPAND_ONLY_PREDEF to YES.++MACRO_EXPANSION = YES++# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES+# then the macro expansion is limited to the macros specified with the+# PREDEFINED and EXPAND_AS_DEFINED tags.++EXPAND_ONLY_PREDEF = YES++# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files+# pointed to by INCLUDE_PATH will be searched when a #include is found.++SEARCH_INCLUDES = YES++# The INCLUDE_PATH tag can be used to specify one or more directories that+# contain include files that are not input files but should be processed by+# the preprocessor.++INCLUDE_PATH = "${Eigen_SOURCE_DIR}/Eigen/src/plugins"++# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard+# patterns (like *.h and *.hpp) to filter out the header-files in the+# directories. If left blank, the patterns specified with FILE_PATTERNS will+# be used.++INCLUDE_FILE_PATTERNS =++# The PREDEFINED tag can be used to specify one or more macro names that+# are defined before the preprocessor is started (similar to the -D option of+# gcc). The argument of the tag is a list of macros of the form: name+# or name=definition (no spaces). If the definition and the = are+# omitted =1 is assumed. To prevent a macro definition from being+# undefined via #undef or recursively expanded use the := operator+# instead of the = operator.++PREDEFINED = EIGEN_EMPTY_STRUCT \+ EIGEN_PARSED_BY_DOXYGEN \+ EIGEN_VECTORIZE \+ EIGEN_QT_SUPPORT \+ EIGEN_STRONG_INLINE=inline \+ "EIGEN2_SUPPORT_STAGE=99" \+ "EIGEN_MAKE_CWISE_BINARY_OP(METHOD,FUNCTOR)=template<typename OtherDerived> const CwiseBinaryOp<FUNCTOR<Scalar>, const Derived, const OtherDerived> METHOD(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const;" \+ "EIGEN_CWISE_PRODUCT_RETURN_TYPE(LHS,RHS)=CwiseBinaryOp<internal::scalar_product_op<typename LHS::Scalar, typename RHS::Scalar >, const LHS, const RHS>"++# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then+# this tag can be used to specify a list of macro names that should be expanded.+# The macro definition that is found in the sources will be used.+# Use the PREDEFINED tag if you want to use a different macro definition that+# overrules the definition found in the source code.++EXPAND_AS_DEFINED = EIGEN_MAKE_TYPEDEFS \+ EIGEN_MAKE_FIXED_TYPEDEFS \+ EIGEN_MAKE_TYPEDEFS_ALL_SIZES \+ EIGEN_CWISE_UNOP_RETURN_TYPE \+ EIGEN_CWISE_BINOP_RETURN_TYPE \+ EIGEN_CURRENT_STORAGE_BASE_CLASS \+ EIGEN_MATHFUNC_IMPL \+ _EIGEN_GENERIC_PUBLIC_INTERFACE \+ EIGEN2_SUPPORT++# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then+# doxygen's preprocessor will remove all references to function-like macros+# that are alone on a line, have an all uppercase name, and do not end with a+# semicolon, because these will confuse the parser if not removed.++SKIP_FUNCTION_MACROS = YES++#---------------------------------------------------------------------------+# Configuration::additions related to external references+#---------------------------------------------------------------------------++# The TAGFILES option can be used to specify one or more tagfiles. For each+# tag file the location of the external documentation should be added. The+# format of a tag file without this location is as follows:+#+# TAGFILES = file1 file2 ...+# Adding location for the tag files is done as follows:+#+# TAGFILES = file1=loc1 "file2 = loc2" ...+# where "loc1" and "loc2" can be relative or absolute paths+# or URLs. Note that each tag file must have a unique name (where the name does+# NOT include the path). If a tag file is not located in the directory in which+# doxygen is run, you must also specify the path to the tagfile here.++TAGFILES = ${EIGEN_DOXY_TAGFILES}+# "${Eigen_BINARY_DIR}/doc/eigen-unsupported.doxytags =unsupported"++# When a file name is specified after GENERATE_TAGFILE, doxygen will create+# a tag file that is based on the input files it reads.++GENERATE_TAGFILE = "${Eigen_BINARY_DIR}/doc/${EIGEN_DOXY_PROJECT_NAME}.doxytags"++# If the ALLEXTERNALS tag is set to YES all external classes will be listed+# in the class index. If set to NO only the inherited external classes+# will be listed.++ALLEXTERNALS = NO++# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed+# in the modules index. If set to NO, only the current project's groups will+# be listed.++EXTERNAL_GROUPS = YES++# The PERL_PATH should be the absolute path and name of the perl script+# interpreter (i.e. the result of `which perl').++PERL_PATH = /usr/bin/perl++#---------------------------------------------------------------------------+# Configuration options related to the dot tool+#---------------------------------------------------------------------------++# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base+# or super classes. Setting the tag to NO turns the diagrams off. Note that+# this option also works with HAVE_DOT disabled, but it is recommended to+# install and use dot, since it yields more powerful graphs.++CLASS_DIAGRAMS = YES++# You can define message sequence charts within doxygen comments using the \msc+# command. Doxygen will then run the mscgen tool (see+# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the+# documentation. The MSCGEN_PATH tag allows you to specify the directory where+# the mscgen tool resides. If left empty the tool is assumed to be found in the+# default search path.++MSCGEN_PATH =++# If set to YES, the inheritance and collaboration graphs will hide+# inheritance and usage relations if the target is undocumented+# or is not a class.++HIDE_UNDOC_RELATIONS = NO++# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is+# available from the path. This tool is part of Graphviz, a graph visualization+# toolkit from AT&T and Lucent Bell Labs. The other options in this section+# have no effect if this option is set to NO (the default)++HAVE_DOT = YES++# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is+# allowed to run in parallel. When set to 0 (the default) doxygen will+# base this on the number of processors available in the system. You can set it+# explicitly to a value larger than 0 to get control over the balance+# between CPU load and processing speed.++DOT_NUM_THREADS = 0++# By default doxygen will use the Helvetica font for all dot files that+# doxygen generates. When you want a differently looking font you can specify+# the font name using DOT_FONTNAME. You need to make sure dot is able to find+# the font, which can be done by putting it in a standard location or by setting+# the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the+# directory containing the font.++DOT_FONTNAME = ++# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs.+# The default size is 10pt.++DOT_FONTSIZE = 10++# By default doxygen will tell dot to use the Helvetica font.+# If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to+# set the path where dot can find it.++DOT_FONTPATH =++# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen+# will generate a graph for each documented class showing the direct and+# indirect inheritance relations. Setting this tag to YES will force the+# CLASS_DIAGRAMS tag to NO.++CLASS_GRAPH = YES++# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen+# will generate a graph for each documented class showing the direct and+# indirect implementation dependencies (inheritance, containment, and+# class references variables) of the class with other documented classes.++COLLABORATION_GRAPH = NO++# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen+# will generate a graph for groups, showing the direct groups dependencies++GROUP_GRAPHS = NO++# If the UML_LOOK tag is set to YES doxygen will generate inheritance and+# collaboration diagrams in a style similar to the OMG's Unified Modeling+# Language.++UML_LOOK = YES++# If the UML_LOOK tag is enabled, the fields and methods are shown inside+# the class node. If there are many fields or methods and many nodes the+# graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS+# threshold limits the number of items for each type to make the size more+# managable. Set this to 0 for no limit. Note that the threshold may be+# exceeded by 50% before the limit is enforced.++UML_LIMIT_NUM_FIELDS = 10++# If set to YES, the inheritance and collaboration graphs will show the+# relations between templates and their instances.++TEMPLATE_RELATIONS = NO++# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT+# tags are set to YES then doxygen will generate a graph for each documented+# file showing the direct and indirect include dependencies of the file with+# other documented files.++INCLUDE_GRAPH = NO++# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each+# documented header file showing the documented files that directly or+# indirectly include this file.++INCLUDED_BY_GRAPH = NO++# If the CALL_GRAPH and HAVE_DOT options are set to YES then+# doxygen will generate a call dependency graph for every global function+# or class method. Note that enabling this option will significantly increase+# the time of a run. So in most cases it will be better to enable call graphs+# for selected functions only using the \callgraph command.++CALL_GRAPH = NO++# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then+# doxygen will generate a caller dependency graph for every global function+# or class method. Note that enabling this option will significantly increase+# the time of a run. So in most cases it will be better to enable caller+# graphs for selected functions only using the \callergraph command.++CALLER_GRAPH = NO++# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen+# will generate a graphical hierarchy of all classes instead of a textual one.++GRAPHICAL_HIERARCHY = NO++# If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES+# then doxygen will show the dependencies a directory has on other directories+# in a graphical way. The dependency relations are determined by the #include+# relations between the files in the directories.++DIRECTORY_GRAPH = NO++# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images+# generated by dot. Possible values are svg, png, jpg, or gif.+# If left blank png will be used. If you choose svg you need to set+# HTML_FILE_EXTENSION to xhtml in order to make the SVG files+# visible in IE 9+ (other browsers do not have this requirement).++DOT_IMAGE_FORMAT = png++# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to+# enable generation of interactive SVG images that allow zooming and panning.+# Note that this requires a modern browser other than Internet Explorer.+# Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you+# need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files+# visible. Older versions of IE do not have SVG support.++INTERACTIVE_SVG = NO++# The tag DOT_PATH can be used to specify the path where the dot tool can be+# found. If left blank, it is assumed the dot tool can be found in the path.++DOT_PATH =++# The DOTFILE_DIRS tag can be used to specify one or more directories that+# contain dot files that are included in the documentation (see the+# \dotfile command).++DOTFILE_DIRS =++# The MSCFILE_DIRS tag can be used to specify one or more directories that+# contain msc files that are included in the documentation (see the+# \mscfile command).++MSCFILE_DIRS =++# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of+# nodes that will be shown in the graph. If the number of nodes in a graph+# becomes larger than this value, doxygen will truncate the graph, which is+# visualized by representing a node as a red box. Note that doxygen if the+# number of direct children of the root node in a graph is already larger than+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.++DOT_GRAPH_MAX_NODES = 50++# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the+# graphs generated by dot. A depth value of 3 means that only nodes reachable+# from the root by following a path via at most 3 edges will be shown. Nodes+# that lay further from the root node will be omitted. Note that setting this+# option to 1 or 2 may greatly reduce the computation time needed for large+# code bases. Also note that the size of a graph can be further restricted by+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.++MAX_DOT_GRAPH_DEPTH = 0++# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent+# background. This is disabled by default, because dot on Windows does not+# seem to support this out of the box. Warning: Depending on the platform used,+# enabling this option may lead to badly anti-aliased labels on the edges of+# a graph (i.e. they become hard to read).++DOT_TRANSPARENT = NO++# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output+# files in one run (i.e. multiple -o and -T options on the command line). This+# makes dot run faster, but since only newer versions of dot (>1.8.10)+# support this, this feature is disabled by default.++DOT_MULTI_TARGETS = NO++# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will+# generate a legend page explaining the meaning of the various boxes and+# arrows in the dot generated graphs.++GENERATE_LEGEND = YES++# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will+# remove the intermediate dot files that are used to generate+# the various graphs.++DOT_CLEANUP = YES
+ eigen3/doc/Eigen_Silly_Professor_64x64.png view
binary file changed (absent → 8355 bytes)
+ eigen3/doc/FixedSizeVectorizable.dox view
@@ -0,0 +1,38 @@+namespace Eigen {++/** \eigenManualPage TopicFixedSizeVectorizable Fixed-size vectorizable Eigen objects++The goal of this page is to explain what we mean by "fixed-size vectorizable".++\section summary Executive Summary++An Eigen object is called "fixed-size vectorizable" if it has fixed size and that size is a multiple of 16 bytes.++Examples include:+\li Eigen::Vector2d+\li Eigen::Vector4d+\li Eigen::Vector4f+\li Eigen::Matrix2d+\li Eigen::Matrix2f+\li Eigen::Matrix4d+\li Eigen::Matrix4f+\li Eigen::Affine3d+\li Eigen::Affine3f+\li Eigen::Quaterniond+\li Eigen::Quaternionf++\section explanation Explanation++First, "fixed-size" should be clear: an Eigen object has fixed size if its number of rows and its number of columns are fixed at compile-time. So for example Matrix3f has fixed size, but MatrixXf doesn't (the opposite of fixed-size is dynamic-size).++The array of coefficients of a fixed-size Eigen object is a plain "static array", it is not dynamically allocated. For example, the data behind a Matrix4f is just a "float array[16]".++Fixed-size objects are typically very small, which means that we want to handle them with zero runtime overhead -- both in terms of memory usage and of speed.++Now, vectorization (both SSE and AltiVec) works with 128-bit packets. Moreover, for performance reasons, these packets need to be have 128-bit alignment.++So it turns out that the only way that fixed-size Eigen objects can be vectorized, is if their size is a multiple of 128 bits, or 16 bytes. Eigen will then request 16-byte alignment for these objects, and henceforth rely on these objects being aligned so no runtime check for alignment is performed.++*/++}
+ eigen3/doc/FunctionsTakingEigenTypes.dox view
@@ -0,0 +1,217 @@+namespace Eigen {++/** \page TopicFunctionTakingEigenTypes Writing Functions Taking %Eigen Types as Parameters++%Eigen's use of expression templates results in potentially every expression being of a different type. If you pass such an expression to a function taking a parameter of type Matrix, your expression will implicitly be evaluated into a temporary Matrix, which will then be passed to the function. This means that you lose the benefit of expression templates. Concretely, this has two drawbacks:+ \li The evaluation into a temporary may be useless and inefficient;+ \li This only allows the function to read from the expression, not to write to it.++Fortunately, all this myriad of expression types have in common that they all inherit a few common, templated base classes. By letting your function take templated parameters of these base types, you can let them play nicely with %Eigen's expression templates.++\eigenAutoToc++\section TopicFirstExamples Some First Examples++This section will provide simple examples for different types of objects %Eigen is offering. Before starting with the actual examples, we need to recapitulate which base objects we can work with (see also \ref TopicClassHierarchy).++ \li MatrixBase: The common base class for all dense matrix expressions (as opposed to array expressions, as opposed to sparse and special matrix classes). Use it in functions that are meant to work only on dense matrices.+ \li ArrayBase: The common base class for all dense array expressions (as opposed to matrix expressions, etc). Use it in functions that are meant to work only on arrays.+ \li DenseBase: The common base class for all dense matrix expression, that is, the base class for both \c MatrixBase and \c ArrayBase. It can be used in functions that are meant to work on both matrices and arrays.+ \li EigenBase: The base class unifying all types of objects that can be evaluated into dense matrices or arrays, for example special matrix classes such as diagonal matrices, permutation matrices, etc. It can be used in functions that are meant to work on any such general type.++<b> %EigenBase Example </b><br/><br/>+Prints the dimensions of the most generic object present in %Eigen. It could be any matrix expressions, any dense or sparse matrix and any array.+<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include function_taking_eigenbase.cpp+</td>+<td>+\verbinclude function_taking_eigenbase.out+</td></tr></table>+<b> %DenseBase Example </b><br/><br/>+Prints a sub-block of the dense expression. Accepts any dense matrix or array expression, but no sparse objects and no special matrix classes such as DiagonalMatrix.+\code+template <typename Derived>+void print_block(const DenseBase<Derived>& b, int x, int y, int r, int c)+{+ std::cout << "block: " << b.block(x,y,r,c) << std::endl;+}+\endcode+<b> %ArrayBase Example </b><br/><br/>+Prints the maximum coefficient of the array or array-expression.+\code+template <typename Derived>+void print_max_coeff(const ArrayBase<Derived> &a)+{+ std::cout << "max: " << a.maxCoeff() << std::endl;+}+\endcode+<b> %MatrixBase Example </b><br/><br/>+Prints the inverse condition number of the given matrix or matrix-expression.+\code+template <typename Derived>+void print_inv_cond(const MatrixBase<Derived>& a)+{+ const typename JacobiSVD<typename Derived::PlainObject>::SingularValuesType&+ sing_vals = a.jacobiSvd().singularValues();+ std::cout << "inv cond: " << sing_vals(sing_vals.size()-1) / sing_vals(0) << std::endl;+}+\endcode+<b> Multiple templated arguments example </b><br/><br/>+Calculate the Euclidean distance between two points.+\code+template <typename DerivedA,typename DerivedB>+typename DerivedA::Scalar squaredist(const MatrixBase<DerivedA>& p1,const MatrixBase<DerivedB>& p2)+{+ return (p1-p2).squaredNorm();+}+\endcode+Notice that we used two template parameters, one per argument. This permits the function to handle inputs of different types, e.g.,+\code+squaredist(v1,2*v2)+\endcode+where the first argument \c v1 is a vector and the second argument \c 2*v2 is an expression.+<br/><br/>++These examples are just intended to give the reader a first impression of how functions can be written which take a plain and constant Matrix or Array argument. They are also intended to give the reader an idea about the most common base classes being the optimal candidates for functions. In the next section we will look in more detail at an example and the different ways it can be implemented, while discussing each implementation's problems and advantages. For the discussion below, Matrix and Array as well as MatrixBase and ArrayBase can be exchanged and all arguments still hold.+++\section TopicUsingRefClass How to write generic, but non-templated function?++In all the previous examples, the functions had to be template functions. This approach allows to write very generic code, but it is often desirable to write non templated function and still keep some level of genericity to avoid stupid copies of the arguments. The typical example is to write functions accepting both a MatrixXf or a block of a MatrixXf. This exactly the purpose of the Ref class. Here is a simple example:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include function_taking_ref.cpp+</td>+<td>+\verbinclude function_taking_ref.out+</td></tr></table>+In the first two calls to inv_cond, no copy occur because the memory layout of the arguments matches the memory layout accepted by Ref<MatrixXf>. However, in the last call, we have a generic expression that will be automatically evaluated into a temporary MatrixXf by the Ref<> object.++A Ref object can also be writable. Here is an example of a function computing the covariance matrix of two input matrices where each row is an observation:+\code+void cov(const Ref<const MatrixXf> x, const Ref<const MatrixXf> y, Ref<MatrixXf> C)+{+ const float num_observations = static_cast<float>(x.rows());+ const RowVectorXf x_mean = x.colwise().sum() / num_observations;+ const RowVectorXf y_mean = y.colwise().sum() / num_observations;+ C = (x.rowwise() - x_mean).transpose() * (y.rowwise() - y_mean) / num_observations;+}+\endcode+and here are two examples calling cov without any copy:+\code+MatrixXf m1, m2, m3+cov(m1, m2, m3);+cov(m1.leftCols<3>(), m2.leftCols<3>(), m3.topLeftCorner<3,3>());+\endcode+The Ref<> class has two other optional template arguments allowing to control the kind of memory layout that can be accepted without any copy. See the class Ref documentation for the details.++\section TopicPlainFunctionsWorking In which cases do functions taking plain Matrix or Array arguments work?++Without using template functions, and without the Ref class, a naive implementation of the previous cov function might look like this+\code+MatrixXf cov(const MatrixXf& x, const MatrixXf& y)+{+ const float num_observations = static_cast<float>(x.rows());+ const RowVectorXf x_mean = x.colwise().sum() / num_observations;+ const RowVectorXf y_mean = y.colwise().sum() / num_observations;+ return (x.rowwise() - x_mean).transpose() * (y.rowwise() - y_mean) / num_observations;+}+\endcode+and contrary to what one might think at first, this implementation is fine unless you require a generic implementation that works with double matrices too and unless you do not care about temporary objects. Why is that the case? Where are temporaries involved? How can code as given below compile?+\code+MatrixXf x,y,z;+MatrixXf C = cov(x,y+z);+\endcode+In this special case, the example is fine and will be working because both parameters are declared as \e const references. The compiler creates a temporary and evaluates the expression x+z into this temporary. Once the function is processed, the temporary is released and the result is assigned to C.++\b Note: Functions taking \e const references to Matrix (or Array) can process expressions at the cost of temporaries.+++\section TopicPlainFunctionsFailing In which cases do functions taking a plain Matrix or Array argument fail?++Here, we consider a slightly modified version of the function given above. This time, we do not want to return the result but pass an additional non-const paramter which allows us to store the result. A first naive implementation might look as follows.+\code+// Note: This code is flawed!+void cov(const MatrixXf& x, const MatrixXf& y, MatrixXf& C)+{+ const float num_observations = static_cast<float>(x.rows());+ const RowVectorXf x_mean = x.colwise().sum() / num_observations;+ const RowVectorXf y_mean = y.colwise().sum() / num_observations;+ C = (x.rowwise() - x_mean).transpose() * (y.rowwise() - y_mean) / num_observations;+}+\endcode+When trying to execute the following code+\code+MatrixXf C = MatrixXf::Zero(3,6);+cov(x,y, C.block(0,0,3,3));+\endcode+the compiler will fail, because it is not possible to convert the expression returned by \c MatrixXf::block() into a non-const \c MatrixXf&. This is the case because the compiler wants to protect you from writing your result to a temporary object. In this special case this protection is not intended -- we want to write to a temporary object. So how can we overcome this problem? ++The solution which is preferred at the moment is based on a little \em hack. One needs to pass a const reference to the matrix and internally the constness needs to be cast away. The correct implementation for C98 compliant compilers would be+\code+template <typename Derived, typename OtherDerived>+void cov(const MatrixBase<Derived>& x, const MatrixBase<Derived>& y, MatrixBase<OtherDerived> const & C)+{+ typedef typename Derived::Scalar Scalar;+ typedef typename internal::plain_row_type<Derived>::type RowVectorType;++ const Scalar num_observations = static_cast<Scalar>(x.rows());++ const RowVectorType x_mean = x.colwise().sum() / num_observations;+ const RowVectorType y_mean = y.colwise().sum() / num_observations;++ const_cast< MatrixBase<OtherDerived>& >(C) =+ (x.rowwise() - x_mean).transpose() * (y.rowwise() - y_mean) / num_observations;+}+\endcode+The implementation above does now not only work with temporary expressions but it also allows to use the function with matrices of arbitrary floating point scalar types.++\b Note: The const cast hack will only work with templated functions. It will not work with the MatrixXf implementation because it is not possible to cast a Block expression to a Matrix reference!++++\section TopicResizingInGenericImplementations How to resize matrices in generic implementations?++One might think we are done now, right? This is not completely true because in order for our covariance function to be generically applicable, we want the follwing code to work+\code+MatrixXf x = MatrixXf::Random(100,3);+MatrixXf y = MatrixXf::Random(100,3);+MatrixXf C;+cov(x, y, C);+\endcode+This is not the case anymore, when we are using an implementation taking MatrixBase as a parameter. In general, %Eigen supports automatic resizing but it is not possible to do so on expressions. Why should resizing of a matrix Block be allowed? It is a reference to a sub-matrix and we definitely don't want to resize that. So how can we incorporate resizing if we cannot resize on MatrixBase? The solution is to resize the derived object as in this implementation.+\code+template <typename Derived, typename OtherDerived>+void cov(const MatrixBase<Derived>& x, const MatrixBase<Derived>& y, MatrixBase<OtherDerived> const & C_)+{+ typedef typename Derived::Scalar Scalar;+ typedef typename internal::plain_row_type<Derived>::type RowVectorType;++ const Scalar num_observations = static_cast<Scalar>(x.rows());++ const RowVectorType x_mean = x.colwise().sum() / num_observations;+ const RowVectorType y_mean = y.colwise().sum() / num_observations;++ MatrixBase<OtherDerived>& C = const_cast< MatrixBase<OtherDerived>& >(C_);+ + C.derived().resize(x.cols(),x.cols()); // resize the derived object+ C = (x.rowwise() - x_mean).transpose() * (y.rowwise() - y_mean) / num_observations;+}+\endcode+This implementation is now working for parameters being expressions and for parameters being matrices and having the wrong size. Resizing the expressions does not do any harm in this case unless they actually require resizing. That means, passing an expression with the wrong dimensions will result in a run-time error (in debug mode only) while passing expressions of the correct size will just work fine.++\b Note: In the above discussion the terms Matrix and Array and MatrixBase and ArrayBase can be exchanged and all arguments still hold.++\section TopicSummary Summary++ - To summarize, the implementation of functions taking non-writable (const referenced) objects is not a big issue and does not lead to problematic situations in terms of compiling and running your program. However, a naive implementation is likely to introduce unnecessary temporary objects in your code. In order to avoid evaluating parameters into temporaries, pass them as (const) references to MatrixBase or ArrayBase (so templatize your function).++ - Functions taking writable (non-const) parameters must take const references and cast away constness within the function body.++ - Functions that take as parameters MatrixBase (or ArrayBase) objects, and potentially need to resize them (in the case where they are resizable), must call resize() on the derived class, as returned by derived().+*/+}
+ eigen3/doc/HiPerformance.dox view
@@ -0,0 +1,128 @@++namespace Eigen {++/** \page TopicWritingEfficientProductExpression Writing efficient matrix product expressions++In general achieving good performance with Eigen does no require any special effort:+simply write your expressions in the most high level way. This is especially true+for small fixed size matrices. For large matrices, however, it might be useful to+take some care when writing your expressions in order to minimize useless evaluations+and optimize the performance.+In this page we will give a brief overview of the Eigen's internal mechanism to simplify+and evaluate complex product expressions, and discuss the current limitations.+In particular we will focus on expressions matching level 2 and 3 BLAS routines, i.e,+all kind of matrix products and triangular solvers.++Indeed, in Eigen we have implemented a set of highly optimized routines which are very similar+to BLAS's ones. Unlike BLAS, those routines are made available to user via a high level and+natural API. Each of these routines can compute in a single evaluation a wide variety of expressions.+Given an expression, the challenge is then to map it to a minimal set of routines.+As explained latter, this mechanism has some limitations, and knowing them will allow+you to write faster code by making your expressions more Eigen friendly.++\section GEMM General Matrix-Matrix product (GEMM)++Let's start with the most common primitive: the matrix product of general dense matrices.+In the BLAS world this corresponds to the GEMM routine. Our equivalent primitive can+perform the following operation:+\f$ C.noalias() += \alpha op1(A) op2(B) \f$+where A, B, and C are column and/or row major matrices (or sub-matrices),+alpha is a scalar value, and op1, op2 can be transpose, adjoint, conjugate, or the identity.+When Eigen detects a matrix product, it analyzes both sides of the product to extract a+unique scalar factor alpha, and for each side, its effective storage order, shape, and conjugation states.+More precisely each side is simplified by iteratively removing trivial expressions such as scalar multiple,+negation and conjugation. Transpose and Block expressions are not evaluated and they only modify the storage order+and shape. All other expressions are immediately evaluated.+For instance, the following expression:+\code m1.noalias() -= s4 * (s1 * m2.adjoint() * (-(s3*m3).conjugate()*s2)) \endcode+is automatically simplified to:+\code m1.noalias() += (s1*s2*conj(s3)*s4) * m2.adjoint() * m3.conjugate() \endcode+which exactly matches our GEMM routine.++\subsection GEMM_Limitations Limitations+Unfortunately, this simplification mechanism is not perfect yet and not all expressions which could be+handled by a single GEMM-like call are correctly detected.+<table class="manual" style="width:100%">+<tr>+<th>Not optimal expression</th>+<th>Evaluated as</th>+<th>Optimal version (single evaluation)</th>+<th>Comments</th>+</tr>+<tr>+<td>\code+m1 += m2 * m3; \endcode</td>+<td>\code+temp = m2 * m3;+m1 += temp; \endcode</td>+<td>\code+m1.noalias() += m2 * m3; \endcode</td>+<td>Use .noalias() to tell Eigen the result and right-hand-sides do not alias. + Otherwise the product m2 * m3 is evaluated into a temporary.</td>+</tr>+<tr class="alt">+<td></td>+<td></td>+<td>\code+m1.noalias() += s1 * (m2 * m3); \endcode</td>+<td>This is a special feature of Eigen. Here the product between a scalar+ and a matrix product does not evaluate the matrix product but instead it+ returns a matrix product expression tracking the scalar scaling factor. <br>+ Without this optimization, the matrix product would be evaluated into a+ temporary as in the next example.</td>+</tr>+<tr>+<td>\code+m1.noalias() += (m2 * m3).adjoint(); \endcode</td>+<td>\code+temp = m2 * m3;+m1 += temp.adjoint(); \endcode</td>+<td>\code+m1.noalias() += m3.adjoint()+* * m2.adjoint(); \endcode</td>+<td>This is because the product expression has the EvalBeforeNesting bit which+ enforces the evaluation of the product by the Tranpose expression.</td>+</tr>+<tr class="alt">+<td>\code+m1 = m1 + m2 * m3; \endcode</td>+<td>\code+temp = m2 * m3;+m1 = m1 + temp; \endcode</td>+<td>\code m1.noalias() += m2 * m3; \endcode</td>+<td>Here there is no way to detect at compile time that the two m1 are the same,+ and so the matrix product will be immediately evaluated.</td>+</tr>+<tr>+<td>\code+m1.noalias() = m4 + m2 * m3; \endcode</td>+<td>\code+temp = m2 * m3;+m1 = m4 + temp; \endcode</td>+<td>\code+m1 = m4;+m1.noalias() += m2 * m3; \endcode</td>+<td>First of all, here the .noalias() in the first expression is useless because+ m2*m3 will be evaluated anyway. However, note how this expression can be rewritten+ so that no temporary is required. (tip: for very small fixed size matrix+ it is slighlty better to rewrite it like this: m1.noalias() = m2 * m3; m1 += m4;</td>+</tr>+<tr class="alt">+<td>\code+m1.noalias() += (s1*m2).block(..) * m3; \endcode</td>+<td>\code+temp = (s1*m2).block(..);+m1 += temp * m3; \endcode</td>+<td>\code+m1.noalias() += s1 * m2.block(..) * m3; \endcode</td>+<td>This is because our expression analyzer is currently not able to extract trivial+ expressions nested in a Block expression. Therefore the nested scalar+ multiple cannot be properly extracted.</td>+</tr>+</table>++Of course all these remarks hold for all other kind of products involving triangular or selfadjoint matrices.++*/++}
+ eigen3/doc/InsideEigenExample.dox view
@@ -0,0 +1,495 @@+namespace Eigen {++/** \page TopicInsideEigenExample What happens inside Eigen, on a simple example++\eigenAutoToc++<hr>+++Consider the following example program:++\code+#include<Eigen/Core>++int main()+{+ int size = 50;+ // VectorXf is a vector of floats, with dynamic size.+ Eigen::VectorXf u(size), v(size), w(size);+ u = v + w;+}+\endcode++The goal of this page is to understand how Eigen compiles it, assuming that SSE2 vectorization is enabled (GCC option -msse2).++\section WhyInteresting Why it's interesting++Maybe you think, that the above example program is so simple, that compiling it shouldn't involve anything interesting. So before starting, let us explain what is nontrivial in compiling it correctly -- that is, producing optimized code -- so that the complexity of Eigen, that we'll explain here, is really useful.++Look at the line of code+\code+ u = v + w; // (*)+\endcode++The first important thing about compiling it, is that the arrays should be traversed only once, like+\code+ for(int i = 0; i < size; i++) u[i] = v[i] + w[i];+\endcode+The problem is that if we make a naive C++ library where the VectorXf class has an operator+ returning a VectorXf, then the line of code (*) will amount to:+\code+ VectorXf tmp = v + w;+ VectorXf u = tmp;+\endcode+Obviously, the introduction of the temporary \a tmp here is useless. It has a very bad effect on performance, first because the creation of \a tmp requires a dynamic memory allocation in this context, and second as there are now two for loops:+\code+ for(int i = 0; i < size; i++) tmp[i] = v[i] + w[i];+ for(int i = 0; i < size; i++) u[i] = tmp[i];+\endcode+Traversing the arrays twice instead of once is terrible for performance, as it means that we do many redundant memory accesses.++The second important thing about compiling the above program, is to make correct use of SSE2 instructions. Notice that Eigen also supports AltiVec and that all the discussion that we make here applies also to AltiVec.++SSE2, like AltiVec, is a set of instructions allowing to perform computations on packets of 128 bits at once. Since a float is 32 bits, this means that SSE2 instructions can handle 4 floats at once. This means that, if correctly used, they can make our computation go up to 4x faster.++However, in the above program, we have chosen size=50, so our vectors consist of 50 float's, and 50 is not a multiple of 4. This means that we cannot hope to do all of that computation using SSE2 instructions. The second best thing, to which we should aim, is to handle the 48 first coefficients with SSE2 instructions, since 48 is the biggest multiple of 4 below 50, and then handle separately, without SSE2, the 49th and 50th coefficients. Something like this:++\code+ for(int i = 0; i < 4*(size/4); i+=4) u.packet(i) = v.packet(i) + w.packet(i);+ for(int i = 4*(size/4); i < size; i++) u[i] = v[i] + w[i];+\endcode++So let us look line by line at our example program, and let's follow Eigen as it compiles it.++\section ConstructingVectors Constructing vectors++Let's analyze the first line:++\code+ Eigen::VectorXf u(size), v(size), w(size);+\endcode++First of all, VectorXf is the following typedef:+\code+ typedef Matrix<float, Dynamic, 1> VectorXf;+\endcode++The class template Matrix is declared in src/Core/util/ForwardDeclarations.h with 6 template parameters, but the last 3 are automatically determined by the first 3. So you don't need to worry about them for now. Here, Matrix\<float, Dynamic, 1\> means a matrix of floats, with a dynamic number of rows and 1 column.++The Matrix class inherits a base class, MatrixBase. Don't worry about it, for now it suffices to say that MatrixBase is what unifies matrices/vectors and all the expressions types -- more on that below.++When we do+\code+ Eigen::VectorXf u(size);+\endcode+the constructor that is called is Matrix::Matrix(int), in src/Core/Matrix.h. Besides some assertions, all it does is to construct the \a m_storage member, which is of type DenseStorage\<float, Dynamic, Dynamic, 1\>.++You may wonder, isn't it overengineering to have the storage in a separate class? The reason is that the Matrix class template covers all kinds of matrices and vector: both fixed-size and dynamic-size. The storage method is not the same in these two cases. For fixed-size, the matrix coefficients are stored as a plain member array. For dynamic-size, the coefficients will be stored as a pointer to a dynamically-allocated array. Because of this, we need to abstract storage away from the Matrix class. That's DenseStorage.++Let's look at this constructor, in src/Core/DenseStorage.h. You can see that there are many partial template specializations of DenseStorages here, treating separately the cases where dimensions are Dynamic or fixed at compile-time. The partial specialization that we are looking at is:+\code+template<typename T, int _Cols> class DenseStorage<T, Dynamic, Dynamic, _Cols>+\endcode++Here, the constructor called is DenseStorage::DenseStorage(int size, int rows, int columns)+with size=50, rows=50, columns=1.++Here is this constructor:+\code+inline DenseStorage(int size, int rows, int) : m_data(internal::aligned_new<T>(size)), m_rows(rows) {}+\endcode++Here, the \a m_data member is the actual array of coefficients of the matrix. As you see, it is dynamically allocated. Rather than calling new[] or malloc(), as you can see, we have our own internal::aligned_new defined in src/Core/util/Memory.h. What it does is that if vectorization is enabled, then it uses a platform-specific call to allocate a 128-bit-aligned array, as that is very useful for vectorization with both SSE2 and AltiVec. If vectorization is disabled, it amounts to the standard new[].++As you can see, the constructor also sets the \a m_rows member to \a size. Notice that there is no \a m_columns member: indeed, in this partial specialization of DenseStorage, we know the number of columns at compile-time, since the _Cols template parameter is different from Dynamic. Namely, in our case, _Cols is 1, which is to say that our vector is just a matrix with 1 column. Hence, there is no need to store the number of columns as a runtime variable.++When you call VectorXf::data() to get the pointer to the array of coefficients, it returns DenseStorage::data() which returns the \a m_data member.++When you call VectorXf::size() to get the size of the vector, this is actually a method in the base class MatrixBase. It determines that the vector is a column-vector, since ColsAtCompileTime==1 (this comes from the template parameters in the typedef VectorXf). It deduces that the size is the number of rows, so it returns VectorXf::rows(), which returns DenseStorage::rows(), which returns the \a m_rows member, which was set to \a size by the constructor.++\section ConstructionOfSumXpr Construction of the sum expression++Now that our vectors are constructed, let's move on to the next line:++\code+u = v + w;+\endcode++The executive summary is that operator+ returns a "sum of vectors" expression, but doesn't actually perform the computation. It is the operator=, whose call occurs thereafter, that does the computation.++Let us now see what Eigen does when it sees this:++\code+v + w+\endcode++Here, v and w are of type VectorXf, which is a typedef for a specialization of Matrix (as we explained above), which is a subclass of MatrixBase. So what is being called is++\code+MatrixBase::operator+(const MatrixBase&)+\endcode++The return type of this operator is+\code+CwiseBinaryOp<internal::scalar_sum_op<float>, VectorXf, VectorXf>+\endcode+The CwiseBinaryOp class is our first encounter with an expression template. As we said, the operator+ doesn't by itself perform any computation, it just returns an abstract "sum of vectors" expression. Since there are also "difference of vectors" and "coefficient-wise product of vectors" expressions, we unify them all as "coefficient-wise binary operations", which we abbreviate as "CwiseBinaryOp". "Coefficient-wise" means that the operations is performed coefficient by coefficient. "binary" means that there are two operands -- we are adding two vectors with one another.++Now you might ask, what if we did something like++\code+v + w + u;+\endcode++The first v + w would return a CwiseBinaryOp as above, so in order for this to compile, we'd need to define an operator+ also in the class CwiseBinaryOp... at this point it starts looking like a nightmare: are we going to have to define all operators in each of the expression classes (as you guessed, CwiseBinaryOp is only one of many) ? This looks like a dead end!++The solution is that CwiseBinaryOp itself, as well as Matrix and all the other expression types, is a subclass of MatrixBase. So it is enough to define once and for all the operators in class MatrixBase.++Since MatrixBase is the common base class of different subclasses, the aspects that depend on the subclass must be abstracted from MatrixBase. This is called polymorphism.++The classical approach to polymorphism in C++ is by means of virtual functions. This is dynamic polymorphism. Here we don't want dynamic polymorphism because the whole design of Eigen is based around the assumption that all the complexity, all the abstraction, gets resolved at compile-time. This is crucial: if the abstraction can't get resolved at compile-time, Eigen's compile-time optimization mechanisms become useless, not to mention that if that abstraction has to be resolved at runtime it'll incur an overhead by itself.++Here, what we want is to have a single class MatrixBase as the base of many subclasses, in such a way that each MatrixBase object (be it a matrix, or vector, or any kind of expression) knows at compile-time (as opposed to run-time) of which particular subclass it is an object (i.e. whether it is a matrix, or an expression, and what kind of expression).++The solution is the <a href="http://en.wikipedia.org/wiki/Curiously_Recurring_Template_Pattern">Curiously Recurring Template Pattern</a>. Let's do the break now. Hopefully you can read this wikipedia page during the break if needed, but it won't be allowed during the exam.++In short, MatrixBase takes a template parameter \a Derived. Whenever we define a subclass Subclass, we actually make Subclass inherit MatrixBase\<Subclass\>. The point is that different subclasses inherit different MatrixBase types. Thanks to this, whenever we have an object of a subclass, and we call on it some MatrixBase method, we still remember even from inside the MatrixBase method which particular subclass we're talking about.++This means that we can put almost all the methods and operators in the base class MatrixBase, and have only the bare minimum in the subclasses. If you look at the subclasses in Eigen, like for instance the CwiseBinaryOp class, they have very few methods. There are coeff() and sometimes coeffRef() methods for access to the coefficients, there are rows() and cols() methods returning the number of rows and columns, but there isn't much more than that. All the meat is in MatrixBase, so it only needs to be coded once for all kinds of expressions, matrices, and vectors.++So let's end this digression and come back to the piece of code from our example program that we were currently analyzing,++\code+v + w+\endcode++Now that MatrixBase is a good friend, let's write fully the prototype of the operator+ that gets called here (this code is from src/Core/MatrixBase.h):++\code+template<typename Derived>+class MatrixBase+{+ // ...++ template<typename OtherDerived>+ const CwiseBinaryOp<internal::scalar_sum_op<typename internal::traits<Derived>::Scalar>, Derived, OtherDerived>+ operator+(const MatrixBase<OtherDerived> &other) const;++ // ...+};+\endcode++Here of course, \a Derived and \a OtherDerived are VectorXf.++As we said, CwiseBinaryOp is also used for other operations such as substration, so it takes another template parameter determining the operation that will be applied to coefficients. This template parameter is a functor, that is, a class in which we have an operator() so it behaves like a function. Here, the functor used is internal::scalar_sum_op. It is defined in src/Core/Functors.h.++Let us now explain the internal::traits here. The internal::scalar_sum_op class takes one template parameter: the type of the numbers to handle. Here of course we want to pass the scalar type (a.k.a. numeric type) of VectorXf, which is \c float. How do we determine which is the scalar type of \a Derived ? Throughout Eigen, all matrix and expression types define a typedef \a Scalar which gives its scalar type. For example, VectorXf::Scalar is a typedef for \c float. So here, if life was easy, we could find the numeric type of \a Derived as just+\code+typename Derived::Scalar+\endcode+Unfortunately, we can't do that here, as the compiler would complain that the type Derived hasn't yet been defined. So we use a workaround: in src/Core/util/ForwardDeclarations.h, we declared (not defined!) all our subclasses, like Matrix, and we also declared the following class template:+\code+template<typename T> struct internal::traits;+\endcode+In src/Core/Matrix.h, right \em before the definition of class Matrix, we define a partial specialization of internal::traits for T=Matrix\<any template parameters\>. In this specialization of internal::traits, we define the Scalar typedef. So when we actually define Matrix, it is legal to refer to "typename internal::traits\<Matrix\>::Scalar".++Anyway, we have declared our operator+. In our case, where \a Derived and \a OtherDerived are VectorXf, the above declaration amounts to:+\code+class MatrixBase<VectorXf>+{+ // ...++ const CwiseBinaryOp<internal::scalar_sum_op<float>, VectorXf, VectorXf>+ operator+(const MatrixBase<VectorXf> &other) const;++ // ...+};+\endcode++Let's now jump to src/Core/CwiseBinaryOp.h to see how it is defined. As you can see there, all it does is to return a CwiseBinaryOp object, and this object is just storing references to the left-hand-side and right-hand-side expressions -- here, these are the vectors \a v and \a w. Well, the CwiseBinaryOp object is also storing an instance of the (empty) functor class, but you shouldn't worry about it as that is a minor implementation detail.++Thus, the operator+ hasn't performed any actual computation. To summarize, the operation \a v + \a w just returned an object of type CwiseBinaryOp which did nothing else than just storing references to \a v and \a w.++\section Assignment The assignment++At this point, the expression \a v + \a w has finished evaluating, so, in the process of compiling the line of code+\code+u = v + w;+\endcode+we now enter the operator=.++What operator= is being called here? The vector u is an object of class VectorXf, i.e. Matrix. In src/Core/Matrix.h, inside the definition of class Matrix, we see this:+\code+ template<typename OtherDerived>+ inline Matrix& operator=(const MatrixBase<OtherDerived>& other)+ {+ eigen_assert(m_storage.data()!=0 && "you cannot use operator= with a non initialized matrix (instead use set()");+ return Base::operator=(other.derived());+ }+\endcode+Here, Base is a typedef for MatrixBase\<Matrix\>. So, what is being called is the operator= of MatrixBase. Let's see its prototype in src/Core/MatrixBase.h:+\code+ template<typename OtherDerived>+ Derived& operator=(const MatrixBase<OtherDerived>& other);+\endcode+Here, \a Derived is VectorXf (since u is a VectorXf) and \a OtherDerived is CwiseBinaryOp. More specifically, as explained in the previous section, \a OtherDerived is:+\code+CwiseBinaryOp<internal::scalar_sum_op<float>, VectorXf, VectorXf>+\endcode+So the full prototype of the operator= being called is:+\code+VectorXf& MatrixBase<VectorXf>::operator=(const MatrixBase<CwiseBinaryOp<internal::scalar_sum_op<float>, VectorXf, VectorXf> > & other);+\endcode+This operator= literally reads "copying a sum of two VectorXf's into another VectorXf".++Let's now look at the implementation of this operator=. It resides in the file src/Core/Assign.h.++What we can see there is:+\code+template<typename Derived>+template<typename OtherDerived>+inline Derived& MatrixBase<Derived>+ ::operator=(const MatrixBase<OtherDerived>& other)+{+ return internal::assign_selector<Derived,OtherDerived>::run(derived(), other.derived());+}+\endcode++OK so our next task is to understand internal::assign_selector :)++Here is its declaration (all that is still in the same file src/Core/Assign.h)+\code+template<typename Derived, typename OtherDerived,+ bool EvalBeforeAssigning = int(OtherDerived::Flags) & EvalBeforeAssigningBit,+ bool NeedToTranspose = Derived::IsVectorAtCompileTime+ && OtherDerived::IsVectorAtCompileTime+ && int(Derived::RowsAtCompileTime) == int(OtherDerived::ColsAtCompileTime)+ && int(Derived::ColsAtCompileTime) == int(OtherDerived::RowsAtCompileTime)+ && int(Derived::SizeAtCompileTime) != 1>+struct internal::assign_selector;+\endcode++So internal::assign_selector takes 4 template parameters, but the 2 last ones are automatically determined by the 2 first ones.++EvalBeforeAssigning is here to enforce the EvalBeforeAssigningBit. As explained <a href="TopicLazyEvaluation.html">here</a>, certain expressions have this flag which makes them automatically evaluate into temporaries before assigning them to another expression. This is the case of the Product expression, in order to avoid strange aliasing effects when doing "m = m * m;" However, of course here our CwiseBinaryOp expression doesn't have the EvalBeforeAssigningBit: we said since the beginning that we didn't want a temporary to be introduced here. So if you go to src/Core/CwiseBinaryOp.h, you'll see that the Flags in internal::traits\<CwiseBinaryOp\> don't include the EvalBeforeAssigningBit. The Flags member of CwiseBinaryOp is then imported from the internal::traits by the EIGEN_GENERIC_PUBLIC_INTERFACE macro. Anyway, here the template parameter EvalBeforeAssigning has the value \c false.++NeedToTranspose is here for the case where the user wants to copy a row-vector into a column-vector. We allow this as a special exception to the general rule that in assignments we require the dimesions to match. Anyway, here both the left-hand and right-hand sides are column vectors, in the sense that ColsAtCompileTime is equal to 1. So NeedToTranspose is \c false too.++So, here we are in the partial specialization:+\code+internal::assign_selector<Derived, OtherDerived, false, false>+\endcode++Here's how it is defined:+\code+template<typename Derived, typename OtherDerived>+struct internal::assign_selector<Derived,OtherDerived,false,false> {+ static Derived& run(Derived& dst, const OtherDerived& other) { return dst.lazyAssign(other.derived()); }+};+\endcode++OK so now our next job is to understand how lazyAssign works :)++\code+template<typename Derived>+template<typename OtherDerived>+inline Derived& MatrixBase<Derived>+ ::lazyAssign(const MatrixBase<OtherDerived>& other)+{+ EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)+ eigen_assert(rows() == other.rows() && cols() == other.cols());+ internal::assign_impl<Derived, OtherDerived>::run(derived(),other.derived());+ return derived();+}+\endcode++What do we see here? Some assertions, and then the only interesting line is:+\code+ internal::assign_impl<Derived, OtherDerived>::run(derived(),other.derived());+\endcode++OK so now we want to know what is inside internal::assign_impl.++Here is its declaration:+\code+template<typename Derived1, typename Derived2,+ int Vectorization = internal::assign_traits<Derived1, Derived2>::Vectorization,+ int Unrolling = internal::assign_traits<Derived1, Derived2>::Unrolling>+struct internal::assign_impl;+\endcode+Again, internal::assign_selector takes 4 template parameters, but the 2 last ones are automatically determined by the 2 first ones.++These two parameters \a Vectorization and \a Unrolling are determined by a helper class internal::assign_traits. Its job is to determine which vectorization strategy to use (that is \a Vectorization) and which unrolling strategy to use (that is \a Unrolling).++We'll not enter into the details of how these strategies are chosen (this is in the implementation of internal::assign_traits at the top of the same file). Let's just say that here \a Vectorization has the value \a LinearVectorization, and \a Unrolling has the value \a NoUnrolling (the latter is obvious since our vectors have dynamic size so there's no way to unroll the loop at compile-time).++So the partial specialization of internal::assign_impl that we're looking at is:+\code+internal::assign_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>+\endcode++Here is how it's defined:+\code+template<typename Derived1, typename Derived2>+struct internal::assign_impl<Derived1, Derived2, LinearVectorization, NoUnrolling>+{+ static void run(Derived1 &dst, const Derived2 &src)+ {+ const int size = dst.size();+ const int packetSize = internal::packet_traits<typename Derived1::Scalar>::size;+ const int alignedStart = internal::assign_traits<Derived1,Derived2>::DstIsAligned ? 0+ : internal::first_aligned(&dst.coeffRef(0), size);+ const int alignedEnd = alignedStart + ((size-alignedStart)/packetSize)*packetSize;++ for(int index = 0; index < alignedStart; index++)+ dst.copyCoeff(index, src);++ for(int index = alignedStart; index < alignedEnd; index += packetSize)+ {+ dst.template copyPacket<Derived2, Aligned, internal::assign_traits<Derived1,Derived2>::SrcAlignment>(index, src);+ }++ for(int index = alignedEnd; index < size; index++)+ dst.copyCoeff(index, src);+ }+};+\endcode++Here's how it works. \a LinearVectorization means that the left-hand and right-hand side expression can be accessed linearly i.e. you can refer to their coefficients by one integer \a index, as opposed to having to refer to its coefficients by two integers \a row, \a column.++As we said at the beginning, vectorization works with blocks of 4 floats. Here, \a PacketSize is 4.++There are two potential problems that we need to deal with:+\li first, vectorization works much better if the packets are 128-bit-aligned. This is especially important for write access. So when writing to the coefficients of \a dst, we want to group these coefficients by packets of 4 such that each of these packets is 128-bit-aligned. In general, this requires to skip a few coefficients at the beginning of \a dst. This is the purpose of \a alignedStart. We then copy these first few coefficients one by one, not by packets. However, in our case, the \a dst expression is a VectorXf and remember that in the construction of the vectors we allocated aligned arrays. Thanks to \a DstIsAligned, Eigen remembers that without having to do any runtime check, so \a alignedStart is zero and this part is avoided altogether.+\li second, the number of coefficients to copy is not in general a multiple of \a packetSize. Here, there are 50 coefficients to copy and \a packetSize is 4. So we'll have to copy the last 2 coefficients one by one, not by packets. Here, \a alignedEnd is 48.++Now come the actual loops.++First, the vectorized part: the 48 first coefficients out of 50 will be copied by packets of 4:+\code+ for(int index = alignedStart; index < alignedEnd; index += packetSize)+ {+ dst.template copyPacket<Derived2, Aligned, internal::assign_traits<Derived1,Derived2>::SrcAlignment>(index, src);+ }+\endcode++What is copyPacket? It is defined in src/Core/Coeffs.h:+\code+template<typename Derived>+template<typename OtherDerived, int StoreMode, int LoadMode>+inline void MatrixBase<Derived>::copyPacket(int index, const MatrixBase<OtherDerived>& other)+{+ eigen_internal_assert(index >= 0 && index < size());+ derived().template writePacket<StoreMode>(index,+ other.derived().template packet<LoadMode>(index));+}+\endcode++OK, what are writePacket() and packet() here?++First, writePacket() here is a method on the left-hand side VectorXf. So we go to src/Core/Matrix.h to look at its definition:+\code+template<int StoreMode>+inline void writePacket(int index, const PacketScalar& x)+{+ internal::pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, x);+}+\endcode+Here, \a StoreMode is \a #Aligned, indicating that we are doing a 128-bit-aligned write access, \a PacketScalar is a type representing a "SSE packet of 4 floats" and internal::pstoret is a function writing such a packet in memory. Their definitions are architecture-specific, we find them in src/Core/arch/SSE/PacketMath.h:++The line in src/Core/arch/SSE/PacketMath.h that determines the PacketScalar type (via a typedef in Matrix.h) is:+\code+template<> struct internal::packet_traits<float> { typedef __m128 type; enum {size=4}; };+\endcode+Here, __m128 is a SSE-specific type. Notice that the enum \a size here is what was used to define \a packetSize above.++And here is the implementation of internal::pstoret:+\code+template<> inline void internal::pstore(float* to, const __m128& from) { _mm_store_ps(to, from); }+\endcode+Here, __mm_store_ps is a SSE-specific intrinsic function, representing a single SSE instruction. The difference between internal::pstore and internal::pstoret is that internal::pstoret is a dispatcher handling both the aligned and unaligned cases, you find its definition in src/Core/GenericPacketMath.h:+\code+template<typename Scalar, typename Packet, int LoadMode>+inline void internal::pstoret(Scalar* to, const Packet& from)+{+ if(LoadMode == Aligned)+ internal::pstore(to, from);+ else+ internal::pstoreu(to, from);+}+\endcode++OK, that explains how writePacket() works. Now let's look into the packet() call. Remember that we are analyzing this line of code inside copyPacket():+\code+derived().template writePacket<StoreMode>(index,+ other.derived().template packet<LoadMode>(index));+\endcode++Here, \a other is our sum expression \a v + \a w. The .derived() is just casting from MatrixBase to the subclass which here is CwiseBinaryOp. So let's go to src/Core/CwiseBinaryOp.h:+\code+class CwiseBinaryOp+{+ // ...+ template<int LoadMode>+ inline PacketScalar packet(int index) const+ {+ return m_functor.packetOp(m_lhs.template packet<LoadMode>(index), m_rhs.template packet<LoadMode>(index));+ }+};+\endcode+Here, \a m_lhs is the vector \a v, and \a m_rhs is the vector \a w. So the packet() function here is Matrix::packet(). The template parameter \a LoadMode is \a #Aligned. So we're looking at+\code+class Matrix+{+ // ...+ template<int LoadMode>+ inline PacketScalar packet(int index) const+ {+ return internal::ploadt<Scalar, LoadMode>(m_storage.data() + index);+ }+};+\endcode+We let you look up the definition of internal::ploadt in GenericPacketMath.h and the internal::pload in src/Core/arch/SSE/PacketMath.h. It is very similar to the above for internal::pstore.++Let's go back to CwiseBinaryOp::packet(). Once the packets from the vectors \a v and \a w have been returned, what does this function do? It calls m_functor.packetOp() on them. What is m_functor? Here we must remember what particular template specialization of CwiseBinaryOp we're dealing with:+\code+CwiseBinaryOp<internal::scalar_sum_op<float>, VectorXf, VectorXf>+\endcode+So m_functor is an object of the empty class internal::scalar_sum_op<float>. As we mentioned above, don't worry about why we constructed an object of this empty class at all -- it's an implementation detail, the point is that some other functors need to store member data.++Anyway, internal::scalar_sum_op is defined in src/Core/Functors.h:+\code+template<typename Scalar> struct internal::scalar_sum_op EIGEN_EMPTY_STRUCT {+ inline const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }+ template<typename PacketScalar>+ inline const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const+ { return internal::padd(a,b); }+};+\endcode+As you can see, all what packetOp() does is to call internal::padd on the two packets. Here is the definition of internal::padd from src/Core/arch/SSE/PacketMath.h:+\code+template<> inline __m128 internal::padd(const __m128& a, const __m128& b) { return _mm_add_ps(a,b); }+\endcode+Here, _mm_add_ps is a SSE-specific intrinsic function, representing a single SSE instruction.++To summarize, the loop+\code+ for(int index = alignedStart; index < alignedEnd; index += packetSize)+ {+ dst.template copyPacket<Derived2, Aligned, internal::assign_traits<Derived1,Derived2>::SrcAlignment>(index, src);+ }+\endcode+has been compiled to the following code: for \a index going from 0 to the 11 ( = 48/4 - 1), read the i-th packet (of 4 floats) from the vector v and the i-th packet from the vector w using two __mm_load_ps SSE instructions, then add them together using a __mm_add_ps instruction, then store the result using a __mm_store_ps instruction.++There remains the second loop handling the last few (here, the last 2) coefficients:+\code+ for(int index = alignedEnd; index < size; index++)+ dst.copyCoeff(index, src);+\endcode+However, it works just like the one we just explained, it is just simpler because there is no SSE vectorization involved here. copyPacket() becomes copyCoeff(), packet() becomes coeff(), writePacket() becomes coeffRef(). If you followed us this far, you can probably understand this part by yourself.++We see that all the C++ abstraction of Eigen goes away during compilation and that we indeed are precisely controlling which assembly instructions we emit. Such is the beauty of C++! Since we have such precise control over the emitted assembly instructions, but such complex logic to choose the right instructions, we can say that Eigen really behaves like an optimizing compiler. If you prefer, you could say that Eigen behaves like a script for the compiler. In a sense, C++ template metaprogramming is scripting the compiler -- and it's been shown that this scripting language is Turing-complete. See <a href="http://en.wikipedia.org/wiki/Template_metaprogramming"> Wikipedia</a>.++*/++}
+ eigen3/doc/Manual.dox view
@@ -0,0 +1,159 @@++// This file strutures pages and modules into a convenient hierarchical structure.++namespace Eigen {++/** \page UserManual_Generalities General topics+ - \subpage Eigen2ToEigen3+ - \subpage TopicFunctionTakingEigenTypes+ - \subpage TopicPreprocessorDirectives+ - \subpage TopicAssertions+ - \subpage TopicCustomizingEigen+ - \subpage TopicMultiThreading+ - \subpage TopicUsingIntelMKL+ - \subpage TopicTemplateKeyword+ - \subpage UserManual_UnderstandingEigen+*/+ +/** \page UserManual_UnderstandingEigen Understanding Eigen+ - \subpage TopicInsideEigenExample+ - \subpage TopicClassHierarchy+ - \subpage TopicLazyEvaluation+*/++/** \page UnclassifiedPages Unclassified pages+ - \subpage TopicResizing+ - \subpage TopicVectorization+ - \subpage TopicEigenExpressionTemplates+ - \subpage TopicScalarTypes+ - \subpage GettingStarted+ - \subpage TutorialSparse_example_details+ - \subpage TopicWritingEfficientProductExpression+ - \subpage Experimental+*/+++/** \defgroup Support_modules Support modules+ * Category of modules which add support for external libraries.+ */+++/** \defgroup DenseMatrixManipulation_chapter Dense matrix and array manipulation */+/** \defgroup DenseMatrixManipulation_Alignement Alignment issues */+/** \defgroup DenseMatrixManipulation_Reference Reference */++/** \addtogroup TutorialMatrixClass+ \ingroup DenseMatrixManipulation_chapter */+/** \addtogroup TutorialMatrixArithmetic+ \ingroup DenseMatrixManipulation_chapter */+/** \addtogroup TutorialArrayClass+ \ingroup DenseMatrixManipulation_chapter */+/** \addtogroup TutorialBlockOperations+ \ingroup DenseMatrixManipulation_chapter */+/** \addtogroup TutorialAdvancedInitialization+ \ingroup DenseMatrixManipulation_chapter */+/** \addtogroup TutorialReductionsVisitorsBroadcasting+ \ingroup DenseMatrixManipulation_chapter */+/** \addtogroup TutorialMapClass+ \ingroup DenseMatrixManipulation_chapter */+/** \addtogroup TopicAliasing+ \ingroup DenseMatrixManipulation_chapter */+/** \addtogroup TopicStorageOrders+ \ingroup DenseMatrixManipulation_chapter */+ +/** \addtogroup DenseMatrixManipulation_Alignement+ \ingroup DenseMatrixManipulation_chapter */+/** \addtogroup TopicUnalignedArrayAssert+ \ingroup DenseMatrixManipulation_Alignement */+/** \addtogroup TopicFixedSizeVectorizable+ \ingroup DenseMatrixManipulation_Alignement */+/** \addtogroup TopicStructHavingEigenMembers+ \ingroup DenseMatrixManipulation_Alignement */+/** \addtogroup TopicStlContainers+ \ingroup DenseMatrixManipulation_Alignement */+/** \addtogroup TopicPassingByValue+ \ingroup DenseMatrixManipulation_Alignement */+/** \addtogroup TopicWrongStackAlignment+ \ingroup DenseMatrixManipulation_Alignement */+ +/** \addtogroup DenseMatrixManipulation_Reference+ \ingroup DenseMatrixManipulation_chapter */+/** \addtogroup Core_Module+ \ingroup DenseMatrixManipulation_Reference */ +/** \addtogroup Jacobi_Module+ \ingroup DenseMatrixManipulation_Reference */ +/** \addtogroup Householder_Module+ \ingroup DenseMatrixManipulation_Reference */ ++/** \addtogroup QuickRefPage+ \ingroup DenseMatrixManipulation_chapter */+++/** \defgroup DenseLinearSolvers_chapter Dense linear problems and decompositions */+/** \defgroup DenseLinearSolvers_Reference Reference */++/** \addtogroup TutorialLinearAlgebra+ \ingroup DenseLinearSolvers_chapter */+/** \addtogroup TopicLinearAlgebraDecompositions+ \ingroup DenseLinearSolvers_chapter */++/** \addtogroup DenseLinearSolvers_Reference+ \ingroup DenseLinearSolvers_chapter */+/** \addtogroup Cholesky_Module+ \ingroup DenseLinearSolvers_Reference */+/** \addtogroup LU_Module+ \ingroup DenseLinearSolvers_Reference */+/** \addtogroup QR_Module+ \ingroup DenseLinearSolvers_Reference */+/** \addtogroup SVD_Module+ \ingroup DenseLinearSolvers_Reference*/+/** \addtogroup Eigenvalues_Module+ \ingroup DenseLinearSolvers_Reference */+++++/** \defgroup Sparse_chapter Sparse linear algebra */+/** \defgroup Sparse_Reference Reference */++/** \addtogroup TutorialSparse+ \ingroup Sparse_chapter */+/** \addtogroup TopicSparseSystems+ \ingroup Sparse_chapter */++/** \addtogroup Sparse_Reference+ \ingroup Sparse_chapter */+/** \addtogroup SparseCore_Module+ \ingroup Sparse_Reference */+/** \addtogroup OrderingMethods_Module+ \ingroup Sparse_Reference */+/** \addtogroup SparseCholesky_Module+ \ingroup Sparse_Reference */+/** \addtogroup SparseLU_Module+ \ingroup Sparse_Reference */+/** \addtogroup SparseQR_Module+ \ingroup Sparse_Reference */+/** \addtogroup IterativeLinearSolvers_Module+ \ingroup Sparse_Reference */+/** \addtogroup Sparse_Module+ \ingroup Sparse_Reference */+/** \addtogroup Support_modules+ \ingroup Sparse_Reference */ ++/** \addtogroup SparseQuickRefPage+ \ingroup Sparse_chapter */+++/** \defgroup Geometry_chapter Geometry */+/** \defgroup Geometry_Reference Reference */++/** \addtogroup TutorialGeometry+ \ingroup Geometry_chapter */+ +/** \addtogroup Geometry_Reference+ \ingroup Geometry_chapter */+/** \addtogroup Geometry_Module+ \ingroup Geometry_Reference */+/** \addtogroup Splines_Module+ \ingroup Geometry_Reference */+}
+ eigen3/doc/Overview.dox view
@@ -0,0 +1,28 @@+namespace Eigen {++/** \mainpage notitle++This is the API documentation for Eigen3. You can <a href="eigen-doc.tgz">download</a> it as a tgz archive for offline reading.++You're already an Eigen2 user? Here is a \link Eigen2ToEigen3 Eigen2 to Eigen3 guide \endlink to help porting your application.++For a first contact with Eigen, the best place is to have a look at the \link GettingStarted getting started \endlink page that show you how to write and compile your first program with Eigen.++Then, the \b quick \b reference \b pages give you a quite complete description of the API in a very condensed format that is specially useful to recall the syntax of a particular feature, or to have a quick look at the API. They currently cover the two following feature sets, and more will come in the future:+ - \link QuickRefPage [QuickRef] Dense matrix and array manipulations \endlink+ - \link SparseQuickRefPage [QuickRef] Sparse linear algebra \endlink++You're a MatLab user? There is also a <a href="AsciiQuickReference.txt">short ASCII reference</a> with Matlab translations.+ +The \b main \b documentation is organized into \em chapters covering different domains of features.+They are themselves composed of \em user \em manual pages describing the different features in a comprehensive way, and \em reference pages that gives you access to the API documentation through the related Eigen's \em modules and \em classes.++Under the \subpage UserManual_Generalities section, you will find documentation on more general topics such as preprocessor directives, controlling assertions, multi-threading, MKL support, some Eigen's internal insights, and much more...++Finally, do not miss the search engine, useful to quickly get to the documentation of a given class or function.++Want more? Checkout the <a href="unsupported/index.html">\em unsupported \em modules </a> documentation.++*/++}
+ eigen3/doc/PassingByValue.dox view
@@ -0,0 +1,40 @@+namespace Eigen {++/** \eigenManualPage TopicPassingByValue Passing Eigen objects by value to functions++Passing objects by value is almost always a very bad idea in C++, as this means useless copies, and one should pass them by reference instead.++With Eigen, this is even more important: passing \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen objects" by value is not only inefficient, it can be illegal or make your program crash! And the reason is that these Eigen objects have alignment modifiers that aren't respected when they are passed by value.++So for example, a function like this, where v is passed by value:++\code+void my_function(Eigen::Vector2d v);+\endcode++needs to be rewritten as follows, passing v by reference:++\code+void my_function(const Eigen::Vector2d& v);+\endcode++Likewise if you have a class having a Eigen object as member:++\code+struct Foo+{+ Eigen::Vector2d v;+};+void my_function(Foo v);+\endcode++This function also needs to be rewritten like this:+\code+void my_function(const Foo& v);+\endcode++Note that on the other hand, there is no problem with functions that return objects by value.++*/++}
+ eigen3/doc/PreprocessorDirectives.dox view
@@ -0,0 +1,119 @@+namespace Eigen {++/** \page TopicPreprocessorDirectives Preprocessor directives++You can control some aspects of %Eigen by defining the preprocessor tokens using \c \#define. These macros+should be defined before any %Eigen headers are included. Often they are best set in the project options.++This page lists the preprocesor tokens recognised by %Eigen.++\eigenAutoToc+++\section TopicPreprocessorDirectivesMajor Macros with major effects++These macros have a major effect and typically break the API (Application Programming Interface) and/or the+ABI (Application Binary Interface). This can be rather dangerous: if parts of your program are compiled with+one option, and other parts (or libraries that you use) are compiled with another option, your program may+fail to link or exhibit subtle bugs. Nevertheless, these options can be useful for people who know what they+are doing.++ - \b EIGEN2_SUPPORT - if defined, enables the Eigen2 compatibility mode. This is meant to ease the transition+ of Eigen2 to Eigen3 (see \ref Eigen2ToEigen3). Not defined by default.+ - \b EIGEN2_SUPPORT_STAGEnn_xxx (for various values of nn and xxx) - staged migration path from Eigen2 to+ Eigen3; see \ref Eigen2SupportModes.+ - \b EIGEN_DEFAULT_DENSE_INDEX_TYPE - the type for column and row indices in matrices, vectors and array+ (DenseBase::Index). Set to \c std::ptrdiff_t by default.+ - \b EIGEN_DEFAULT_IO_FORMAT - the IOFormat to use when printing a matrix if no %IOFormat is specified.+ Defaults to the %IOFormat constructed by the default constructor IOFormat::IOFormat().+ - \b EIGEN_INITIALIZE_MATRICES_BY_ZERO - if defined, all entries of newly constructed matrices and arrays are+ initialized to zero, as are new entries in matrices and arrays after resizing. Not defined by default.+ - \b EIGEN_INITIALIZE_MATRICES_BY_NAN - if defined, all entries of newly constructed matrices and arrays are+ initialized to NaN, as are new entries in matrices and arrays after resizing. This option is especially+ useful for debugging purpose, though a memory tool like <a href="http://valgrind.org/">valgrind</a> is+ preferable. Not defined by default.+ - \b EIGEN_NO_AUTOMATIC_RESIZING - if defined, the matrices (or arrays) on both sides of an assignment + <tt>a = b</tt> have to be of the same size; otherwise, %Eigen automatically resizes \c a so that it is of+ the correct size. Not defined by default.+++\section TopicPreprocessorDirectivesAssertions Assertions++The %Eigen library contains many assertions to guard against programming errors, both at compile time and at+run time. However, these assertions do cost time and can thus be turned off.++ - \b EIGEN_NO_DEBUG - disables %Eigen's assertions if defined. Not defined by default, unless the+ \c NDEBUG macro is defined (this is a standard C++ macro which disables all asserts). + - \b EIGEN_NO_STATIC_ASSERT - if defined, compile-time static assertions are replaced by runtime assertions; + this saves compilation time. Not defined by default.+ - \b eigen_assert - macro with one argument that is used inside %Eigen for assertions. By default, it is+ basically defined to be \c assert, which aborts the program if the assertion is violated. Redefine this+ macro if you want to do something else, like throwing an exception.+ - \b EIGEN_MPL2_ONLY - disable non MPL2 compatible features, or in other words disable the features which+ are still under the LGPL.+++\section TopicPreprocessorDirectivesPerformance Alignment, vectorization and performance tweaking++ - \b EIGEN_MALLOC_ALREADY_ALIGNED - Can be set to 0 or 1 to tell whether default system malloc already+ returns aligned buffers. In not defined, then this information is automatically deduced from the compiler+ and system preprocessor tokens.+ - \b EIGEN_DONT_ALIGN - disables alignment completely. %Eigen will not try to align its objects and does not+ expect that any objects passed to it are aligned. This will turn off vectorization. Not defined by default.+ - \b EIGEN_DONT_ALIGN_STATICALLY - disables alignment of arrays on the stack. Not defined by default, unless+ \c EIGEN_DONT_ALIGN is defined.+ - \b EIGEN_DONT_PARALLELIZE - if defined, this disables multi-threading. This is only relevant if you enabled OpenMP.+ See \ref TopicMultiThreading for details.+ - \b EIGEN_DONT_VECTORIZE - disables explicit vectorization when defined. Not defined by default, unless + alignment is disabled by %Eigen's platform test or the user defining \c EIGEN_DONT_ALIGN.+ - \b EIGEN_FAST_MATH - enables some optimizations which might affect the accuracy of the result. This currently+ enables the SSE vectorization of sin() and cos(), and speedups sqrt() for single precision. Defined to 1 by default.+ Define it to 0 to disable.+ - \b EIGEN_UNROLLING_LIMIT - defines the size of a loop to enable meta unrolling. Set it to zero to disable+ unrolling. The size of a loop here is expressed in %Eigen's own notion of "number of FLOPS", it does not+ correspond to the number of iterations or the number of instructions. The default is value 100.+ - \b EIGEN_STACK_ALLOCATION_LIMIT - defines the maximum bytes for a buffer to be allocated on the stack. For internal+ temporary buffers, dynamic memory allocation is employed as a fall back. For fixed-size matrices or arrays, exceeding+ this threshold raises a compile time assertion. Use 0 to set no limit. Default is 128 KB.+++\section TopicPreprocessorDirectivesPlugins Plugins++It is possible to add new methods to many fundamental classes in %Eigen by writing a plugin. As explained in+the section \ref ExtendingMatrixBase, the plugin is specified by defining a \c EIGEN_xxx_PLUGIN macro. The+following macros are supported; none of them are defined by default.++ - \b EIGEN_ARRAY_PLUGIN - filename of plugin for extending the Array class.+ - \b EIGEN_ARRAYBASE_PLUGIN - filename of plugin for extending the ArrayBase class.+ - \b EIGEN_CWISE_PLUGIN - filename of plugin for extending the Cwise class.+ - \b EIGEN_DENSEBASE_PLUGIN - filename of plugin for extending the DenseBase class.+ - \b EIGEN_DYNAMICSPARSEMATRIX_PLUGIN - filename of plugin for extending the DynamicSparseMatrix class.+ - \b EIGEN_MATRIX_PLUGIN - filename of plugin for extending the Matrix class.+ - \b EIGEN_MATRIXBASE_PLUGIN - filename of plugin for extending the MatrixBase class.+ - \b EIGEN_PLAINOBJECTBASE_PLUGIN - filename of plugin for extending the PlainObjectBase class.+ - \b EIGEN_QUATERNIONBASE_PLUGIN - filename of plugin for extending the QuaternionBase class.+ - \b EIGEN_SPARSEMATRIX_PLUGIN - filename of plugin for extending the SparseMatrix class.+ - \b EIGEN_SPARSEMATRIXBASE_PLUGIN - filename of plugin for extending the SparseMatrixBase class.+ - \b EIGEN_SPARSEVECTOR_PLUGIN - filename of plugin for extending the SparseVector class.+ - \b EIGEN_TRANSFORM_PLUGIN - filename of plugin for extending the Transform class.+ - \b EIGEN_FUNCTORS_PLUGIN - filename of plugin for adding new functors and specializations of functor_traits.+++\section TopicPreprocessorDirectivesDevelopers Macros for Eigen developers++These macros are mainly meant for people developing %Eigen and for testing purposes. Even though, they might be useful for power users and the curious for debugging and testing purpose, they \b should \b not \b be \b used by real-word code.++ - \b EIGEN_DEFAULT_TO_ROW_MAJOR - when defined, the default storage order for matrices becomes row-major+ instead of column-major. Not defined by default.+ - \b EIGEN_INTERNAL_DEBUGGING - if defined, enables assertions in %Eigen's internal routines. This is useful+ for debugging %Eigen itself. Not defined by default.+ - \b EIGEN_NO_MALLOC - if defined, any request from inside the %Eigen to allocate memory from the heap+ results in an assertion failure. This is useful to check that some routine does not allocate memory+ dynamically. Not defined by default.+ - \b EIGEN_RUNTIME_NO_MALLOC - if defined, a new switch is introduced which can be turned on and off by+ calling <tt>set_is_malloc_allowed(bool)</tt>. If malloc is not allowed and %Eigen tries to allocate memory+ dynamically anyway, an assertion failure results. Not defined by default.++*/++}
+ eigen3/doc/QuickReference.dox view
@@ -0,0 +1,727 @@+namespace Eigen {++/** \eigenManualPage QuickRefPage Quick reference guide++\eigenAutoToc++<hr>++<a href="#" class="top">top</a>+\section QuickRef_Headers Modules and Header files++The Eigen library is divided in a Core module and several additional modules. Each module has a corresponding header file which has to be included in order to use the module. The \c %Dense and \c Eigen header files are provided to conveniently gain access to several modules at once.++<table class="manual">+<tr><th>Module</th><th>Header file</th><th>Contents</th></tr>+<tr><td>\link Core_Module Core \endlink</td><td>\code#include <Eigen/Core>\endcode</td><td>Matrix and Array classes, basic linear algebra (including triangular and selfadjoint products), array manipulation</td></tr>+<tr class="alt"><td>\link Geometry_Module Geometry \endlink</td><td>\code#include <Eigen/Geometry>\endcode</td><td>Transform, Translation, Scaling, Rotation2D and 3D rotations (Quaternion, AngleAxis)</td></tr>+<tr><td>\link LU_Module LU \endlink</td><td>\code#include <Eigen/LU>\endcode</td><td>Inverse, determinant, LU decompositions with solver (FullPivLU, PartialPivLU)</td></tr>+<tr><td>\link Cholesky_Module Cholesky \endlink</td><td>\code#include <Eigen/Cholesky>\endcode</td><td>LLT and LDLT Cholesky factorization with solver</td></tr>+<tr class="alt"><td>\link Householder_Module Householder \endlink</td><td>\code#include <Eigen/Householder>\endcode</td><td>Householder transformations; this module is used by several linear algebra modules</td></tr>+<tr><td>\link SVD_Module SVD \endlink</td><td>\code#include <Eigen/SVD>\endcode</td><td>SVD decomposition with least-squares solver (JacobiSVD)</td></tr>+<tr class="alt"><td>\link QR_Module QR \endlink</td><td>\code#include <Eigen/QR>\endcode</td><td>QR decomposition with solver (HouseholderQR, ColPivHouseholderQR, FullPivHouseholderQR)</td></tr>+<tr><td>\link Eigenvalues_Module Eigenvalues \endlink</td><td>\code#include <Eigen/Eigenvalues>\endcode</td><td>Eigenvalue, eigenvector decompositions (EigenSolver, SelfAdjointEigenSolver, ComplexEigenSolver)</td></tr>+<tr class="alt"><td>\link Sparse_modules Sparse \endlink</td><td>\code#include <Eigen/Sparse>\endcode</td><td>%Sparse matrix storage and related basic linear algebra (SparseMatrix, DynamicSparseMatrix, SparseVector)</td></tr>+<tr><td></td><td>\code#include <Eigen/Dense>\endcode</td><td>Includes Core, Geometry, LU, Cholesky, SVD, QR, and Eigenvalues header files</td></tr>+<tr class="alt"><td></td><td>\code#include <Eigen/Eigen>\endcode</td><td>Includes %Dense and %Sparse header files (the whole Eigen library)</td></tr>+</table>++<a href="#" class="top">top</a>+\section QuickRef_Types Array, matrix and vector types+++\b Recall: Eigen provides two kinds of dense objects: mathematical matrices and vectors which are both represented by the template class Matrix, and general 1D and 2D arrays represented by the template class Array:+\code+typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, Options> MyMatrixType;+typedef Array<Scalar, RowsAtCompileTime, ColsAtCompileTime, Options> MyArrayType;+\endcode++\li \c Scalar is the scalar type of the coefficients (e.g., \c float, \c double, \c bool, \c int, etc.).+\li \c RowsAtCompileTime and \c ColsAtCompileTime are the number of rows and columns of the matrix as known at compile-time or \c Dynamic.+\li \c Options can be \c ColMajor or \c RowMajor, default is \c ColMajor. (see class Matrix for more options)++All combinations are allowed: you can have a matrix with a fixed number of rows and a dynamic number of columns, etc. The following are all valid:+\code+Matrix<double, 6, Dynamic> // Dynamic number of columns (heap allocation)+Matrix<double, Dynamic, 2> // Dynamic number of rows (heap allocation)+Matrix<double, Dynamic, Dynamic, RowMajor> // Fully dynamic, row major (heap allocation)+Matrix<double, 13, 3> // Fully fixed (usually allocated on stack)+\endcode++In most cases, you can simply use one of the convenience typedefs for \ref matrixtypedefs "matrices" and \ref arraytypedefs "arrays". Some examples:+<table class="example">+<tr><th>Matrices</th><th>Arrays</th></tr>+<tr><td>\code+Matrix<float,Dynamic,Dynamic> <=> MatrixXf+Matrix<double,Dynamic,1> <=> VectorXd+Matrix<int,1,Dynamic> <=> RowVectorXi+Matrix<float,3,3> <=> Matrix3f+Matrix<float,4,1> <=> Vector4f+\endcode</td><td>\code+Array<float,Dynamic,Dynamic> <=> ArrayXXf+Array<double,Dynamic,1> <=> ArrayXd+Array<int,1,Dynamic> <=> RowArrayXi+Array<float,3,3> <=> Array33f+Array<float,4,1> <=> Array4f+\endcode</td></tr>+</table>++Conversion between the matrix and array worlds:+\code+Array44f a1, a1;+Matrix4f m1, m2;+m1 = a1 * a2; // coeffwise product, implicit conversion from array to matrix.+a1 = m1 * m2; // matrix product, implicit conversion from matrix to array.+a2 = a1 + m1.array(); // mixing array and matrix is forbidden+m2 = a1.matrix() + m1; // and explicit conversion is required.+ArrayWrapper<Matrix4f> m1a(m1); // m1a is an alias for m1.array(), they share the same coefficients+MatrixWrapper<Array44f> a1m(a1);+\endcode++In the rest of this document we will use the following symbols to emphasize the features which are specifics to a given kind of object:+\li <a name="matrixonly"></a>\matrixworld linear algebra matrix and vector only+\li <a name="arrayonly"></a>\arrayworld array objects only++\subsection QuickRef_Basics Basic matrix manipulation++<table class="manual">+<tr><th></th><th>1D objects</th><th>2D objects</th><th>Notes</th></tr>+<tr><td>Constructors</td>+<td>\code+Vector4d v4;+Vector2f v1(x, y);+Array3i v2(x, y, z);+Vector4d v3(x, y, z, w);++VectorXf v5; // empty object+ArrayXf v6(size);+\endcode</td><td>\code+Matrix4f m1;+++++MatrixXf m5; // empty object+MatrixXf m6(nb_rows, nb_columns);+\endcode</td><td class="note">+By default, the coefficients \n are left uninitialized</td></tr>+<tr class="alt"><td>Comma initializer</td>+<td>\code+Vector3f v1; v1 << x, y, z;+ArrayXf v2(4); v2 << 1, 2, 3, 4;++\endcode</td><td>\code+Matrix3f m1; m1 << 1, 2, 3,+ 4, 5, 6,+ 7, 8, 9;+\endcode</td><td></td></tr>++<tr><td>Comma initializer (bis)</td>+<td colspan="2">+\include Tutorial_commainit_02.cpp+</td>+<td>+output:+\verbinclude Tutorial_commainit_02.out+</td>+</tr>++<tr class="alt"><td>Runtime info</td>+<td>\code+vector.size();++vector.innerStride();+vector.data();+\endcode</td><td>\code+matrix.rows(); matrix.cols();+matrix.innerSize(); matrix.outerSize();+matrix.innerStride(); matrix.outerStride();+matrix.data();+\endcode</td><td class="note">Inner/Outer* are storage order dependent</td></tr>+<tr><td>Compile-time info</td>+<td colspan="2">\code+ObjectType::Scalar ObjectType::RowsAtCompileTime+ObjectType::RealScalar ObjectType::ColsAtCompileTime+ObjectType::Index ObjectType::SizeAtCompileTime+\endcode</td><td></td></tr>+<tr class="alt"><td>Resizing</td>+<td>\code+vector.resize(size);+++vector.resizeLike(other_vector);+vector.conservativeResize(size);+\endcode</td><td>\code+matrix.resize(nb_rows, nb_cols);+matrix.resize(Eigen::NoChange, nb_cols);+matrix.resize(nb_rows, Eigen::NoChange);+matrix.resizeLike(other_matrix);+matrix.conservativeResize(nb_rows, nb_cols);+\endcode</td><td class="note">no-op if the new sizes match,<br/>otherwise data are lost<br/><br/>resizing with data preservation</td></tr>++<tr><td>Coeff access with \n range checking</td>+<td>\code+vector(i) vector.x()+vector[i] vector.y()+ vector.z()+ vector.w()+\endcode</td><td>\code+matrix(i,j)+\endcode</td><td class="note">Range checking is disabled if \n NDEBUG or EIGEN_NO_DEBUG is defined</td></tr>++<tr class="alt"><td>Coeff access without \n range checking</td>+<td>\code+vector.coeff(i)+vector.coeffRef(i)+\endcode</td><td>\code+matrix.coeff(i,j)+matrix.coeffRef(i,j)+\endcode</td><td></td></tr>++<tr><td>Assignment/copy</td>+<td colspan="2">\code+object = expression;+object_of_float = expression_of_double.cast<float>();+\endcode</td><td class="note">the destination is automatically resized (if possible)</td></tr>++</table>++\subsection QuickRef_PredefMat Predefined Matrices++<table class="manual">+<tr>+ <th>Fixed-size matrix or vector</th>+ <th>Dynamic-size matrix</th>+ <th>Dynamic-size vector</th>+</tr>+<tr style="border-bottom-style: none;">+ <td>+\code+typedef {Matrix3f|Array33f} FixedXD;+FixedXD x;++x = FixedXD::Zero();+x = FixedXD::Ones();+x = FixedXD::Constant(value);+x = FixedXD::Random();+x = FixedXD::LinSpaced(size, low, high);++x.setZero();+x.setOnes();+x.setConstant(value);+x.setRandom();+x.setLinSpaced(size, low, high);+\endcode+ </td>+ <td>+\code+typedef {MatrixXf|ArrayXXf} Dynamic2D;+Dynamic2D x;++x = Dynamic2D::Zero(rows, cols);+x = Dynamic2D::Ones(rows, cols);+x = Dynamic2D::Constant(rows, cols, value);+x = Dynamic2D::Random(rows, cols);+N/A++x.setZero(rows, cols);+x.setOnes(rows, cols);+x.setConstant(rows, cols, value);+x.setRandom(rows, cols);+N/A+\endcode+ </td>+ <td>+\code+typedef {VectorXf|ArrayXf} Dynamic1D;+Dynamic1D x;++x = Dynamic1D::Zero(size);+x = Dynamic1D::Ones(size);+x = Dynamic1D::Constant(size, value);+x = Dynamic1D::Random(size);+x = Dynamic1D::LinSpaced(size, low, high);++x.setZero(size);+x.setOnes(size);+x.setConstant(size, value);+x.setRandom(size);+x.setLinSpaced(size, low, high);+\endcode+ </td>+</tr>++<tr><td colspan="3">Identity and \link MatrixBase::Unit basis vectors \endlink \matrixworld</td></tr>+<tr style="border-bottom-style: none;">+ <td>+\code+x = FixedXD::Identity();+x.setIdentity();++Vector3f::UnitX() // 1 0 0+Vector3f::UnitY() // 0 1 0+Vector3f::UnitZ() // 0 0 1+\endcode+ </td>+ <td>+\code+x = Dynamic2D::Identity(rows, cols);+x.setIdentity(rows, cols);++++N/A+\endcode+ </td>+ <td>\code+N/A+++VectorXf::Unit(size,i)+VectorXf::Unit(4,1) == Vector4f(0,1,0,0)+ == Vector4f::UnitY()+\endcode+ </td>+</tr>+</table>++++\subsection QuickRef_Map Mapping external arrays++<table class="manual">+<tr>+<td>Contiguous \n memory</td>+<td>\code+float data[] = {1,2,3,4};+Map<Vector3f> v1(data); // uses v1 as a Vector3f object+Map<ArrayXf> v2(data,3); // uses v2 as a ArrayXf object+Map<Array22f> m1(data); // uses m1 as a Array22f object+Map<MatrixXf> m2(data,2,2); // uses m2 as a MatrixXf object+\endcode</td>+</tr>+<tr>+<td>Typical usage \n of strides</td>+<td>\code+float data[] = {1,2,3,4,5,6,7,8,9};+Map<VectorXf,0,InnerStride<2> > v1(data,3); // = [1,3,5]+Map<VectorXf,0,InnerStride<> > v2(data,3,InnerStride<>(3)); // = [1,4,7]+Map<MatrixXf,0,OuterStride<3> > m2(data,2,3); // both lines |1,4,7|+Map<MatrixXf,0,OuterStride<> > m1(data,2,3,OuterStride<>(3)); // are equal to: |2,5,8|+\endcode</td>+</tr>+</table>+++<a href="#" class="top">top</a>+\section QuickRef_ArithmeticOperators Arithmetic Operators++<table class="manual">+<tr><td>+add \n subtract</td><td>\code+mat3 = mat1 + mat2; mat3 += mat1;+mat3 = mat1 - mat2; mat3 -= mat1;\endcode+</td></tr>+<tr class="alt"><td>+scalar product</td><td>\code+mat3 = mat1 * s1; mat3 *= s1; mat3 = s1 * mat1;+mat3 = mat1 / s1; mat3 /= s1;\endcode+</td></tr>+<tr><td>+matrix/vector \n products \matrixworld</td><td>\code+col2 = mat1 * col1;+row2 = row1 * mat1; row1 *= mat1;+mat3 = mat1 * mat2; mat3 *= mat1; \endcode+</td></tr>+<tr class="alt"><td>+transposition \n adjoint \matrixworld</td><td>\code+mat1 = mat2.transpose(); mat1.transposeInPlace();+mat1 = mat2.adjoint(); mat1.adjointInPlace();+\endcode+</td></tr>+<tr><td>+\link MatrixBase::dot() dot \endlink product \n inner product \matrixworld</td><td>\code+scalar = vec1.dot(vec2);+scalar = col1.adjoint() * col2;+scalar = (col1.adjoint() * col2).value();\endcode+</td></tr>+<tr class="alt"><td>+outer product \matrixworld</td><td>\code+mat = col1 * col2.transpose();\endcode+</td></tr>++<tr><td>+\link MatrixBase::norm() norm \endlink \n \link MatrixBase::normalized() normalization \endlink \matrixworld</td><td>\code+scalar = vec1.norm(); scalar = vec1.squaredNorm()+vec2 = vec1.normalized(); vec1.normalize(); // inplace \endcode+</td></tr>++<tr class="alt"><td>+\link MatrixBase::cross() cross product \endlink \matrixworld</td><td>\code+#include <Eigen/Geometry>+vec3 = vec1.cross(vec2);\endcode</td></tr>+</table>++<a href="#" class="top">top</a>+\section QuickRef_Coeffwise Coefficient-wise \& Array operators+Coefficient-wise operators for matrices and vectors:+<table class="manual">+<tr><th>Matrix API \matrixworld</th><th>Via Array conversions</th></tr>+<tr><td>\code+mat1.cwiseMin(mat2)+mat1.cwiseMax(mat2)+mat1.cwiseAbs2()+mat1.cwiseAbs()+mat1.cwiseSqrt()+mat1.cwiseProduct(mat2)+mat1.cwiseQuotient(mat2)\endcode+</td><td>\code+mat1.array().min(mat2.array())+mat1.array().max(mat2.array())+mat1.array().abs2()+mat1.array().abs()+mat1.array().sqrt()+mat1.array() * mat2.array()+mat1.array() / mat2.array()+\endcode</td></tr>+</table>++It is also very simple to apply any user defined function \c foo using DenseBase::unaryExpr together with std::ptr_fun:+\code mat1.unaryExpr(std::ptr_fun(foo))\endcode++Array operators:\arrayworld++<table class="manual">+<tr><td>Arithmetic operators</td><td>\code+array1 * array2 array1 / array2 array1 *= array2 array1 /= array2+array1 + scalar array1 - scalar array1 += scalar array1 -= scalar+\endcode</td></tr>+<tr><td>Comparisons</td><td>\code+array1 < array2 array1 > array2 array1 < scalar array1 > scalar+array1 <= array2 array1 >= array2 array1 <= scalar array1 >= scalar+array1 == array2 array1 != array2 array1 == scalar array1 != scalar+\endcode</td></tr>+<tr><td>Trigo, power, and \n misc functions \n and the STL variants</td><td>\code+array1.min(array2) +array1.max(array2) +array1.abs2()+array1.abs() abs(array1)+array1.sqrt() sqrt(array1)+array1.log() log(array1)+array1.exp() exp(array1)+array1.pow(exponent) pow(array1,exponent)+array1.square()+array1.cube()+array1.inverse()+array1.sin() sin(array1)+array1.cos() cos(array1)+array1.tan() tan(array1)+array1.asin() asin(array1)+array1.acos() acos(array1)+\endcode+</td></tr>+</table>++<a href="#" class="top">top</a>+\section QuickRef_Reductions Reductions++Eigen provides several reduction methods such as:+\link DenseBase::minCoeff() minCoeff() \endlink, \link DenseBase::maxCoeff() maxCoeff() \endlink,+\link DenseBase::sum() sum() \endlink, \link DenseBase::prod() prod() \endlink,+\link MatrixBase::trace() trace() \endlink \matrixworld,+\link MatrixBase::norm() norm() \endlink \matrixworld, \link MatrixBase::squaredNorm() squaredNorm() \endlink \matrixworld,+\link DenseBase::all() all() \endlink, and \link DenseBase::any() any() \endlink.+All reduction operations can be done matrix-wise,+\link DenseBase::colwise() column-wise \endlink or+\link DenseBase::rowwise() row-wise \endlink. Usage example:+<table class="manual">+<tr><td rowspan="3" style="border-right-style:dashed;vertical-align:middle">\code+ 5 3 1+mat = 2 7 8+ 9 4 6 \endcode+</td> <td>\code mat.minCoeff(); \endcode</td><td>\code 1 \endcode</td></tr>+<tr class="alt"><td>\code mat.colwise().minCoeff(); \endcode</td><td>\code 2 3 1 \endcode</td></tr>+<tr style="vertical-align:middle"><td>\code mat.rowwise().minCoeff(); \endcode</td><td>\code+1+2+4+\endcode</td></tr>+</table>++Special versions of \link DenseBase::minCoeff(IndexType*,IndexType*) const minCoeff \endlink and \link DenseBase::maxCoeff(IndexType*,IndexType*) const maxCoeff \endlink:+\code+int i, j;+s = vector.minCoeff(&i); // s == vector[i]+s = matrix.maxCoeff(&i, &j); // s == matrix(i,j)+\endcode+Typical use cases of all() and any():+\code+if((array1 > 0).all()) ... // if all coefficients of array1 are greater than 0 ...+if((array1 < array2).any()) ... // if there exist a pair i,j such that array1(i,j) < array2(i,j) ...+\endcode+++<a href="#" class="top">top</a>\section QuickRef_Blocks Sub-matrices++Read-write access to a \link DenseBase::col(Index) column \endlink+or a \link DenseBase::row(Index) row \endlink of a matrix (or array):+\code+mat1.row(i) = mat2.col(j);+mat1.col(j1).swap(mat1.col(j2));+\endcode++Read-write access to sub-vectors:+<table class="manual">+<tr>+<th>Default versions</th>+<th>Optimized versions when the size \n is known at compile time</th></tr>+<th></th>++<tr><td>\code vec1.head(n)\endcode</td><td>\code vec1.head<n>()\endcode</td><td>the first \c n coeffs </td></tr>+<tr><td>\code vec1.tail(n)\endcode</td><td>\code vec1.tail<n>()\endcode</td><td>the last \c n coeffs </td></tr>+<tr><td>\code vec1.segment(pos,n)\endcode</td><td>\code vec1.segment<n>(pos)\endcode</td>+ <td>the \c n coeffs in the \n range [\c pos : \c pos + \c n - 1]</td></tr>+<tr class="alt"><td colspan="3">++Read-write access to sub-matrices:</td></tr>+<tr>+ <td>\code mat1.block(i,j,rows,cols)\endcode+ \link DenseBase::block(Index,Index,Index,Index) (more) \endlink</td>+ <td>\code mat1.block<rows,cols>(i,j)\endcode+ \link DenseBase::block(Index,Index) (more) \endlink</td>+ <td>the \c rows x \c cols sub-matrix \n starting from position (\c i,\c j)</td></tr>+<tr><td>\code+ mat1.topLeftCorner(rows,cols)+ mat1.topRightCorner(rows,cols)+ mat1.bottomLeftCorner(rows,cols)+ mat1.bottomRightCorner(rows,cols)\endcode+ <td>\code+ mat1.topLeftCorner<rows,cols>()+ mat1.topRightCorner<rows,cols>()+ mat1.bottomLeftCorner<rows,cols>()+ mat1.bottomRightCorner<rows,cols>()\endcode+ <td>the \c rows x \c cols sub-matrix \n taken in one of the four corners</td></tr>+ <tr><td>\code+ mat1.topRows(rows)+ mat1.bottomRows(rows)+ mat1.leftCols(cols)+ mat1.rightCols(cols)\endcode+ <td>\code+ mat1.topRows<rows>()+ mat1.bottomRows<rows>()+ mat1.leftCols<cols>()+ mat1.rightCols<cols>()\endcode+ <td>specialized versions of block() \n when the block fit two corners</td></tr>+</table>++++<a href="#" class="top">top</a>\section QuickRef_Misc Miscellaneous operations++\subsection QuickRef_Reverse Reverse+Vectors, rows, and/or columns of a matrix can be reversed (see DenseBase::reverse(), DenseBase::reverseInPlace(), VectorwiseOp::reverse()).+\code+vec.reverse() mat.colwise().reverse() mat.rowwise().reverse()+vec.reverseInPlace()+\endcode++\subsection QuickRef_Replicate Replicate+Vectors, matrices, rows, and/or columns can be replicated in any direction (see DenseBase::replicate(), VectorwiseOp::replicate())+\code+vec.replicate(times) vec.replicate<Times>+mat.replicate(vertical_times, horizontal_times) mat.replicate<VerticalTimes, HorizontalTimes>()+mat.colwise().replicate(vertical_times, horizontal_times) mat.colwise().replicate<VerticalTimes, HorizontalTimes>()+mat.rowwise().replicate(vertical_times, horizontal_times) mat.rowwise().replicate<VerticalTimes, HorizontalTimes>()+\endcode+++<a href="#" class="top">top</a>\section QuickRef_DiagTriSymm Diagonal, Triangular, and Self-adjoint matrices+(matrix world \matrixworld)++\subsection QuickRef_Diagonal Diagonal matrices++<table class="example">+<tr><th>Operation</th><th>Code</th></tr>+<tr><td>+view a vector \link MatrixBase::asDiagonal() as a diagonal matrix \endlink \n </td><td>\code+mat1 = vec1.asDiagonal();\endcode+</td></tr>+<tr><td>+Declare a diagonal matrix</td><td>\code+DiagonalMatrix<Scalar,SizeAtCompileTime> diag1(size);+diag1.diagonal() = vector;\endcode+</td></tr>+<tr><td>Access the \link MatrixBase::diagonal() diagonal \endlink and \link MatrixBase::diagonal(Index) super/sub diagonals \endlink of a matrix as a vector (read/write)</td>+ <td>\code+vec1 = mat1.diagonal(); mat1.diagonal() = vec1; // main diagonal+vec1 = mat1.diagonal(+n); mat1.diagonal(+n) = vec1; // n-th super diagonal+vec1 = mat1.diagonal(-n); mat1.diagonal(-n) = vec1; // n-th sub diagonal+vec1 = mat1.diagonal<1>(); mat1.diagonal<1>() = vec1; // first super diagonal+vec1 = mat1.diagonal<-2>(); mat1.diagonal<-2>() = vec1; // second sub diagonal+\endcode</td>+</tr>++<tr><td>Optimized products and inverse</td>+ <td>\code+mat3 = scalar * diag1 * mat1;+mat3 += scalar * mat1 * vec1.asDiagonal();+mat3 = vec1.asDiagonal().inverse() * mat1+mat3 = mat1 * diag1.inverse()+\endcode</td>+</tr>++</table>++\subsection QuickRef_TriangularView Triangular views++TriangularView gives a view on a triangular part of a dense matrix and allows to perform optimized operations on it. The opposite triangular part is never referenced and can be used to store other information.++\note The .triangularView() template member function requires the \c template keyword if it is used on an+object of a type that depends on a template parameter; see \ref TopicTemplateKeyword for details.++<table class="example">+<tr><th>Operation</th><th>Code</th></tr>+<tr><td>+Reference to a triangular with optional \n+unit or null diagonal (read/write):+</td><td>\code+m.triangularView<Xxx>()+\endcode \n+\c Xxx = ::Upper, ::Lower, ::StrictlyUpper, ::StrictlyLower, ::UnitUpper, ::UnitLower+</td></tr>+<tr><td>+Writing to a specific triangular part:\n (only the referenced triangular part is evaluated)+</td><td>\code+m1.triangularView<Eigen::Lower>() = m2 + m3 \endcode+</td></tr>+<tr><td>+Conversion to a dense matrix setting the opposite triangular part to zero:+</td><td>\code+m2 = m1.triangularView<Eigen::UnitUpper>()\endcode+</td></tr>+<tr><td>+Products:+</td><td>\code+m3 += s1 * m1.adjoint().triangularView<Eigen::UnitUpper>() * m2+m3 -= s1 * m2.conjugate() * m1.adjoint().triangularView<Eigen::Lower>() \endcode+</td></tr>+<tr><td>+Solving linear equations:\n+\f$ M_2 := L_1^{-1} M_2 \f$ \n+\f$ M_3 := {L_1^*}^{-1} M_3 \f$ \n+\f$ M_4 := M_4 U_1^{-1} \f$+</td><td>\n \code+L1.triangularView<Eigen::UnitLower>().solveInPlace(M2)+L1.triangularView<Eigen::Lower>().adjoint().solveInPlace(M3)+U1.triangularView<Eigen::Upper>().solveInPlace<OnTheRight>(M4)\endcode+</td></tr>+</table>++\subsection QuickRef_SelfadjointMatrix Symmetric/selfadjoint views++Just as for triangular matrix, you can reference any triangular part of a square matrix to see it as a selfadjoint+matrix and perform special and optimized operations. Again the opposite triangular part is never referenced and can be+used to store other information.++\note The .selfadjointView() template member function requires the \c template keyword if it is used on an+object of a type that depends on a template parameter; see \ref TopicTemplateKeyword for details.++<table class="example">+<tr><th>Operation</th><th>Code</th></tr>+<tr><td>+Conversion to a dense matrix:+</td><td>\code+m2 = m.selfadjointView<Eigen::Lower>();\endcode+</td></tr>+<tr><td>+Product with another general matrix or vector:+</td><td>\code+m3 = s1 * m1.conjugate().selfadjointView<Eigen::Upper>() * m3;+m3 -= s1 * m3.adjoint() * m1.selfadjointView<Eigen::Lower>();\endcode+</td></tr>+<tr><td>+Rank 1 and rank K update: \n+\f$ upper(M_1) \mathrel{{+}{=}} s_1 M_2 M_2^* \f$ \n+\f$ lower(M_1) \mathbin{{-}{=}} M_2^* M_2 \f$+</td><td>\n \code+M1.selfadjointView<Eigen::Upper>().rankUpdate(M2,s1);+M1.selfadjointView<Eigen::Lower>().rankUpdate(M2.adjoint(),-1); \endcode+</td></tr>+<tr><td>+Rank 2 update: (\f$ M \mathrel{{+}{=}} s u v^* + s v u^* \f$)+</td><td>\code+M.selfadjointView<Eigen::Upper>().rankUpdate(u,v,s);+\endcode+</td></tr>+<tr><td>+Solving linear equations:\n(\f$ M_2 := M_1^{-1} M_2 \f$)+</td><td>\code+// via a standard Cholesky factorization+m2 = m1.selfadjointView<Eigen::Upper>().llt().solve(m2);+// via a Cholesky factorization with pivoting+m2 = m1.selfadjointView<Eigen::Lower>().ldlt().solve(m2);+\endcode+</td></tr>+</table>++*/++/*+<table class="tutorial_code">+<tr><td>+\link MatrixBase::asDiagonal() make a diagonal matrix \endlink \n from a vector </td><td>\code+mat1 = vec1.asDiagonal();\endcode+</td></tr>+<tr><td>+Declare a diagonal matrix</td><td>\code+DiagonalMatrix<Scalar,SizeAtCompileTime> diag1(size);+diag1.diagonal() = vector;\endcode+</td></tr>+<tr><td>Access \link MatrixBase::diagonal() the diagonal and super/sub diagonals of a matrix \endlink as a vector (read/write)</td>+ <td>\code+vec1 = mat1.diagonal(); mat1.diagonal() = vec1; // main diagonal+vec1 = mat1.diagonal(+n); mat1.diagonal(+n) = vec1; // n-th super diagonal+vec1 = mat1.diagonal(-n); mat1.diagonal(-n) = vec1; // n-th sub diagonal+vec1 = mat1.diagonal<1>(); mat1.diagonal<1>() = vec1; // first super diagonal+vec1 = mat1.diagonal<-2>(); mat1.diagonal<-2>() = vec1; // second sub diagonal+\endcode</td>+</tr>++<tr><td>View on a triangular part of a matrix (read/write)</td>+ <td>\code+mat2 = mat1.triangularView<Xxx>();+// Xxx = Upper, Lower, StrictlyUpper, StrictlyLower, UnitUpper, UnitLower+mat1.triangularView<Upper>() = mat2 + mat3; // only the upper part is evaluated and referenced+\endcode</td></tr>++<tr><td>View a triangular part as a symmetric/self-adjoint matrix (read/write)</td>+ <td>\code+mat2 = mat1.selfadjointView<Xxx>(); // Xxx = Upper or Lower+mat1.selfadjointView<Upper>() = mat2 + mat2.adjoint(); // evaluated and write to the upper triangular part only+\endcode</td></tr>++</table>++Optimized products:+\code+mat3 += scalar * vec1.asDiagonal() * mat1+mat3 += scalar * mat1 * vec1.asDiagonal()+mat3.noalias() += scalar * mat1.triangularView<Xxx>() * mat2+mat3.noalias() += scalar * mat2 * mat1.triangularView<Xxx>()+mat3.noalias() += scalar * mat1.selfadjointView<Upper or Lower>() * mat2+mat3.noalias() += scalar * mat2 * mat1.selfadjointView<Upper or Lower>()+mat1.selfadjointView<Upper or Lower>().rankUpdate(mat2);+mat1.selfadjointView<Upper or Lower>().rankUpdate(mat2.adjoint(), scalar);+\endcode++Inverse products: (all are optimized)+\code+mat3 = vec1.asDiagonal().inverse() * mat1+mat3 = mat1 * diag1.inverse()+mat1.triangularView<Xxx>().solveInPlace(mat2)+mat1.triangularView<Xxx>().solveInPlace<OnTheRight>(mat2)+mat2 = mat1.selfadjointView<Upper or Lower>().llt().solve(mat2)+\endcode++*/+}
+ eigen3/doc/QuickStartGuide.dox view
@@ -0,0 +1,100 @@+namespace Eigen {++/** \page GettingStarted Getting started++\eigenAutoToc++This is a very short guide on how to get started with Eigen. It has a dual purpose. It serves as a minimal introduction to the Eigen library for people who want to start coding as soon as possible. You can also read this page as the first part of the Tutorial, which explains the library in more detail; in this case you will continue with \ref TutorialMatrixClass.++\section GettingStartedInstallation How to "install" Eigen?++In order to use Eigen, you just need to download and extract Eigen's source code (see <a href="http://eigen.tuxfamily.org/index.php?title=Main_Page#Download">the wiki</a> for download instructions). In fact, the header files in the \c Eigen subdirectory are the only files required to compile programs using Eigen. The header files are the same for all platforms. It is not necessary to use CMake or install anything.+++\section GettingStartedFirstProgram A simple first program++Here is a rather simple program to get you started.++\include QuickStart_example.cpp++We will explain the program after telling you how to compile it.+++\section GettingStartedCompiling Compiling and running your first program++There is no library to link to. The only thing that you need to keep in mind when compiling the above program is that the compiler must be able to find the Eigen header files. The directory in which you placed Eigen's source code must be in the include path. With GCC you use the -I option to achieve this, so you can compile the program with a command like this:++\code g++ -I /path/to/eigen/ my_program.cpp -o my_program \endcode++On Linux or Mac OS X, another option is to symlink or copy the Eigen folder into /usr/local/include/. This way, you can compile the program with:++\code g++ my_program.cpp -o my_program \endcode++When you run the program, it produces the following output:++\include QuickStart_example.out+++\section GettingStartedExplanation Explanation of the first program++The Eigen header files define many types, but for simple applications it may be enough to use only the \c MatrixXd type. This represents a matrix of arbitrary size (hence the \c X in \c MatrixXd), in which every entry is a \c double (hence the \c d in \c MatrixXd). See the \ref QuickRef_Types "quick reference guide" for an overview of the different types you can use to represent a matrix.++The \c Eigen/Dense header file defines all member functions for the MatrixXd type and related types (see also the \ref QuickRef_Headers "table of header files"). All classes and functions defined in this header file (and other Eigen header files) are in the \c Eigen namespace. ++The first line of the \c main function declares a variable of type \c MatrixXd and specifies that it is a matrix with 2 rows and 2 columns (the entries are not initialized). The statement <tt>m(0,0) = 3</tt> sets the entry in the top-left corner to 3. You need to use round parentheses to refer to entries in the matrix. As usual in computer science, the index of the first index is 0, as opposed to the convention in mathematics that the first index is 1.++The following three statements sets the other three entries. The final line outputs the matrix \c m to the standard output stream.+++\section GettingStartedExample2 Example 2: Matrices and vectors++Here is another example, which combines matrices with vectors. Concentrate on the left-hand program for now; we will talk about the right-hand program later.++<table class="manual">+<tr><th>Size set at run time:</th><th>Size set at compile time:</th></tr>+<tr><td>+\include QuickStart_example2_dynamic.cpp+</td>+<td>+\include QuickStart_example2_fixed.cpp+</td></tr></table>++The output is as follows:++\include QuickStart_example2_dynamic.out+++\section GettingStartedExplanation2 Explanation of the second example++The second example starts by declaring a 3-by-3 matrix \c m which is initialized using the \link DenseBase::Random(Index,Index) Random() \endlink method with random values between -1 and 1. The next line applies a linear mapping such that the values are between 10 and 110. The function call \link DenseBase::Constant(Index,Index,const Scalar&) MatrixXd::Constant\endlink(3,3,1.2) returns a 3-by-3 matrix expression having all coefficients equal to 1.2. The rest is standard arithmetics.++The next line of the \c main function introduces a new type: \c VectorXd. This represents a (column) vector of arbitrary size. Here, the vector \c v is created to contain \c 3 coefficients which are left unitialized. The one but last line uses the so-called comma-initializer, explained in \ref TutorialAdvancedInitialization, to set all coefficients of the vector \c v to be as follows:++\f[+v =+\begin{bmatrix}+ 1 \\+ 2 \\+ 3+\end{bmatrix}.+\f]++The final line of the program multiplies the matrix \c m with the vector \c v and outputs the result.++Now look back at the second example program. We presented two versions of it. In the version in the left column, the matrix is of type \c MatrixXd which represents matrices of arbitrary size. The version in the right column is similar, except that the matrix is of type \c Matrix3d, which represents matrices of a fixed size (here 3-by-3). Because the type already encodes the size of the matrix, it is not necessary to specify the size in the constructor; compare <tt>MatrixXd m(3,3)</tt> with <tt>Matrix3d m</tt>. Similarly, we have \c VectorXd on the left (arbitrary size) versus \c Vector3d on the right (fixed size). Note that here the coefficients of vector \c v are directly set in the constructor, though the same syntax of the left example could be used too.++The use of fixed-size matrices and vectors has two advantages. The compiler emits better (faster) code because it knows the size of the matrices and vectors. Specifying the size in the type also allows for more rigorous checking at compile-time. For instance, the compiler will complain if you try to multiply a \c Matrix4d (a 4-by-4 matrix) with a \c Vector3d (a vector of size 3). However, the use of many types increases compilation time and the size of the executable. The size of the matrix may also not be known at compile-time. A rule of thumb is to use fixed-size matrices for size 4-by-4 and smaller.+++\section GettingStartedConclusion Where to go from here?++It's worth taking the time to read the \ref TutorialMatrixClass "long tutorial".++However if you think you don't need it, you can directly use the classes documentation and our \ref QuickRefPage.++\li \b Next: \ref TutorialMatrixClass++*/++}+
+ eigen3/doc/SparseLinearSystems.dox view
@@ -0,0 +1,183 @@+namespace Eigen {+/** \eigenManualPage TopicSparseSystems Solving Sparse Linear Systems+In Eigen, there are several methods available to solve linear systems when the coefficient matrix is sparse. Because of the special representation of this class of matrices, special care should be taken in order to get a good performance. See \ref TutorialSparse for a detailed introduction about sparse matrices in Eigen. This page lists the sparse solvers available in Eigen. The main steps that are common to all these linear solvers are introduced as well. Depending on the properties of the matrix, the desired accuracy, the end-user is able to tune those steps in order to improve the performance of its code. Note that it is not required to know deeply what's hiding behind these steps: the last section presents a benchmark routine that can be easily used to get an insight on the performance of all the available solvers. ++\eigenAutoToc++\section TutorialSparseDirectSolvers Sparse solvers++%Eigen currently provides a limited set of built-in solvers, as well as wrappers to external solver libraries.+They are summarized in the following table:++<table class="manual">+<tr><th>Class</th><th>Module</th><th>Solver kind</th><th>Matrix kind</th><th>Features related to performance</th>+ <th>Dependencies,License</th><th class="width20em"><p>Notes</p></th></tr>+<tr><td>SimplicialLLT </td><td>\link SparseCholesky_Module SparseCholesky \endlink</td><td>Direct LLt factorization</td><td>SPD</td><td>Fill-in reducing</td>+ <td>built-in, LGPL</td>+ <td>SimplicialLDLT is often preferable</td></tr>+<tr><td>SimplicialLDLT </td><td>\link SparseCholesky_Module SparseCholesky \endlink</td><td>Direct LDLt factorization</td><td>SPD</td><td>Fill-in reducing</td>+ <td>built-in, LGPL</td>+ <td>Recommended for very sparse and not too large problems (e.g., 2D Poisson eq.)</td></tr>+<tr><td>ConjugateGradient</td><td>\link IterativeLinearSolvers_Module IterativeLinearSolvers \endlink</td><td>Classic iterative CG</td><td>SPD</td><td>Preconditionning</td>+ <td>built-in, MPL2</td>+ <td>Recommended for large symmetric problems (e.g., 3D Poisson eq.)</td></tr>+<tr><td>BiCGSTAB</td><td>\link IterativeLinearSolvers_Module IterativeLinearSolvers \endlink</td><td>Iterative stabilized bi-conjugate gradient</td><td>Square</td><td>Preconditionning</td>+ <td>built-in, MPL2</td>+ <td>To speedup the convergence, try it with the \ref IncompleteLUT preconditioner.</td></tr>+<tr><td>SparseLU</td> <td>\link SparseLU_Module SparseLU \endlink </td> <td>LU factorization </td>+ <td>Square </td><td>Fill-in reducing, Leverage fast dense algebra</td>+ <td> built-in, MPL2</td> <td>optimized for small and large problems with irregular patterns </td></tr>+<tr><td>SparseQR</td> <td>\link SparseQR_Module SparseQR \endlink</td> <td> QR factorization</td>+ <td>Any, rectangular</td><td> Fill-in reducing</td>+ <td>built-in, MPL2</td><td>recommended for least-square problems, has a basic rank-revealing feature</td></tr>+<tr> <th colspan="7"> Wrappers to external solvers </th></tr>+<tr><td>PastixLLT \n PastixLDLT \n PastixLU</td><td>\link PaStiXSupport_Module PaStiXSupport \endlink</td><td>Direct LLt, LDLt, LU factorizations</td><td>SPD \n SPD \n Square</td><td>Fill-in reducing, Leverage fast dense algebra, Multithreading</td>+ <td>Requires the <a href="http://pastix.gforge.inria.fr">PaStiX</a> package, \b CeCILL-C </td>+ <td>optimized for tough problems and symmetric patterns</td></tr>+<tr><td>CholmodSupernodalLLT</td><td>\link CholmodSupport_Module CholmodSupport \endlink</td><td>Direct LLt factorization</td><td>SPD</td><td>Fill-in reducing, Leverage fast dense algebra</td>+ <td>Requires the <a href="http://www.cise.ufl.edu/research/sparse/SuiteSparse/">SuiteSparse</a> package, \b GPL </td>+ <td></td></tr>+<tr><td>UmfPackLU</td><td>\link UmfPackSupport_Module UmfPackSupport \endlink</td><td>Direct LU factorization</td><td>Square</td><td>Fill-in reducing, Leverage fast dense algebra</td>+ <td>Requires the <a href="http://www.cise.ufl.edu/research/sparse/SuiteSparse/">SuiteSparse</a> package, \b GPL </td>+ <td></td></tr>+<tr><td>SuperLU</td><td>\link SuperLUSupport_Module SuperLUSupport \endlink</td><td>Direct LU factorization</td><td>Square</td><td>Fill-in reducing, Leverage fast dense algebra</td>+ <td>Requires the <a href="http://crd-legacy.lbl.gov/~xiaoye/SuperLU/">SuperLU</a> library, (BSD-like)</td>+ <td></td></tr>+<tr><td>SPQR</td><td>\link SPQRSupport_Module SPQRSupport \endlink </td> <td> QR factorization </td> + <td> Any, rectangular</td><td>fill-in reducing, multithreaded, fast dense algebra</td>+ <td> requires the <a href="http://www.cise.ufl.edu/research/sparse/SuiteSparse/">SuiteSparse</a> package, \b GPL </td><td>recommended for linear least-squares problems, has a rank-revealing feature</tr>+</table>++Here \c SPD means symmetric positive definite.++All these solvers follow the same general concept.+Here is a typical and general example:+\code+#include <Eigen/RequiredModuleName>+// ...+SparseMatrix<double> A;+// fill A+VectorXd b, x;+// fill b+// solve Ax = b+SolverClassName<SparseMatrix<double> > solver;+solver.compute(A);+if(solver.info()!=Success) {+ // decomposition failed+ return;+}+x = solver.solve(b);+if(solver.info()!=Success) {+ // solving failed+ return;+}+// solve for another right hand side:+x1 = solver.solve(b1);+\endcode++For \c SPD solvers, a second optional template argument allows to specify which triangular part have to be used, e.g.:++\code+#include <Eigen/IterativeLinearSolvers>++ConjugateGradient<SparseMatrix<double>, Eigen::Upper> solver;+x = solver.compute(A).solve(b);+\endcode+In the above example, only the upper triangular part of the input matrix A is considered for solving. The opposite triangle might either be empty or contain arbitrary values.++In the case where multiple problems with the same sparsity pattern have to be solved, then the "compute" step can be decomposed as follow:+\code+SolverClassName<SparseMatrix<double> > solver;+solver.analyzePattern(A); // for this step the numerical values of A are not used+solver.factorize(A);+x1 = solver.solve(b1);+x2 = solver.solve(b2);+...+A = ...; // modify the values of the nonzeros of A, the nonzeros pattern must stay unchanged+solver.factorize(A);+x1 = solver.solve(b1);+x2 = solver.solve(b2);+...+\endcode+The compute() method is equivalent to calling both analyzePattern() and factorize().++Finally, each solver provides some specific features, such as determinant, access to the factors, controls of the iterations, and so on.+More details are availble in the documentations of the respective classes.++\section TheSparseCompute The Compute Step+In the compute() function, the matrix is generally factorized: LLT for self-adjoint matrices, LDLT for general hermitian matrices, LU for non hermitian matrices and QR for rectangular matrices. These are the results of using direct solvers. For this class of solvers precisely, the compute step is further subdivided into analyzePattern() and factorize(). ++The goal of analyzePattern() is to reorder the nonzero elements of the matrix, such that the factorization step creates less fill-in. This step exploits only the structure of the matrix. Hence, the results of this step can be used for other linear systems where the matrix has the same structure. Note however that sometimes, some external solvers (like SuperLU) require that the values of the matrix are set in this step, for instance to equilibrate the rows and columns of the matrix. In this situation, the results of this step should not be used with other matrices.++Eigen provides a limited set of methods to reorder the matrix in this step, either built-in (COLAMD, AMD) or external (METIS). These methods are set in template parameter list of the solver :+\code+DirectSolverClassName<SparseMatrix<double>, OrderingMethod<IndexType> > solver;+\endcode ++See the \link OrderingMethods_Module OrderingMethods module \endlink for the list of available methods and the associated options. ++In factorize(), the factors of the coefficient matrix are computed. This step should be called each time the values of the matrix change. However, the structural pattern of the matrix should not change between multiple calls. ++For iterative solvers, the compute step is used to eventually setup a preconditioner. For instance, with the ILUT preconditioner, the incomplete factors L and U are computed in this step. Remember that, basically, the goal of the preconditioner is to speedup the convergence of an iterative method by solving a modified linear system where the coefficient matrix has more clustered eigenvalues. For real problems, an iterative solver should always be used with a preconditioner. In Eigen, a preconditioner is selected by simply adding it as a template parameter to the iterative solver object. +\code+IterativeSolverClassName<SparseMatrix<double>, PreconditionerName<SparseMatrix<double> > solver; +\endcode+The member function preconditioner() returns a read-write reference to the preconditioner + to directly interact with it. See the \link IterativeLinearSolvers_Module Iterative solvers module \endlink and the documentation of each class for the list of available methods.++\section TheSparseSolve The Solve step+The solve() function computes the solution of the linear systems with one or many right hand sides.+\code+X = solver.solve(B);+\endcode +Here, B can be a vector or a matrix where the columns form the different right hand sides. The solve() function can be called several times as well, for instance when all the right hand sides are not available at once. +\code+x1 = solver.solve(b1);+// Get the second right hand side b2+x2 = solver.solve(b2); +// ...+\endcode+For direct methods, the solution are computed at the machine precision. Sometimes, the solution need not be too accurate. In this case, the iterative methods are more suitable and the desired accuracy can be set before the solve step using \b setTolerance(). For all the available functions, please, refer to the documentation of the \link IterativeLinearSolvers_Module Iterative solvers module \endlink. ++\section BenchmarkRoutine+Most of the time, all you need is to know how much time it will take to qolve your system, and hopefully, what is the most suitable solver. In Eigen, we provide a benchmark routine that can be used for this purpose. It is very easy to use. In the build directory, navigate to bench/spbench and compile the routine by typing \b make \e spbenchsolver. Run it with --help option to get the list of all available options. Basically, the matrices to test should be in <a href="http://math.nist.gov/MatrixMarket/formats.html">MatrixMarket Coordinate format</a>, and the routine returns the statistics from all available solvers in Eigen. ++The following table gives an example of XML statistics from several Eigen built-in and external solvers. +<TABLE border="1">+ <TR><TH>Matrix <TH> N <TH> NNZ <TH> <TH > UMFPACK <TH > SUPERLU <TH > PASTIX LU <TH >BiCGSTAB <TH > BiCGSTAB+ILUT <TH >GMRES+ILUT<TH > LDLT <TH> CHOLMOD LDLT <TH > PASTIX LDLT <TH > LLT <TH > CHOLMOD SP LLT <TH > CHOLMOD LLT <TH > PASTIX LLT <TH> CG</TR>+<TR><TH rowspan="4">vector_graphics <TD rowspan="4"> 12855 <TD rowspan="4"> 72069 <TH>Compute Time <TD>0.0254549<TD>0.0215677<TD>0.0701827<TD>0.000153388<TD>0.0140107<TD>0.0153709<TD>0.0101601<TD style="background-color:red">0.00930502<TD>0.0649689+<TR><TH>Solve Time <TD>0.00337835<TD>0.000951826<TD>0.00484373<TD>0.0374886<TD>0.0046445<TD>0.00847754<TD>0.000541813<TD style="background-color:red">0.000293696<TD>0.00485376+<TR><TH>Total Time <TD>0.0288333<TD>0.0225195<TD>0.0750265<TD>0.037642<TD>0.0186552<TD>0.0238484<TD>0.0107019<TD style="background-color:red">0.00959871<TD>0.0698227+<TR><TH>Error(Iter) <TD> 1.299e-16 <TD> 2.04207e-16 <TD> 4.83393e-15 <TD> 3.94856e-11 (80) <TD> 1.03861e-12 (3) <TD> 5.81088e-14 (6) <TD> 1.97578e-16 <TD> 1.83927e-16 <TD> 4.24115e-15+<TR><TH rowspan="4">poisson_SPD <TD rowspan="4"> 19788 <TD rowspan="4"> 308232 <TH>Compute Time <TD>0.425026<TD>1.82378<TD>0.617367<TD>0.000478921<TD>1.34001<TD>1.33471<TD>0.796419<TD>0.857573<TD>0.473007<TD>0.814826<TD style="background-color:red">0.184719<TD>0.861555<TD>0.470559<TD>0.000458188+<TR><TH>Solve Time <TD>0.0280053<TD>0.0194402<TD>0.0268747<TD>0.249437<TD>0.0548444<TD>0.0926991<TD>0.00850204<TD>0.0053171<TD>0.0258932<TD>0.00874603<TD style="background-color:red">0.00578155<TD>0.00530361<TD>0.0248942<TD>0.239093+<TR><TH>Total Time <TD>0.453031<TD>1.84322<TD>0.644241<TD>0.249916<TD>1.39486<TD>1.42741<TD>0.804921<TD>0.862891<TD>0.4989<TD>0.823572<TD style="background-color:red">0.190501<TD>0.866859<TD>0.495453<TD>0.239551+<TR><TH>Error(Iter) <TD> 4.67146e-16 <TD> 1.068e-15 <TD> 1.3397e-15 <TD> 6.29233e-11 (201) <TD> 3.68527e-11 (6) <TD> 3.3168e-15 (16) <TD> 1.86376e-15 <TD> 1.31518e-16 <TD> 1.42593e-15 <TD> 3.45361e-15 <TD> 3.14575e-16 <TD> 2.21723e-15 <TD> 7.21058e-16 <TD> 9.06435e-12 (261) +<TR><TH rowspan="4">sherman2 <TD rowspan="4"> 1080 <TD rowspan="4"> 23094 <TH>Compute Time <TD style="background-color:red">0.00631754<TD>0.015052<TD>0.0247514 <TD> -<TD>0.0214425<TD>0.0217988+<TR><TH>Solve Time <TD style="background-color:red">0.000478424<TD>0.000337998<TD>0.0010291 <TD> -<TD>0.00243152<TD>0.00246152+<TR><TH>Total Time <TD style="background-color:red">0.00679597<TD>0.01539<TD>0.0257805 <TD> -<TD>0.023874<TD>0.0242603+<TR><TH>Error(Iter) <TD> 1.83099e-15 <TD> 8.19351e-15 <TD> 2.625e-14 <TD> 1.3678e+69 (1080) <TD> 4.1911e-12 (7) <TD> 5.0299e-13 (12) +<TR><TH rowspan="4">bcsstk01_SPD <TD rowspan="4"> 48 <TD rowspan="4"> 400 <TH>Compute Time <TD>0.000169079<TD>0.00010789<TD>0.000572538<TD>1.425e-06<TD>9.1612e-05<TD>8.3985e-05<TD style="background-color:red">5.6489e-05<TD>7.0913e-05<TD>0.000468251<TD>5.7389e-05<TD>8.0212e-05<TD>5.8394e-05<TD>0.000463017<TD>1.333e-06+<TR><TH>Solve Time <TD>1.2288e-05<TD>1.1124e-05<TD>0.000286387<TD>8.5896e-05<TD>1.6381e-05<TD>1.6984e-05<TD style="background-color:red">3.095e-06<TD>4.115e-06<TD>0.000325438<TD>3.504e-06<TD>7.369e-06<TD>3.454e-06<TD>0.000294095<TD>6.0516e-05+<TR><TH>Total Time <TD>0.000181367<TD>0.000119014<TD>0.000858925<TD>8.7321e-05<TD>0.000107993<TD>0.000100969<TD style="background-color:red">5.9584e-05<TD>7.5028e-05<TD>0.000793689<TD>6.0893e-05<TD>8.7581e-05<TD>6.1848e-05<TD>0.000757112<TD>6.1849e-05+<TR><TH>Error(Iter) <TD> 1.03474e-16 <TD> 2.23046e-16 <TD> 2.01273e-16 <TD> 4.87455e-07 (48) <TD> 1.03553e-16 (2) <TD> 3.55965e-16 (2) <TD> 2.48189e-16 <TD> 1.88808e-16 <TD> 1.97976e-16 <TD> 2.37248e-16 <TD> 1.82701e-16 <TD> 2.71474e-16 <TD> 2.11322e-16 <TD> 3.547e-09 (48) +<TR><TH rowspan="4">sherman1 <TD rowspan="4"> 1000 <TD rowspan="4"> 3750 <TH>Compute Time <TD>0.00228805<TD>0.00209231<TD>0.00528268<TD>9.846e-06<TD>0.00163522<TD>0.00162155<TD>0.000789259<TD style="background-color:red">0.000804495<TD>0.00438269+<TR><TH>Solve Time <TD>0.000213788<TD>9.7983e-05<TD>0.000938831<TD>0.00629835<TD>0.000361764<TD>0.00078794<TD>4.3989e-05<TD style="background-color:red">2.5331e-05<TD>0.000917166+<TR><TH>Total Time <TD>0.00250184<TD>0.00219029<TD>0.00622151<TD>0.0063082<TD>0.00199698<TD>0.00240949<TD>0.000833248<TD style="background-color:red">0.000829826<TD>0.00529986+<TR><TH>Error(Iter) <TD> 1.16839e-16 <TD> 2.25968e-16 <TD> 2.59116e-16 <TD> 3.76779e-11 (248) <TD> 4.13343e-11 (4) <TD> 2.22347e-14 (10) <TD> 2.05861e-16 <TD> 1.83555e-16 <TD> 1.02917e-15+<TR><TH rowspan="4">young1c <TD rowspan="4"> 841 <TD rowspan="4"> 4089 <TH>Compute Time <TD>0.00235843<TD style="background-color:red">0.00217228<TD>0.00568075<TD>1.2735e-05<TD>0.00264866<TD>0.00258236+<TR><TH>Solve Time <TD>0.000329599<TD style="background-color:red">0.000168634<TD>0.00080118<TD>0.0534738<TD>0.00187193<TD>0.00450211+<TR><TH>Total Time <TD>0.00268803<TD style="background-color:red">0.00234091<TD>0.00648193<TD>0.0534865<TD>0.00452059<TD>0.00708447+<TR><TH>Error(Iter) <TD> 1.27029e-16 <TD> 2.81321e-16 <TD> 5.0492e-15 <TD> 8.0507e-11 (706) <TD> 3.00447e-12 (8) <TD> 1.46532e-12 (16) +<TR><TH rowspan="4">mhd1280b <TD rowspan="4"> 1280 <TD rowspan="4"> 22778 <TH>Compute Time <TD>0.00234898<TD>0.00207079<TD>0.00570918<TD>2.5976e-05<TD>0.00302563<TD>0.00298036<TD>0.00144525<TD style="background-color:red">0.000919922<TD>0.00426444+<TR><TH>Solve Time <TD>0.00103392<TD>0.000211911<TD>0.00105<TD>0.0110432<TD>0.000628287<TD>0.00392089<TD>0.000138303<TD style="background-color:red">6.2446e-05<TD>0.00097564+<TR><TH>Total Time <TD>0.0033829<TD>0.0022827<TD>0.00675918<TD>0.0110692<TD>0.00365392<TD>0.00690124<TD>0.00158355<TD style="background-color:red">0.000982368<TD>0.00524008+<TR><TH>Error(Iter) <TD> 1.32953e-16 <TD> 3.08646e-16 <TD> 6.734e-16 <TD> 8.83132e-11 (40) <TD> 1.51153e-16 (1) <TD> 6.08556e-16 (8) <TD> 1.89264e-16 <TD> 1.97477e-16 <TD> 6.68126e-09+<TR><TH rowspan="4">crashbasis <TD rowspan="4"> 160000 <TD rowspan="4"> 1750416 <TH>Compute Time <TD>3.2019<TD>5.7892<TD>15.7573<TD style="background-color:red">0.00383515<TD>3.1006<TD>3.09921+<TR><TH>Solve Time <TD>0.261915<TD>0.106225<TD>0.402141<TD style="background-color:red">1.49089<TD>0.24888<TD>0.443673+<TR><TH>Total Time <TD>3.46381<TD>5.89542<TD>16.1594<TD style="background-color:red">1.49473<TD>3.34948<TD>3.54288+<TR><TH>Error(Iter) <TD> 1.76348e-16 <TD> 4.58395e-16 <TD> 1.67982e-14 <TD> 8.64144e-11 (61) <TD> 8.5996e-12 (2) <TD> 6.04042e-14 (5) ++</TABLE>+*/+}
+ eigen3/doc/SparseQuickReference.dox view
@@ -0,0 +1,248 @@+namespace Eigen {+/** \eigenManualPage SparseQuickRefPage Quick reference guide for sparse matrices+\eigenAutoToc++<hr>++In this page, we give a quick summary of the main operations available for sparse matrices in the class SparseMatrix. First, it is recommended to read the introductory tutorial at \ref TutorialSparse. The important point to have in mind when working on sparse matrices is how they are stored : +i.e either row major or column major. The default is column major. Most arithmetic operations on sparse matrices will assert that they have the same storage order. ++\section SparseMatrixInit Sparse Matrix Initialization+<table class="manual">+<tr><th> Category </th> <th> Operations</th> <th>Notes</th></tr>+<tr><td>Constructor</td>+<td>+\code+ SparseMatrix<double> sm1(1000,1000); + SparseMatrix<std::complex<double>,RowMajor> sm2;+\endcode+</td> <td> Default is ColMajor</td> </tr>+<tr class="alt">+<td> Resize/Reserve</td>+<td> + \code+ sm1.resize(m,n); //Change sm1 to a m x n matrix. + sm1.reserve(nnz); // Allocate room for nnz nonzeros elements. + \endcode +</td>+<td> Note that when calling reserve(), it is not required that nnz is the exact number of nonzero elements in the final matrix. However, an exact estimation will avoid multiple reallocations during the insertion phase. </td>+</tr>+<tr> +<td> Assignment </td>+<td> +\code + SparseMatrix<double,Colmajor> sm1;+ // Initialize sm2 with sm1.+ SparseMatrix<double,Rowmajor> sm2(sm1), sm3; + // Assignment and evaluations modify the storage order.+ sm3 = sm1; + \endcode+</td>+<td> The copy constructor can be used to convert from a storage order to another</td>+</tr>+<tr class="alt">+<td> Element-wise Insertion</td>+<td>+\code +// Insert a new element; + sm1.insert(i, j) = v_ij; ++// Update the value v_ij+ sm1.coeffRef(i,j) = v_ij;+ sm1.coeffRef(i,j) += v_ij;+ sm1.coeffRef(i,j) -= v_ij;+\endcode+</td>+<td> insert() assumes that the element does not already exist; otherwise, use coeffRef()</td>+</tr>+<tr> +<td> Batch insertion</td>+<td>+\code+ std::vector< Eigen::Triplet<double> > tripletList;+ tripletList.reserve(estimation_of_entries);+ // -- Fill tripletList with nonzero elements...+ sm1.setFromTriplets(TripletList.begin(), TripletList.end());+\endcode+</td>+<td>A complete example is available at \link TutorialSparseFilling Triplet Insertion \endlink.</td>+</tr>+<tr class="alt"> +<td> Constant or Random Insertion</td>+<td>+\code+sm1.setZero();+\endcode+</td>+<td>Remove all non-zero coefficients</td>+</tr>+</table>+++\section SparseBasicInfos Matrix properties+Beyond the basic functions rows() and cols(), there are some useful functions that are available to easily get some informations from the matrix. +<table class="manual">+<tr>+ <td> \code+ sm1.rows(); // Number of rows+ sm1.cols(); // Number of columns + sm1.nonZeros(); // Number of non zero values + sm1.outerSize(); // Number of columns (resp. rows) for a column major (resp. row major )+ sm1.innerSize(); // Number of rows (resp. columns) for a row major (resp. column major)+ sm1.norm(); // Euclidian norm of the matrix+ sm1.squaredNorm(); // Squared norm of the matrix+ sm1.blueNorm();+ sm1.isVector(); // Check if sm1 is a sparse vector or a sparse matrix+ sm1.isCompressed(); // Check if sm1 is in compressed form+ ...+ \endcode </td>+</tr>+</table>++\section SparseBasicOps Arithmetic operations+It is easy to perform arithmetic operations on sparse matrices provided that the dimensions are adequate and that the matrices have the same storage order. Note that the evaluation can always be done in a matrix with a different storage order. In the following, \b sm denotes a sparse matrix, \b dm a dense matrix and \b dv a dense vector.+<table class="manual">+<tr><th> Operations </th> <th> Code </th> <th> Notes </th></tr>++<tr>+ <td> add subtract </td> + <td> \code+ sm3 = sm1 + sm2; + sm3 = sm1 - sm2;+ sm2 += sm1; + sm2 -= sm1; \endcode+ </td>+ <td> + sm1 and sm2 should have the same storage order+ </td> +</tr>++<tr class="alt"><td>+ scalar product</td><td>\code+ sm3 = sm1 * s1; sm3 *= s1; + sm3 = s1 * sm1 + s2 * sm2; sm3 /= s1;\endcode+ </td>+ <td>+ Many combinations are possible if the dimensions and the storage order agree.+</tr>++<tr>+ <td> %Sparse %Product </td>+ <td> \code+ sm3 = sm1 * sm2;+ dm2 = sm1 * dm1;+ dv2 = sm1 * dv1;+ \endcode </td>+ <td>+ </td>+</tr> ++<tr class='alt'>+ <td> transposition, adjoint</td>+ <td> \code+ sm2 = sm1.transpose();+ sm2 = sm1.adjoint();+ \endcode </td>+ <td>+ Note that the transposition change the storage order. There is no support for transposeInPlace().+ </td>+</tr> +<tr>+<td> Permutation </td>+<td> +\code +perm.indices(); // Reference to the vector of indices+sm1.twistedBy(perm); // Permute rows and columns+sm2 = sm1 * perm; //Permute the columns+sm2 = perm * sm1; // Permute the columns+\endcode +</td>+<td> ++</td>+</tr>+<tr>+ <td>+ Component-wise ops+ </td>+ <td>\code + sm1.cwiseProduct(sm2);+ sm1.cwiseQuotient(sm2);+ sm1.cwiseMin(sm2);+ sm1.cwiseMax(sm2);+ sm1.cwiseAbs();+ sm1.cwiseSqrt();+ \endcode</td>+ <td>+ sm1 and sm2 should have the same storage order+ </td>+</tr>+</table>++\section sparseotherops Other supported operations+<table class="manual">+<tr><th>Operations</th> <th> Code </th> <th> Notes</th> </tr>+<tr>+<td>Sub-matrices</td> +<td> +\code + sm1.block(startRow, startCol, rows, cols); + sm1.block(startRow, startCol); + sm1.topLeftCorner(rows, cols); + sm1.topRightCorner(rows, cols);+ sm1.bottomLeftCorner( rows, cols);+ sm1.bottomRightCorner( rows, cols);+ \endcode+</td> <td> </td>+</tr>+<tr> +<td> Range </td>+<td> +\code + sm1.innerVector(outer); + sm1.innerVectors(start, size);+ sm1.leftCols(size);+ sm2.rightCols(size);+ sm1.middleRows(start, numRows);+ sm1.middleCols(start, numCols);+ sm1.col(j);+\endcode+</td>+<td>A inner vector is either a row (for row-major) or a column (for column-major). As stated earlier, the evaluation can be done in a matrix with different storage order </td>+</tr>+<tr>+<td> Triangular and selfadjoint views</td>+<td> +\code+ sm2 = sm1.triangularview<Lower>();+ sm2 = sm1.selfadjointview<Lower>();+\endcode+</td>+<td> Several combination between triangular views and blocks views are possible+\code + \endcode </td>+</tr>+<tr> +<td>Triangular solve </td>+<td> +\code + dv2 = sm1.triangularView<Upper>().solve(dv1);+ dv2 = sm1.topLeftCorner(size, size).triangularView<Lower>().solve(dv1);+\endcode +</td>+<td> For general sparse solve, Use any suitable module described at \ref TopicSparseSystems </td>+</tr>+<tr>+<td> Low-level API</td>+<td>+\code+sm1.valuePtr(); // Pointer to the values+sm1.innerIndextr(); // Pointer to the indices.+sm1.outerIndexPtr(); //Pointer to the beginning of each inner vector+\endcode+</td>+<td> If the matrix is not in compressed form, makeCompressed() should be called before. Note that these functions are mostly provided for interoperability purposes with external libraries. A better access to the values of the matrix is done by using the InnerIterator class as described in \link TutorialSparse the Tutorial Sparse \endlink section</td>+</tr>+</table>+*/+}
+ eigen3/doc/StlContainers.dox view
@@ -0,0 +1,62 @@+namespace Eigen {++/** \eigenManualPage TopicStlContainers Using STL Containers with Eigen++\eigenAutoToc++\section summary Executive summary++Using STL containers on \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen types", or classes having members of such types, requires taking the following two steps:++\li A 16-byte-aligned allocator must be used. Eigen does provide one ready for use: aligned_allocator.+\li If you want to use the std::vector container, you need to \#include <Eigen/StdVector>.++These issues arise only with \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen types" and \ref TopicStructHavingEigenMembers "structures having such Eigen objects as member". For other Eigen types, such as Vector3f or MatrixXd, no special care is needed when using STL containers.++\section allocator Using an aligned allocator++STL containers take an optional template parameter, the allocator type. When using STL containers on \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen types", you need tell the container to use an allocator that will always allocate memory at 16-byte-aligned locations. Fortunately, Eigen does provide such an allocator: Eigen::aligned_allocator.++For example, instead of+\code+std::map<int, Eigen::Vector4f>+\endcode+you need to use+\code+std::map<int, Eigen::Vector4f, std::less<int>, + Eigen::aligned_allocator<std::pair<const int, Eigen::Vector4f> > >+\endcode+Note that the third parameter "std::less<int>" is just the default value, but we have to include it because we want to specify the fourth parameter, which is the allocator type.++\section vector The case of std::vector++The situation with std::vector was even worse (explanation below) so we had to specialize it for the Eigen::aligned_allocator type. In practice you \b must use the Eigen::aligned_allocator (not another aligned allocator), \b and \#include <Eigen/StdVector>.++Here is an example:+\code+#include<Eigen/StdVector>+/* ... */+std::vector<Eigen::Vector4f,Eigen::aligned_allocator<Eigen::Vector4f> >+\endcode++\subsection vector_spec An alternative - specializing std::vector for Eigen types++As an alternative to the recommended approach described above, you have the option to specialize std::vector for Eigen types requiring alignment. +The advantage is that you won't need to declare std::vector all over with Eigen::allocator. One drawback on the other hand side is that+the specialization needs to be defined before all code pieces in which e.g. std::vector<Vector2d> is used. Otherwise, without knowing the specialization+the compiler will compile that particular instance with the default std::allocator and you program is most likely to crash.++Here is an example:+\code+#include<Eigen/StdVector>+/* ... */+EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Matrix2d)+std::vector<Eigen::Vector2d>+\endcode++<span class="note">\b Explanation: The resize() method of std::vector takes a value_type argument (defaulting to value_type()). So with std::vector<Eigen::Vector4f>, some Eigen::Vector4f objects will be passed by value, which discards any alignment modifiers, so a Eigen::Vector4f can be created at an unaligned location. In order to avoid that, the only solution we saw was to specialize std::vector to make it work on a slight modification of, here, Eigen::Vector4f, that is able to deal properly with this situation.+</span>++*/++}
+ eigen3/doc/StorageOrders.dox view
@@ -0,0 +1,86 @@+namespace Eigen {++/** \eigenManualPage TopicStorageOrders Storage orders++There are two different storage orders for matrices and two-dimensional arrays: column-major and row-major.+This page explains these storage orders and how to specify which one should be used.++\eigenAutoToc+++\section TopicStorageOrdersIntro Column-major and row-major storage++The entries of a matrix form a two-dimensional grid. However, when the matrix is stored in memory, the entries+have to somehow be laid out linearly. There are two main ways to do this, by row and by column.++We say that a matrix is stored in \b row-major order if it is stored row by row. The entire first row is+stored first, followed by the entire second row, and so on. Consider for example the matrix++\f[+A = \begin{bmatrix}+8 & 2 & 2 & 9 \\+9 & 1 & 4 & 4 \\+3 & 5 & 4 & 5+\end{bmatrix}.+\f]++If this matrix is stored in row-major order, then the entries are laid out in memory as follows:++\code 8 2 2 9 9 1 4 4 3 5 4 5 \endcode++On the other hand, a matrix is stored in \b column-major order if it is stored column by column, starting with+the entire first column, followed by the entire second column, and so on. If the above matrix is stored in+column-major order, it is laid out as follows:++\code 8 9 3 2 1 5 2 4 4 9 4 5 \endcode++This example is illustrated by the following Eigen code. It uses the PlainObjectBase::data() function, which+returns a pointer to the memory location of the first entry of the matrix.++<table class="example">+<tr><th>Example</th><th>Output</th></tr>+<tr><td>+\include TopicStorageOrders_example.cpp+</td>+<td>+\verbinclude TopicStorageOrders_example.out+</td></tr></table>+++\section TopicStorageOrdersInEigen Storage orders in Eigen++The storage order of a matrix or a two-dimensional array can be set by specifying the \c Options template+parameter for Matrix or Array. As \ref TutorialMatrixClass explains, the %Matrix class template has six+template parameters, of which three are compulsory (\c Scalar, \c RowsAtCompileTime and \c ColsAtCompileTime)+and three are optional (\c Options, \c MaxRowsAtCompileTime and \c MaxColsAtCompileTime). If the \c Options+parameter is set to \c RowMajor, then the matrix or array is stored in row-major order; if it is set to +\c ColMajor, then it is stored in column-major order. This mechanism is used in the above Eigen program to+specify the storage order.++If the storage order is not specified, then Eigen defaults to storing the entry in column-major. This is also+the case if one of the convenience typedefs (\c Matrix3f, \c ArrayXXd, etc.) is used.++Matrices and arrays using one storage order can be assigned to matrices and arrays using the other storage+order, as happens in the above program when \c Arowmajor is initialized using \c Acolmajor. Eigen will reorder+the entries automatically. More generally, row-major and column-major matrices can be mixed in an expression+as we want.+++\section TopicStorageOrdersWhich Which storage order to choose?++So, which storage order should you use in your program? There is no simple answer to this question; it depends+on your application. Here are some points to keep in mind:++ - Your users may expect you to use a specific storage order. Alternatively, you may use other libraries than+ Eigen, and these other libraries may expect a certain storage order. In these cases it may be easiest and+ fastest to use this storage order in your whole program.+ - Algorithms that traverse a matrix row by row will go faster when the matrix is stored in row-major order+ because of better data locality. Similarly, column-by-column traversal is faster for column-major+ matrices. It may be worthwhile to experiment a bit to find out what is faster for your particular+ application.+ - The default in Eigen is column-major. Naturally, most of the development and testing of the Eigen library+ is thus done with column-major matrices. This means that, even though we aim to support column-major and+ row-major storage orders transparently, the Eigen library may well work best with column-major matrices.++*/+}
+ eigen3/doc/StructHavingEigenMembers.dox view
@@ -0,0 +1,190 @@+namespace Eigen {++/** \eigenManualPage TopicStructHavingEigenMembers Structures Having Eigen Members++\eigenAutoToc++\section summary Executive Summary++If you define a structure having members of \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen types", you must overload its "operator new" so that it generates 16-bytes-aligned pointers. Fortunately, Eigen provides you with a macro EIGEN_MAKE_ALIGNED_OPERATOR_NEW that does that for you.++\section what What kind of code needs to be changed?++The kind of code that needs to be changed is this:++\code+class Foo+{+ ...+ Eigen::Vector2d v;+ ...+};++...++Foo *foo = new Foo;+\endcode++In other words: you have a class that has as a member a \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen object", and then you dynamically create an object of that class.++\section how How should such code be modified?++Very easy, you just need to put a EIGEN_MAKE_ALIGNED_OPERATOR_NEW macro in a public part of your class, like this:++\code+class Foo+{+ ...+ Eigen::Vector2d v;+ ...+public:+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW+};++...++Foo *foo = new Foo;+\endcode++This macro makes "new Foo" always return an aligned pointer.++If this approach is too intrusive, see also the \ref othersolutions.++\section why Why is this needed?++OK let's say that your code looks like this:++\code+class Foo+{+ ...+ Eigen::Vector2d v;+ ...+};++...++Foo *foo = new Foo;+\endcode++A Eigen::Vector2d consists of 2 doubles, which is 128 bits. Which is exactly the size of a SSE packet, which makes it possible to use SSE for all sorts of operations on this vector. But SSE instructions (at least the ones that Eigen uses, which are the fast ones) require 128-bit alignment. Otherwise you get a segmentation fault.++For this reason, Eigen takes care by itself to require 128-bit alignment for Eigen::Vector2d, by doing two things:+\li Eigen requires 128-bit alignment for the Eigen::Vector2d's array (of 2 doubles). With GCC, this is done with a __attribute__ ((aligned(16))).+\li Eigen overloads the "operator new" of Eigen::Vector2d so it will always return 128-bit aligned pointers.++Thus, normally, you don't have to worry about anything, Eigen handles alignment for you...++... except in one case. When you have a class Foo like above, and you dynamically allocate a new Foo as above, then, since Foo doesn't have aligned "operator new", the returned pointer foo is not necessarily 128-bit aligned.++The alignment attribute of the member v is then relative to the start of the class, foo. If the foo pointer wasn't aligned, then foo->v won't be aligned either!++The solution is to let class Foo have an aligned "operator new", as we showed in the previous section.++\section movetotop Should I then put all the members of Eigen types at the beginning of my class?++That's not required. Since Eigen takes care of declaring 128-bit alignment, all members that need it are automatically 128-bit aligned relatively to the class. So code like this works fine:++\code+class Foo+{+ double x;+ Eigen::Vector2d v;+public:+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW+};+\endcode++\section dynamicsize What about dynamic-size matrices and vectors?++Dynamic-size matrices and vectors, such as Eigen::VectorXd, allocate dynamically their own array of coefficients, so they take care of requiring absolute alignment automatically. So they don't cause this issue. The issue discussed here is only with \ref TopicFixedSizeVectorizable "fixed-size vectorizable matrices and vectors".++\section bugineigen So is this a bug in Eigen?++No, it's not our bug. It's more like an inherent problem of the C++98 language specification, and seems to be taken care of in the upcoming language revision: <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2341.pdf">see this document</a>.++\section conditional What if I want to do this conditionnally (depending on template parameters) ?++For this situation, we offer the macro EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign). It will generate aligned operators like EIGEN_MAKE_ALIGNED_OPERATOR_NEW if NeedsToAlign is true. It will generate operators with the default alignment if NeedsToAlign is false.++Example:++\code+template<int n> class Foo+{+ typedef Eigen::Matrix<float,n,1> Vector;+ enum { NeedsToAlign = (sizeof(Vector)%16)==0 };+ ...+ Vector v;+ ...+public:+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)+};++...++Foo<4> *foo4 = new Foo<4>; // foo4 is guaranteed to be 128bit-aligned+Foo<3> *foo3 = new Foo<3>; // foo3 has only the system default alignment guarantee+\endcode+++\section othersolutions Other solutions++In case putting the EIGEN_MAKE_ALIGNED_OPERATOR_NEW macro everywhere is too intrusive, there exists at least two other solutions.++\subsection othersolutions1 Disabling alignment++The first is to disable alignment requirement for the fixed size members:+\code+class Foo+{+ ...+ Eigen::Matrix<double,2,1,Eigen::DontAlign> v;+ ...+};+\endcode+This has for effect to disable vectorization when using \c v.+If a function of Foo uses it several times, then it still possible to re-enable vectorization by copying it into an aligned temporary vector:+\code+void Foo::bar()+{+ Eigen::Vector2d av(v);+ // use av instead of v+ ...+ // if av changed, then do:+ v = av;+}+\endcode++\subsection othersolutions2 Private structure++The second consist in storing the fixed-size objects into a private struct which will be dynamically allocated at the construction time of the main object:++\code+struct Foo_d+{+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW+ Vector2d v;+ ...+};+++struct Foo {+ Foo() { init_d(); }+ ~Foo() { delete d; }+ void bar()+ {+ // use d->v instead of v+ ...+ }+private:+ void init_d() { d = new Foo_d; }+ Foo_d* d;+};+\endcode++The clear advantage here is that the class Foo remains unchanged regarding alignment issues. The drawback is that a heap allocation will be required whatsoever.++*/++}
+ eigen3/doc/TemplateKeyword.dox view
@@ -0,0 +1,132 @@+namespace Eigen {++/** \page TopicTemplateKeyword The template and typename keywords in C++++There are two uses for the \c template and \c typename keywords in C++. One of them is fairly well known+amongst programmers: to define templates. The other use is more obscure: to specify that an expression refers+to a template function or a type. This regularly trips up programmers that use the %Eigen library, often+leading to error messages from the compiler that are difficult to understand.++\eigenAutoToc+++\section TopicTemplateKeywordToDefineTemplates Using the template and typename keywords to define templates++The \c template and \c typename keywords are routinely used to define templates. This is not the topic of this+page as we assume that the reader is aware of this (otherwise consult a C++ book). The following example+should illustrate this use of the \c template keyword.++\code+template <typename T>+bool isPositive(T x)+{+ return x > 0;+}+\endcode++We could just as well have written <tt>template <class T></tt>; the keywords \c typename and \c class have the+same meaning in this context.+++\section TopicTemplateKeywordExample An example showing the second use of the template keyword++Let us illustrate the second use of the \c template keyword with an example. Suppose we want to write a+function which copies all entries in the upper triangular part of a matrix into another matrix, while keeping+the lower triangular part unchanged. A straightforward implementation would be as follows:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include TemplateKeyword_simple.cpp+</td>+<td>+\verbinclude TemplateKeyword_simple.out+</td></tr></table>++That works fine, but it is not very flexible. First, it only works with dynamic-size matrices of+single-precision floats; the function \c copyUpperTriangularPart() does not accept static-size matrices or+matrices with double-precision numbers. Second, if you use an expression such as+<tt>mat.topLeftCorner(3,3)</tt> as the parameter \c src, then this is copied into a temporary variable of type+MatrixXf; this copy can be avoided.++As explained in \ref TopicFunctionTakingEigenTypes, both issues can be resolved by making +\c copyUpperTriangularPart() accept any object of type MatrixBase. This leads to the following code:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include TemplateKeyword_flexible.cpp+</td>+<td>+\verbinclude TemplateKeyword_flexible.out+</td></tr></table>++The one line in the body of the function \c copyUpperTriangularPart() shows the second, more obscure use of+the \c template keyword in C++. Even though it may look strange, the \c template keywords are necessary+according to the standard. Without it, the compiler may reject the code with an error message like "no match+for operator<".+++\section TopicTemplateKeywordExplanation Explanation++The reason that the \c template keyword is necessary in the last example has to do with the rules for how+templates are supposed to be compiled in C++. The compiler has to check the code for correct syntax at the+point where the template is defined, without knowing the actual value of the template arguments (\c Derived1+and \c Derived2 in the example). That means that the compiler cannot know that <tt>dst.triangularPart</tt> is+a member template and that the following < symbol is part of the delimiter for the template+parameter. Another possibility would be that <tt>dst.triangularPart</tt> is a member variable with the <+symbol refering to the <tt>operator<()</tt> function. In fact, the compiler should choose the second+possibility, according to the standard. If <tt>dst.triangularPart</tt> is a member template (as in our case),+the programmer should specify this explicitly with the \c template keyword and write <tt>dst.template+triangularPart</tt>.++The precise rules are rather complicated, but ignoring some subtleties we can summarize them as follows:+- A <em>dependent name</em> is name that depends (directly or indirectly) on a template parameter. In the+ example, \c dst is a dependent name because it is of type <tt>MatrixBase<Derived1></tt> which depends+ on the template parameter \c Derived1.+- If the code contains either one of the contructions <tt>xxx.yyy</tt> or <tt>xxx->yyy</tt> and \c xxx is a+ dependent name and \c yyy refers to a member template, then the \c template keyword must be used before + \c yyy, leading to <tt>xxx.template yyy</tt> or <tt>xxx->template yyy</tt>.+- If the code contains the contruction <tt>xxx::yyy</tt> and \c xxx is a dependent name and \c yyy refers to a+ member typedef, then the \c typename keyword must be used before the whole construction, leading to+ <tt>typename xxx::yyy</tt>.++As an example where the \c typename keyword is required, consider the following code in \ref TutorialSparse+for iterating over the non-zero entries of a sparse matrix type:++\code+SparseMatrixType mat(rows,cols);+for (int k=0; k<mat.outerSize(); ++k)+ for (SparseMatrixType::InnerIterator it(mat,k); it; ++it)+ {+ /* ... */+ }+\endcode++If \c SparseMatrixType depends on a template parameter, then the \c typename keyword is required:++\code+template <typename T>+void iterateOverSparseMatrix(const SparseMatrix<T>& mat;+{+ for (int k=0; k<m1.outerSize(); ++k)+ for (typename SparseMatrix<T>::InnerIterator it(mat,k); it; ++it)+ {+ /* ... */+ }+}+\endcode+++\section TopicTemplateKeywordResources Resources for further reading++For more information and a fuller explanation of this topic, the reader may consult the following sources:+- The book "C++ Template Metaprogramming" by David Abrahams and Aleksey Gurtovoy contains a very good+ explanation in Appendix B ("The typename and template Keywords") which formed the basis for this page.+- http://pages.cs.wisc.edu/~driscoll/typename.html+- http://www.parashift.com/c++-faq-lite/templates.html#faq-35.18+- http://www.comeaucomputing.com/techtalk/templates/#templateprefix+- http://www.comeaucomputing.com/techtalk/templates/#typename++*/+}
+ eigen3/doc/TopicAliasing.dox view
@@ -0,0 +1,215 @@+namespace Eigen {++/** \eigenManualPage TopicAliasing Aliasing++In %Eigen, aliasing refers to assignment statement in which the same matrix (or array or vector) appears on the+left and on the right of the assignment operators. Statements like <tt>mat = 2 * mat;</tt> or <tt>mat =+mat.transpose();</tt> exhibit aliasing. The aliasing in the first example is harmless, but the aliasing in the+second example leads to unexpected results. This page explains what aliasing is, when it is harmful, and what+to do about it.++\eigenAutoToc+++\section TopicAliasingExamples Examples++Here is a simple example exhibiting aliasing:++<table class="example">+<tr><th>Example</th><th>Output</th></tr>+<tr><td>+\include TopicAliasing_block.cpp+</td>+<td>+\verbinclude TopicAliasing_block.out+</td></tr></table>++The output is not what one would expect. The problem is the assignment+\code+mat.bottomRightCorner(2,2) = mat.topLeftCorner(2,2);+\endcode+This assignment exhibits aliasing: the coefficient \c mat(1,1) appears both in the block+<tt>mat.bottomRightCorner(2,2)</tt> on the left-hand side of the assignment and the block+<tt>mat.topLeftCorner(2,2)</tt> on the right-hand side. After the assignment, the (2,2) entry in the bottom+right corner should have the value of \c mat(1,1) before the assignment, which is 5. However, the output shows+that \c mat(2,2) is actually 1. The problem is that %Eigen uses lazy evaluation (see +\ref TopicEigenExpressionTemplates) for <tt>mat.topLeftCorner(2,2)</tt>. The result is similar to+\code+mat(1,1) = mat(0,0);+mat(1,2) = mat(0,1);+mat(2,1) = mat(1,0);+mat(2,2) = mat(1,1);+\endcode+Thus, \c mat(2,2) is assigned the \e new value of \c mat(1,1) instead of the old value. The next section+explains how to solve this problem by calling \link DenseBase::eval() eval()\endlink.++Aliasing occurs more naturally when trying to shrink a matrix. For example, the expressions <tt>vec =+vec.head(n)</tt> and <tt>mat = mat.block(i,j,r,c)</tt> exhibit aliasing.++In general, aliasing cannot be detected at compile time: if \c mat in the first example were a bit bigger,+then the blocks would not overlap, and there would be no aliasing problem. However, %Eigen does detect some+instances of aliasing, albeit at run time. The following example exhibiting aliasing was mentioned in \ref+TutorialMatrixArithmetic :++<table class="example">+<tr><th>Example</th><th>Output</th></tr>+<tr><td>+\include tut_arithmetic_transpose_aliasing.cpp+</td>+<td>+\verbinclude tut_arithmetic_transpose_aliasing.out+</td></tr></table>++Again, the output shows the aliasing issue. However, by default %Eigen uses a run-time assertion to detect this+and exits with a message like++\verbatim+void Eigen::DenseBase<Derived>::checkTransposeAliasing(const OtherDerived&) const +[with OtherDerived = Eigen::Transpose<Eigen::Matrix<int, 2, 2, 0, 2, 2> >, Derived = Eigen::Matrix<int, 2, 2, 0, 2, 2>]: +Assertion `(!internal::check_transpose_aliasing_selector<Scalar,internal::blas_traits<Derived>::IsTransposed,OtherDerived>::run(internal::extract_data(derived()), other)) +&& "aliasing detected during transposition, use transposeInPlace() or evaluate the rhs into a temporary using .eval()"' failed.+\endverbatim++The user can turn %Eigen's run-time assertions like the one to detect this aliasing problem off by defining the+EIGEN_NO_DEBUG macro, and the above program was compiled with this macro turned off in order to illustrate the+aliasing problem. See \ref TopicAssertions for more information about %Eigen's run-time assertions.+++\section TopicAliasingSolution Resolving aliasing issues++If you understand the cause of the aliasing issue, then it is obvious what must happen to solve it: %Eigen has+to evaluate the right-hand side fully into a temporary matrix/array and then assign it to the left-hand+side. The function \link DenseBase::eval() eval() \endlink does precisely that.++For example, here is the corrected version of the first example above:++<table class="example">+<tr><th>Example</th><th>Output</th></tr>+<tr><td>+\include TopicAliasing_block_correct.cpp+</td>+<td>+\verbinclude TopicAliasing_block_correct.out+</td></tr></table>++Now, \c mat(2,2) equals 5 after the assignment, as it should be.++The same solution also works for the second example, with the transpose: simply replace the line +<tt>a = a.transpose();</tt> with <tt>a = a.transpose().eval();</tt>. However, in this common case there is a+better solution. %Eigen provides the special-purpose function +\link DenseBase::transposeInPlace() transposeInPlace() \endlink which replaces a matrix by its transpose. +This is shown below:++<table class="example">+<tr><th>Example</th><th>Output</th></tr>+<tr><td>+\include tut_arithmetic_transpose_inplace.cpp+</td>+<td>+\verbinclude tut_arithmetic_transpose_inplace.out+</td></tr></table>++If an xxxInPlace() function is available, then it is best to use it, because it indicates more clearly what you+are doing. This may also allow %Eigen to optimize more aggressively. These are some of the xxxInPlace()+functions provided: ++<table class="manual">+<tr><th>Original function</th><th>In-place function</th></tr>+<tr> <td> MatrixBase::adjoint() </td> <td> MatrixBase::adjointInPlace() </td> </tr>+<tr class="alt"> <td> DenseBase::reverse() </td> <td> DenseBase::reverseInPlace() </td> </tr>+<tr> <td> LDLT::solve() </td> <td> LDLT::solveInPlace() </td> </tr>+<tr class="alt"> <td> LLT::solve() </td> <td> LLT::solveInPlace() </td> </tr>+<tr> <td> TriangularView::solve() </td> <td> TriangularView::solveInPlace() </td> </tr>+<tr class="alt"> <td> DenseBase::transpose() </td> <td> DenseBase::transposeInPlace() </td> </tr>+</table>++In the special case where a matrix or vector is shrunk using an expression like <tt>vec = vec.head(n)</tt>,+you can use \link PlainObjectBase::conservativeResize() conservativeResize() \endlink.+++\section TopicAliasingCwise Aliasing and component-wise operations++As explained above, it may be dangerous if the same matrix or array occurs on both the left-hand side and the+right-hand side of an assignment operator, and it is then often necessary to evaluate the right-hand side+explicitly. However, applying component-wise operations (such as matrix addition, scalar multiplication and+array multiplication) is safe. ++The following example has only component-wise operations. Thus, there is no need for \link DenseBase::eval()+eval() \endlink even though the same matrix appears on both sides of the assignments.++<table class="example">+<tr><th>Example</th><th>Output</th></tr>+<tr><td>+\include TopicAliasing_cwise.cpp+</td>+<td>+\verbinclude TopicAliasing_cwise.out+</td></tr></table>++In general, an assignment is safe if the (i,j) entry of the expression on the right-hand side depends only on+the (i,j) entry of the matrix or array on the left-hand side and not on any other entries. In that case it is+not necessary to evaluate the right-hand side explicitly.+++\section TopicAliasingMatrixMult Aliasing and matrix multiplication++Matrix multiplication is the only operation in %Eigen that assumes aliasing by default. Thus, if \c matA is a+matrix, then the statement <tt>matA = matA * matA;</tt> is safe. All other operations in %Eigen assume that+there are no aliasing problems, either because the result is assigned to a different matrix or because it is a+component-wise operation.++<table class="example">+<tr><th>Example</th><th>Output</th></tr>+<tr><td>+\include TopicAliasing_mult1.cpp+</td>+<td>+\verbinclude TopicAliasing_mult1.out+</td></tr></table>++However, this comes at a price. When executing the expression <tt>matA = matA * matA</tt>, %Eigen evaluates the+product in a temporary matrix which is assigned to \c matA after the computation. This is fine. But %Eigen does+the same when the product is assigned to a different matrix (e.g., <tt>matB = matA * matA</tt>). In that case,+it is more efficient to evaluate the product directly into \c matB instead of evaluating it first into a+temporary matrix and copying that matrix to \c matB.++The user can indicate with the \link MatrixBase::noalias() noalias()\endlink function that there is no+aliasing, as follows: <tt>matB.noalias() = matA * matA</tt>. This allows %Eigen to evaluate the matrix product+<tt>matA * matA</tt> directly into \c matB.++<table class="example">+<tr><th>Example</th><th>Output</th></tr>+<tr><td>+\include TopicAliasing_mult2.cpp+</td>+<td>+\verbinclude TopicAliasing_mult2.out+</td></tr></table>++Of course, you should not use \c noalias() when there is in fact aliasing taking place. If you do, then you+may get wrong results:++<table class="example">+<tr><th>Example</th><th>Output</th></tr>+<tr><td>+\include TopicAliasing_mult3.cpp+</td>+<td>+\verbinclude TopicAliasing_mult3.out+</td></tr></table>+++\section TopicAliasingSummary Summary++Aliasing occurs when the same matrix or array coefficients appear both on the left- and the right-hand side of+an assignment operator.+ - Aliasing is harmless with coefficient-wise computations; this includes scalar multiplication and matrix or+ array addition.+ - When you multiply two matrices, %Eigen assumes that aliasing occurs. If you know that there is no aliasing,+ then you can use \link MatrixBase::noalias() noalias()\endlink.+ - In all other situations, %Eigen assumes that there is no aliasing issue and thus gives the wrong result if+ aliasing does in fact occur. To prevent this, you have to use \link DenseBase::eval() eval() \endlink or+ one of the xxxInPlace() functions.++*/+}
+ eigen3/doc/TopicAssertions.dox view
@@ -0,0 +1,108 @@+namespace Eigen {++/** \page TopicAssertions Assertions++\eigenAutoToc++\section PlainAssert Assertions++The macro eigen_assert is defined to be \c eigen_plain_assert by default. We use eigen_plain_assert instead of \c assert to work around a known bug for GCC <= 4.3. Basically, eigen_plain_assert \a is \c assert.++\subsection RedefineAssert Redefining assertions++Both eigen_assert and eigen_plain_assert are defined in Macros.h. Defining eigen_assert indirectly gives you a chance to change its behavior. You can redefine this macro if you want to do something else such as throwing an exception, and fall back to its default behavior with eigen_plain_assert. The code below tells Eigen to throw an std::runtime_error:++\code+#include <stdexcept>+#undef eigen_assert+#define eigen_assert(x) \+ if (!x) { throw (std::runtime_error("Put your message here")); }+\endcode++\subsection DisableAssert Disabling assertions++Assertions cost run time and can be turned off. You can suppress eigen_assert by defining \c EIGEN_NO_DEBUG \b before including Eigen headers. \c EIGEN_NO_DEBUG is undefined by default unless \c NDEBUG is defined.++\section StaticAssert Static assertions++Static assertions are not standardized until C++11. However, in the Eigen library, there are many conditions can and should be detectedat compile time. For instance, we use static assertions to prevent the code below from compiling.++\code+Matrix3d() + Matrix4d(); // adding matrices of different sizes+Matrix4cd() * Vector3cd(); // invalid product known at compile time+\endcode++Static assertions are defined in StaticAssert.h. If there is native static_assert, we use it. Otherwise, we have implemented an assertion macro that can show a limited range of messages.++One can easily come up with static assertions without messages, such as:++\code+#define STATIC_ASSERT(x) \+ switch(0) { case 0: case x:; }+\endcode++However, the example above obviously cannot tell why the assertion failed. Therefore, we define a \c struct in namespace Eigen::internal to handle available messages.++\code+template<bool condition>+struct static_assertion {};++template<>+struct static_assertion<true>+{+ enum {+ YOU_TRIED_CALLING_A_VECTOR_METHOD_ON_A_MATRIX,+ YOU_MIXED_VECTORS_OF_DIFFERENT_SIZES,+ // see StaticAssert.h for all enums.+ };+};+\endcode++And then, we define EIGEN_STATIC_ASSERT(CONDITION,MSG) to access Eigen::internal::static_assertion<bool(CONDITION)>::MSG. If the condition evaluates into \c false, your compiler displays a lot of messages explaining there is no MSG in static_assert<false>. Nevertheless, this is \a not in what we are interested. As you can see, all members of static_assert<true> are ALL_CAPS_AND_THEY_ARE_SHOUTING.++\warning+When using this macro, MSG should be a member of static_assertion<true>, or the static assertion \b always fails.+Currently, it can only be used in function scope.++\subsection DerivedStaticAssert Derived static assertions++There are other macros derived from EIGEN_STATIC_ASSERT to enhance readability. Their names are self-explanatory.++- \b EIGEN_STATIC_ASSERT_FIXED_SIZE(TYPE) - passes if \a TYPE is fixed size.+- \b EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(TYPE) - passes if \a TYPE is dynamic size.+- \b EIGEN_STATIC_ASSERT_LVALUE(Derived) - failes if \a Derived is read-only.+- \b EIGEN_STATIC_ASSERT_ARRAYXPR(Derived) - passes if \a Derived is an array expression.+- <b>EIGEN_STATIC_ASSERT_SAME_XPR_KIND(Derived1, Derived2)</b> - failes if the two expressions are an array one and a matrix one.++Because Eigen handles both fixed-size and dynamic-size expressions, some conditions cannot be clearly determined at compile time. We classify them into strict assertions and permissive assertions.++\subsubsection StrictAssertions Strict assertions++These assertions fail if the condition <b>may not</b> be met. For example, MatrixXd may not be a vector, so it fails EIGEN_STATIC_ASSERT_VECTOR_ONLY.++- \b EIGEN_STATIC_ASSERT_VECTOR_ONLY(TYPE) - passes if \a TYPE must be a vector type.+- <b>EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(TYPE, SIZE)</b> - passes if \a TYPE must be a vector of the given size.+- <b>EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(TYPE, ROWS, COLS)</b> - passes if \a TYPE must be a matrix with given rows and columns.++\subsubsection PermissiveAssertions Permissive assertions++These assertions fail if the condition \b cannot be met. For example, MatrixXd and Matrix4d may have the same size, so they pass EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE.++- \b EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(TYPE0,TYPE1) - fails if the two vector expression types must have different sizes.+- \b EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(TYPE0,TYPE1) - fails if the two matrix expression types must have different sizes.+- \b EIGEN_STATIC_ASSERT_SIZE_1x1(TYPE) - fails if \a TYPE cannot be an 1x1 expression.++See StaticAssert.h for details such as what messages they throw.++\subsection DisableStaticAssert Disabling static assertions++If \c EIGEN_NO_STATIC_ASSERT is defined, static assertions turn into <tt>eigen_assert</tt>'s, working like:++\code+#define EIGEN_STATIC_ASSERT(CONDITION,MSG) eigen_assert((CONDITION) && #MSG);+\endcode++This saves compile time but consumes more run time. \c EIGEN_NO_STATIC_ASSERT is undefined by default.++*/+}
+ eigen3/doc/TopicEigenExpressionTemplates.dox view
@@ -0,0 +1,12 @@+namespace Eigen {++/** \page TopicEigenExpressionTemplates Expression templates in Eigen+++TODO: write this dox page!++Is linked from the tutorial on arithmetic ops.++*/++}
+ eigen3/doc/TopicLazyEvaluation.dox view
@@ -0,0 +1,65 @@+namespace Eigen {++/** \page TopicLazyEvaluation Lazy Evaluation and Aliasing++Executive summary: Eigen has intelligent compile-time mechanisms to enable lazy evaluation and removing temporaries where appropriate.+It will handle aliasing automatically in most cases, for example with matrix products. The automatic behavior can be overridden+manually by using the MatrixBase::eval() and MatrixBase::noalias() methods.++When you write a line of code involving a complex expression such as++\code mat1 = mat2 + mat3 * (mat4 + mat5); \endcode++Eigen determines automatically, for each sub-expression, whether to evaluate it into a temporary variable. Indeed, in certain cases it is better to evaluate immediately a sub-expression into a temporary variable, while in other cases it is better to avoid that.++A traditional math library without expression templates always evaluates all sub-expressions into temporaries. So with this code,++\code vec1 = vec2 + vec3; \endcode++a traditional library would evaluate \c vec2 + vec3 into a temporary \c vec4 and then copy \c vec4 into \c vec1. This is of course inefficient: the arrays are traversed twice, so there are a lot of useless load/store operations.++Expression-templates-based libraries can avoid evaluating sub-expressions into temporaries, which in many cases results in large speed improvements. This is called <i>lazy evaluation</i> as an expression is getting evaluated as late as possible, instead of immediately. However, most other expression-templates-based libraries <i>always</i> choose lazy evaluation. There are two problems with that: first, lazy evaluation is not always a good choice for performance; second, lazy evaluation can be very dangerous, for example with matrix products: doing <tt>matrix = matrix*matrix</tt> gives a wrong result if the matrix product is lazy-evaluated, because of the way matrix product works.++For these reasons, Eigen has intelligent compile-time mechanisms to determine automatically when to use lazy evaluation, and when on the contrary it should evaluate immediately into a temporary variable.++So in the basic example,++\code matrix1 = matrix2 + matrix3; \endcode++Eigen chooses lazy evaluation. Thus the arrays are traversed only once, producing optimized code. If you really want to force immediate evaluation, use \link MatrixBase::eval() eval()\endlink:++\code matrix1 = (matrix2 + matrix3).eval(); \endcode++Here is now a more involved example:++\code matrix1 = -matrix2 + matrix3 + 5 * matrix4; \endcode++Eigen chooses lazy evaluation at every stage in that example, which is clearly the correct choice. In fact, lazy evaluation is the "default choice" and Eigen will choose it except in a few circumstances.++<b>The first circumstance</b> in which Eigen chooses immediate evaluation, is when it sees an assignment <tt>a = b;</tt> and the expression \c b has the evaluate-before-assigning \link flags flag\endlink. The most important example of such an expression is the \link GeneralProduct matrix product expression\endlink. For example, when you do++\code matrix = matrix * matrix; \endcode++Eigen first evaluates <tt>matrix * matrix</tt> into a temporary matrix, and then copies it into the original \c matrix. This guarantees a correct result as we saw above that lazy evaluation gives wrong results with matrix products. It also doesn't cost much, as the cost of the matrix product itself is much higher.++What if you know that the result does no alias the operand of the product and want to force lazy evaluation? Then use \link MatrixBase::noalias() .noalias()\endlink instead. Here is an example:++\code matrix1.noalias() = matrix2 * matrix2; \endcode++Here, since we know that matrix2 is not the same matrix as matrix1, we know that lazy evaluation is not dangerous, so we may force lazy evaluation. Concretely, the effect of noalias() here is to bypass the evaluate-before-assigning \link flags flag\endlink.++<b>The second circumstance</b> in which Eigen chooses immediate evaluation, is when it sees a nested expression such as <tt>a + b</tt> where \c b is already an expression having the evaluate-before-nesting \link flags flag\endlink. Again, the most important example of such an expression is the \link GeneralProduct matrix product expression\endlink. For example, when you do++\code matrix1 = matrix2 + matrix3 * matrix4; \endcode++the product <tt>matrix3 * matrix4</tt> gets evaluated immediately into a temporary matrix. Indeed, experiments showed that it is often beneficial for performance to evaluate immediately matrix products when they are nested into bigger expressions.++<b>The third circumstance</b> in which Eigen chooses immediate evaluation, is when its cost model shows that the total cost of an operation is reduced if a sub-expression gets evaluated into a temporary. Indeed, in certain cases, an intermediate result is sufficiently costly to compute and is reused sufficiently many times, that is worth "caching". Here is an example:++\code matrix1 = matrix2 * (matrix3 + matrix4); \endcode++Here, provided the matrices have at least 2 rows and 2 columns, each coefficienct of the expression <tt>matrix3 + matrix4</tt> is going to be used several times in the matrix product. Instead of computing the sum everytime, it is much better to compute it once and store it in a temporary variable. Eigen understands this and evaluates <tt>matrix3 + matrix4</tt> into a temporary variable before evaluating the product.++*/++}
+ eigen3/doc/TopicLinearAlgebraDecompositions.dox view
@@ -0,0 +1,261 @@+namespace Eigen {++/** \eigenManualPage TopicLinearAlgebraDecompositions Catalogue of dense decompositions++This page presents a catalogue of the dense matrix decompositions offered by Eigen.+For an introduction on linear solvers and decompositions, check this \link TutorialLinearAlgebra page \endlink.++\section TopicLinAlgBigTable Catalogue of decompositions offered by Eigen++<table class="manual-vl">+ <tr>+ <th class="meta"></th>+ <th class="meta" colspan="5">Generic information, not Eigen-specific</th>+ <th class="meta" colspan="3">Eigen-specific</th>+ </tr>++ <tr>+ <th>Decomposition</th>+ <th>Requirements on the matrix</th>+ <th>Speed</th>+ <th>Algorithm reliability and accuracy</th>+ <th>Rank-revealing</th>+ <th>Allows to compute (besides linear solving)</th>+ <th>Linear solver provided by Eigen</th>+ <th>Maturity of Eigen's implementation</th>+ <th>Optimizations</th>+ </tr>++ <tr>+ <td>PartialPivLU</td>+ <td>Invertible</td>+ <td>Fast</td>+ <td>Depends on condition number</td>+ <td>-</td>+ <td>-</td>+ <td>Yes</td>+ <td>Excellent</td>+ <td>Blocking, Implicit MT</td>+ </tr>++ <tr class="alt">+ <td>FullPivLU</td>+ <td>-</td>+ <td>Slow</td>+ <td>Proven</td>+ <td>Yes</td>+ <td>-</td>+ <td>Yes</td>+ <td>Excellent</td>+ <td>-</td>+ </tr>++ <tr>+ <td>HouseholderQR</td>+ <td>-</td>+ <td>Fast</td>+ <td>Depends on condition number</td>+ <td>-</td>+ <td>Orthogonalization</td>+ <td>Yes</td>+ <td>Excellent</td>+ <td>Blocking</td>+ </tr>++ <tr class="alt">+ <td>ColPivHouseholderQR</td>+ <td>-</td>+ <td>Fast</td>+ <td>Good</td>+ <td>Yes</td>+ <td>Orthogonalization</td>+ <td>Yes</td>+ <td>Excellent</td>+ <td><em>Soon: blocking</em></td>+ </tr>++ <tr>+ <td>FullPivHouseholderQR</td>+ <td>-</td>+ <td>Slow</td>+ <td>Proven</td>+ <td>Yes</td>+ <td>Orthogonalization</td>+ <td>Yes</td>+ <td>Average</td>+ <td>-</td>+ </tr>++ <tr class="alt">+ <td>LLT</td>+ <td>Positive definite</td>+ <td>Very fast</td>+ <td>Depends on condition number</td>+ <td>-</td>+ <td>-</td>+ <td>Yes</td>+ <td>Excellent</td>+ <td>Blocking</td>+ </tr>++ <tr>+ <td>LDLT</td>+ <td>Positive or negative semidefinite<sup><a href="#note1">1</a></sup></td>+ <td>Very fast</td>+ <td>Good</td>+ <td>-</td>+ <td>-</td>+ <td>Yes</td>+ <td>Excellent</td>+ <td><em>Soon: blocking</em></td>+ </tr>++ <tr><th class="inter" colspan="9">\n Singular values and eigenvalues decompositions</th></tr>++ <tr>+ <td>JacobiSVD (two-sided)</td>+ <td>-</td>+ <td>Slow (but fast for small matrices)</td>+ <td>Excellent-Proven<sup><a href="#note3">3</a></sup></td>+ <td>Yes</td>+ <td>Singular values/vectors, least squares</td>+ <td>Yes (and does least squares)</td>+ <td>Excellent</td>+ <td>R-SVD</td>+ </tr>++ <tr class="alt">+ <td>SelfAdjointEigenSolver</td>+ <td>Self-adjoint</td>+ <td>Fast-average<sup><a href="#note2">2</a></sup></td>+ <td>Good</td>+ <td>Yes</td>+ <td>Eigenvalues/vectors</td>+ <td>-</td>+ <td>Good</td>+ <td><em>Closed forms for 2x2 and 3x3</em></td>+ </tr>++ <tr>+ <td>ComplexEigenSolver</td>+ <td>Square</td>+ <td>Slow-very slow<sup><a href="#note2">2</a></sup></td>+ <td>Depends on condition number</td>+ <td>Yes</td>+ <td>Eigenvalues/vectors</td>+ <td>-</td>+ <td>Average</td>+ <td>-</td>+ </tr>++ <tr class="alt">+ <td>EigenSolver</td>+ <td>Square and real</td>+ <td>Average-slow<sup><a href="#note2">2</a></sup></td>+ <td>Depends on condition number</td>+ <td>Yes</td>+ <td>Eigenvalues/vectors</td>+ <td>-</td>+ <td>Average</td>+ <td>-</td>+ </tr>++ <tr>+ <td>GeneralizedSelfAdjointEigenSolver</td>+ <td>Square</td>+ <td>Fast-average<sup><a href="#note2">2</a></sup></td>+ <td>Depends on condition number</td>+ <td>-</td>+ <td>Generalized eigenvalues/vectors</td>+ <td>-</td>+ <td>Good</td>+ <td>-</td>+ </tr>++ <tr><th class="inter" colspan="9">\n Helper decompositions</th></tr>++ <tr>+ <td>RealSchur</td>+ <td>Square and real</td>+ <td>Average-slow<sup><a href="#note2">2</a></sup></td>+ <td>Depends on condition number</td>+ <td>Yes</td>+ <td>-</td>+ <td>-</td>+ <td>Average</td>+ <td>-</td>+ </tr>++ <tr class="alt">+ <td>ComplexSchur</td>+ <td>Square</td>+ <td>Slow-very slow<sup><a href="#note2">2</a></sup></td>+ <td>Depends on condition number</td>+ <td>Yes</td>+ <td>-</td>+ <td>-</td>+ <td>Average</td>+ <td>-</td>+ </tr>++ <tr class="alt">+ <td>Tridiagonalization</td>+ <td>Self-adjoint</td>+ <td>Fast</td>+ <td>Good</td>+ <td>-</td>+ <td>-</td>+ <td>-</td>+ <td>Good</td>+ <td><em>Soon: blocking</em></td>+ </tr>++ <tr>+ <td>HessenbergDecomposition</td>+ <td>Square</td>+ <td>Average</td>+ <td>Good</td>+ <td>-</td>+ <td>-</td>+ <td>-</td>+ <td>Good</td>+ <td><em>Soon: blocking</em></td>+ </tr>++</table>++\b Notes:+<ul>+<li><a name="note1">\b 1: </a>There exist two variants of the LDLT algorithm. Eigen's one produces a pure diagonal D matrix, and therefore it cannot handle indefinite matrices, unlike Lapack's one which produces a block diagonal D matrix.</li>+<li><a name="note2">\b 2: </a>Eigenvalues, SVD and Schur decompositions rely on iterative algorithms. Their convergence speed depends on how well the eigenvalues are separated.</li>+<li><a name="note3">\b 3: </a>Our JacobiSVD is two-sided, making for proven and optimal precision for square matrices. For non-square matrices, we have to use a QR preconditioner first. The default choice, ColPivHouseholderQR, is already very reliable, but if you want it to be proven, use FullPivHouseholderQR instead.+</ul>++\section TopicLinAlgTerminology Terminology++<dl>+ <dt><b>Selfadjoint</b></dt>+ <dd>For a real matrix, selfadjoint is a synonym for symmetric. For a complex matrix, selfadjoint is a synonym for \em hermitian.+ More generally, a matrix \f$ A \f$ is selfadjoint if and only if it is equal to its adjoint \f$ A^* \f$. The adjoint is also called the \em conjugate \em transpose. </dd>+ <dt><b>Positive/negative definite</b></dt>+ <dd>A selfadjoint matrix \f$ A \f$ is positive definite if \f$ v^* A v > 0 \f$ for any non zero vector \f$ v \f$.+ In the same vein, it is negative definite if \f$ v^* A v < 0 \f$ for any non zero vector \f$ v \f$ </dd>+ <dt><b>Positive/negative semidefinite</b></dt>+ <dd>A selfadjoint matrix \f$ A \f$ is positive semi-definite if \f$ v^* A v \ge 0 \f$ for any non zero vector \f$ v \f$.+ In the same vein, it is negative semi-definite if \f$ v^* A v \le 0 \f$ for any non zero vector \f$ v \f$ </dd>++ <dt><b>Blocking</b></dt>+ <dd>Means the algorithm can work per block, whence guaranteeing a good scaling of the performance for large matrices.</dd>+ <dt><b>Implicit Multi Threading (MT)</b></dt>+ <dd>Means the algorithm can take advantage of multicore processors via OpenMP. "Implicit" means the algortihm itself is not parallelized, but that it relies on parallelized matrix-matrix product rountines.</dd>+ <dt><b>Explicit Multi Threading (MT)</b></dt>+ <dd>Means the algorithm is explicitely parallelized to take advantage of multicore processors via OpenMP.</dd>+ <dt><b>Meta-unroller</b></dt>+ <dd>Means the algorithm is automatically and explicitly unrolled for very small fixed size matrices.</dd>+ <dt><b></b></dt>+ <dd></dd>+</dl>++*/++}
+ eigen3/doc/TopicMultithreading.dox view
@@ -0,0 +1,46 @@+namespace Eigen {++/** \page TopicMultiThreading Eigen and multi-threading++\section TopicMultiThreading_MakingEigenMT Make Eigen run in parallel++Some Eigen's algorithms can exploit the multiple cores present in your hardware. To this end, it is enough to enable OpenMP on your compiler, for instance:+ * GCC: \c -fopenmp+ * ICC: \c -openmp+ * MSVC: check the respective option in the build properties.+You can control the number of thread that will be used using either the OpenMP API or Eiegn's API using the following priority:+\code+ OMP_NUM_THREADS=n ./my_program+ omp_set_num_threads(n);+ Eigen::setNbThreads(n);+\endcode+Unless setNbThreads has been called, Eigen uses the number of threads specified by OpenMP. You can restore this bahavior by calling \code setNbThreads(0); \endcode+You can query the number of threads that will be used with:+\code+n = Eigen::nbThreads( );+\endcode+You can disable Eigen's multi threading at compile time by defining the EIGEN_DONT_PARALLELIZE preprocessor token.++Currently, the following algorithms can make use of multi-threading:+ * general matrix - matrix products+ * PartialPivLU++\section TopicMultiThreading_UsingEigenWithMT Using Eigen in a multi-threaded application++In the case your own application is multithreaded, and multiple threads make calls to Eigen, then you have to initialize Eigen by calling the following routine \b before creating the threads:+\code+#include <Eigen/Core>++int main(int argc, char** argv)+{+ Eigen::initParallel();+ + ...+}+\endcode++In the case your application is parallelized with OpenMP, you might want to disable Eigen's own parallization as detailed in the previous section.++*/++}
+ eigen3/doc/TopicResizing.dox view
@@ -0,0 +1,11 @@+namespace Eigen {++/** \page TopicResizing Resizing+++TODO: write this dox page!++Is linked from the tutorial on the Matrix class.++*/+}
+ eigen3/doc/TopicScalarTypes.dox view
@@ -0,0 +1,12 @@+namespace Eigen {++/** \page TopicScalarTypes Scalar types+++TODO: write this dox page!++Is linked from the tutorial on the Matrix class.++*/++}
+ eigen3/doc/TopicVectorization.dox view
@@ -0,0 +1,9 @@+namespace Eigen {++/** \page TopicVectorization Vectorization+++TODO: write this dox page!++*/+}
+ eigen3/doc/TutorialAdvancedInitialization.dox view
@@ -0,0 +1,162 @@+namespace Eigen {++/** \eigenManualPage TutorialAdvancedInitialization Advanced initialization++This page discusses several advanced methods for initializing matrices. It gives more details on the+comma-initializer, which was introduced before. It also explains how to get special matrices such as the+identity matrix and the zero matrix.++\eigenAutoToc++\section TutorialAdvancedInitializationCommaInitializer The comma initializer++Eigen offers a comma initializer syntax which allows the user to easily set all the coefficients of a matrix,+vector or array. Simply list the coefficients, starting at the top-left corner and moving from left to right+and from the top to the bottom. The size of the object needs to be specified beforehand. If you list too few+or too many coefficients, Eigen will complain.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_commainit_01.cpp+</td>+<td>+\verbinclude Tutorial_commainit_01.out+</td></tr></table>++Moreover, the elements of the initialization list may themselves be vectors or matrices. A common use is+to join vectors or matrices together. For example, here is how to join two row vectors together. Remember+that you have to set the size before you can use the comma initializer.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_AdvancedInitialization_Join.cpp+</td>+<td>+\verbinclude Tutorial_AdvancedInitialization_Join.out+</td></tr></table>++We can use the same technique to initialize matrices with a block structure.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_AdvancedInitialization_Block.cpp+</td>+<td>+\verbinclude Tutorial_AdvancedInitialization_Block.out+</td></tr></table>++The comma initializer can also be used to fill block expressions such as <tt>m.row(i)</tt>. Here is a more+complicated way to get the same result as in the first example above:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_commainit_01b.cpp+</td>+<td>+\verbinclude Tutorial_commainit_01b.out+</td></tr></table>+++\section TutorialAdvancedInitializationSpecialMatrices Special matrices and arrays++The Matrix and Array classes have static methods like \link DenseBase::Zero() Zero()\endlink, which can be+used to initialize all coefficients to zero. There are three variants. The first variant takes no arguments+and can only be used for fixed-size objects. If you want to initialize a dynamic-size object to zero, you need+to specify the size. Thus, the second variant requires one argument and can be used for one-dimensional+dynamic-size objects, while the third variant requires two arguments and can be used for two-dimensional+objects. All three variants are illustrated in the following example:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_AdvancedInitialization_Zero.cpp+</td>+<td>+\verbinclude Tutorial_AdvancedInitialization_Zero.out+</td></tr></table>++Similarly, the static method \link DenseBase::Constant() Constant\endlink(value) sets all coefficients to \c value.+If the size of the object needs to be specified, the additional arguments go before the \c value+argument, as in <tt>MatrixXd::Constant(rows, cols, value)</tt>. The method \link DenseBase::Random() Random()+\endlink fills the matrix or array with random coefficients. The identity matrix can be obtained by calling+\link MatrixBase::Identity() Identity()\endlink; this method is only available for Matrix, not for Array,+because "identity matrix" is a linear algebra concept. The method+\link DenseBase::LinSpaced LinSpaced\endlink(size, low, high) is only available for vectors and+one-dimensional arrays; it yields a vector of the specified size whose coefficients are equally spaced between+\c low and \c high. The method \c LinSpaced() is illustrated in the following example, which prints a table+with angles in degrees, the corresponding angle in radians, and their sine and cosine.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_AdvancedInitialization_LinSpaced.cpp+</td>+<td>+\verbinclude Tutorial_AdvancedInitialization_LinSpaced.out+</td></tr></table>++This example shows that objects like the ones returned by LinSpaced() can be assigned to variables (and+expressions). Eigen defines utility functions like \link DenseBase::setZero() setZero()\endlink, +\link MatrixBase::setIdentity() \endlink and \link DenseBase::setLinSpaced() \endlink to do this+conveniently. The following example contrasts three ways to construct the matrix+\f$ J = \bigl[ \begin{smallmatrix} O & I \\ I & O \end{smallmatrix} \bigr] \f$: using static methods and+assignment, using static methods and the comma-initializer, or using the setXxx() methods.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_AdvancedInitialization_ThreeWays.cpp+</td>+<td>+\verbinclude Tutorial_AdvancedInitialization_ThreeWays.out+</td></tr></table>++A summary of all pre-defined matrix, vector and array objects can be found in the \ref QuickRefPage.+++\section TutorialAdvancedInitializationTemporaryObjects Usage as temporary objects++As shown above, static methods as Zero() and Constant() can be used to initialize variables at the time of+declaration or at the right-hand side of an assignment operator. You can think of these methods as returning a+matrix or array; in fact, they return so-called \ref TopicEigenExpressionTemplates "expression objects" which+evaluate to a matrix or array when needed, so that this syntax does not incur any overhead.++These expressions can also be used as a temporary object. The second example in+the \ref GettingStarted guide, which we reproduce here, already illustrates this.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include QuickStart_example2_dynamic.cpp+</td>+<td>+\verbinclude QuickStart_example2_dynamic.out+</td></tr></table>++The expression <tt>m + MatrixXf::Constant(3,3,1.2)</tt> constructs the 3-by-3 matrix expression with all its coefficients+equal to 1.2 plus the corresponding coefficient of \a m.++The comma-initializer, too, can also be used to construct temporary objects. The following example constructs a random+matrix of size 2-by-3, and then multiplies this matrix on the left with +\f$ \bigl[ \begin{smallmatrix} 0 & 1 \\ 1 & 0 \end{smallmatrix} \bigr] \f$.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_AdvancedInitialization_CommaTemporary.cpp+</td>+<td>+\verbinclude Tutorial_AdvancedInitialization_CommaTemporary.out+</td></tr></table>++The \link CommaInitializer::finished() finished() \endlink method is necessary here to get the actual matrix+object once the comma initialization of our temporary submatrix is done.+++*/++}
+ eigen3/doc/TutorialArrayClass.dox view
@@ -0,0 +1,192 @@+namespace Eigen {++/** \eigenManualPage TutorialArrayClass The Array class and coefficient-wise operations++This page aims to provide an overview and explanations on how to use+Eigen's Array class.++\eigenAutoToc+ +\section TutorialArrayClassIntro What is the Array class?++The Array class provides general-purpose arrays, as opposed to the Matrix class which+is intended for linear algebra. Furthermore, the Array class provides an easy way to+perform coefficient-wise operations, which might not have a linear algebraic meaning,+such as adding a constant to every coefficient in the array or multiplying two arrays coefficient-wise.+++\section TutorialArrayClassTypes Array types+Array is a class template taking the same template parameters as Matrix.+As with Matrix, the first three template parameters are mandatory:+\code+Array<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>+\endcode+The last three template parameters are optional. Since this is exactly the same as for Matrix,+we won't explain it again here and just refer to \ref TutorialMatrixClass.++Eigen also provides typedefs for some common cases, in a way that is similar to the Matrix typedefs+but with some slight differences, as the word "array" is used for both 1-dimensional and 2-dimensional arrays.+We adopt the convention that typedefs of the form ArrayNt stand for 1-dimensional arrays, where N and t are+the size and the scalar type, as in the Matrix typedefs explained on \ref TutorialMatrixClass "this page". For 2-dimensional arrays, we+use typedefs of the form ArrayNNt. Some examples are shown in the following table:++<table class="manual">+ <tr>+ <th>Type </th>+ <th>Typedef </th>+ </tr>+ <tr>+ <td> \code Array<float,Dynamic,1> \endcode </td>+ <td> \code ArrayXf \endcode </td>+ </tr>+ <tr>+ <td> \code Array<float,3,1> \endcode </td>+ <td> \code Array3f \endcode </td>+ </tr>+ <tr>+ <td> \code Array<double,Dynamic,Dynamic> \endcode </td>+ <td> \code ArrayXXd \endcode </td>+ </tr>+ <tr>+ <td> \code Array<double,3,3> \endcode </td>+ <td> \code Array33d \endcode </td>+ </tr>+</table>+++\section TutorialArrayClassAccess Accessing values inside an Array++The parenthesis operator is overloaded to provide write and read access to the coefficients of an array, just as with matrices.+Furthermore, the \c << operator can be used to initialize arrays (via the comma initializer) or to print them.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_ArrayClass_accessors.cpp+</td>+<td>+\verbinclude Tutorial_ArrayClass_accessors.out+</td></tr></table>++For more information about the comma initializer, see \ref TutorialAdvancedInitialization.+++\section TutorialArrayClassAddSub Addition and subtraction++Adding and subtracting two arrays is the same as for matrices.+The operation is valid if both arrays have the same size, and the addition or subtraction is done coefficient-wise.++Arrays also support expressions of the form <tt>array + scalar</tt> which add a scalar to each coefficient in the array.+This provides a functionality that is not directly available for Matrix objects.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_ArrayClass_addition.cpp+</td>+<td>+\verbinclude Tutorial_ArrayClass_addition.out+</td></tr></table>+++\section TutorialArrayClassMult Array multiplication++First of all, of course you can multiply an array by a scalar, this works in the same way as matrices. Where arrays+are fundamentally different from matrices, is when you multiply two together. Matrices interpret+multiplication as matrix product and arrays interpret multiplication as coefficient-wise product. Thus, two +arrays can be multiplied if and only if they have the same dimensions.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_ArrayClass_mult.cpp+</td>+<td>+\verbinclude Tutorial_ArrayClass_mult.out+</td></tr></table>+++\section TutorialArrayClassCwiseOther Other coefficient-wise operations++The Array class defines other coefficient-wise operations besides the addition, subtraction and multiplication+operators described above. For example, the \link ArrayBase::abs() .abs() \endlink method takes the absolute+value of each coefficient, while \link ArrayBase::sqrt() .sqrt() \endlink computes the square root of the+coefficients. If you have two arrays of the same size, you can call \link ArrayBase::min(const Eigen::ArrayBase<OtherDerived>&) const .min(.) \endlink to+construct the array whose coefficients are the minimum of the corresponding coefficients of the two given+arrays. These operations are illustrated in the following example.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_ArrayClass_cwise_other.cpp+</td>+<td>+\verbinclude Tutorial_ArrayClass_cwise_other.out+</td></tr></table>++More coefficient-wise operations can be found in the \ref QuickRefPage.+++\section TutorialArrayClassConvert Converting between array and matrix expressions++When should you use objects of the Matrix class and when should you use objects of the Array class? You cannot+apply Matrix operations on arrays, or Array operations on matrices. Thus, if you need to do linear algebraic+operations such as matrix multiplication, then you should use matrices; if you need to do coefficient-wise+operations, then you should use arrays. However, sometimes it is not that simple, but you need to use both+Matrix and Array operations. In that case, you need to convert a matrix to an array or reversely. This gives+access to all operations regardless of the choice of declaring objects as arrays or as matrices.++\link MatrixBase Matrix expressions \endlink have an \link MatrixBase::array() .array() \endlink method that+'converts' them into \link ArrayBase array expressions\endlink, so that coefficient-wise operations+can be applied easily. Conversely, \link ArrayBase array expressions \endlink+have a \link ArrayBase::matrix() .matrix() \endlink method. As with all Eigen expression abstractions,+this doesn't have any runtime cost (provided that you let your compiler optimize).+Both \link MatrixBase::array() .array() \endlink and \link ArrayBase::matrix() .matrix() \endlink +can be used as rvalues and as lvalues.++Mixing matrices and arrays in an expression is forbidden with Eigen. For instance, you cannot add a matrix and+array directly; the operands of a \c + operator should either both be matrices or both be arrays. However,+it is easy to convert from one to the other with \link MatrixBase::array() .array() \endlink and +\link ArrayBase::matrix() .matrix()\endlink. The exception to this rule is the assignment operator: it is+allowed to assign a matrix expression to an array variable, or to assign an array expression to a matrix+variable.++The following example shows how to use array operations on a Matrix object by employing the +\link MatrixBase::array() .array() \endlink method. For example, the statement +<tt>result = m.array() * n.array()</tt> takes two matrices \c m and \c n, converts them both to an array, uses+* to multiply them coefficient-wise and assigns the result to the matrix variable \c result (this is legal+because Eigen allows assigning array expressions to matrix variables). ++As a matter of fact, this usage case is so common that Eigen provides a \link MatrixBase::cwiseProduct() const+.cwiseProduct(.) \endlink method for matrices to compute the coefficient-wise product. This is also shown in+the example program.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_ArrayClass_interop_matrix.cpp+</td>+<td>+\verbinclude Tutorial_ArrayClass_interop_matrix.out+</td></tr></table>++Similarly, if \c array1 and \c array2 are arrays, then the expression <tt>array1.matrix() * array2.matrix()</tt>+computes their matrix product.++Here is a more advanced example. The expression <tt>(m.array() + 4).matrix() * m</tt> adds 4 to every+coefficient in the matrix \c m and then computes the matrix product of the result with \c m. Similarly, the+expression <tt>(m.array() * n.array()).matrix() * m</tt> computes the coefficient-wise product of the matrices+\c m and \c n and then the matrix product of the result with \c m.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_ArrayClass_interop.cpp+</td>+<td>+\verbinclude Tutorial_ArrayClass_interop.out+</td></tr></table>++*/++}
+ eigen3/doc/TutorialBlockOperations.dox view
@@ -0,0 +1,228 @@+namespace Eigen {++/** \eigenManualPage TutorialBlockOperations Block operations++This page explains the essentials of block operations.+A block is a rectangular part of a matrix or array. Blocks expressions can be used both+as rvalues and as lvalues. As usual with Eigen expressions, this abstraction has zero runtime cost+provided that you let your compiler optimize.++\eigenAutoToc++\section TutorialBlockOperationsUsing Using block operations++The most general block operation in Eigen is called \link DenseBase::block() .block() \endlink.+There are two versions, whose syntax is as follows:++<table class="manual">+<tr><th>\b %Block \b operation</td>+<th>Version constructing a \n dynamic-size block expression</th>+<th>Version constructing a \n fixed-size block expression</th></tr>+<tr><td>%Block of size <tt>(p,q)</tt>, starting at <tt>(i,j)</tt></td>+ <td>\code+matrix.block(i,j,p,q);\endcode </td>+ <td>\code +matrix.block<p,q>(i,j);\endcode </td>+</tr>+</table>++As always in Eigen, indices start at 0.++Both versions can be used on fixed-size and dynamic-size matrices and arrays.+These two expressions are semantically equivalent.+The only difference is that the fixed-size version will typically give you faster code if the block size is small,+but requires this size to be known at compile time.++The following program uses the dynamic-size and fixed-size versions to print the values of several blocks inside a+matrix.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_BlockOperations_print_block.cpp+</td>+<td>+\verbinclude Tutorial_BlockOperations_print_block.out+</td></tr></table>++In the above example the \link DenseBase::block() .block() \endlink function was employed as a \em rvalue, i.e.+it was only read from. However, blocks can also be used as \em lvalues, meaning that you can assign to a block.++This is illustrated in the following example. This example also demonstrates blocks in arrays, which works exactly like the above-demonstrated blocks in matrices.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_BlockOperations_block_assignment.cpp+</td>+<td>+\verbinclude Tutorial_BlockOperations_block_assignment.out+</td></tr></table>++While the \link DenseBase::block() .block() \endlink method can be used for any block operation, there are+other methods for special cases, providing more specialized API and/or better performance. On the topic of performance, all what+matters is that you give Eigen as much information as possible at compile time. For example, if your block is a single whole column in a matrix,+using the specialized \link DenseBase::col() .col() \endlink function described below lets Eigen know that, which can give it optimization opportunities.++The rest of this page describes these specialized methods.++\section TutorialBlockOperationsSyntaxColumnRows Columns and rows++Individual columns and rows are special cases of blocks. Eigen provides methods to easily address them:+\link DenseBase::col() .col() \endlink and \link DenseBase::row() .row()\endlink.++<table class="manual">+<tr><th>%Block operation</th>+<th>Method</th>+<tr><td>i<sup>th</sup> row+ \link DenseBase::row() * \endlink</td>+ <td>\code+matrix.row(i);\endcode </td>+</tr>+<tr><td>j<sup>th</sup> column+ \link DenseBase::col() * \endlink</td>+ <td>\code+matrix.col(j);\endcode </td>+</tr>+</table>++The argument for \p col() and \p row() is the index of the column or row to be accessed. As always in Eigen, indices start at 0.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_BlockOperations_colrow.cpp+</td>+<td>+\verbinclude Tutorial_BlockOperations_colrow.out+</td></tr></table>++That example also demonstrates that block expressions (here columns) can be used in arithmetic like any other expression.+++\section TutorialBlockOperationsSyntaxCorners Corner-related operations++Eigen also provides special methods for blocks that are flushed against one of the corners or sides of a+matrix or array. For instance, \link DenseBase::topLeftCorner() .topLeftCorner() \endlink can be used to refer+to a block in the top-left corner of a matrix.++The different possibilities are summarized in the following table:++<table class="manual">+<tr><th>%Block \b operation</td>+<th>Version constructing a \n dynamic-size block expression</th>+<th>Version constructing a \n fixed-size block expression</th></tr>+<tr><td>Top-left p by q block \link DenseBase::topLeftCorner() * \endlink</td>+ <td>\code+matrix.topLeftCorner(p,q);\endcode </td>+ <td>\code +matrix.topLeftCorner<p,q>();\endcode </td>+</tr>+<tr><td>Bottom-left p by q block+ \link DenseBase::bottomLeftCorner() * \endlink</td>+ <td>\code+matrix.bottomLeftCorner(p,q);\endcode </td>+ <td>\code +matrix.bottomLeftCorner<p,q>();\endcode </td>+</tr>+<tr><td>Top-right p by q block+ \link DenseBase::topRightCorner() * \endlink</td>+ <td>\code+matrix.topRightCorner(p,q);\endcode </td>+ <td>\code +matrix.topRightCorner<p,q>();\endcode </td>+</tr>+<tr><td>Bottom-right p by q block+ \link DenseBase::bottomRightCorner() * \endlink</td>+ <td>\code+matrix.bottomRightCorner(p,q);\endcode </td>+ <td>\code +matrix.bottomRightCorner<p,q>();\endcode </td>+</tr>+<tr><td>%Block containing the first q rows+ \link DenseBase::topRows() * \endlink</td>+ <td>\code+matrix.topRows(q);\endcode </td>+ <td>\code +matrix.topRows<q>();\endcode </td>+</tr>+<tr><td>%Block containing the last q rows+ \link DenseBase::bottomRows() * \endlink</td>+ <td>\code+matrix.bottomRows(q);\endcode </td>+ <td>\code +matrix.bottomRows<q>();\endcode </td>+</tr>+<tr><td>%Block containing the first p columns+ \link DenseBase::leftCols() * \endlink</td>+ <td>\code+matrix.leftCols(p);\endcode </td>+ <td>\code +matrix.leftCols<p>();\endcode </td>+</tr>+<tr><td>%Block containing the last q columns+ \link DenseBase::rightCols() * \endlink</td>+ <td>\code+matrix.rightCols(q);\endcode </td>+ <td>\code +matrix.rightCols<q>();\endcode </td>+</tr>+</table>++Here is a simple example illustrating the use of the operations presented above:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_BlockOperations_corner.cpp+</td>+<td>+\verbinclude Tutorial_BlockOperations_corner.out+</td></tr></table>+++\section TutorialBlockOperationsSyntaxVectors Block operations for vectors++Eigen also provides a set of block operations designed specifically for the special case of vectors and one-dimensional arrays:++<table class="manual">+<tr><th> %Block operation</th>+<th>Version constructing a \n dynamic-size block expression</th>+<th>Version constructing a \n fixed-size block expression</th></tr>+<tr><td>%Block containing the first \p n elements + \link DenseBase::head() * \endlink</td>+ <td>\code+vector.head(n);\endcode </td>+ <td>\code +vector.head<n>();\endcode </td>+</tr>+<tr><td>%Block containing the last \p n elements+ \link DenseBase::tail() * \endlink</td>+ <td>\code+vector.tail(n);\endcode </td>+ <td>\code +vector.tail<n>();\endcode </td>+</tr>+<tr><td>%Block containing \p n elements, starting at position \p i+ \link DenseBase::segment() * \endlink</td>+ <td>\code+vector.segment(i,n);\endcode </td>+ <td>\code +vector.segment<n>(i);\endcode </td>+</tr>+</table>+++An example is presented below:+<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_BlockOperations_vector.cpp+</td>+<td>+\verbinclude Tutorial_BlockOperations_vector.out+</td></tr></table>++*/++}
+ eigen3/doc/TutorialGeometry.dox view
@@ -0,0 +1,241 @@+namespace Eigen {++/** \eigenManualPage TutorialGeometry Space transformations++In this page, we will introduce the many possibilities offered by the \ref Geometry_Module "geometry module" to deal with 2D and 3D rotations and projective or affine transformations.++\eigenAutoToc++Eigen's Geometry module provides two different kinds of geometric transformations:+ - Abstract transformations, such as rotations (represented by \ref AngleAxis "angle and axis" or by a \ref Quaternion "quaternion"), \ref Translation "translations", \ref Scaling "scalings". These transformations are NOT represented as matrices, but you can nevertheless mix them with matrices and vectors in expressions, and convert them to matrices if you wish.+ - Projective or affine transformation matrices: see the Transform class. These are really matrices.++\note If you are working with OpenGL 4x4 matrices then Affine3f and Affine3d are what you want. Since Eigen defaults to column-major storage, you can directly use the Transform::data() method to pass your transformation matrix to OpenGL.++You can construct a Transform from an abstract transformation, like this:+\code+ Transform t(AngleAxis(angle,axis));+\endcode+or like this:+\code+ Transform t;+ t = AngleAxis(angle,axis);+\endcode+But note that unfortunately, because of how C++ works, you can \b not do this:+\code+ Transform t = AngleAxis(angle,axis);+\endcode+<span class="note">\b Explanation: In the C++ language, this would require Transform to have a non-explicit conversion constructor from AngleAxis, but we really don't want to allow implicit casting here.+</span>++\section TutorialGeoElementaryTransformations Transformation types++<table class="manual">+<tr><th>Transformation type</th><th>Typical initialization code</th></tr>+<tr><td>+\ref Rotation2D "2D rotation" from an angle</td><td>\code+Rotation2D<float> rot2(angle_in_radian);\endcode</td></tr>+<tr class="alt"><td>+3D rotation as an \ref AngleAxis "angle + axis"</td><td>\code+AngleAxis<float> aa(angle_in_radian, Vector3f(ax,ay,az));\endcode+<span class="note">The axis vector must be normalized.</span></td></tr>+<tr><td>+3D rotation as a \ref Quaternion "quaternion"</td><td>\code+Quaternion<float> q; q = AngleAxis<float>(angle_in_radian, axis);\endcode</td></tr>+<tr class="alt"><td>+N-D Scaling</td><td>\code+Scaling(sx, sy)+Scaling(sx, sy, sz)+Scaling(s)+Scaling(vecN)\endcode</td></tr>+<tr><td>+N-D Translation</td><td>\code+Translation<float,2>(tx, ty)+Translation<float,3>(tx, ty, tz)+Translation<float,N>(s)+Translation<float,N>(vecN)\endcode</td></tr>+<tr class="alt"><td>+N-D \ref TutorialGeoTransform "Affine transformation"</td><td>\code+Transform<float,N,Affine> t = concatenation_of_any_transformations;+Transform<float,3,Affine> t = Translation3f(p) * AngleAxisf(a,axis) * Scaling(s);\endcode</td></tr>+<tr><td>+N-D Linear transformations \n+<em class=note>(pure rotations, \n scaling, etc.)</em></td><td>\code+Matrix<float,N> t = concatenation_of_rotations_and_scalings;+Matrix<float,2> t = Rotation2Df(a) * Scaling(s);+Matrix<float,3> t = AngleAxisf(a,axis) * Scaling(s);\endcode</td></tr>+</table>++<strong>Notes on rotations</strong>\n To transform more than a single vector the preferred+representations are rotation matrices, while for other usages Quaternion is the+representation of choice as they are compact, fast and stable. Finally Rotation2D and+AngleAxis are mainly convenient types to create other rotation objects.++<strong>Notes on Translation and Scaling</strong>\n Like AngleAxis, these classes were+designed to simplify the creation/initialization of linear (Matrix) and affine (Transform)+transformations. Nevertheless, unlike AngleAxis which is inefficient to use, these classes+might still be interesting to write generic and efficient algorithms taking as input any+kind of transformations.++Any of the above transformation types can be converted to any other types of the same nature,+or to a more generic type. Here are some additional examples:+<table class="manual">+<tr><td>\code+Rotation2Df r; r = Matrix2f(..); // assumes a pure rotation matrix+AngleAxisf aa; aa = Quaternionf(..);+AngleAxisf aa; aa = Matrix3f(..); // assumes a pure rotation matrix+Matrix2f m; m = Rotation2Df(..);+Matrix3f m; m = Quaternionf(..); Matrix3f m; m = Scaling(..);+Affine3f m; m = AngleAxis3f(..); Affine3f m; m = Scaling(..);+Affine3f m; m = Translation3f(..); Affine3f m; m = Matrix3f(..);+\endcode</td></tr>+</table>+++<a href="#" class="top">top</a>\section TutorialGeoCommontransformationAPI Common API across transformation types++To some extent, Eigen's \ref Geometry_Module "geometry module" allows you to write+generic algorithms working on any kind of transformation representations:+<table class="manual">+<tr><td>+Concatenation of two transformations</td><td>\code+gen1 * gen2;\endcode</td></tr>+<tr class="alt"><td>Apply the transformation to a vector</td><td>\code+vec2 = gen1 * vec1;\endcode</td></tr>+<tr><td>Get the inverse of the transformation</td><td>\code+gen2 = gen1.inverse();\endcode</td></tr>+<tr class="alt"><td>Spherical interpolation \n (Rotation2D and Quaternion only)</td><td>\code+rot3 = rot1.slerp(alpha,rot2);\endcode</td></tr>+</table>++++<a href="#" class="top">top</a>\section TutorialGeoTransform Affine transformations+Generic affine transformations are represented by the Transform class which internaly+is a (Dim+1)^2 matrix. In Eigen we have chosen to not distinghish between points and+vectors such that all points are actually represented by displacement vectors from the+origin ( \f$ \mathbf{p} \equiv \mathbf{p}-0 \f$ ). With that in mind, real points and+vector distinguish when the transformation is applied.+<table class="manual">+<tr><td>+Apply the transformation to a \b point </td><td>\code+VectorNf p1, p2;+p2 = t * p1;\endcode</td></tr>+<tr class="alt"><td>+Apply the transformation to a \b vector </td><td>\code+VectorNf vec1, vec2;+vec2 = t.linear() * vec1;\endcode</td></tr>+<tr><td>+Apply a \em general transformation \n to a \b normal \b vector+(<a href="http://femto.cs.uiuc.edu/faqs/cga-faq.html#S5.27">explanations</a>)</td><td>\code+VectorNf n1, n2;+MatrixNf normalMatrix = t.linear().inverse().transpose();+n2 = (normalMatrix * n1).normalized();\endcode</td></tr>+<tr class="alt"><td>+Apply a transformation with \em pure \em rotation \n to a \b normal \b vector+(no scaling, no shear)</td><td>\code+n2 = t.linear() * n1;\endcode</td></tr>+<tr><td>+OpenGL compatibility \b 3D </td><td>\code+glLoadMatrixf(t.data());\endcode</td></tr>+<tr class="alt"><td>+OpenGL compatibility \b 2D </td><td>\code+Affine3f aux(Affine3f::Identity());+aux.linear().topLeftCorner<2,2>() = t.linear();+aux.translation().start<2>() = t.translation();+glLoadMatrixf(aux.data());\endcode</td></tr>+</table>++\b Component \b accessors+<table class="manual">+<tr><td>+full read-write access to the internal matrix</td><td>\code+t.matrix() = matN1xN1; // N1 means N+1+matN1xN1 = t.matrix();+\endcode</td></tr>+<tr class="alt"><td>+coefficient accessors</td><td>\code+t(i,j) = scalar; <=> t.matrix()(i,j) = scalar;+scalar = t(i,j); <=> scalar = t.matrix()(i,j);+\endcode</td></tr>+<tr><td>+translation part</td><td>\code+t.translation() = vecN;+vecN = t.translation();+\endcode</td></tr>+<tr class="alt"><td>+linear part</td><td>\code+t.linear() = matNxN;+matNxN = t.linear();+\endcode</td></tr>+<tr><td>+extract the rotation matrix</td><td>\code+matNxN = t.rotation();+\endcode</td></tr>+</table>+++\b Transformation \b creation \n+While transformation objects can be created and updated concatenating elementary transformations,+the Transform class also features a procedural API:+<table class="manual">+<tr><th></th><th>procedural API</th><th>equivalent natural API </th></tr>+<tr><td>Translation</td><td>\code+t.translate(Vector_(tx,ty,..));+t.pretranslate(Vector_(tx,ty,..));+\endcode</td><td>\code+t *= Translation_(tx,ty,..);+t = Translation_(tx,ty,..) * t;+\endcode</td></tr>+<tr class="alt"><td>\b Rotation \n <em class="note">In 2D and for the procedural API, any_rotation can also \n be an angle in radian</em></td><td>\code+t.rotate(any_rotation);+t.prerotate(any_rotation);+\endcode</td><td>\code+t *= any_rotation;+t = any_rotation * t;+\endcode</td></tr>+<tr><td>Scaling</td><td>\code+t.scale(Vector_(sx,sy,..));+t.scale(s);+t.prescale(Vector_(sx,sy,..));+t.prescale(s);+\endcode</td><td>\code+t *= Scaling(sx,sy,..);+t *= Scaling(s);+t = Scaling(sx,sy,..) * t;+t = Scaling(s) * t;+\endcode</td></tr>+<tr class="alt"><td>Shear transformation \n ( \b 2D \b only ! )</td><td>\code+t.shear(sx,sy);+t.preshear(sx,sy);+\endcode</td><td></td></tr>+</table>++Note that in both API, any many transformations can be concatenated in a single expression as shown in the two following equivalent examples:+<table class="manual">+<tr><td>\code+t.pretranslate(..).rotate(..).translate(..).scale(..);+\endcode</td></tr>+<tr><td>\code+t = Translation_(..) * t * RotationType(..) * Translation_(..) * Scaling(..);+\endcode</td></tr>+</table>++++<a href="#" class="top">top</a>\section TutorialGeoEulerAngles Euler angles+<table class="manual">+<tr><td style="max-width:30em;">+Euler angles might be convenient to create rotation objects.+On the other hand, since there exist 24 different conventions, they are pretty confusing to use. This example shows how+to create a rotation matrix according to the 2-1-2 convention.</td><td>\code+Matrix3f m;+m = AngleAxisf(angle1, Vector3f::UnitZ())+* * AngleAxisf(angle2, Vector3f::UnitY())+* * AngleAxisf(angle3, Vector3f::UnitZ());+\endcode</td></tr>+</table>++*/++}
+ eigen3/doc/TutorialLinearAlgebra.dox view
@@ -0,0 +1,255 @@+namespace Eigen {++/** \eigenManualPage TutorialLinearAlgebra Linear algebra and decompositions++This page explains how to solve linear systems, compute various decompositions such as LU,+QR, %SVD, eigendecompositions... After reading this page, don't miss our+\link TopicLinearAlgebraDecompositions catalogue \endlink of dense matrix decompositions.++\eigenAutoToc++\section TutorialLinAlgBasicSolve Basic linear solving++\b The \b problem: You have a system of equations, that you have written as a single matrix equation+ \f[ Ax \: = \: b \f]+Where \a A and \a b are matrices (\a b could be a vector, as a special case). You want to find a solution \a x.++\b The \b solution: You can choose between various decompositions, depending on what your matrix \a A looks like,+and depending on whether you favor speed or accuracy. However, let's start with an example that works in all cases,+and is a good compromise:+<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr>+ <td>\include TutorialLinAlgExSolveColPivHouseholderQR.cpp </td>+ <td>\verbinclude TutorialLinAlgExSolveColPivHouseholderQR.out </td>+</tr>+</table>++In this example, the colPivHouseholderQr() method returns an object of class ColPivHouseholderQR. Since here the+matrix is of type Matrix3f, this line could have been replaced by:+\code+ColPivHouseholderQR<Matrix3f> dec(A);+Vector3f x = dec.solve(b);+\endcode++Here, ColPivHouseholderQR is a QR decomposition with column pivoting. It's a good compromise for this tutorial, as it+works for all matrices while being quite fast. Here is a table of some other decompositions that you can choose from,+depending on your matrix and the trade-off you want to make:++<table class="manual">+ <tr>+ <th>Decomposition</th>+ <th>Method</th>+ <th>Requirements on the matrix</th>+ <th>Speed</th>+ <th>Accuracy</th>+ </tr>+ <tr>+ <td>PartialPivLU</td>+ <td>partialPivLu()</td>+ <td>Invertible</td>+ <td>++</td>+ <td>+</td>+ </tr>+ <tr class="alt">+ <td>FullPivLU</td>+ <td>fullPivLu()</td>+ <td>None</td>+ <td>-</td>+ <td>+++</td>+ </tr>+ <tr>+ <td>HouseholderQR</td>+ <td>householderQr()</td>+ <td>None</td>+ <td>++</td>+ <td>+</td>+ </tr>+ <tr class="alt">+ <td>ColPivHouseholderQR</td>+ <td>colPivHouseholderQr()</td>+ <td>None</td>+ <td>+</td>+ <td>++</td>+ </tr>+ <tr>+ <td>FullPivHouseholderQR</td>+ <td>fullPivHouseholderQr()</td>+ <td>None</td>+ <td>-</td>+ <td>+++</td>+ </tr>+ <tr class="alt">+ <td>LLT</td>+ <td>llt()</td>+ <td>Positive definite</td>+ <td>+++</td>+ <td>+</td>+ </tr>+ <tr>+ <td>LDLT</td>+ <td>ldlt()</td>+ <td>Positive or negative semidefinite</td>+ <td>+++</td>+ <td>++</td>+ </tr>+</table>++All of these decompositions offer a solve() method that works as in the above example.++For example, if your matrix is positive definite, the above table says that a very good+choice is then the LDLT decomposition. Here's an example, also demonstrating that using a general+matrix (not a vector) as right hand side is possible.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr>+ <td>\include TutorialLinAlgExSolveLDLT.cpp </td>+ <td>\verbinclude TutorialLinAlgExSolveLDLT.out </td>+</tr>+</table>++For a \ref TopicLinearAlgebraDecompositions "much more complete table" comparing all decompositions supported by Eigen (notice that Eigen+supports many other decompositions), see our special page on+\ref TopicLinearAlgebraDecompositions "this topic".++\section TutorialLinAlgSolutionExists Checking if a solution really exists++Only you know what error margin you want to allow for a solution to be considered valid.+So Eigen lets you do this computation for yourself, if you want to, as in this example:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr>+ <td>\include TutorialLinAlgExComputeSolveError.cpp </td>+ <td>\verbinclude TutorialLinAlgExComputeSolveError.out </td>+</tr>+</table>++\section TutorialLinAlgEigensolving Computing eigenvalues and eigenvectors++You need an eigendecomposition here, see available such decompositions on \ref TopicLinearAlgebraDecompositions "this page".+Make sure to check if your matrix is self-adjoint, as is often the case in these problems. Here's an example using+SelfAdjointEigenSolver, it could easily be adapted to general matrices using EigenSolver or ComplexEigenSolver.++The computation of eigenvalues and eigenvectors does not necessarily converge, but such failure to converge is+very rare. The call to info() is to check for this possibility.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr>+ <td>\include TutorialLinAlgSelfAdjointEigenSolver.cpp </td>+ <td>\verbinclude TutorialLinAlgSelfAdjointEigenSolver.out </td>+</tr>+</table>++\section TutorialLinAlgInverse Computing inverse and determinant++First of all, make sure that you really want this. While inverse and determinant are fundamental mathematical concepts,+in \em numerical linear algebra they are not as popular as in pure mathematics. Inverse computations are often+advantageously replaced by solve() operations, and the determinant is often \em not a good way of checking if a matrix+is invertible.++However, for \em very \em small matrices, the above is not true, and inverse and determinant can be very useful.++While certain decompositions, such as PartialPivLU and FullPivLU, offer inverse() and determinant() methods, you can also+call inverse() and determinant() directly on a matrix. If your matrix is of a very small fixed size (at most 4x4) this+allows Eigen to avoid performing a LU decomposition, and instead use formulas that are more efficient on such small matrices.++Here is an example:+<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr>+ <td>\include TutorialLinAlgInverseDeterminant.cpp </td>+ <td>\verbinclude TutorialLinAlgInverseDeterminant.out </td>+</tr>+</table>++\section TutorialLinAlgLeastsquares Least squares solving++The best way to do least squares solving is with a SVD decomposition. Eigen provides one as the JacobiSVD class, and its solve()+is doing least-squares solving.++Here is an example:+<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr>+ <td>\include TutorialLinAlgSVDSolve.cpp </td>+ <td>\verbinclude TutorialLinAlgSVDSolve.out </td>+</tr>+</table>++Another way, potentially faster but less reliable, is to use a LDLT decomposition+of the normal matrix. In any case, just read any reference text on least squares, and it will be very easy for you+to implement any linear least squares computation on top of Eigen.++\section TutorialLinAlgSeparateComputation Separating the computation from the construction++In the above examples, the decomposition was computed at the same time that the decomposition object was constructed.+There are however situations where you might want to separate these two things, for example if you don't know,+at the time of the construction, the matrix that you will want to decompose; or if you want to reuse an existing+decomposition object.++What makes this possible is that:+\li all decompositions have a default constructor,+\li all decompositions have a compute(matrix) method that does the computation, and that may be called again+ on an already-computed decomposition, reinitializing it.++For example:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr>+ <td>\include TutorialLinAlgComputeTwice.cpp </td>+ <td>\verbinclude TutorialLinAlgComputeTwice.out </td>+</tr>+</table>++Finally, you can tell the decomposition constructor to preallocate storage for decomposing matrices of a given size,+so that when you subsequently decompose such matrices, no dynamic memory allocation is performed (of course, if you+are using fixed-size matrices, no dynamic memory allocation happens at all). This is done by just+passing the size to the decomposition constructor, as in this example:+\code+HouseholderQR<MatrixXf> qr(50,50);+MatrixXf A = MatrixXf::Random(50,50);+qr.compute(A); // no dynamic memory allocation+\endcode++\section TutorialLinAlgRankRevealing Rank-revealing decompositions++Certain decompositions are rank-revealing, i.e. are able to compute the rank of a matrix. These are typically+also the decompositions that behave best in the face of a non-full-rank matrix (which in the square case means a+singular matrix). On \ref TopicLinearAlgebraDecompositions "this table" you can see for all our decompositions+whether they are rank-revealing or not.++Rank-revealing decompositions offer at least a rank() method. They can also offer convenience methods such as isInvertible(),+and some are also providing methods to compute the kernel (null-space) and image (column-space) of the matrix, as is the+case with FullPivLU:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr>+ <td>\include TutorialLinAlgRankRevealing.cpp </td>+ <td>\verbinclude TutorialLinAlgRankRevealing.out </td>+</tr>+</table>++Of course, any rank computation depends on the choice of an arbitrary threshold, since practically no+floating-point matrix is \em exactly rank-deficient. Eigen picks a sensible default threshold, which depends+on the decomposition but is typically the diagonal size times machine epsilon. While this is the best default we+could pick, only you know what is the right threshold for your application. You can set this by calling setThreshold()+on your decomposition object before calling rank() or any other method that needs to use such a threshold.+The decomposition itself, i.e. the compute() method, is independent of the threshold. You don't need to recompute the+decomposition after you've changed the threshold.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr>+ <td>\include TutorialLinAlgSetThreshold.cpp </td>+ <td>\verbinclude TutorialLinAlgSetThreshold.out </td>+</tr>+</table>++*/++}
+ eigen3/doc/TutorialMapClass.dox view
@@ -0,0 +1,86 @@+namespace Eigen {++/** \eigenManualPage TutorialMapClass Interfacing with raw buffers: the Map class++This page explains how to work with "raw" C/C++ arrays.+This can be useful in a variety of contexts, particularly when "importing" vectors and matrices from other libraries into %Eigen.++\eigenAutoToc++\section TutorialMapIntroduction Introduction++Occasionally you may have a pre-defined array of numbers that you want to use within %Eigen as a vector or matrix. While one option is to make a copy of the data, most commonly you probably want to re-use this memory as an %Eigen type. Fortunately, this is very easy with the Map class.++\section TutorialMapTypes Map types and declaring Map variables++A Map object has a type defined by its %Eigen equivalent:+\code+Map<Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime> >+\endcode+Note that, in this default case, a Map requires just a single template parameter. ++To construct a Map variable, you need two other pieces of information: a pointer to the region of memory defining the array of coefficients, and the desired shape of the matrix or vector. For example, to define a matrix of \c float with sizes determined at compile time, you might do the following:+\code+Map<MatrixXf> mf(pf,rows,columns);+\endcode+where \c pf is a \c float \c * pointing to the array of memory. A fixed-size read-only vector of integers might be declared as+\code+Map<const Vector4i> mi(pi);+\endcode+where \c pi is an \c int \c *. In this case the size does not have to be passed to the constructor, because it is already specified by the Matrix/Array type.++Note that Map does not have a default constructor; you \em must pass a pointer to intialize the object. However, you can work around this requirement (see \ref TutorialMapPlacementNew).++Map is flexible enough to accomodate a variety of different data representations. There are two other (optional) template parameters:+\code+Map<typename MatrixType,+ int MapOptions,+ typename StrideType>+\endcode+\li \c MapOptions specifies whether the pointer is \c #Aligned, or \c #Unaligned. The default is \c #Unaligned.+\li \c StrideType allows you to specify a custom layout for the memory array, using the Stride class. One example would be to specify that the data array is organized in row-major format:+<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr>+<td>\include Tutorial_Map_rowmajor.cpp </td>+<td>\verbinclude Tutorial_Map_rowmajor.out </td>+</table>+However, Stride is even more flexible than this; for details, see the documentation for the Map and Stride classes.++\section TutorialMapUsing Using Map variables++You can use a Map object just like any other %Eigen type:+<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr>+<td>\include Tutorial_Map_using.cpp </td>+<td>\verbinclude Tutorial_Map_using.out </td>+</table>++All %Eigen functions are written to accept Map objects just like other %Eigen types. However, when writing your own functions taking %Eigen types, this does \em not happen automatically: a Map type is not identical to its Dense equivalent. See \ref TopicFunctionTakingEigenTypes for details.++\section TutorialMapPlacementNew Changing the mapped array++It is possible to change the array of a Map object after declaration, using the C++ "placement new" syntax:+<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr>+<td>\include Map_placement_new.cpp </td>+<td>\verbinclude Map_placement_new.out </td>+</table>+Despite appearances, this does not invoke the memory allocator, because the syntax specifies the location for storing the result.++This syntax makes it possible to declare a Map object without first knowing the mapped array's location in memory:+\code+Map<Matrix3f> A(NULL); // don't try to use this matrix yet!+VectorXf b(n_matrices);+for (int i = 0; i < n_matrices; i++)+{+ new (&A) Map<Matrix3f>(get_matrix_pointer(i));+ b(i) = A.trace();+}+\endcode++*/++}
+ eigen3/doc/TutorialMatrixArithmetic.dox view
@@ -0,0 +1,214 @@+namespace Eigen {++/** \eigenManualPage TutorialMatrixArithmetic Matrix and vector arithmetic++This page aims to provide an overview and some details on how to perform arithmetic+between matrices, vectors and scalars with Eigen.++\eigenAutoToc++\section TutorialArithmeticIntroduction Introduction++Eigen offers matrix/vector arithmetic operations either through overloads of common C++ arithmetic operators such as +, -, *,+or through special methods such as dot(), cross(), etc.+For the Matrix class (matrices and vectors), operators are only overloaded to support+linear-algebraic operations. For example, \c matrix1 \c * \c matrix2 means matrix-matrix product,+and \c vector \c + \c scalar is just not allowed. If you want to perform all kinds of array operations,+not linear algebra, see the \ref TutorialArrayClass "next page".++\section TutorialArithmeticAddSub Addition and subtraction++The left hand side and right hand side must, of course, have the same numbers of rows and of columns. They must+also have the same \c Scalar type, as Eigen doesn't do automatic type promotion. The operators at hand here are:+\li binary operator + as in \c a+b+\li binary operator - as in \c a-b+\li unary operator - as in \c -a+\li compound operator += as in \c a+=b+\li compound operator -= as in \c a-=b++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include tut_arithmetic_add_sub.cpp+</td>+<td>+\verbinclude tut_arithmetic_add_sub.out+</td></tr></table>++\section TutorialArithmeticScalarMulDiv Scalar multiplication and division++Multiplication and division by a scalar is very simple too. The operators at hand here are:+\li binary operator * as in \c matrix*scalar+\li binary operator * as in \c scalar*matrix+\li binary operator / as in \c matrix/scalar+\li compound operator *= as in \c matrix*=scalar+\li compound operator /= as in \c matrix/=scalar++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include tut_arithmetic_scalar_mul_div.cpp+</td>+<td>+\verbinclude tut_arithmetic_scalar_mul_div.out+</td></tr></table>+++\section TutorialArithmeticMentionXprTemplates A note about expression templates++This is an advanced topic that we explain on \ref TopicEigenExpressionTemplates "this page",+but it is useful to just mention it now. In Eigen, arithmetic operators such as \c operator+ don't+perform any computation by themselves, they just return an "expression object" describing the computation to be+performed. The actual computation happens later, when the whole expression is evaluated, typically in \c operator=.+While this might sound heavy, any modern optimizing compiler is able to optimize away that abstraction and+the result is perfectly optimized code. For example, when you do:+\code+VectorXf a(50), b(50), c(50), d(50);+...+a = 3*b + 4*c + 5*d;+\endcode+Eigen compiles it to just one for loop, so that the arrays are traversed only once. Simplifying (e.g. ignoring+SIMD optimizations), this loop looks like this:+\code+for(int i = 0; i < 50; ++i)+ a[i] = 3*b[i] + 4*c[i] + 5*d[i];+\endcode+Thus, you should not be afraid of using relatively large arithmetic expressions with Eigen: it only gives Eigen+more opportunities for optimization.++\section TutorialArithmeticTranspose Transposition and conjugation++The transpose \f$ a^T \f$, conjugate \f$ \bar{a} \f$, and adjoint (i.e., conjugate transpose) \f$ a^* \f$ of a matrix or vector \f$ a \f$ are obtained by the member functions \link DenseBase::transpose() transpose()\endlink, \link MatrixBase::conjugate() conjugate()\endlink, and \link MatrixBase::adjoint() adjoint()\endlink, respectively.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include tut_arithmetic_transpose_conjugate.cpp+</td>+<td>+\verbinclude tut_arithmetic_transpose_conjugate.out+</td></tr></table>++For real matrices, \c conjugate() is a no-operation, and so \c adjoint() is equivalent to \c transpose().++As for basic arithmetic operators, \c transpose() and \c adjoint() simply return a proxy object without doing the actual transposition. If you do <tt>b = a.transpose()</tt>, then the transpose is evaluated at the same time as the result is written into \c b. However, there is a complication here. If you do <tt>a = a.transpose()</tt>, then Eigen starts writing the result into \c a before the evaluation of the transpose is finished. Therefore, the instruction <tt>a = a.transpose()</tt> does not replace \c a with its transpose, as one would expect:+<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include tut_arithmetic_transpose_aliasing.cpp+</td>+<td>+\verbinclude tut_arithmetic_transpose_aliasing.out+</td></tr></table>+This is the so-called \ref TopicAliasing "aliasing issue". In "debug mode", i.e., when \ref TopicAssertions "assertions" have not been disabled, such common pitfalls are automatically detected. ++For \em in-place transposition, as for instance in <tt>a = a.transpose()</tt>, simply use the \link DenseBase::transposeInPlace() transposeInPlace()\endlink function:+<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include tut_arithmetic_transpose_inplace.cpp+</td>+<td>+\verbinclude tut_arithmetic_transpose_inplace.out+</td></tr></table>+There is also the \link MatrixBase::adjointInPlace() adjointInPlace()\endlink function for complex matrices.++\section TutorialArithmeticMatrixMul Matrix-matrix and matrix-vector multiplication++Matrix-matrix multiplication is again done with \c operator*. Since vectors are a special+case of matrices, they are implicitly handled there too, so matrix-vector product is really just a special+case of matrix-matrix product, and so is vector-vector outer product. Thus, all these cases are handled by just+two operators:+\li binary operator * as in \c a*b+\li compound operator *= as in \c a*=b (this multiplies on the right: \c a*=b is equivalent to <tt>a = a*b</tt>)++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include tut_arithmetic_matrix_mul.cpp+</td>+<td>+\verbinclude tut_arithmetic_matrix_mul.out+</td></tr></table>++Note: if you read the above paragraph on expression templates and are worried that doing \c m=m*m might cause+aliasing issues, be reassured for now: Eigen treats matrix multiplication as a special case and takes care of+introducing a temporary here, so it will compile \c m=m*m as:+\code+tmp = m*m;+m = tmp;+\endcode+If you know your matrix product can be safely evaluated into the destination matrix without aliasing issue, then you can use the \link MatrixBase::noalias() noalias()\endlink function to avoid the temporary, e.g.:+\code+c.noalias() += a * b;+\endcode+For more details on this topic, see the page on \ref TopicAliasing "aliasing".++\b Note: for BLAS users worried about performance, expressions such as <tt>c.noalias() -= 2 * a.adjoint() * b;</tt> are fully optimized and trigger a single gemm-like function call.++\section TutorialArithmeticDotAndCross Dot product and cross product++For dot product and cross product, you need the \link MatrixBase::dot() dot()\endlink and \link MatrixBase::cross() cross()\endlink methods. Of course, the dot product can also be obtained as a 1x1 matrix as u.adjoint()*v.+<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include tut_arithmetic_dot_cross.cpp+</td>+<td>+\verbinclude tut_arithmetic_dot_cross.out+</td></tr></table>++Remember that cross product is only for vectors of size 3. Dot product is for vectors of any sizes.+When using complex numbers, Eigen's dot product is conjugate-linear in the first variable and linear in the+second variable.++\section TutorialArithmeticRedux Basic arithmetic reduction operations+Eigen also provides some reduction operations to reduce a given matrix or vector to a single value such as the sum (computed by \link DenseBase::sum() sum()\endlink), product (\link DenseBase::prod() prod()\endlink), or the maximum (\link DenseBase::maxCoeff() maxCoeff()\endlink) and minimum (\link DenseBase::minCoeff() minCoeff()\endlink) of all its coefficients.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include tut_arithmetic_redux_basic.cpp+</td>+<td>+\verbinclude tut_arithmetic_redux_basic.out+</td></tr></table>++The \em trace of a matrix, as returned by the function \link MatrixBase::trace() trace()\endlink, is the sum of the diagonal coefficients and can also be computed as efficiently using <tt>a.diagonal().sum()</tt>, as we will see later on.++There also exist variants of the \c minCoeff and \c maxCoeff functions returning the coordinates of the respective coefficient via the arguments:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include tut_arithmetic_redux_minmax.cpp+</td>+<td>+\verbinclude tut_arithmetic_redux_minmax.out+</td></tr></table>+++\section TutorialArithmeticValidity Validity of operations+Eigen checks the validity of the operations that you perform. When possible,+it checks them at compile time, producing compilation errors. These error messages can be long and ugly,+but Eigen writes the important message in UPPERCASE_LETTERS_SO_IT_STANDS_OUT. For example:+\code+ Matrix3f m;+ Vector4f v;+ v = m*v; // Compile-time error: YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES+\endcode++Of course, in many cases, for example when checking dynamic sizes, the check cannot be performed at compile time.+Eigen then uses runtime assertions. This means that the program will abort with an error message when executing an illegal operation if it is run in "debug mode", and it will probably crash if assertions are turned off.++\code+ MatrixXf m(3,3);+ VectorXf v(4);+ v = m * v; // Run-time assertion failure here: "invalid matrix product"+\endcode++For more details on this topic, see \ref TopicAssertions "this page".++*/++}
+ eigen3/doc/TutorialMatrixClass.dox view
@@ -0,0 +1,265 @@+namespace Eigen {++/** \eigenManualPage TutorialMatrixClass The Matrix class++\eigenAutoToc++In Eigen, all matrices and vectors are objects of the Matrix template class.+Vectors are just a special case of matrices, with either 1 row or 1 column.++\section TutorialMatrixFirst3Params The first three template parameters of Matrix++The Matrix class takes six template parameters, but for now it's enough to+learn about the first three first parameters. The three remaining parameters have default+values, which for now we will leave untouched, and which we+\ref TutorialMatrixOptTemplParams "discuss below".++The three mandatory template parameters of Matrix are:+\code+Matrix<typename Scalar, int RowsAtCompileTime, int ColsAtCompileTime>+\endcode+\li \c Scalar is the scalar type, i.e. the type of the coefficients.+ That is, if you want a matrix of floats, choose \c float here.+ See \ref TopicScalarTypes "Scalar types" for a list of all supported+ scalar types and for how to extend support to new types.+\li \c RowsAtCompileTime and \c ColsAtCompileTime are the number of rows+ and columns of the matrix as known at compile time (see + \ref TutorialMatrixDynamic "below" for what to do if the number is not+ known at compile time).++We offer a lot of convenience typedefs to cover the usual cases. For example, \c Matrix4f is+a 4x4 matrix of floats. Here is how it is defined by Eigen:+\code+typedef Matrix<float, 4, 4> Matrix4f;+\endcode+We discuss \ref TutorialMatrixTypedefs "below" these convenience typedefs.++\section TutorialMatrixVectors Vectors++As mentioned above, in Eigen, vectors are just a special case of+matrices, with either 1 row or 1 column. The case where they have 1 column is the most common;+such vectors are called column-vectors, often abbreviated as just vectors. In the other case+where they have 1 row, they are called row-vectors.++For example, the convenience typedef \c Vector3f is a (column) vector of 3 floats. It is defined as follows by Eigen:+\code+typedef Matrix<float, 3, 1> Vector3f;+\endcode+We also offer convenience typedefs for row-vectors, for example:+\code+typedef Matrix<int, 1, 2> RowVector2i;+\endcode++\section TutorialMatrixDynamic The special value Dynamic++Of course, Eigen is not limited to matrices whose dimensions are known at compile time.+The \c RowsAtCompileTime and \c ColsAtCompileTime template parameters can take the special+value \c Dynamic which indicates that the size is unknown at compile time, so must+be handled as a run-time variable. In Eigen terminology, such a size is referred to as a+\em dynamic \em size; while a size that is known at compile time is called a+\em fixed \em size. For example, the convenience typedef \c MatrixXd, meaning+a matrix of doubles with dynamic size, is defined as follows:+\code+typedef Matrix<double, Dynamic, Dynamic> MatrixXd;+\endcode+And similarly, we define a self-explanatory typedef \c VectorXi as follows:+\code+typedef Matrix<int, Dynamic, 1> VectorXi;+\endcode+You can perfectly have e.g. a fixed number of rows with a dynamic number of columns, as in:+\code+Matrix<float, 3, Dynamic>+\endcode++\section TutorialMatrixConstructors Constructors++A default constructor is always available, never performs any dynamic memory allocation, and never initializes the matrix coefficients. You can do:+\code+Matrix3f a;+MatrixXf b;+\endcode+Here,+\li \c a is a 3-by-3 matrix, with a plain float[9] array of uninitialized coefficients,+\li \c b is a dynamic-size matrix whose size is currently 0-by-0, and whose array of+coefficients hasn't yet been allocated at all.++Constructors taking sizes are also available. For matrices, the number of rows is always passed first.+For vectors, just pass the vector size. They allocate the array of coefficients+with the given size, but don't initialize the coefficients themselves:+\code+MatrixXf a(10,15);+VectorXf b(30);+\endcode+Here,+\li \c a is a 10x15 dynamic-size matrix, with allocated but currently uninitialized coefficients.+\li \c b is a dynamic-size vector of size 30, with allocated but currently uninitialized coefficients.++In order to offer a uniform API across fixed-size and dynamic-size matrices, it is legal to use these+constructors on fixed-size matrices, even if passing the sizes is useless in this case. So this is legal:+\code+Matrix3f a(3,3);+\endcode+and is a no-operation.++Finally, we also offer some constructors to initialize the coefficients of small fixed-size vectors up to size 4:+\code+Vector2d a(5.0, 6.0);+Vector3d b(5.0, 6.0, 7.0);+Vector4d c(5.0, 6.0, 7.0, 8.0);+\endcode++\section TutorialMatrixCoeffAccessors Coefficient accessors++The primary coefficient accessors and mutators in Eigen are the overloaded parenthesis operators.+For matrices, the row index is always passed first. For vectors, just pass one index.+The numbering starts at 0. This example is self-explanatory:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include tut_matrix_coefficient_accessors.cpp+</td>+<td>+\verbinclude tut_matrix_coefficient_accessors.out+</td></tr></table>++Note that the syntax <tt> m(index) </tt>+is not restricted to vectors, it is also available for general matrices, meaning index-based access+in the array of coefficients. This however depends on the matrix's storage order. All Eigen matrices default to+column-major storage order, but this can be changed to row-major, see \ref TopicStorageOrders "Storage orders".++The operator[] is also overloaded for index-based access in vectors, but keep in mind that C++ doesn't allow operator[] to+take more than one argument. We restrict operator[] to vectors, because an awkwardness in the C++ language+would make matrix[i,j] compile to the same thing as matrix[j] !++\section TutorialMatrixCommaInitializer Comma-initialization++%Matrix and vector coefficients can be conveniently set using the so-called \em comma-initializer syntax.+For now, it is enough to know this example:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr>+<td>\include Tutorial_commainit_01.cpp </td>+<td>\verbinclude Tutorial_commainit_01.out </td>+</tr></table>+++The right-hand side can also contain matrix expressions as discussed in \ref TutorialAdvancedInitialization "this page".++\section TutorialMatrixSizesResizing Resizing++The current size of a matrix can be retrieved by \link EigenBase::rows() rows()\endlink, \link EigenBase::cols() cols() \endlink and \link EigenBase::size() size()\endlink. These methods return the number of rows, the number of columns and the number of coefficients, respectively. Resizing a dynamic-size matrix is done by the \link PlainObjectBase::resize(Index,Index) resize() \endlink method.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr>+<td>\include tut_matrix_resize.cpp </td>+<td>\verbinclude tut_matrix_resize.out </td>+</tr></table>++The resize() method is a no-operation if the actual matrix size doesn't change; otherwise it is destructive: the values of the coefficients may change.+If you want a conservative variant of resize() which does not change the coefficients, use \link PlainObjectBase::conservativeResize() conservativeResize()\endlink, see \ref TopicResizing "this page" for more details.++All these methods are still available on fixed-size matrices, for the sake of API uniformity. Of course, you can't actually+resize a fixed-size matrix. Trying to change a fixed size to an actually different value will trigger an assertion failure;+but the following code is legal:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr>+<td>\include tut_matrix_resize_fixed_size.cpp </td>+<td>\verbinclude tut_matrix_resize_fixed_size.out </td>+</tr></table>+++\section TutorialMatrixAssignment Assignment and resizing++Assignment is the action of copying a matrix into another, using \c operator=. Eigen resizes the matrix on the left-hand side automatically so that it matches the size of the matrix on the right-hand size. For example:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr>+<td>\include tut_matrix_assignment_resizing.cpp </td>+<td>\verbinclude tut_matrix_assignment_resizing.out </td>+</tr></table>++Of course, if the left-hand side is of fixed size, resizing it is not allowed.++If you do not want this automatic resizing to happen (for example for debugging purposes), you can disable it, see+\ref TopicResizing "this page".+++\section TutorialMatrixFixedVsDynamic Fixed vs. Dynamic size++When should one use fixed sizes (e.g. \c Matrix4f), and when should one prefer dynamic sizes (e.g. \c MatrixXf)?+The simple answer is: use fixed+sizes for very small sizes where you can, and use dynamic sizes for larger sizes or where you have to. For small sizes,+especially for sizes smaller than (roughly) 16, using fixed sizes is hugely beneficial+to performance, as it allows Eigen to avoid dynamic memory allocation and to unroll+loops. Internally, a fixed-size Eigen matrix is just a plain array, i.e. doing+\code Matrix4f mymatrix; \endcode+really amounts to just doing+\code float mymatrix[16]; \endcode+so this really has zero runtime cost. By contrast, the array of a dynamic-size matrix+is always allocated on the heap, so doing+\code MatrixXf mymatrix(rows,columns); \endcode+amounts to doing+\code float *mymatrix = new float[rows*columns]; \endcode+and in addition to that, the MatrixXf object stores its number of rows and columns as+member variables.++The limitation of using fixed sizes, of course, is that this is only possible+when you know the sizes at compile time. Also, for large enough sizes, say for sizes+greater than (roughly) 32, the performance benefit of using fixed sizes becomes negligible.+Worse, trying to create a very large matrix using fixed sizes inside a function could result in a+stack overflow, since Eigen will try to allocate the array automatically as a local variable, and+this is normally done on the stack.+Finally, depending on circumstances, Eigen can also be more aggressive trying to vectorize+(use SIMD instructions) when dynamic sizes are used, see \ref TopicVectorization "Vectorization".++\section TutorialMatrixOptTemplParams Optional template parameters++We mentioned at the beginning of this page that the Matrix class takes six template parameters,+but so far we only discussed the first three. The remaining three parameters are optional. Here is+the complete list of template parameters:+\code+Matrix<typename Scalar,+ int RowsAtCompileTime,+ int ColsAtCompileTime,+ int Options = 0,+ int MaxRowsAtCompileTime = RowsAtCompileTime,+ int MaxColsAtCompileTime = ColsAtCompileTime>+\endcode+\li \c Options is a bit field. Here, we discuss only one bit: \c RowMajor. It specifies that the matrices+ of this type use row-major storage order; by default, the storage order is column-major. See the page on+ \ref TopicStorageOrders "storage orders". For example, this type means row-major 3x3 matrices:+ \code+ Matrix<float, 3, 3, RowMajor>+ \endcode+\li \c MaxRowsAtCompileTime and \c MaxColsAtCompileTime are useful when you want to specify that, even though+ the exact sizes of your matrices are not known at compile time, a fixed upper bound is known at+ compile time. The biggest reason why you might want to do that is to avoid dynamic memory allocation.+ For example the following matrix type uses a plain array of 12 floats, without dynamic memory allocation:+ \code+ Matrix<float, Dynamic, Dynamic, 0, 3, 4>+ \endcode++\section TutorialMatrixTypedefs Convenience typedefs++Eigen defines the following Matrix typedefs:+\li MatrixNt for Matrix<type, N, N>. For example, MatrixXi for Matrix<int, Dynamic, Dynamic>.+\li VectorNt for Matrix<type, N, 1>. For example, Vector2f for Matrix<float, 2, 1>.+\li RowVectorNt for Matrix<type, 1, N>. For example, RowVector3d for Matrix<double, 1, 3>.++Where:+\li N can be any one of \c 2, \c 3, \c 4, or \c X (meaning \c Dynamic).+\li t can be any one of \c i (meaning int), \c f (meaning float), \c d (meaning double),+ \c cf (meaning complex<float>), or \c cd (meaning complex<double>). The fact that typedefs are only+ defined for these five types doesn't mean that they are the only supported scalar types. For example,+ all standard integer types are supported, see \ref TopicScalarTypes "Scalar types".+++*/++}
+ eigen3/doc/TutorialReductionsVisitorsBroadcasting.dox view
@@ -0,0 +1,257 @@+namespace Eigen {++/** \eigenManualPage TutorialReductionsVisitorsBroadcasting Reductions, visitors and broadcasting++This page explains Eigen's reductions, visitors and broadcasting and how they are used with+\link MatrixBase matrices \endlink and \link ArrayBase arrays \endlink.++\eigenAutoToc++\section TutorialReductionsVisitorsBroadcastingReductions Reductions+In Eigen, a reduction is a function taking a matrix or array, and returning a single+scalar value. One of the most used reductions is \link DenseBase::sum() .sum() \endlink,+returning the sum of all the coefficients inside a given matrix or array.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include tut_arithmetic_redux_basic.cpp+</td>+<td>+\verbinclude tut_arithmetic_redux_basic.out+</td></tr></table>++The \em trace of a matrix, as returned by the function \c trace(), is the sum of the diagonal coefficients and can equivalently be computed <tt>a.diagonal().sum()</tt>.+++\subsection TutorialReductionsVisitorsBroadcastingReductionsNorm Norm computations++The (Euclidean a.k.a. \f$\ell^2\f$) squared norm of a vector can be obtained \link MatrixBase::squaredNorm() squaredNorm() \endlink. It is equal to the dot product of the vector by itself, and equivalently to the sum of squared absolute values of its coefficients.++Eigen also provides the \link MatrixBase::norm() norm() \endlink method, which returns the square root of \link MatrixBase::squaredNorm() squaredNorm() \endlink.++These operations can also operate on matrices; in that case, a n-by-p matrix is seen as a vector of size (n*p), so for example the \link MatrixBase::norm() norm() \endlink method returns the "Frobenius" or "Hilbert-Schmidt" norm. We refrain from speaking of the \f$\ell^2\f$ norm of a matrix because that can mean different things.++If you want other \f$\ell^p\f$ norms, use the \link MatrixBase::lpNorm() lpNnorm<p>() \endlink method. The template parameter \a p can take the special value \a Infinity if you want the \f$\ell^\infty\f$ norm, which is the maximum of the absolute values of the coefficients.++The following example demonstrates these methods.++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_ReductionsVisitorsBroadcasting_reductions_norm.cpp+</td>+<td>+\verbinclude Tutorial_ReductionsVisitorsBroadcasting_reductions_norm.out+</td></tr></table>++\subsection TutorialReductionsVisitorsBroadcastingReductionsBool Boolean reductions++The following reductions operate on boolean values:+ - \link DenseBase::all() all() \endlink returns \b true if all of the coefficients in a given Matrix or Array evaluate to \b true .+ - \link DenseBase::any() any() \endlink returns \b true if at least one of the coefficients in a given Matrix or Array evaluates to \b true .+ - \link DenseBase::count() count() \endlink returns the number of coefficients in a given Matrix or Array that evaluate to \b true.++These are typically used in conjunction with the coefficient-wise comparison and equality operators provided by Array. For instance, <tt>array > 0</tt> is an %Array of the same size as \c array , with \b true at those positions where the corresponding coefficient of \c array is positive. Thus, <tt>(array > 0).all()</tt> tests whether all coefficients of \c array are positive. This can be seen in the following example:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_ReductionsVisitorsBroadcasting_reductions_bool.cpp+</td>+<td>+\verbinclude Tutorial_ReductionsVisitorsBroadcasting_reductions_bool.out+</td></tr></table>++\subsection TutorialReductionsVisitorsBroadcastingReductionsUserdefined User defined reductions++TODO++In the meantime you can have a look at the DenseBase::redux() function.++\section TutorialReductionsVisitorsBroadcastingVisitors Visitors+Visitors are useful when one wants to obtain the location of a coefficient inside +a Matrix or Array. The simplest examples are +\link MatrixBase::maxCoeff() maxCoeff(&x,&y) \endlink and +\link MatrixBase::minCoeff() minCoeff(&x,&y)\endlink, which can be used to find+the location of the greatest or smallest coefficient in a Matrix or +Array.++The arguments passed to a visitor are pointers to the variables where the+row and column position are to be stored. These variables should be of type+\link DenseBase::Index Index \endlink, as shown below:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_ReductionsVisitorsBroadcasting_visitors.cpp+</td>+<td>+\verbinclude Tutorial_ReductionsVisitorsBroadcasting_visitors.out+</td></tr></table>++Note that both functions also return the value of the minimum or maximum coefficient if needed,+as if it was a typical reduction operation.++\section TutorialReductionsVisitorsBroadcastingPartialReductions Partial reductions+Partial reductions are reductions that can operate column- or row-wise on a Matrix or +Array, applying the reduction operation on each column or row and +returning a column or row-vector with the corresponding values. Partial reductions are applied +with \link DenseBase::colwise() colwise() \endlink or \link DenseBase::rowwise() rowwise() \endlink.++A simple example is obtaining the maximum of the elements +in each column in a given matrix, storing the result in a row-vector:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_ReductionsVisitorsBroadcasting_colwise.cpp+</td>+<td>+\verbinclude Tutorial_ReductionsVisitorsBroadcasting_colwise.out+</td></tr></table>++The same operation can be performed row-wise:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_ReductionsVisitorsBroadcasting_rowwise.cpp+</td>+<td>+\verbinclude Tutorial_ReductionsVisitorsBroadcasting_rowwise.out+</td></tr></table>++<b>Note that column-wise operations return a 'row-vector' while row-wise operations+return a 'column-vector'</b>++\subsection TutorialReductionsVisitorsBroadcastingPartialReductionsCombined Combining partial reductions with other operations+It is also possible to use the result of a partial reduction to do further processing.+Here is another example that finds the column whose sum of elements is the maximum+ within a matrix. With column-wise partial reductions this can be coded as:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_ReductionsVisitorsBroadcasting_maxnorm.cpp+</td>+<td>+\verbinclude Tutorial_ReductionsVisitorsBroadcasting_maxnorm.out+</td></tr></table>++The previous example applies the \link DenseBase::sum() sum() \endlink reduction on each column+though the \link DenseBase::colwise() colwise() \endlink visitor, obtaining a new matrix whose+size is 1x4.++Therefore, if+\f[+\mbox{m} = \begin{bmatrix} 1 & 2 & 6 & 9 \\+ 3 & 1 & 7 & 2 \end{bmatrix}+\f]++then++\f[+\mbox{m.colwise().sum()} = \begin{bmatrix} 4 & 3 & 13 & 11 \end{bmatrix}+\f]++The \link DenseBase::maxCoeff() maxCoeff() \endlink reduction is finally applied +to obtain the column index where the maximum sum is found, +which is the column index 2 (third column) in this case.+++\section TutorialReductionsVisitorsBroadcastingBroadcasting Broadcasting+The concept behind broadcasting is similar to partial reductions, with the difference that broadcasting +constructs an expression where a vector (column or row) is interpreted as a matrix by replicating it in +one direction.++A simple example is to add a certain column-vector to each column in a matrix. +This can be accomplished with:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple.cpp+</td>+<td>+\verbinclude Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple.out+</td></tr></table>++We can interpret the instruction <tt>mat.colwise() += v</tt> in two equivalent ways. It adds the vector \c v+to every column of the matrix. Alternatively, it can be interpreted as repeating the vector \c v four times to+form a four-by-two matrix which is then added to \c mat:+\f[+\begin{bmatrix} 1 & 2 & 6 & 9 \\ 3 & 1 & 7 & 2 \end{bmatrix}++ \begin{bmatrix} 0 & 0 & 0 & 0 \\ 1 & 1 & 1 & 1 \end{bmatrix}+= \begin{bmatrix} 1 & 2 & 6 & 9 \\ 4 & 2 & 8 & 3 \end{bmatrix}.+\f]+The operators <tt>-=</tt>, <tt>+</tt> and <tt>-</tt> can also be used column-wise and row-wise. On arrays, we +can also use the operators <tt>*=</tt>, <tt>/=</tt>, <tt>*</tt> and <tt>/</tt> to perform coefficient-wise +multiplication and division column-wise or row-wise. These operators are not available on matrices because it+is not clear what they would do. If you want multiply column 0 of a matrix \c mat with \c v(0), column 1 with +\c v(1), and so on, then use <tt>mat = mat * v.asDiagonal()</tt>.++It is important to point out that the vector to be added column-wise or row-wise must be of type Vector,+and cannot be a Matrix. If this is not met then you will get compile-time error. This also means that+broadcasting operations can only be applied with an object of type Vector, when operating with Matrix.+The same applies for the Array class, where the equivalent for VectorXf is ArrayXf. As always, you should+not mix arrays and matrices in the same expression.++To perform the same operation row-wise we can do:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple_rowwise.cpp+</td>+<td>+\verbinclude Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple_rowwise.out+</td></tr></table>++\subsection TutorialReductionsVisitorsBroadcastingBroadcastingCombined Combining broadcasting with other operations+Broadcasting can also be combined with other operations, such as Matrix or Array operations, +reductions and partial reductions.++Now that broadcasting, reductions and partial reductions have been introduced, we can dive into a more advanced example that finds+the nearest neighbour of a vector <tt>v</tt> within the columns of matrix <tt>m</tt>. The Euclidean distance will be used in this example,+computing the squared Euclidean distance with the partial reduction named \link MatrixBase::squaredNorm() squaredNorm() \endlink:++<table class="example">+<tr><th>Example:</th><th>Output:</th></tr>+<tr><td>+\include Tutorial_ReductionsVisitorsBroadcasting_broadcast_1nn.cpp+</td>+<td>+\verbinclude Tutorial_ReductionsVisitorsBroadcasting_broadcast_1nn.out+</td></tr></table>++The line that does the job is +\code+ (m.colwise() - v).colwise().squaredNorm().minCoeff(&index);+\endcode++We will go step by step to understand what is happening:++ - <tt>m.colwise() - v</tt> is a broadcasting operation, subtracting <tt>v</tt> from each column in <tt>m</tt>. The result of this operation+is a new matrix whose size is the same as matrix <tt>m</tt>: \f[+ \mbox{m.colwise() - v} = + \begin{bmatrix}+ -1 & 21 & 4 & 7 \\+ 0 & 8 & 4 & -1+ \end{bmatrix}+\f]++ - <tt>(m.colwise() - v).colwise().squaredNorm()</tt> is a partial reduction, computing the squared norm column-wise. The result of+this operation is a row-vector where each coefficient is the squared Euclidean distance between each column in <tt>m</tt> and <tt>v</tt>: \f[+ \mbox{(m.colwise() - v).colwise().squaredNorm()} =+ \begin{bmatrix}+ 1 & 505 & 32 & 50+ \end{bmatrix}+\f]++ - Finally, <tt>minCoeff(&index)</tt> is used to obtain the index of the column in <tt>m</tt> that is closest to <tt>v</tt> in terms of Euclidean+distance.++*/++}
+ eigen3/doc/TutorialSparse.dox view
@@ -0,0 +1,341 @@+namespace Eigen {++/** \eigenManualPage TutorialSparse Sparse matrix manipulations++\eigenAutoToc++Manipulating and solving sparse problems involves various modules which are summarized below:++<table class="manual">+<tr><th>Module</th><th>Header file</th><th>Contents</th></tr>+<tr><td>\link SparseCore_Module SparseCore \endlink</td><td>\code#include <Eigen/SparseCore>\endcode</td><td>SparseMatrix and SparseVector classes, matrix assembly, basic sparse linear algebra (including sparse triangular solvers)</td></tr>+<tr><td>\link SparseCholesky_Module SparseCholesky \endlink</td><td>\code#include <Eigen/SparseCholesky>\endcode</td><td>Direct sparse LLT and LDLT Cholesky factorization to solve sparse self-adjoint positive definite problems</td></tr>+<tr><td>\link SparseLU_Module SparseLU \endlink</td><td>\code #include<Eigen/SparseLU> \endcode</td>+<td>%Sparse LU factorization to solve general square sparse systems</td></tr>+<tr><td>\link SparseQR_Module SparseQR \endlink</td><td>\code #include<Eigen/SparseQR>\endcode </td><td>%Sparse QR factorization for solving sparse linear least-squares problems</td></tr>+<tr><td>\link IterativeLinearSolvers_Module IterativeLinearSolvers \endlink</td><td>\code#include <Eigen/IterativeLinearSolvers>\endcode</td><td>Iterative solvers to solve large general linear square problems (including self-adjoint positive definite problems)</td></tr>+<tr><td>\link Sparse_Module Sparse \endlink</td><td>\code#include <Eigen/Sparse>\endcode</td><td>Includes all the above modules</td></tr>+</table>++\section TutorialSparseIntro Sparse matrix format++In many applications (e.g., finite element methods) it is common to deal with very large matrices where only a few coefficients are different from zero. In such cases, memory consumption can be reduced and performance increased by using a specialized representation storing only the nonzero coefficients. Such a matrix is called a sparse matrix.++\b The \b %SparseMatrix \b class++The class SparseMatrix is the main sparse matrix representation of Eigen's sparse module; it offers high performance and low memory usage.+It implements a more versatile variant of the widely-used Compressed Column (or Row) Storage scheme.+It consists of four compact arrays:+ - \c Values: stores the coefficient values of the non-zeros.+ - \c InnerIndices: stores the row (resp. column) indices of the non-zeros.+ - \c OuterStarts: stores for each column (resp. row) the index of the first non-zero in the previous two arrays.+ - \c InnerNNZs: stores the number of non-zeros of each column (resp. row).+The word \c inner refers to an \em inner \em vector that is a column for a column-major matrix, or a row for a row-major matrix.+The word \c outer refers to the other direction.++This storage scheme is better explained on an example. The following matrix+<table class="manual">+<tr><td> 0</td><td>3</td><td> 0</td><td>0</td><td> 0</td></tr>+<tr><td>22</td><td>0</td><td> 0</td><td>0</td><td>17</td></tr>+<tr><td> 7</td><td>5</td><td> 0</td><td>1</td><td> 0</td></tr>+<tr><td> 0</td><td>0</td><td> 0</td><td>0</td><td> 0</td></tr>+<tr><td> 0</td><td>0</td><td>14</td><td>0</td><td> 8</td></tr>+</table>++and one of its possible sparse, \b column \b major representation:+<table class="manual">+<tr><td>Values:</td> <td>22</td><td>7</td><td>_</td><td>3</td><td>5</td><td>14</td><td>_</td><td>_</td><td>1</td><td>_</td><td>17</td><td>8</td></tr>+<tr><td>InnerIndices:</td> <td> 1</td><td>2</td><td>_</td><td>0</td><td>2</td><td> 4</td><td>_</td><td>_</td><td>2</td><td>_</td><td> 1</td><td>4</td></tr>+</table>+<table class="manual">+<tr><td>OuterStarts:</td><td>0</td><td>3</td><td>5</td><td>8</td><td>10</td><td>\em 12 </td></tr>+<tr><td>InnerNNZs:</td> <td>2</td><td>2</td><td>1</td><td>1</td><td> 2</td><td></td></tr>+</table>++Currently the elements of a given inner vector are guaranteed to be always sorted by increasing inner indices.+The \c "_" indicates available free space to quickly insert new elements.+Assuming no reallocation is needed, the insertion of a random element is therefore in O(nnz_j) where nnz_j is the number of nonzeros of the respective inner vector.+On the other hand, inserting elements with increasing inner indices in a given inner vector is much more efficient since this only requires to increase the respective \c InnerNNZs entry that is a O(1) operation.++The case where no empty space is available is a special case, and is refered as the \em compressed mode.+It corresponds to the widely used Compressed Column (or Row) Storage schemes (CCS or CRS).+Any SparseMatrix can be turned to this form by calling the SparseMatrix::makeCompressed() function.+In this case, one can remark that the \c InnerNNZs array is redundant with \c OuterStarts because we the equality: \c InnerNNZs[j] = \c OuterStarts[j+1]-\c OuterStarts[j].+Therefore, in practice a call to SparseMatrix::makeCompressed() frees this buffer.++It is worth noting that most of our wrappers to external libraries requires compressed matrices as inputs.++The results of %Eigen's operations always produces \b compressed sparse matrices.+On the other hand, the insertion of a new element into a SparseMatrix converts this later to the \b uncompressed mode.++Here is the previous matrix represented in compressed mode:+<table class="manual">+<tr><td>Values:</td> <td>22</td><td>7</td><td>3</td><td>5</td><td>14</td><td>1</td><td>17</td><td>8</td></tr>+<tr><td>InnerIndices:</td> <td> 1</td><td>2</td><td>0</td><td>2</td><td> 4</td><td>2</td><td> 1</td><td>4</td></tr>+</table>+<table class="manual">+<tr><td>OuterStarts:</td><td>0</td><td>2</td><td>4</td><td>5</td><td>6</td><td>\em 8 </td></tr>+</table>++A SparseVector is a special case of a SparseMatrix where only the \c Values and \c InnerIndices arrays are stored.+There is no notion of compressed/uncompressed mode for a SparseVector.+++\section TutorialSparseExample First example++Before describing each individual class, let's start with the following typical example: solving the Laplace equation \f$ \nabla u = 0 \f$ on a regular 2D grid using a finite difference scheme and Dirichlet boundary conditions.+Such problem can be mathematically expressed as a linear problem of the form \f$ Ax=b \f$ where \f$ x \f$ is the vector of \c m unknowns (in our case, the values of the pixels), \f$ b \f$ is the right hand side vector resulting from the boundary conditions, and \f$ A \f$ is an \f$ m \times m \f$ matrix containing only a few non-zero elements resulting from the discretization of the Laplacian operator.++<table class="manual">+<tr><td>+\include Tutorial_sparse_example.cpp+</td>+<td>+\image html Tutorial_sparse_example.jpeg+</td></tr></table>++In this example, we start by defining a column-major sparse matrix type of double \c SparseMatrix<double>, and a triplet list of the same scalar type \c Triplet<double>. A triplet is a simple object representing a non-zero entry as the triplet: \c row index, \c column index, \c value.++In the main function, we declare a list \c coefficients of triplets (as a std vector) and the right hand side vector \f$ b \f$ which are filled by the \a buildProblem function.+The raw and flat list of non-zero entries is then converted to a true SparseMatrix object \c A.+Note that the elements of the list do not have to be sorted, and possible duplicate entries will be summed up.++The last step consists of effectively solving the assembled problem.+Since the resulting matrix \c A is symmetric by construction, we can perform a direct Cholesky factorization via the SimplicialLDLT class which behaves like its LDLT counterpart for dense objects.++The resulting vector \c x contains the pixel values as a 1D array which is saved to a jpeg file shown on the right of the code above.++Describing the \a buildProblem and \a save functions is out of the scope of this tutorial. They are given \ref TutorialSparse_example_details "here" for the curious and reproducibility purpose.+++++\section TutorialSparseSparseMatrix The SparseMatrix class++\b %Matrix \b and \b vector \b properties \n++The SparseMatrix and SparseVector classes take three template arguments:+ * the scalar type (e.g., double)+ * the storage order (ColMajor or RowMajor, the default is ColMajor)+ * the inner index type (default is \c int).++As for dense Matrix objects, constructors takes the size of the object.+Here are some examples:++\code+SparseMatrix<std::complex<float> > mat(1000,2000); // declares a 1000x2000 column-major compressed sparse matrix of complex<float>+SparseMatrix<double,RowMajor> mat(1000,2000); // declares a 1000x2000 row-major compressed sparse matrix of double+SparseVector<std::complex<float> > vec(1000); // declares a column sparse vector of complex<float> of size 1000+SparseVector<double,RowMajor> vec(1000); // declares a row sparse vector of double of size 1000+\endcode++In the rest of the tutorial, \c mat and \c vec represent any sparse-matrix and sparse-vector objects, respectively.++The dimensions of a matrix can be queried using the following functions:+<table class="manual">+<tr><td>Standard \n dimensions</td><td>\code+mat.rows()+mat.cols()\endcode</td>+<td>\code+vec.size() \endcode</td>+</tr>+<tr><td>Sizes along the \n inner/outer dimensions</td><td>\code+mat.innerSize()+mat.outerSize()\endcode</td>+<td></td>+</tr>+<tr><td>Number of non \n zero coefficients</td><td>\code+mat.nonZeros() \endcode</td>+<td>\code+vec.nonZeros() \endcode</td></tr>+</table>+++\b Iterating \b over \b the \b nonzero \b coefficients \n++Random access to the elements of a sparse object can be done through the \c coeffRef(i,j) function.+However, this function involves a quite expensive binary search.+In most cases, one only wants to iterate over the non-zeros elements. This is achieved by a standard loop over the outer dimension, and then by iterating over the non-zeros of the current inner vector via an InnerIterator. Thus, the non-zero entries have to be visited in the same order than the storage order.+Here is an example:+<table class="manual">+<tr><td>+\code+SparseMatrix<double> mat(rows,cols);+for (int k=0; k<mat.outerSize(); ++k)+ for (SparseMatrix<double>::InnerIterator it(mat,k); it; ++it)+ {+ it.value();+ it.row(); // row index+ it.col(); // col index (here it is equal to k)+ it.index(); // inner index, here it is equal to it.row()+ }+\endcode+</td><td>+\code+SparseVector<double> vec(size);+for (SparseVector<double>::InnerIterator it(vec); it; ++it)+{+ it.value(); // == vec[ it.index() ]+ it.index();+}+\endcode+</td></tr>+</table>+For a writable expression, the referenced value can be modified using the valueRef() function.+If the type of the sparse matrix or vector depends on a template parameter, then the \c typename keyword is+required to indicate that \c InnerIterator denotes a type; see \ref TopicTemplateKeyword for details.+++\section TutorialSparseFilling Filling a sparse matrix++Because of the special storage scheme of a SparseMatrix, special care has to be taken when adding new nonzero entries.+For instance, the cost of a single purely random insertion into a SparseMatrix is \c O(nnz), where \c nnz is the current number of non-zero coefficients.++The simplest way to create a sparse matrix while guaranteeing good performance is thus to first build a list of so-called \em triplets, and then convert it to a SparseMatrix.++Here is a typical usage example:+\code+typedef Eigen::Triplet<double> T;+std::vector<T> tripletList;+tripletList.reserve(estimation_of_entries);+for(...)+{+ // ...+ tripletList.push_back(T(i,j,v_ij));+}+SparseMatrixType mat(rows,cols);+mat.setFromTriplets(tripletList.begin(), tripletList.end());+// mat is ready to go!+\endcode+The \c std::vector of triplets might contain the elements in arbitrary order, and might even contain duplicated elements that will be summed up by setFromTriplets().+See the SparseMatrix::setFromTriplets() function and class Triplet for more details.+++In some cases, however, slightly higher performance, and lower memory consumption can be reached by directly inserting the non-zeros into the destination matrix.+A typical scenario of this approach is illustrated bellow:+\code+1: SparseMatrix<double> mat(rows,cols); // default is column major+2: mat.reserve(VectorXi::Constant(cols,6));+3: for each i,j such that v_ij != 0+4: mat.insert(i,j) = v_ij; // alternative: mat.coeffRef(i,j) += v_ij;+5: mat.makeCompressed(); // optional+\endcode++- The key ingredient here is the line 2 where we reserve room for 6 non-zeros per column. In many cases, the number of non-zeros per column or row can easily be known in advance. If it varies significantly for each inner vector, then it is possible to specify a reserve size for each inner vector by providing a vector object with an operator[](int j) returning the reserve size of the \c j-th inner vector (e.g., via a VectorXi or std::vector<int>). If only a rought estimate of the number of nonzeros per inner-vector can be obtained, it is highly recommended to overestimate it rather than the opposite. If this line is omitted, then the first insertion of a new element will reserve room for 2 elements per inner vector.+- The line 4 performs a sorted insertion. In this example, the ideal case is when the \c j-th column is not full and contains non-zeros whose inner-indices are smaller than \c i. In this case, this operation boils down to trivial O(1) operation.+- When calling insert(i,j) the element \c i \c ,j must not already exists, otherwise use the coeffRef(i,j) method that will allow to, e.g., accumulate values. This method first performs a binary search and finally calls insert(i,j) if the element does not already exist. It is more flexible than insert() but also more costly.+- The line 5 suppresses the remaining empty space and transforms the matrix into a compressed column storage.++++\section TutorialSparseFeatureSet Supported operators and functions++Because of their special storage format, sparse matrices cannot offer the same level of flexibility than dense matrices.+In Eigen's sparse module we chose to expose only the subset of the dense matrix API which can be efficiently implemented.+In the following \em sm denotes a sparse matrix, \em sv a sparse vector, \em dm a dense matrix, and \em dv a dense vector.++\subsection TutorialSparse_BasicOps Basic operations++%Sparse expressions support most of the unary and binary coefficient wise operations:+\code+sm1.real() sm1.imag() -sm1 0.5*sm1+sm1+sm2 sm1-sm2 sm1.cwiseProduct(sm2)+\endcode+However, a strong restriction is that the storage orders must match. For instance, in the following example:+\code+sm4 = sm1 + sm2 + sm3;+\endcode+sm1, sm2, and sm3 must all be row-major or all column major.+On the other hand, there is no restriction on the target matrix sm4.+For instance, this means that for computing \f$ A^T + A \f$, the matrix \f$ A^T \f$ must be evaluated into a temporary matrix of compatible storage order:+\code+SparseMatrix<double> A, B;+B = SparseMatrix<double>(A.transpose()) + A;+\endcode++Some binary coefficient-wise operators can also mix sparse and dense expressions:+\code+sm2 = sm1.cwiseProduct(dm1);+dm1 += sm1;+\endcode++However, it is not yet possible to add a sparse and a dense matrix as in <tt>dm2 = sm1 + dm1</tt>.+Please write this as the equivalent <tt>dm2 = dm1; dm2 += sm1</tt> (we plan to lift this restriction+in the next release of %Eigen).++%Sparse expressions also support transposition:+\code+sm1 = sm2.transpose();+sm1 = sm2.adjoint();+\endcode+However, there is no transposeInPlace() method.+++\subsection TutorialSparse_Products Matrix products++%Eigen supports various kind of sparse matrix products which are summarize below:+ - \b sparse-dense:+ \code+dv2 = sm1 * dv1;+dm2 = dm1 * sm1.adjoint();+dm2 = 2. * sm1 * dm1;+ \endcode+ - \b symmetric \b sparse-dense. The product of a sparse symmetric matrix with a dense matrix (or vector) can also be optimized by specifying the symmetry with selfadjointView():+ \code+dm2 = sm1.selfadjointView<>() * dm1; // if all coefficients of A are stored+dm2 = A.selfadjointView<Upper>() * dm1; // if only the upper part of A is stored+dm2 = A.selfadjointView<Lower>() * dm1; // if only the lower part of A is stored+ \endcode+ - \b sparse-sparse. For sparse-sparse products, two different algorithms are available. The default one is conservative and preserve the explicit zeros that might appear:+ \code+sm3 = sm1 * sm2;+sm3 = 4 * sm1.adjoint() * sm2;+ \endcode+ The second algorithm prunes on the fly the explicit zeros, or the values smaller than a given threshold. It is enabled and controlled through the prune() functions:+ \code+sm3 = (sm1 * sm2).pruned(); // removes numerical zeros+sm3 = (sm1 * sm2).pruned(ref); // removes elements much smaller than ref+sm3 = (sm1 * sm2).pruned(ref,epsilon); // removes elements smaller than ref*epsilon+ \endcode++ - \b permutations. Finally, permutations can be applied to sparse matrices too:+ \code+PermutationMatrix<Dynamic,Dynamic> P = ...;+sm2 = P * sm1;+sm2 = sm1 * P.inverse();+sm2 = sm1.transpose() * P;+ \endcode+++\subsection TutorialSparse_TriangularSelfadjoint Triangular and selfadjoint views++Just as with dense matrices, the triangularView() function can be used to address a triangular part of the matrix, and perform triangular solves with a dense right hand side:+\code+dm2 = sm1.triangularView<Lower>(dm1);+dv2 = sm1.transpose().triangularView<Upper>(dv1);+\endcode++The selfadjointView() function permits various operations:+ - optimized sparse-dense matrix products:+ \code+dm2 = sm1.selfadjointView<>() * dm1; // if all coefficients of A are stored+dm2 = A.selfadjointView<Upper>() * dm1; // if only the upper part of A is stored+dm2 = A.selfadjointView<Lower>() * dm1; // if only the lower part of A is stored+ \endcode+ - copy of triangular parts:+ \code+sm2 = sm1.selfadjointView<Upper>(); // makes a full selfadjoint matrix from the upper triangular part+sm2.selfadjointView<Lower>() = sm1.selfadjointView<Upper>(); // copies the upper triangular part to the lower triangular part+ \endcode+ - application of symmetric permutations:+ \code+PermutationMatrix<Dynamic,Dynamic> P = ...;+sm2 = A.selfadjointView<Upper>().twistedBy(P); // compute P S P' from the upper triangular part of A, and make it a full matrix+sm2.selfadjointView<Lower>() = A.selfadjointView<Lower>().twistedBy(P); // compute P S P' from the lower triangular part of A, and then only compute the lower part+ \endcode++Please, refer to the \link SparseQuickRefPage Quick Reference \endlink guide for the list of supported operations. The list of linear solvers available is \link TopicSparseSystems here. \endlink++*/++}
+ eigen3/doc/TutorialSparse_example_details.dox view
@@ -0,0 +1,4 @@+/**+\page TutorialSparse_example_details+\include Tutorial_sparse_example_details.cpp+*/
+ eigen3/doc/UnalignedArrayAssert.dox view
@@ -0,0 +1,114 @@+namespace Eigen {++/** \eigenManualPage TopicUnalignedArrayAssert Explanation of the assertion on unaligned arrays++Hello! You are seeing this webpage because your program terminated on an assertion failure like this one:+<pre>+my_program: path/to/eigen/Eigen/src/Core/DenseStorage.h:44:+Eigen::internal::matrix_array<T, Size, MatrixOptions, Align>::internal::matrix_array()+[with T = double, int Size = 2, int MatrixOptions = 2, bool Align = true]:+Assertion `(reinterpret_cast<size_t>(array) & 0xf) == 0 && "this assertion+is explained here: http://eigen.tuxfamily.org/dox/UnalignedArrayAssert.html+**** READ THIS WEB PAGE !!! ****"' failed.+</pre>++There are 4 known causes for this issue. Please read on to understand them and learn how to fix them.++\eigenAutoToc++\section where Where in my own code is the cause of the problem?++First of all, you need to find out where in your own code this assertion was triggered from. At first glance, the error message doesn't look helpful, as it refers to a file inside Eigen! However, since your program crashed, if you can reproduce the crash, you can get a backtrace using any debugger. For example, if you're using GCC, you can use the GDB debugger as follows:+\code+$ gdb ./my_program # Start GDB on your program+> run # Start running your program+... # Now reproduce the crash!+> bt # Obtain the backtrace+\endcode+Now that you know precisely where in your own code the problem is happening, read on to understand what you need to change.++\section c1 Cause 1: Structures having Eigen objects as members++If you have code like this,++\code+class Foo+{+ //...+ Eigen::Vector2d v;+ //...+};+//...+Foo *foo = new Foo;+\endcode++then you need to read this separate page: \ref TopicStructHavingEigenMembers "Structures Having Eigen Members".++Note that here, Eigen::Vector2d is only used as an example, more generally the issue arises for all \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen types".++\section c2 Cause 2: STL Containers++If you use STL Containers such as std::vector, std::map, ..., with Eigen objects, or with classes containing Eigen objects, like this,++\code+std::vector<Eigen::Matrix2f> my_vector;+struct my_class { ... Eigen::Matrix2f m; ... };+std::map<int, my_class> my_map;+\endcode++then you need to read this separate page: \ref TopicStlContainers "Using STL Containers with Eigen".++Note that here, Eigen::Matrix2f is only used as an example, more generally the issue arises for all \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen types" and \ref TopicStructHavingEigenMembers "structures having such Eigen objects as member".++\section c3 Cause 3: Passing Eigen objects by value++If some function in your code is getting an Eigen object passed by value, like this,++\code+void func(Eigen::Vector4d v);+\endcode++then you need to read this separate page: \ref TopicPassingByValue "Passing Eigen objects by value to functions".++Note that here, Eigen::Vector4d is only used as an example, more generally the issue arises for all \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen types".++\section c4 Cause 4: Compiler making a wrong assumption on stack alignment (for instance GCC on Windows)++This is a must-read for people using GCC on Windows (like MinGW or TDM-GCC). If you have this assertion failure in an innocent function declaring a local variable like this:++\code+void foo()+{+ Eigen::Quaternionf q;+ //...+}+\endcode++then you need to read this separate page: \ref TopicWrongStackAlignment "Compiler making a wrong assumption on stack alignment".++Note that here, Eigen::Quaternionf is only used as an example, more generally the issue arises for all \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen types".++\section explanation General explanation of this assertion++\ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen objects" must absolutely be created at 16-byte-aligned locations, otherwise SIMD instructions adressing them will crash.++Eigen normally takes care of these alignment issues for you, by setting an alignment attribute on them and by overloading their "operator new".++However there are a few corner cases where these alignment settings get overridden: they are the possible causes for this assertion.++\section getrid I don't care about vectorization, how do I get rid of that stuff?++Two possibilities:+<ul>+ <li>Define EIGEN_DONT_ALIGN_STATICALLY. That disables all 128-bit static alignment code, while keeping 128-bit heap alignment. This has the effect of+ disabling vectorization for fixed-size objects (like Matrix4d) while keeping vectorization of dynamic-size objects+ (like MatrixXd). But do note that this breaks ABI compatibility with the default behavior of 128-bit static alignment.</li>+ <li>Or define both EIGEN_DONT_VECTORIZE and EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT. This keeps the+ 128-bit alignment code and thus preserves ABI compatibility, but completely disables vectorization.</li>+</ul>++For more information, see <a href="http://eigen.tuxfamily.org/index.php?title=FAQ#I_disabled_vectorization.2C_but_I.27m_still_getting_annoyed_about_alignment_issues.21">this FAQ</a>.++*/++}
+ eigen3/doc/UsingIntelMKL.dox view
@@ -0,0 +1,168 @@+/*+ Copyright (c) 2011, Intel Corporation. All rights reserved.+ Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr>++ Redistribution and use in source and binary forms, with or without modification,+ are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright notice, this+ list of conditions and the following disclaimer.+ * Redistributions in binary form must reproduce the above copyright notice,+ this list of conditions and the following disclaimer in the documentation+ and/or other materials provided with the distribution.+ * Neither the name of Intel Corporation nor the names of its contributors may+ be used to endorse or promote products derived from this software without+ specific prior written permission.++ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.++ ********************************************************************************+ * Content : Documentation on the use of Intel MKL through Eigen+ ********************************************************************************+*/++namespace Eigen {++/** \page TopicUsingIntelMKL Using Intel® Math Kernel Library from Eigen++\section TopicUsingIntelMKL_Intro Eigen and Intel® Math Kernel Library (Intel® MKL)++Since Eigen version 3.1 and later, users can benefit from built-in Intel MKL optimizations with an installed copy of Intel MKL 10.3 (or later).+<a href="http://eigen.tuxfamily.org/Counter/redirect_to_mkl.php"> Intel MKL </a> provides highly optimized multi-threaded mathematical routines for x86-compatible architectures.+Intel MKL is available on Linux, Mac and Windows for both Intel64 and IA32 architectures.++\warning Be aware that Intel® MKL is a proprietary software. It is the responsibility of the users to buy MKL licenses for their products. Moreover, the license of the user product has to allow linking to proprietary software that excludes any unmodified versions of the GPL.++Using Intel MKL through Eigen is easy:+-# define the \c EIGEN_USE_MKL_ALL macro before including any Eigen's header+-# link your program to MKL libraries (see the <a href="http://software.intel.com/en-us/articles/intel-mkl-link-line-advisor/">MKL linking advisor</a>)+-# on a 64bits system, you must use the LP64 interface (not the ILP64 one)++When doing so, a number of Eigen's algorithms are silently substituted with calls to Intel MKL routines.+These substitutions apply only for \b Dynamic \b or \b large enough objects with one of the following four standard scalar types: \c float, \c double, \c complex<float>, and \c complex<double>.+Operations on other scalar types or mixing reals and complexes will continue to use the built-in algorithms.++In addition you can coarsely select choose which parts will be substituted by defining one or multiple of the following macros:++<table class="manual">+<tr><td>\c EIGEN_USE_BLAS </td><td>Enables the use of external BLAS level 2 and 3 routines (currently works with Intel MKL only)</td></tr>+<tr class="alt"><td>\c EIGEN_USE_LAPACKE </td><td>Enables the use of external Lapack routines via the <a href="http://www.netlib.org/lapack/lapacke.html">Intel Lapacke</a> C interface to Lapack (currently works with Intel MKL only)</td></tr>+<tr><td>\c EIGEN_USE_LAPACKE_STRICT </td><td>Same as \c EIGEN_USE_LAPACKE but algorithm of lower robustness are disabled. This currently concerns only JacobiSVD which otherwise would be replaced by \c gesvd that is less robust than Jacobi rotations.</td></tr>+<tr class="alt"><td>\c EIGEN_USE_MKL_VML </td><td>Enables the use of Intel VML (vector operations)</td></tr>+<tr><td>\c EIGEN_USE_MKL_ALL </td><td>Defines \c EIGEN_USE_BLAS, \c EIGEN_USE_LAPACKE, and \c EIGEN_USE_MKL_VML </td></tr>+</table>++Finally, the PARDISO sparse solver shipped with Intel MKL can be used through the \ref PardisoLU, \ref PardisoLLT and \ref PardisoLDLT classes of the \ref PardisoSupport_Module.+++\section TopicUsingIntelMKL_SupportedFeatures List of supported features++The breadth of Eigen functionality covered by Intel MKL is listed in the table below.+<table class="manual">+<tr><th>Functional domain</th><th>Code example</th><th>MKL routines</th></tr>+<tr><td>Matrix-matrix operations \n \c EIGEN_USE_BLAS </td><td>\code+m1*m2.transpose();+m1.selfadjointView<Lower>()*m2;+m1*m2.triangularView<Upper>();+m1.selfadjointView<Lower>().rankUpdate(m2,1.0);+\endcode</td><td>\code+?gemm+?symm/?hemm+?trmm+dsyrk/ssyrk+\endcode</td></tr>+<tr class="alt"><td>Matrix-vector operations \n \c EIGEN_USE_BLAS </td><td>\code+m1.adjoint()*b;+m1.selfadjointView<Lower>()*b;+m1.triangularView<Upper>()*b;+\endcode</td><td>\code+?gemv+?symv/?hemv+?trmv+\endcode</td></tr>+<tr><td>LU decomposition \n \c EIGEN_USE_LAPACKE \n \c EIGEN_USE_LAPACKE_STRICT </td><td>\code+v1 = m1.lu().solve(v2);+\endcode</td><td>\code+?getrf+\endcode</td></tr>+<tr class="alt"><td>Cholesky decomposition \n \c EIGEN_USE_LAPACKE \n \c EIGEN_USE_LAPACKE_STRICT </td><td>\code+v1 = m2.selfadjointView<Upper>().llt().solve(v2);+\endcode</td><td>\code+?potrf+\endcode</td></tr>+<tr><td>QR decomposition \n \c EIGEN_USE_LAPACKE \n \c EIGEN_USE_LAPACKE_STRICT </td><td>\code+m1.householderQr();+m1.colPivHouseholderQr();+\endcode</td><td>\code+?geqrf+?geqp3+\endcode</td></tr>+<tr class="alt"><td>Singular value decomposition \n \c EIGEN_USE_LAPACKE </td><td>\code+JacobiSVD<MatrixXd> svd;+svd.compute(m1, ComputeThinV);+\endcode</td><td>\code+?gesvd+\endcode</td></tr>+<tr><td>Eigen-value decompositions \n \c EIGEN_USE_LAPACKE \n \c EIGEN_USE_LAPACKE_STRICT </td><td>\code+EigenSolver<MatrixXd> es(m1);+ComplexEigenSolver<MatrixXcd> ces(m1);+SelfAdjointEigenSolver<MatrixXd> saes(m1+m1.transpose());+GeneralizedSelfAdjointEigenSolver<MatrixXd>+ gsaes(m1+m1.transpose(),m2+m2.transpose());+\endcode</td><td>\code+?gees+?gees+?syev/?heev+?syev/?heev,+?potrf+\endcode</td></tr>+<tr class="alt"><td>Schur decomposition \n \c EIGEN_USE_LAPACKE \n \c EIGEN_USE_LAPACKE_STRICT </td><td>\code+RealSchur<MatrixXd> schurR(m1);+ComplexSchur<MatrixXcd> schurC(m1);+\endcode</td><td>\code+?gees+\endcode</td></tr>+<tr><td>Vector Math \n \c EIGEN_USE_MKL_VML </td><td>\code+v2=v1.array().sin();+v2=v1.array().asin();+v2=v1.array().cos();+v2=v1.array().acos();+v2=v1.array().tan();+v2=v1.array().exp();+v2=v1.array().log();+v2=v1.array().sqrt();+v2=v1.array().square();+v2=v1.array().pow(1.5);+\endcode</td><td>\code+v?Sin+v?Asin+v?Cos+v?Acos+v?Tan+v?Exp+v?Ln+v?Sqrt+v?Sqr+v?Powx+\endcode</td></tr>+</table>+In the examples, m1 and m2 are dense matrices and v1 and v2 are dense vectors.+++\section TopicUsingIntelMKL_Links Links+- Intel MKL can be purchased and downloaded <a href="http://eigen.tuxfamily.org/Counter/redirect_to_mkl.php">here</a>.+- Intel MKL is also bundled with <a href="http://software.intel.com/en-us/articles/intel-composer-xe/">Intel Composer XE</a>.+++*/++}
+ eigen3/doc/WrongStackAlignment.dox view
@@ -0,0 +1,56 @@+namespace Eigen {++/** \eigenManualPage TopicWrongStackAlignment Compiler making a wrong assumption on stack alignment++<h4>It appears that this was a GCC bug that has been fixed in GCC 4.5.+If you hit this issue, please upgrade to GCC 4.5 and report to us, so we can update this page.</h4>++This is an issue that, so far, we met only with GCC on Windows: for instance, MinGW and TDM-GCC.++By default, in a function like this,++\code+void foo()+{+ Eigen::Quaternionf q;+ //...+}+\endcode++GCC assumes that the stack is already 16-byte-aligned so that the object \a q will be created at a 16-byte-aligned location. For this reason, it doesn't take any special care to explicitly align the object \a q, as Eigen requires.++The problem is that, in some particular cases, this assumption can be wrong on Windows, where the stack is only guaranteed to have 4-byte alignment. Indeed, even though GCC takes care of aligning the stack in the main function and does its best to keep it aligned, when a function is called from another thread or from a binary compiled with another compiler, the stack alignment can be corrupted. This results in the object 'q' being created at an unaligned location, making your program crash with the \ref TopicUnalignedArrayAssert "assertion on unaligned arrays". So far we found the three following solutions.+++\section sec_sol1 Local solution++A local solution is to mark such a function with this attribute:+\code+__attribute__((force_align_arg_pointer)) void foo()+{+ Eigen::Quaternionf q;+ //...+}+\endcode+Read <a href="http://gcc.gnu.org/onlinedocs/gcc-4.4.0/gcc/Function-Attributes.html#Function-Attributes">this GCC documentation</a> to understand what this does. Of course this should only be done on GCC on Windows, so for portability you'll have to encapsulate this in a macro which you leave empty on other platforms. The advantage of this solution is that you can finely select which function might have a corrupted stack alignment. Of course on the downside this has to be done for every such function, so you may prefer one of the following two global solutions.+++\section sec_sol2 Global solutions++A global solution is to edit your project so that when compiling with GCC on Windows, you pass this option to GCC:+\code+-mincoming-stack-boundary=2+\endcode+Explanation: this tells GCC that the stack is only required to be aligned to 2^2=4 bytes, so that GCC now knows that it really must take extra care to honor the 16 byte alignment of \ref TopicFixedSizeVectorizable "fixed-size vectorizable Eigen types" when needed.++Another global solution is to pass this option to gcc:+\code+-mstackrealign+\endcode+which has the same effect than adding the \c force_align_arg_pointer attribute to all functions.++These global solutions are easy to use, but note that they may slowdown your program because they lead to extra prologue/epilogue instructions for every function.++*/++}
@@ -0,0 +1,240 @@++// generate a table of contents in the side-nav based on the h1/h2 tags of the current page.+function generate_autotoc() {+ var headers = $("h1, h2");+ if(headers.length > 1) {+ var toc = $("#side-nav").append('<div id="nav-toc" class="toc"><h3>Table of contents</h3></div>');+ toc = $("#nav-toc");+ var footerHeight = footer.height();+ toc = toc.append('<ul></ul>');+ toc = toc.find('ul');+ var indices = new Array();+ indices[0] = 0;+ indices[1] = 0;++ var h1counts = $("h1").length;+ headers.each(function(i) {+ var current = $(this);+ var levelTag = current[0].tagName.charAt(1);+ if(h1counts==0)+ levelTag--;+ var cur_id = current.attr("id");++ indices[levelTag-1]+=1; + var prefix = indices[0];+ if (levelTag >1) {+ prefix+="."+indices[1];+ }+ + // Uncomment to add number prefixes+ // current.html(prefix + " " + current.html());+ for(var l = levelTag; l < 2; ++l){+ indices[l] = 0;+ }++ if(cur_id == undefined) {+ current.attr('id', 'title' + i);+ current.addClass('anchor');+ toc.append("<li class='level" + levelTag + "'><a id='link" + i + "' href='#title" ++ i + "' title='" + current.prop("tagName") + "'>" + current.text() + "</a></li>");+ } else {+ toc.append("<li class='level" + levelTag + "'><a id='" + cur_id + "' href='#title" ++ i + "' title='" + current.prop("tagName") + "'>" + current.text() + "</a></li>");+ }+ });+ resizeHeight();+ }+}+++var global_navtree_object;++// Overloaded to remove links to sections/subsections+function getNode(o, po)+{+ po.childrenVisited = true;+ var l = po.childrenData.length-1;+ for (var i in po.childrenData) {+ var nodeData = po.childrenData[i];+ if((!nodeData[1]) || (nodeData[1].indexOf('#')==-1)) // <- we added this line+ po.children[i] = newNode(o, po, nodeData[0], nodeData[1], nodeData[2], i==l);+ }+}++// Overloaded to adjust the size of the navtree wrt the toc+function resizeHeight() +{+ var toc = $("#nav-toc");+ var tocHeight = toc.height(); // <- we added this line+ var headerHeight = header.height();+ var footerHeight = footer.height();+ var windowHeight = $(window).height() - headerHeight - footerHeight;+ content.css({height:windowHeight + "px"});+ navtree.css({height:(windowHeight-tocHeight) + "px"}); // <- we modified this line+ sidenav.css({height:(windowHeight) + "px",top: headerHeight+"px"});+}++// Overloaded to save the root node into global_navtree_object+function initNavTree(toroot,relpath)+{+ var o = new Object();+ global_navtree_object = o; // <- we added this line+ o.toroot = toroot;+ o.node = new Object();+ o.node.li = document.getElementById("nav-tree-contents");+ o.node.childrenData = NAVTREE;+ o.node.children = new Array();+ o.node.childrenUL = document.createElement("ul");+ o.node.getChildrenUL = function() { return o.node.childrenUL; };+ o.node.li.appendChild(o.node.childrenUL);+ o.node.depth = 0;+ o.node.relpath = relpath;+ o.node.expanded = false;+ o.node.isLast = true;+ o.node.plus_img = document.createElement("img");+ o.node.plus_img.src = relpath+"ftv2pnode.png";+ o.node.plus_img.width = 16;+ o.node.plus_img.height = 22;++ if (localStorageSupported()) {+ var navSync = $('#nav-sync');+ if (cachedLink()) {+ showSyncOff(navSync,relpath);+ navSync.removeClass('sync');+ } else {+ showSyncOn(navSync,relpath);+ }+ navSync.click(function(){ toggleSyncButton(relpath); });+ }++ navTo(o,toroot,window.location.hash,relpath);++ $(window).bind('hashchange', function(){+ if (window.location.hash && window.location.hash.length>1){+ var a;+ if ($(location).attr('hash')){+ var clslink=stripPath($(location).attr('pathname'))+':'++ $(location).attr('hash').substring(1);+ a=$('.item a[class$="'+clslink+'"]');+ }+ if (a==null || !$(a).parent().parent().hasClass('selected')){+ $('.item').removeClass('selected');+ $('.item').removeAttr('id');+ }+ var link=stripPath2($(location).attr('pathname'));+ navTo(o,link,$(location).attr('hash'),relpath);+ } else if (!animationInProgress) {+ $('#doc-content').scrollTop(0);+ $('.item').removeClass('selected');+ $('.item').removeAttr('id');+ navTo(o,toroot,window.location.hash,relpath);+ }+ })++ $(window).load(showRoot);+}++// return false if the the node has no children at all, or has only section/subsection children+function checkChildrenData(node) {+ if (!(typeof(node.childrenData)==='string')) {+ for (var i in node.childrenData) {+ var url = node.childrenData[i][1];+ if(url.indexOf("#")==-1)+ return true;+ }+ return false;+ }+ return (node.childrenData);+}++// Modified to:+// 1 - remove the root node +// 2 - remove the section/subsection children+function createIndent(o,domNode,node,level)+{+ var level=-2; // <- we replaced level=-1 by level=-2+ var n = node;+ while (n.parentNode) { level++; n=n.parentNode; }+ var imgNode = document.createElement("img");+ imgNode.style.paddingLeft=(16*(level)).toString()+'px';+ imgNode.width = 16;+ imgNode.height = 22;+ imgNode.border = 0;+ if (checkChildrenData(node)) { // <- we modified this line to use checkChildrenData(node) instead of node.childrenData+ node.plus_img = imgNode;+ node.expandToggle = document.createElement("a");+ node.expandToggle.href = "javascript:void(0)";+ node.expandToggle.onclick = function() {+ if (node.expanded) {+ $(node.getChildrenUL()).slideUp("fast");+ node.plus_img.src = node.relpath+"ftv2pnode.png";+ node.expanded = false;+ } else {+ expandNode(o, node, false, false);+ }+ }+ node.expandToggle.appendChild(imgNode);+ domNode.appendChild(node.expandToggle);+ imgNode.src = node.relpath+"ftv2pnode.png";+ } else {+ imgNode.src = node.relpath+"ftv2node.png";+ domNode.appendChild(imgNode);+ } +}++// Overloaded to automatically expand the selected node+function selectAndHighlight(hash,n)+{+ var a;+ if (hash) {+ var link=stripPath($(location).attr('pathname'))+':'+hash.substring(1);+ a=$('.item a[class$="'+link+'"]');+ }+ if (a && a.length) {+ a.parent().parent().addClass('selected');+ a.parent().parent().attr('id','selected');+ highlightAnchor();+ } else if (n) {+ $(n.itemDiv).addClass('selected');+ $(n.itemDiv).attr('id','selected');+ }+ if ($('#nav-tree-contents .item:first').hasClass('selected')) {+ $('#nav-sync').css('top','30px');+ } else {+ $('#nav-sync').css('top','5px');+ }+ expandNode(global_navtree_object, n, true, true); // <- we added this line+ showRoot();+}+++$(document).ready(function() {+ + generate_autotoc();+ + (function (){ // wait until the first "selected" element has been created+ try {+ + // this line will triger an exception if there is no #selected element, i.e., before the tree structure is complete.+ document.getElementById("selected").className = "item selected";+ + // ok, the default tree has been created, we can keep going...+ + // expand the "Chapters" node+ if(window.location.href.indexOf('unsupported')==-1)+ expandNode(global_navtree_object, global_navtree_object.node.children[0].children[2], true, true);+ else+ expandNode(global_navtree_object, global_navtree_object.node.children[0].children[1], true, true);+ + // Hide the root node "Eigen"+ $(document.getElementsByClassName('index.html')[0]).parent().parent().css({display:"none"});+ + } catch (err) {+ setTimeout(arguments.callee, 10);+ }+ })();+});++$(window).load(function() {+ resizeHeight();+});
+ eigen3/doc/eigendoxy.css view
@@ -0,0 +1,211 @@++/******** Eigen specific CSS code ************/++/**** Styles removing elements ****/++/* remove the "modules|classes" link for module pages (they are already in the TOC) */+div.summary {+ display:none;+}++/* remove */+div.contents hr {+ display:none;+}++/**** ****/++p, dl.warning, dl.attention, dl.note+{+ max-width:60em;+ text-align:justify;+}++li {+ max-width:55em;+ text-align:justify; +}++img {+ border: 0;+}++div.fragment {+ display:table; /* this allows the element to be larger than its parent */+ padding: 0pt;+}+pre.fragment {+ border: 1px solid #cccccc;++ margin: 2px 0px 2px 0px;+ padding: 3px 5px 3px 5px;+}++++/* Common style for all Eigen's tables */++table.example, table.manual, table.manual-vl {+ max-width:100%;+ border-collapse: collapse;+ border-style: solid;+ border-width: 1px;+ border-color: #cccccc;+ font-size: 1em;+ + box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);+ -moz-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);+ -webkit-box-shadow: 5px 5px 5px rgba(0, 0, 0, 0.15);+}++table.example th, table.manual th, table.manual-vl th {+ padding: 0.5em 0.5em 0.5em 0.5em;+ text-align: left;+ padding-right: 1em;+ color: #555555;+ background-color: #F4F4E5;+ + background-image: -webkit-gradient(linear,center top,center bottom,from(#FFFFFF), color-stop(0.3,#FFFFFF), color-stop(0.30,#FFFFFF), color-stop(0.98,#F4F4E5), to(#ECECDE));+ background-image: -moz-linear-gradient(center top, #FFFFFF 0%, #FFFFFF 30%, #F4F4E5 98%, #ECECDE);+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFF', endColorstr='#F4F4E5');+}++table.example td, table.manual td, table.manual-vl td {+ vertical-align:top;+ border-width: 1px;+ border-color: #cccccc;+}++/* header of headers */+table th.meta {+ text-align:center;+ font-size: 1.2em;+ background-color:#FFFFFF;+}++/* intermediate header */+table th.inter {+ text-align:left;+ background-color:#FFFFFF;+ background-image:none;+ border-style:solid solid solid solid;+ border-width: 1px;+ border-color: #cccccc;+}++/** class for exemple / output tables **/++table.example {+}++table.example th {+}++table.example td {+ padding: 0.5em 0.5em 0.5em 0.5em;+ vertical-align:top;+}++/* standard class for the manual */++table.manual, table.manual-vl {+ padding: 0.2em 0em 0.5em 0em;+}++table.manual th, table.manual-vl th {+ margin: 0em 0em 0.3em 0em;+}++table.manual td, table.manual-vl td {+ padding: 0.3em 0.5em 0.3em 0.5em;+ vertical-align:top;+ border-width: 1px;+}++table.manual td.alt, table.manual tr.alt, table.manual-vl td.alt, table.manual-vl tr.alt {+ background-color: #F4F4E5;+}++table.manual-vl th, table.manual-vl td, table.manual-vl td.alt {+ border-color: #cccccc;+ border-width: 1px;+ border-style: none solid none solid;+}++table.manual-vl th.inter {+ border-style: solid solid solid solid;+}++h2 {+ margin-top:2em;+ border-style: none none solid none;+ border-width: 1px;+ border-color: #cccccc;+}++/**** Table of content in the side-nav ****/+++div.toc {+ margin:0;+ padding: 0.3em 0 0 0;+ width:100%;+ float:none;+ position:absolute;+ bottom:0;+ border-radius:0px;+ border-style: solid none none none;+}++div.toc h3 {+ margin-left: 0.5em;+ margin-bottom: 0.2em;+}++div.toc ul {+ margin: 0.2em 0 0.4em 0.5em;+}++/**** old Eigen's styles ****/+++table.tutorial_code td {+ border-color: transparent; /* required for Firefox */+ padding: 3pt 5pt 3pt 5pt;+ vertical-align: top;+}+++/* Whenever doxygen meets a '\n' or a '<BR/>', it will put + * the text containing the characted into a <p class="starttd">.+ * This little hack togehter with table.tutorial_code td.note+ * aims at fixing this issue. */+table.tutorial_code td.note p.starttd {+ margin: 0px;+ border: none;+ padding: 0px;+}++div.eimainmenu {+ text-align: center;+}++/* center version number on main page */+h3.version { + text-align: center;+}+++td.width20em p.endtd {+ width: 20em;+}++.bigwarning {+ font-size:2em;+ font-weight:bold;+ margin:1em;+ padding:1em;+ color:red;+ border:solid;+}+
@@ -0,0 +1,36 @@+<!-- start footer part -->+<!--BEGIN GENERATE_TREEVIEW-->+<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->+ <ul>+ $navpath+ <li class="footer">$generatedby+ <a href="http://www.doxygen.org/index.html">+ <img class="footer" src="$relpath$doxygen.png" alt="doxygen"/></a> $doxygenversion </li>+ </ul>+</div>+<!--END GENERATE_TREEVIEW-->+<!--BEGIN !GENERATE_TREEVIEW-->+<hr class="footer"/><address class="footer"><small>+$generatedby  <a href="http://www.doxygen.org/index.html">+<img class="footer" src="$relpath$doxygen.png" alt="doxygen"/>+</a> $doxygenversion+</small></address>+<!--END !GENERATE_TREEVIEW-->++<!-- Piwik -->+<script type="text/javascript">+var pkBaseURL = (("https:" == document.location.protocol) ? "https://stats.sylphide-consulting.com/piwik/" : "http://stats.sylphide-consulting.com/piwik/");+document.write(unescape("%3Cscript src='" + pkBaseURL + "piwik.js' type='text/javascript'%3E%3C/script%3E"));+</script><script type="text/javascript">+try {+var piwikTracker = Piwik.getTracker(pkBaseURL + "piwik.php", 20);+piwikTracker.trackPageView();+piwikTracker.enableLinkTracking();+} catch( err ) {}+</script><noscript><p><img src="http://stats.sylphide-consulting.com/piwik/piwik.php?idsite=20" style="border:0" alt="" /></p></noscript>+<!-- End Piwik Tracking Code -->++</body>+</html>++
+ eigen3/doc/eigendoxy_header.html.in view
@@ -0,0 +1,61 @@+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">+<html xmlns="http://www.w3.org/1999/xhtml">+<head>+<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>+<meta http-equiv="X-UA-Compatible" content="IE=9"/>+<meta name="generator" content="Doxygen $doxygenversion"/>+<!--BEGIN PROJECT_NAME--><title>$projectname: $title</title><!--END PROJECT_NAME-->+<!--BEGIN !PROJECT_NAME--><title>$title</title><!--END !PROJECT_NAME-->+<link href="$relpath$tabs.css" rel="stylesheet" type="text/css"/>+<script type="text/javascript" src="$relpath$jquery.js"></script>+<script type="text/javascript" src="$relpath$dynsections.js"></script>+$treeview+$search+$mathjax+<link href="$relpath$$stylesheet" rel="stylesheet" type="text/css" />+<link href="$relpath$eigendoxy.css" rel="stylesheet" type="text/css">+<!-- $extrastylesheet -->+<script type="text/javascript" src="$relpath$eigen_navtree_hacks.js"></script>+<!-- <script type="text/javascript"> -->+<!-- </script> -->++</head>+<body>+<div id="top"><!-- do not remove this div, it is closed by doxygen! -->+<!-- <a name="top"></a> -->++<!--BEGIN TITLEAREA-->+<div id="titlearea">+<table cellspacing="0" cellpadding="0">+ <tbody>+ <tr style="height: 56px;">+ <!--BEGIN PROJECT_LOGO-->+ <td id="projectlogo"><img alt="Logo" src="$relpath$$projectlogo"/></td>+ <!--END PROJECT_LOGO-->+ <!--BEGIN PROJECT_NAME-->+ <td style="padding-left: 0.5em;">+ <div id="projectname"><a href="http://eigen.tuxfamily.org">$projectname</a>+ <!--BEGIN PROJECT_NUMBER--> <span id="projectnumber">$projectnumber</span><!--END PROJECT_NUMBER-->+ </div>+ <!--BEGIN PROJECT_BRIEF--><div id="projectbrief">$projectbrief</div><!--END PROJECT_BRIEF-->+ </td>+ <!--END PROJECT_NAME-->+ <!--BEGIN !PROJECT_NAME-->+ <!--BEGIN PROJECT_BRIEF-->+ <td style="padding-left: 0.5em;">+ <div id="projectbrief">$projectbrief</div>+ </td>+ <!--END PROJECT_BRIEF-->+ <!--END !PROJECT_NAME-->+ <!--BEGIN DISABLE_INDEX-->+ <!--BEGIN SEARCHENGINE-->+ <td>$searchbox</td>+ <!--END SEARCHENGINE-->+ <!--END DISABLE_INDEX-->+ </tr>+ </tbody>+</table>+</div>+<!--END TITLEAREA-->+<!-- end header part -->+
+ eigen3/doc/eigendoxy_layout.xml.in view
@@ -0,0 +1,178 @@+<?xml version="1.0"?>+<doxygenlayout version="1.0">+ <!-- Navigation index tabs for HTML output -->+ <navindex>+ <tab type="user" url="index.html" title="Overview" />+ <tab type="user" url="@ref GettingStarted" title="Getting started" />+ <tab type="modules" visible="yes" title="Chapters" intro=""/>+ <tab type="mainpage" visible="yes" title=""/>+ <tab type="classlist" visible="yes" title="" intro=""/>+<!-- <tab type="classmembers" visible="yes" title="" intro=""/> -->+ </navindex>++ <!-- Layout definition for a class page -->+ <class>+ <briefdescription visible="no"/>+ <includes visible="$SHOW_INCLUDE_FILES"/>+ <detaileddescription title=""/>+ <inheritancegraph visible="$CLASS_GRAPH"/>+ <collaborationgraph visible="$COLLABORATION_GRAPH"/>+ <allmemberslink visible="yes"/>+ <memberdecl>+ <nestedclasses visible="yes" title=""/>+ <publictypes title=""/>+ <publicslots title=""/>+ <signals title=""/>+ <publicmethods title=""/>+ <publicstaticmethods title=""/>+ <publicattributes title=""/>+ <publicstaticattributes title=""/>+ <protectedtypes title=""/>+ <protectedslots title=""/>+ <protectedmethods title=""/>+ <protectedstaticmethods title=""/>+ <protectedattributes title=""/>+ <protectedstaticattributes title=""/>+ <packagetypes title=""/>+ <packagemethods title=""/>+ <packagestaticmethods title=""/>+ <packageattributes title=""/>+ <packagestaticattributes title=""/>+ <properties title=""/>+ <events title=""/>+ <privatetypes title=""/>+ <privateslots title=""/>+ <privatemethods title=""/>+ <privatestaticmethods title=""/>+ <privateattributes title=""/>+ <privatestaticattributes title=""/>+ <friends title=""/>+ <related title="" subtitle=""/>+ <membergroups visible="yes"/>+ </memberdecl>+ + <memberdef>+ <inlineclasses title=""/>+ <typedefs title=""/>+ <enums title=""/>+ <constructors title=""/>+ <functions title=""/>+ <related title=""/>+ <variables title=""/>+ <properties title=""/>+ <events title=""/>+ </memberdef>+ <usedfiles visible="$SHOW_USED_FILES"/>+ <authorsection visible="yes"/>+ </class>++ <!-- Layout definition for a namespace page -->+ <namespace>+ <briefdescription visible="yes"/>+ <memberdecl>+ <nestednamespaces visible="yes" title=""/>+ <classes visible="yes" title=""/>+ <typedefs title=""/>+ <enums title=""/>+ <functions title=""/>+ <variables title=""/>+ <membergroups visible="yes"/>+ </memberdecl>+ <detaileddescription title=""/>+ <memberdef>+ <inlineclasses title=""/>+ <typedefs title=""/>+ <enums title=""/>+ <functions title=""/>+ <variables title=""/>+ </memberdef>+ <authorsection visible="yes"/>+ </namespace>++ <!-- Layout definition for a file page -->+ <file>+ <briefdescription visible="yes"/>+ <includes visible="$SHOW_INCLUDE_FILES"/>+ <includegraph visible="$INCLUDE_GRAPH"/>+ <includedbygraph visible="$INCLUDED_BY_GRAPH"/>+ <sourcelink visible="yes"/>+ <memberdecl>+ <classes visible="yes" title=""/>+ <namespaces visible="yes" title=""/>+ <defines title=""/>+ <typedefs title=""/>+ <enums title=""/>+ <functions title=""/>+ <variables title=""/>+ <membergroups visible="yes"/>+ </memberdecl>+ <detaileddescription title=""/>+ <memberdef>+ <inlineclasses title=""/>+ <defines title=""/>+ <typedefs title=""/>+ <enums title=""/>+ <functions title=""/>+ <variables title=""/>+ </memberdef>+ <authorsection/>+ </file>++ <!-- Layout definition for a group page -->+ <group>+ <briefdescription visible="no"/>+ <detaileddescription title=""/>+ <groupgraph visible="$GROUP_GRAPHS"/>+ <memberdecl>+ <nestedgroups visible="yes" title=""/>+ <dirs visible="yes" title=""/>+ <files visible="yes" title=""/>+ <namespaces visible="yes" title=""/>+ <classes visible="yes" title=""/>+ <defines title=""/>+ <typedefs title=""/>+ <enums title=""/>+ <enumvalues title=""/>+ <functions title=""/>+ <variables title=""/>+ <signals title=""/>+ <publicslots title=""/>+ <protectedslots title=""/>+ <privateslots title=""/>+ <events title=""/>+ <properties title=""/>+ <friends title=""/>+ <membergroups visible="yes"/>+ </memberdecl>+ + <memberdef>+ <pagedocs/>+ <inlineclasses title=""/>+ <defines title=""/>+ <typedefs title=""/>+ <enums title=""/>+ <enumvalues title=""/>+ <functions title=""/>+ <variables title=""/>+ <signals title=""/>+ <publicslots title=""/>+ <protectedslots title=""/>+ <privateslots title=""/>+ <events title=""/>+ <properties title=""/>+ <friends title=""/>+ </memberdef>+ <authorsection visible="yes"/>+ </group>++ <!-- Layout definition for a directory page -->+ <directory>+ <briefdescription visible="yes"/>+ <directorygraph visible="yes"/>+ <memberdecl>+ <dirs visible="yes"/>+ <files visible="yes"/>+ </memberdecl>+ <detaileddescription title=""/>+ </directory>+</doxygenlayout>
+ eigen3/doc/eigendoxy_tabs.css view
@@ -0,0 +1,59 @@+.tabs, .tabs2, .tabs3 {+ background-image: url('tab_b.png');+ width: 100%;+ z-index: 101;+ font-size: 13px;+}++.tabs2 {+ font-size: 10px;+}+.tabs3 {+ font-size: 9px;+}++.tablist {+ margin: 0;+ padding: 0;+ display: table;+}++.tablist li {+ float: left;+ display: table-cell;+ background-image: url('tab_b.png');+ line-height: 36px;+ list-style: none;+}++.tablist a {+ display: block;+ padding: 0 20px;+ font-weight: bold;+ background-image:url('tab_s.png');+ background-repeat:no-repeat;+ background-position:right;+ color: #283A5D;+ text-shadow: 0px 1px 1px rgba(255, 255, 255, 0.9);+ text-decoration: none;+ outline: none;+}++.tabs3 .tablist a {+ padding: 0 10px;+}++.tablist a:hover {+ background-image: url('tab_h.png');+ background-repeat:repeat-x;+ color: #fff;+ text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);+ text-decoration: none;+}++.tablist li.current a {+ background-image: url('tab_a.png');+ background-repeat:repeat-x;+ color: #fff;+ text-shadow: 0px 1px 1px rgba(0, 0, 0, 1.0);+}
+ eigen3/doc/examples/.krazy view
@@ -0,0 +1,2 @@+EXCLUDE copyright+EXCLUDE license
+ eigen3/doc/examples/CMakeLists.txt view
@@ -0,0 +1,16 @@+file(GLOB examples_SRCS "*.cpp")++foreach(example_src ${examples_SRCS})+ get_filename_component(example ${example_src} NAME_WE)+ add_executable(${example} ${example_src})+ if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)+ target_link_libraries(${example} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})+ endif()+ add_custom_command(+ TARGET ${example}+ POST_BUILD+ COMMAND ${example}+ ARGS >${CMAKE_CURRENT_BINARY_DIR}/${example}.out+ )+ add_dependencies(all_examples ${example})+endforeach(example_src)
+ eigen3/doc/examples/DenseBase_middleCols_int.cpp view
@@ -0,0 +1,15 @@+#include <Eigen/Core>+#include <iostream>++using namespace Eigen;+using namespace std;++int main(void)+{+ int const N = 5;+ MatrixXi A(N,N);+ A.setRandom();+ cout << "A =\n" << A << '\n' << endl;+ cout << "A(1..3,:) =\n" << A.middleCols(1,3) << endl;+ return 0;+}
+ eigen3/doc/examples/DenseBase_middleRows_int.cpp view
@@ -0,0 +1,15 @@+#include <Eigen/Core>+#include <iostream>++using namespace Eigen;+using namespace std;++int main(void)+{+ int const N = 5;+ MatrixXi A(N,N);+ A.setRandom();+ cout << "A =\n" << A << '\n' << endl;+ cout << "A(2..3,:) =\n" << A.middleRows(2,2) << endl;+ return 0;+}
+ eigen3/doc/examples/DenseBase_template_int_middleCols.cpp view
@@ -0,0 +1,15 @@+#include <Eigen/Core>+#include <iostream>++using namespace Eigen;+using namespace std;++int main(void)+{+ int const N = 5;+ MatrixXi A(N,N);+ A.setRandom();+ cout << "A =\n" << A << '\n' << endl;+ cout << "A(:,1..3) =\n" << A.middleCols<3>(1) << endl;+ return 0;+}
+ eigen3/doc/examples/DenseBase_template_int_middleRows.cpp view
@@ -0,0 +1,15 @@+#include <Eigen/Core>+#include <iostream>++using namespace Eigen;+using namespace std;++int main(void)+{+ int const N = 5;+ MatrixXi A(N,N);+ A.setRandom();+ cout << "A =\n" << A << '\n' << endl;+ cout << "A(1..3,:) =\n" << A.middleRows<3>(1) << endl;+ return 0;+}
+ eigen3/doc/examples/MatrixBase_cwise_const.cpp view
@@ -0,0 +1,18 @@+#define EIGEN2_SUPPORT+#include <Eigen/Core>+#include <iostream>++using namespace Eigen;+using namespace std;++int main()+{+ Matrix3i m = Matrix3i::Random();+ cout << "Here is the matrix m:" << endl << m << endl;+ Matrix3i n = Matrix3i::Random();+ cout << "And here is the matrix n:" << endl << n << endl;+ cout << "The coefficient-wise product of m and n is:" << endl;+ cout << m.cwise() * n << endl;+ cout << "Taking the cube of the coefficients of m yields:" << endl;+ cout << m.cwise().pow(3) << endl;+}
+ eigen3/doc/examples/QuickStart_example.cpp view
@@ -0,0 +1,14 @@+#include <iostream>+#include <Eigen/Dense>++using Eigen::MatrixXd;++int main()+{+ MatrixXd m(2,2);+ m(0,0) = 3;+ m(1,0) = 2.5;+ m(0,1) = -1;+ m(1,1) = m(1,0) + m(0,1);+ std::cout << m << std::endl;+}
+ eigen3/doc/examples/QuickStart_example2_dynamic.cpp view
@@ -0,0 +1,15 @@+#include <iostream>+#include <Eigen/Dense>++using namespace Eigen;+using namespace std;++int main()+{+ MatrixXd m = MatrixXd::Random(3,3);+ m = (m + MatrixXd::Constant(3,3,1.2)) * 50;+ cout << "m =" << endl << m << endl;+ VectorXd v(3);+ v << 1, 2, 3;+ cout << "m * v =" << endl << m * v << endl;+}
+ eigen3/doc/examples/QuickStart_example2_fixed.cpp view
@@ -0,0 +1,15 @@+#include <iostream>+#include <Eigen/Dense>++using namespace Eigen;+using namespace std;++int main()+{+ Matrix3d m = Matrix3d::Random();+ m = (m + Matrix3d::Constant(1.2)) * 50;+ cout << "m =" << endl << m << endl;+ Vector3d v(1,2,3);+ + cout << "m * v =" << endl << m * v << endl;+}
+ eigen3/doc/examples/TemplateKeyword_flexible.cpp view
@@ -0,0 +1,22 @@+#include <Eigen/Dense>+#include <iostream>++using namespace Eigen;++template <typename Derived1, typename Derived2>+void copyUpperTriangularPart(MatrixBase<Derived1>& dst, const MatrixBase<Derived2>& src)+{+ /* Note the 'template' keywords in the following line! */+ dst.template triangularView<Upper>() = src.template triangularView<Upper>();+}++int main()+{+ MatrixXi m1 = MatrixXi::Ones(5,5);+ MatrixXi m2 = MatrixXi::Random(4,4);+ std::cout << "m2 before copy:" << std::endl;+ std::cout << m2 << std::endl << std::endl;+ copyUpperTriangularPart(m2, m1.topLeftCorner(4,4));+ std::cout << "m2 after copy:" << std::endl;+ std::cout << m2 << std::endl << std::endl;+}
+ eigen3/doc/examples/TemplateKeyword_simple.cpp view
@@ -0,0 +1,20 @@+#include <Eigen/Dense>+#include <iostream>++using namespace Eigen;++void copyUpperTriangularPart(MatrixXf& dst, const MatrixXf& src)+{+ dst.triangularView<Upper>() = src.triangularView<Upper>();+}++int main()+{+ MatrixXf m1 = MatrixXf::Ones(4,4);+ MatrixXf m2 = MatrixXf::Random(4,4);+ std::cout << "m2 before copy:" << std::endl;+ std::cout << m2 << std::endl << std::endl;+ copyUpperTriangularPart(m2, m1);+ std::cout << "m2 after copy:" << std::endl;+ std::cout << m2 << std::endl << std::endl;+}
+ eigen3/doc/examples/TutorialLinAlgComputeTwice.cpp view
@@ -0,0 +1,23 @@+#include <iostream>+#include <Eigen/Dense>++using namespace std;+using namespace Eigen;++int main()+{+ Matrix2f A, b;+ LLT<Matrix2f> llt;+ A << 2, -1, -1, 3;+ b << 1, 2, 3, 1;+ cout << "Here is the matrix A:\n" << A << endl;+ cout << "Here is the right hand side b:\n" << b << endl;+ cout << "Computing LLT decomposition..." << endl;+ llt.compute(A);+ cout << "The solution is:\n" << llt.solve(b) << endl;+ A(1,1)++;+ cout << "The matrix A is now:\n" << A << endl;+ cout << "Computing LLT decomposition..." << endl;+ llt.compute(A);+ cout << "The solution is now:\n" << llt.solve(b) << endl;+}
+ eigen3/doc/examples/TutorialLinAlgExComputeSolveError.cpp view
@@ -0,0 +1,14 @@+#include <iostream>+#include <Eigen/Dense>++using namespace std;+using namespace Eigen;++int main()+{+ MatrixXd A = MatrixXd::Random(100,100);+ MatrixXd b = MatrixXd::Random(100,50);+ MatrixXd x = A.fullPivLu().solve(b);+ double relative_error = (A*x - b).norm() / b.norm(); // norm() is L2 norm+ cout << "The relative error is:\n" << relative_error << endl;+}
+ eigen3/doc/examples/TutorialLinAlgExSolveColPivHouseholderQR.cpp view
@@ -0,0 +1,17 @@+#include <iostream>+#include <Eigen/Dense>++using namespace std;+using namespace Eigen;++int main()+{+ Matrix3f A;+ Vector3f b;+ A << 1,2,3, 4,5,6, 7,8,10;+ b << 3, 3, 4;+ cout << "Here is the matrix A:\n" << A << endl;+ cout << "Here is the vector b:\n" << b << endl;+ Vector3f x = A.colPivHouseholderQr().solve(b);+ cout << "The solution is:\n" << x << endl;+}
+ eigen3/doc/examples/TutorialLinAlgExSolveLDLT.cpp view
@@ -0,0 +1,16 @@+#include <iostream>+#include <Eigen/Dense>++using namespace std;+using namespace Eigen;++int main()+{+ Matrix2f A, b;+ A << 2, -1, -1, 3;+ b << 1, 2, 3, 1;+ cout << "Here is the matrix A:\n" << A << endl;+ cout << "Here is the right hand side b:\n" << b << endl;+ Matrix2f x = A.ldlt().solve(b);+ cout << "The solution is:\n" << x << endl;+}
+ eigen3/doc/examples/TutorialLinAlgInverseDeterminant.cpp view
@@ -0,0 +1,16 @@+#include <iostream>+#include <Eigen/Dense>++using namespace std;+using namespace Eigen;++int main()+{+ Matrix3f A;+ A << 1, 2, 1,+ 2, 1, 0,+ -1, 1, 2;+ cout << "Here is the matrix A:\n" << A << endl;+ cout << "The determinant of A is " << A.determinant() << endl;+ cout << "The inverse of A is:\n" << A.inverse() << endl;+}
+ eigen3/doc/examples/TutorialLinAlgRankRevealing.cpp view
@@ -0,0 +1,20 @@+#include <iostream>+#include <Eigen/Dense>++using namespace std;+using namespace Eigen;++int main()+{+ Matrix3f A;+ A << 1, 2, 5,+ 2, 1, 4,+ 3, 0, 3;+ cout << "Here is the matrix A:\n" << A << endl;+ FullPivLU<Matrix3f> lu_decomp(A);+ cout << "The rank of A is " << lu_decomp.rank() << endl;+ cout << "Here is a matrix whose columns form a basis of the null-space of A:\n"+ << lu_decomp.kernel() << endl;+ cout << "Here is a matrix whose columns form a basis of the column-space of A:\n"+ << lu_decomp.image(A) << endl; // yes, have to pass the original A+}
+ eigen3/doc/examples/TutorialLinAlgSVDSolve.cpp view
@@ -0,0 +1,15 @@+#include <iostream>+#include <Eigen/Dense>++using namespace std;+using namespace Eigen;++int main()+{+ MatrixXf A = MatrixXf::Random(3, 2);+ cout << "Here is the matrix A:\n" << A << endl;+ VectorXf b = VectorXf::Random(3);+ cout << "Here is the right hand side b:\n" << b << endl;+ cout << "The least-squares solution is:\n"+ << A.jacobiSvd(ComputeThinU | ComputeThinV).solve(b) << endl;+}
+ eigen3/doc/examples/TutorialLinAlgSelfAdjointEigenSolver.cpp view
@@ -0,0 +1,18 @@+#include <iostream>+#include <Eigen/Dense>++using namespace std;+using namespace Eigen;++int main()+{+ Matrix2f A;+ A << 1, 2, 2, 3;+ cout << "Here is the matrix A:\n" << A << endl;+ SelfAdjointEigenSolver<Matrix2f> eigensolver(A);+ if (eigensolver.info() != Success) abort();+ cout << "The eigenvalues of A are:\n" << eigensolver.eigenvalues() << endl;+ cout << "Here's a matrix whose columns are eigenvectors of A \n"+ << "corresponding to these eigenvalues:\n"+ << eigensolver.eigenvectors() << endl;+}
+ eigen3/doc/examples/TutorialLinAlgSetThreshold.cpp view
@@ -0,0 +1,16 @@+#include <iostream>+#include <Eigen/Dense>++using namespace std;+using namespace Eigen;++int main()+{+ Matrix2d A;+ A << 2, 1,+ 2, 0.9999999999;+ FullPivLU<Matrix2d> lu(A);+ cout << "By default, the rank of A is found to be " << lu.rank() << endl;+ lu.setThreshold(1e-5);+ cout << "With threshold 1e-5, the rank of A is found to be " << lu.rank() << endl;+}
+ eigen3/doc/examples/Tutorial_ArrayClass_accessors.cpp view
@@ -0,0 +1,24 @@+#include <Eigen/Dense>+#include <iostream>++using namespace Eigen;+using namespace std;++int main()+{+ ArrayXXf m(2,2);+ + // assign some values coefficient by coefficient+ m(0,0) = 1.0; m(0,1) = 2.0;+ m(1,0) = 3.0; m(1,1) = m(0,1) + m(1,0);+ + // print values to standard output+ cout << m << endl << endl;+ + // using the comma-initializer is also allowed+ m << 1.0,2.0,+ 3.0,4.0;+ + // print values to standard output+ cout << m << endl;+}
+ eigen3/doc/examples/Tutorial_ArrayClass_addition.cpp view
@@ -0,0 +1,23 @@+#include <Eigen/Dense>+#include <iostream>++using namespace Eigen;+using namespace std;++int main()+{+ ArrayXXf a(3,3);+ ArrayXXf b(3,3);+ a << 1,2,3,+ 4,5,6,+ 7,8,9;+ b << 1,2,3,+ 1,2,3,+ 1,2,3;+ + // Adding two arrays+ cout << "a + b = " << endl << a + b << endl << endl;++ // Subtracting a scalar from an array+ cout << "a - 2 = " << endl << a - 2 << endl;+}
+ eigen3/doc/examples/Tutorial_ArrayClass_cwise_other.cpp view
@@ -0,0 +1,19 @@+#include <Eigen/Dense>+#include <iostream>++using namespace Eigen;+using namespace std;++int main()+{+ ArrayXf a = ArrayXf::Random(5);+ a *= 2;+ cout << "a =" << endl + << a << endl;+ cout << "a.abs() =" << endl + << a.abs() << endl;+ cout << "a.abs().sqrt() =" << endl + << a.abs().sqrt() << endl;+ cout << "a.min(a.abs().sqrt()) =" << endl + << a.min(a.abs().sqrt()) << endl;+}
+ eigen3/doc/examples/Tutorial_ArrayClass_interop.cpp view
@@ -0,0 +1,22 @@+#include <Eigen/Dense>+#include <iostream>++using namespace Eigen;+using namespace std;++int main()+{+ MatrixXf m(2,2);+ MatrixXf n(2,2);+ MatrixXf result(2,2);++ m << 1,2,+ 3,4;+ n << 5,6,+ 7,8;+ + result = (m.array() + 4).matrix() * m;+ cout << "-- Combination 1: --" << endl << result << endl << endl;+ result = (m.array() * n.array()).matrix() * m;+ cout << "-- Combination 2: --" << endl << result << endl << endl;+}
+ eigen3/doc/examples/Tutorial_ArrayClass_interop_matrix.cpp view
@@ -0,0 +1,26 @@+#include <Eigen/Dense>+#include <iostream>++using namespace Eigen;+using namespace std;++int main()+{+ MatrixXf m(2,2);+ MatrixXf n(2,2);+ MatrixXf result(2,2);++ m << 1,2,+ 3,4;+ n << 5,6,+ 7,8;++ result = m * n;+ cout << "-- Matrix m*n: --" << endl << result << endl << endl;+ result = m.array() * n.array();+ cout << "-- Array m*n: --" << endl << result << endl << endl;+ result = m.cwiseProduct(n);+ cout << "-- With cwiseProduct: --" << endl << result << endl << endl;+ result = m.array() + 4;+ cout << "-- Array m + 4: --" << endl << result << endl << endl;+}
+ eigen3/doc/examples/Tutorial_ArrayClass_mult.cpp view
@@ -0,0 +1,16 @@+#include <Eigen/Dense>+#include <iostream>++using namespace Eigen;+using namespace std;++int main()+{+ ArrayXXf a(2,2);+ ArrayXXf b(2,2);+ a << 1,2,+ 3,4;+ b << 5,6,+ 7,8;+ cout << "a * b = " << endl << a * b << endl;+}
+ eigen3/doc/examples/Tutorial_BlockOperations_block_assignment.cpp view
@@ -0,0 +1,18 @@+#include <Eigen/Dense>+#include <iostream>++using namespace std;+using namespace Eigen;++int main()+{+ Array22f m;+ m << 1,2,+ 3,4;+ Array44f a = Array44f::Constant(0.6);+ cout << "Here is the array a:" << endl << a << endl << endl;+ a.block<2,2>(1,1) = m;+ cout << "Here is now a with m copied into its central 2x2 block:" << endl << a << endl << endl;+ a.block(0,0,2,3) = a.block(2,1,2,3);+ cout << "Here is now a with bottom-right 2x3 block copied into top-left 2x2 block:" << endl << a << endl << endl;+}
+ eigen3/doc/examples/Tutorial_BlockOperations_colrow.cpp view
@@ -0,0 +1,17 @@+#include <Eigen/Dense>+#include <iostream>++using namespace std;++int main()+{+ Eigen::MatrixXf m(3,3);+ m << 1,2,3,+ 4,5,6,+ 7,8,9;+ cout << "Here is the matrix m:" << endl << m << endl;+ cout << "2nd Row: " << m.row(1) << endl;+ m.col(2) += 3 * m.col(0);+ cout << "After adding 3 times the first column into the third column, the matrix m is:\n";+ cout << m << endl;+}
+ eigen3/doc/examples/Tutorial_BlockOperations_corner.cpp view
@@ -0,0 +1,17 @@+#include <Eigen/Dense>+#include <iostream>++using namespace std;++int main()+{+ Eigen::Matrix4f m;+ m << 1, 2, 3, 4,+ 5, 6, 7, 8,+ 9, 10,11,12,+ 13,14,15,16;+ cout << "m.leftCols(2) =" << endl << m.leftCols(2) << endl << endl;+ cout << "m.bottomRows<2>() =" << endl << m.bottomRows<2>() << endl << endl;+ m.topLeftCorner(1,3) = m.bottomRightCorner(3,1).transpose();+ cout << "After assignment, m = " << endl << m << endl;+}
+ eigen3/doc/examples/Tutorial_BlockOperations_print_block.cpp view
@@ -0,0 +1,20 @@+#include <Eigen/Dense>+#include <iostream>++using namespace std;++int main()+{+ Eigen::MatrixXf m(4,4);+ m << 1, 2, 3, 4,+ 5, 6, 7, 8,+ 9,10,11,12,+ 13,14,15,16;+ cout << "Block in the middle" << endl;+ cout << m.block<2,2>(1,1) << endl << endl;+ for (int i = 1; i <= 3; ++i)+ {+ cout << "Block of size " << i << "x" << i << endl;+ cout << m.block(0,0,i,i) << endl << endl;+ }+}
+ eigen3/doc/examples/Tutorial_BlockOperations_vector.cpp view
@@ -0,0 +1,14 @@+#include <Eigen/Dense>+#include <iostream>++using namespace std;++int main()+{+ Eigen::ArrayXf v(6);+ v << 1, 2, 3, 4, 5, 6;+ cout << "v.head(3) =" << endl << v.head(3) << endl << endl;+ cout << "v.tail<3>() = " << endl << v.tail<3>() << endl << endl;+ v.segment(1,4) *= 2;+ cout << "after 'v.segment(1,4) *= 2', v =" << endl << v << endl;+}
+ eigen3/doc/examples/Tutorial_PartialLU_solve.cpp view
@@ -0,0 +1,18 @@+#include <Eigen/Core>+#include <Eigen/LU>+#include <iostream>++using namespace std;+using namespace Eigen;++int main()+{+ Matrix3f A;+ Vector3f b;+ A << 1,2,3, 4,5,6, 7,8,10;+ b << 3, 3, 4;+ cout << "Here is the matrix A:" << endl << A << endl;+ cout << "Here is the vector b:" << endl << b << endl;+ Vector3f x = A.lu().solve(b);+ cout << "The solution is:" << endl << x << endl;+}
+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_broadcast_1nn.cpp view
@@ -0,0 +1,24 @@+#include <iostream>+#include <Eigen/Dense>++using namespace std;+using namespace Eigen;++int main()+{+ Eigen::MatrixXf m(2,4);+ Eigen::VectorXf v(2);+ + m << 1, 23, 6, 9,+ 3, 11, 7, 2;+ + v << 2,+ 3;++ MatrixXf::Index index;+ // find nearest neighbour+ (m.colwise() - v).colwise().squaredNorm().minCoeff(&index);++ cout << "Nearest neighbour is column " << index << ":" << endl;+ cout << m.col(index) << endl;+}
+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple.cpp view
@@ -0,0 +1,21 @@+#include <iostream>+#include <Eigen/Dense>++using namespace std;+int main()+{+ Eigen::MatrixXf mat(2,4);+ Eigen::VectorXf v(2);+ + mat << 1, 2, 6, 9,+ 3, 1, 7, 2;+ + v << 0,+ 1;+ + //add v to each column of m+ mat.colwise() += v;+ + std::cout << "Broadcasting result: " << std::endl;+ std::cout << mat << std::endl;+}
+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_broadcast_simple_rowwise.cpp view
@@ -0,0 +1,20 @@+#include <iostream>+#include <Eigen/Dense>++using namespace std;+int main()+{+ Eigen::MatrixXf mat(2,4);+ Eigen::VectorXf v(4);+ + mat << 1, 2, 6, 9,+ 3, 1, 7, 2;+ + v << 0,1,2,3;+ + //add v to each row of m+ mat.rowwise() += v.transpose();+ + std::cout << "Broadcasting result: " << std::endl;+ std::cout << mat << std::endl;+}
+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_colwise.cpp view
@@ -0,0 +1,13 @@+#include <iostream>+#include <Eigen/Dense>++using namespace std;+int main()+{+ Eigen::MatrixXf mat(2,4);+ mat << 1, 2, 6, 9,+ 3, 1, 7, 2;+ + std::cout << "Column's maximum: " << std::endl+ << mat.colwise().maxCoeff() << std::endl;+}
+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_maxnorm.cpp view
@@ -0,0 +1,20 @@+#include <iostream>+#include <Eigen/Dense>++using namespace std;+using namespace Eigen;+int main()+{+ MatrixXf mat(2,4);+ mat << 1, 2, 6, 9,+ 3, 1, 7, 2;+ + MatrixXf::Index maxIndex;+ float maxNorm = mat.colwise().sum().maxCoeff(&maxIndex);+ + std::cout << "Maximum sum at position " << maxIndex << std::endl;++ std::cout << "The corresponding vector is: " << std::endl;+ std::cout << mat.col( maxIndex ) << std::endl;+ std::cout << "And its sum is is: " << maxNorm << std::endl;+}
+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_reductions_bool.cpp view
@@ -0,0 +1,21 @@+#include <Eigen/Dense>+#include <iostream>++using namespace std;+using namespace Eigen;++int main()+{+ ArrayXXf a(2,2);+ + a << 1,2,+ 3,4;++ cout << "(a > 0).all() = " << (a > 0).all() << endl;+ cout << "(a > 0).any() = " << (a > 0).any() << endl;+ cout << "(a > 0).count() = " << (a > 0).count() << endl;+ cout << endl;+ cout << "(a > 2).all() = " << (a > 2).all() << endl;+ cout << "(a > 2).any() = " << (a > 2).any() << endl;+ cout << "(a > 2).count() = " << (a > 2).count() << endl;+}
+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_reductions_norm.cpp view
@@ -0,0 +1,28 @@+#include <Eigen/Dense>+#include <iostream>++using namespace std;+using namespace Eigen;++int main()+{+ VectorXf v(2);+ MatrixXf m(2,2), n(2,2);+ + v << -1,+ 2;+ + m << 1,-2,+ -3,4;++ cout << "v.squaredNorm() = " << v.squaredNorm() << endl;+ cout << "v.norm() = " << v.norm() << endl;+ cout << "v.lpNorm<1>() = " << v.lpNorm<1>() << endl;+ cout << "v.lpNorm<Infinity>() = " << v.lpNorm<Infinity>() << endl;++ cout << endl;+ cout << "m.squaredNorm() = " << m.squaredNorm() << endl;+ cout << "m.norm() = " << m.norm() << endl;+ cout << "m.lpNorm<1>() = " << m.lpNorm<1>() << endl;+ cout << "m.lpNorm<Infinity>() = " << m.lpNorm<Infinity>() << endl;+}
+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_rowwise.cpp view
@@ -0,0 +1,13 @@+#include <iostream>+#include <Eigen/Dense>++using namespace std;+int main()+{+ Eigen::MatrixXf mat(2,4);+ mat << 1, 2, 6, 9,+ 3, 1, 7, 2;+ + std::cout << "Row's maximum: " << std::endl+ << mat.rowwise().maxCoeff() << std::endl;+}
+ eigen3/doc/examples/Tutorial_ReductionsVisitorsBroadcasting_visitors.cpp view
@@ -0,0 +1,26 @@+#include <iostream>+#include <Eigen/Dense>++using namespace std;+using namespace Eigen;++int main()+{+ Eigen::MatrixXf m(2,2);+ + m << 1, 2,+ 3, 4;++ //get location of maximum+ MatrixXf::Index maxRow, maxCol;+ float max = m.maxCoeff(&maxRow, &maxCol);++ //get location of minimum+ MatrixXf::Index minRow, minCol;+ float min = m.minCoeff(&minRow, &minCol);++ cout << "Max: " << max << ", at: " <<+ maxRow << "," << maxCol << endl;+ cout << "Min: " << min << ", at: " <<+ minRow << "," << minCol << endl;+}
+ eigen3/doc/examples/Tutorial_simple_example_dynamic_size.cpp view
@@ -0,0 +1,22 @@+#include <Eigen/Core>+#include <iostream>++using namespace Eigen;++int main()+{+ for (int size=1; size<=4; ++size)+ {+ MatrixXi m(size,size+1); // a (size)x(size+1)-matrix of int's+ for (int j=0; j<m.cols(); ++j) // loop over columns+ for (int i=0; i<m.rows(); ++i) // loop over rows+ m(i,j) = i+j*m.rows(); // to access matrix coefficients,+ // use operator()(int,int)+ std::cout << m << "\n\n";+ }++ VectorXf v(4); // a vector of 4 float's+ // to access vector coefficients, use either operator () or operator []+ v[0] = 1; v[1] = 2; v(2) = 3; v(3) = 4;+ std::cout << "\nv:\n" << v << std::endl;+}
+ eigen3/doc/examples/Tutorial_simple_example_fixed_size.cpp view
@@ -0,0 +1,15 @@+#include <Eigen/Core>+#include <iostream>++using namespace Eigen;++int main()+{+ Matrix3f m3;+ m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9;+ Matrix4f m4 = Matrix4f::Identity();+ Vector4i v4(1, 2, 3, 4);++ std::cout << "m3\n" << m3 << "\nm4:\n"+ << m4 << "\nv4:\n" << v4 << std::endl;+}
+ eigen3/doc/examples/class_Block.cpp view
@@ -0,0 +1,27 @@+#include <Eigen/Core>+#include <iostream>+using namespace Eigen;+using namespace std;++template<typename Derived>+Eigen::Block<Derived>+topLeftCorner(MatrixBase<Derived>& m, int rows, int cols)+{+ return Eigen::Block<Derived>(m.derived(), 0, 0, rows, cols);+}++template<typename Derived>+const Eigen::Block<const Derived>+topLeftCorner(const MatrixBase<Derived>& m, int rows, int cols)+{+ return Eigen::Block<const Derived>(m.derived(), 0, 0, rows, cols);+}++int main(int, char**)+{+ Matrix4d m = Matrix4d::Identity();+ cout << topLeftCorner(4*m, 2, 3) << endl; // calls the const version+ topLeftCorner(m, 2, 3) *= 5; // calls the non-const version+ cout << "Now the matrix m is:" << endl << m << endl;+ return 0;+}
+ eigen3/doc/examples/class_CwiseBinaryOp.cpp view
@@ -0,0 +1,18 @@+#include <Eigen/Core>+#include <iostream>+using namespace Eigen;+using namespace std;++// define a custom template binary functor+template<typename Scalar> struct MakeComplexOp {+ EIGEN_EMPTY_STRUCT_CTOR(MakeComplexOp)+ typedef complex<Scalar> result_type;+ complex<Scalar> operator()(const Scalar& a, const Scalar& b) const { return complex<Scalar>(a,b); }+};++int main(int, char**)+{+ Matrix4d m1 = Matrix4d::Random(), m2 = Matrix4d::Random();+ cout << m1.binaryExpr(m2, MakeComplexOp<double>()) << endl;+ return 0;+}
+ eigen3/doc/examples/class_CwiseUnaryOp.cpp view
@@ -0,0 +1,19 @@+#include <Eigen/Core>+#include <iostream>+using namespace Eigen;+using namespace std;++// define a custom template unary functor+template<typename Scalar>+struct CwiseClampOp {+ CwiseClampOp(const Scalar& inf, const Scalar& sup) : m_inf(inf), m_sup(sup) {}+ const Scalar operator()(const Scalar& x) const { return x<m_inf ? m_inf : (x>m_sup ? m_sup : x); }+ Scalar m_inf, m_sup;+};++int main(int, char**)+{+ Matrix4d m1 = Matrix4d::Random();+ cout << m1 << endl << "becomes: " << endl << m1.unaryExpr(CwiseClampOp<double>(-0.5,0.5)) << endl;+ return 0;+}
+ eigen3/doc/examples/class_CwiseUnaryOp_ptrfun.cpp view
@@ -0,0 +1,20 @@+#include <Eigen/Core>+#include <iostream>+using namespace Eigen;+using namespace std;++// define function to be applied coefficient-wise+double ramp(double x)+{+ if (x > 0)+ return x;+ else + return 0;+}++int main(int, char**)+{+ Matrix4d m1 = Matrix4d::Random();+ cout << m1 << endl << "becomes: " << endl << m1.unaryExpr(ptr_fun(ramp)) << endl;+ return 0;+}
+ eigen3/doc/examples/class_FixedBlock.cpp view
@@ -0,0 +1,27 @@+#include <Eigen/Core>+#include <iostream>+using namespace Eigen;+using namespace std;++template<typename Derived>+Eigen::Block<Derived, 2, 2>+topLeft2x2Corner(MatrixBase<Derived>& m)+{+ return Eigen::Block<Derived, 2, 2>(m.derived(), 0, 0);+}++template<typename Derived>+const Eigen::Block<const Derived, 2, 2>+topLeft2x2Corner(const MatrixBase<Derived>& m)+{+ return Eigen::Block<const Derived, 2, 2>(m.derived(), 0, 0);+}++int main(int, char**)+{+ Matrix3d m = Matrix3d::Identity();+ cout << topLeft2x2Corner(4*m) << endl; // calls the const version+ topLeft2x2Corner(m) *= 2; // calls the non-const version+ cout << "Now the matrix m is:" << endl << m << endl;+ return 0;+}
+ eigen3/doc/examples/class_FixedVectorBlock.cpp view
@@ -0,0 +1,27 @@+#include <Eigen/Core>+#include <iostream>+using namespace Eigen;+using namespace std;++template<typename Derived>+Eigen::VectorBlock<Derived, 2>+firstTwo(MatrixBase<Derived>& v)+{+ return Eigen::VectorBlock<Derived, 2>(v.derived(), 0);+}++template<typename Derived>+const Eigen::VectorBlock<const Derived, 2>+firstTwo(const MatrixBase<Derived>& v)+{+ return Eigen::VectorBlock<const Derived, 2>(v.derived(), 0);+}++int main(int, char**)+{+ Matrix<int,1,6> v; v << 1,2,3,4,5,6;+ cout << firstTwo(4*v) << endl; // calls the const version+ firstTwo(v) *= 2; // calls the non-const version+ cout << "Now the vector v is:" << endl << v << endl;+ return 0;+}
+ eigen3/doc/examples/class_VectorBlock.cpp view
@@ -0,0 +1,27 @@+#include <Eigen/Core>+#include <iostream>+using namespace Eigen;+using namespace std;++template<typename Derived>+Eigen::VectorBlock<Derived>+segmentFromRange(MatrixBase<Derived>& v, int start, int end)+{+ return Eigen::VectorBlock<Derived>(v.derived(), start, end-start);+}++template<typename Derived>+const Eigen::VectorBlock<const Derived>+segmentFromRange(const MatrixBase<Derived>& v, int start, int end)+{+ return Eigen::VectorBlock<const Derived>(v.derived(), start, end-start);+}++int main(int, char**)+{+ Matrix<int,1,6> v; v << 1,2,3,4,5,6;+ cout << segmentFromRange(2*v, 2, 4) << endl; // calls the const version+ segmentFromRange(v, 1, 3) *= 5; // calls the non-const version+ cout << "Now the vector v is:" << endl << v << endl;+ return 0;+}
+ eigen3/doc/examples/function_taking_eigenbase.cpp view
@@ -0,0 +1,18 @@+#include <iostream>+#include <Eigen/Core>+using namespace Eigen;++template <typename Derived>+void print_size(const EigenBase<Derived>& b)+{+ std::cout << "size (rows, cols): " << b.size() << " (" << b.rows()+ << ", " << b.cols() << ")" << std::endl;+}++int main()+{+ Vector3f v;+ print_size(v);+ // v.asDiagonal() returns a 3x3 diagonal matrix pseudo-expression+ print_size(v.asDiagonal());+}
+ eigen3/doc/examples/function_taking_ref.cpp view
@@ -0,0 +1,19 @@+#include <iostream>+#include <Eigen/SVD>+using namespace Eigen;+using namespace std;++float inv_cond(const Ref<const MatrixXf>& a)+{+ const VectorXf sing_vals = a.jacobiSvd().singularValues();+ return sing_vals(sing_vals.size()-1) / sing_vals(0);+}++int main()+{+ Matrix4f m = Matrix4f::Random();+ cout << "matrix m:" << endl << m << endl << endl;+ cout << "inv_cond(m): " << inv_cond(m) << endl;+ cout << "inv_cond(m(1:3,1:3)): " << inv_cond(m.topLeftCorner(3,3)) << endl;+ cout << "inv_cond(m+I): " << inv_cond(m+Matrix4f::Identity()) << endl;+}
+ eigen3/doc/examples/tut_arithmetic_add_sub.cpp view
@@ -0,0 +1,22 @@+#include <iostream>+#include <Eigen/Dense>++using namespace Eigen;++int main()+{+ Matrix2d a;+ a << 1, 2,+ 3, 4;+ MatrixXd b(2,2);+ b << 2, 3,+ 1, 4;+ std::cout << "a + b =\n" << a + b << std::endl;+ std::cout << "a - b =\n" << a - b << std::endl;+ std::cout << "Doing a += b;" << std::endl;+ a += b;+ std::cout << "Now a =\n" << a << std::endl;+ Vector3d v(1,2,3);+ Vector3d w(1,0,0);+ std::cout << "-v + w - v =\n" << -v + w - v << std::endl;+}
+ eigen3/doc/examples/tut_arithmetic_dot_cross.cpp view
@@ -0,0 +1,15 @@+#include <iostream>+#include <Eigen/Dense>++using namespace Eigen;+using namespace std;+int main()+{+ Vector3d v(1,2,3);+ Vector3d w(0,1,2);++ cout << "Dot product: " << v.dot(w) << endl;+ double dp = v.adjoint()*w; // automatic conversion of the inner product to a scalar+ cout << "Dot product via a matrix product: " << dp << endl;+ cout << "Cross product:\n" << v.cross(w) << endl;+}
+ eigen3/doc/examples/tut_arithmetic_matrix_mul.cpp view
@@ -0,0 +1,19 @@+#include <iostream>+#include <Eigen/Dense>++using namespace Eigen;+int main()+{+ Matrix2d mat;+ mat << 1, 2,+ 3, 4;+ Vector2d u(-1,1), v(2,0);+ std::cout << "Here is mat*mat:\n" << mat*mat << std::endl;+ std::cout << "Here is mat*u:\n" << mat*u << std::endl;+ std::cout << "Here is u^T*mat:\n" << u.transpose()*mat << std::endl;+ std::cout << "Here is u^T*v:\n" << u.transpose()*v << std::endl;+ std::cout << "Here is u*v^T:\n" << u*v.transpose() << std::endl;+ std::cout << "Let's multiply mat by itself" << std::endl;+ mat = mat*mat;+ std::cout << "Now mat is mat:\n" << mat << std::endl;+}
+ eigen3/doc/examples/tut_arithmetic_redux_basic.cpp view
@@ -0,0 +1,16 @@+#include <iostream>+#include <Eigen/Dense>++using namespace std;+int main()+{+ Eigen::Matrix2d mat;+ mat << 1, 2,+ 3, 4;+ cout << "Here is mat.sum(): " << mat.sum() << endl;+ cout << "Here is mat.prod(): " << mat.prod() << endl;+ cout << "Here is mat.mean(): " << mat.mean() << endl;+ cout << "Here is mat.minCoeff(): " << mat.minCoeff() << endl;+ cout << "Here is mat.maxCoeff(): " << mat.maxCoeff() << endl;+ cout << "Here is mat.trace(): " << mat.trace() << endl;+}
+ eigen3/doc/examples/tut_arithmetic_scalar_mul_div.cpp view
@@ -0,0 +1,17 @@+#include <iostream>+#include <Eigen/Dense>++using namespace Eigen;++int main()+{+ Matrix2d a;+ a << 1, 2,+ 3, 4;+ Vector3d v(1,2,3);+ std::cout << "a * 2.5 =\n" << a * 2.5 << std::endl;+ std::cout << "0.1 * v =\n" << 0.1 * v << std::endl;+ std::cout << "Doing v *= 2;" << std::endl;+ v *= 2;+ std::cout << "Now v =\n" << v << std::endl;+}
+ eigen3/doc/examples/tut_matrix_coefficient_accessors.cpp view
@@ -0,0 +1,18 @@+#include <iostream>+#include <Eigen/Dense>++using namespace Eigen;++int main()+{+ MatrixXd m(2,2);+ m(0,0) = 3;+ m(1,0) = 2.5;+ m(0,1) = -1;+ m(1,1) = m(1,0) + m(0,1);+ std::cout << "Here is the matrix m:\n" << m << std::endl;+ VectorXd v(2);+ v(0) = 4;+ v(1) = v(0) - 1;+ std::cout << "Here is the vector v:\n" << v << std::endl;+}
+ eigen3/doc/examples/tut_matrix_resize.cpp view
@@ -0,0 +1,18 @@+#include <iostream>+#include <Eigen/Dense>++using namespace Eigen;++int main()+{+ MatrixXd m(2,5);+ m.resize(4,3);+ std::cout << "The matrix m is of size "+ << m.rows() << "x" << m.cols() << std::endl;+ std::cout << "It has " << m.size() << " coefficients" << std::endl;+ VectorXd v(2);+ v.resize(5);+ std::cout << "The vector v is of size " << v.size() << std::endl;+ std::cout << "As a matrix, v is of size "+ << v.rows() << "x" << v.cols() << std::endl;+}
+ eigen3/doc/examples/tut_matrix_resize_fixed_size.cpp view
@@ -0,0 +1,12 @@+#include <iostream>+#include <Eigen/Dense>++using namespace Eigen;++int main()+{+ Matrix4d m;+ m.resize(4,4); // no operation+ std::cout << "The matrix m is of size "+ << m.rows() << "x" << m.cols() << std::endl;+}
+ eigen3/doc/snippets/.krazy view
@@ -0,0 +1,2 @@+EXCLUDE copyright+EXCLUDE license
+ eigen3/doc/snippets/AngleAxis_mimic_euler.cpp view
@@ -0,0 +1,5 @@+Matrix3f m;+m = AngleAxisf(0.25*M_PI, Vector3f::UnitX())+ * AngleAxisf(0.5*M_PI, Vector3f::UnitY())+ * AngleAxisf(0.33*M_PI, Vector3f::UnitZ());+cout << m << endl << "is unitary: " << m.isUnitary() << endl;
+ eigen3/doc/snippets/CMakeLists.txt view
@@ -0,0 +1,28 @@+file(GLOB snippets_SRCS "*.cpp")++add_custom_target(all_snippets)++foreach(snippet_src ${snippets_SRCS})+ get_filename_component(snippet ${snippet_src} NAME_WE)+ set(compile_snippet_target compile_${snippet})+ set(compile_snippet_src ${compile_snippet_target}.cpp)+ file(READ ${snippet_src} snippet_source_code)+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/compile_snippet.cpp.in+ ${CMAKE_CURRENT_BINARY_DIR}/${compile_snippet_src})+ add_executable(${compile_snippet_target}+ ${CMAKE_CURRENT_BINARY_DIR}/${compile_snippet_src})+ if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)+ target_link_libraries(${compile_snippet_target} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})+ endif()+ add_custom_command(+ TARGET ${compile_snippet_target}+ POST_BUILD+ COMMAND ${compile_snippet_target}+ ARGS >${CMAKE_CURRENT_BINARY_DIR}/${snippet}.out+ )+ add_dependencies(all_snippets ${compile_snippet_target})+ set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${compile_snippet_src}+ PROPERTIES OBJECT_DEPENDS ${snippet_src})+endforeach(snippet_src)++ei_add_target_property(compile_tut_arithmetic_transpose_aliasing COMPILE_FLAGS -DEIGEN_NO_DEBUG)
+ eigen3/doc/snippets/ColPivHouseholderQR_solve.cpp view
@@ -0,0 +1,8 @@+Matrix3f m = Matrix3f::Random();+Matrix3f y = Matrix3f::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the matrix y:" << endl << y << endl;+Matrix3f x;+x = m.colPivHouseholderQr().solve(y);+assert(y.isApprox(m*x));+cout << "Here is a solution x to the equation mx=y:" << endl << x << endl;
+ eigen3/doc/snippets/ComplexEigenSolver_compute.cpp view
@@ -0,0 +1,16 @@+MatrixXcf A = MatrixXcf::Random(4,4);+cout << "Here is a random 4x4 matrix, A:" << endl << A << endl << endl;++ComplexEigenSolver<MatrixXcf> ces;+ces.compute(A);+cout << "The eigenvalues of A are:" << endl << ces.eigenvalues() << endl;+cout << "The matrix of eigenvectors, V, is:" << endl << ces.eigenvectors() << endl << endl;++complex<float> lambda = ces.eigenvalues()[0];+cout << "Consider the first eigenvalue, lambda = " << lambda << endl;+VectorXcf v = ces.eigenvectors().col(0);+cout << "If v is the corresponding eigenvector, then lambda * v = " << endl << lambda * v << endl;+cout << "... and A * v = " << endl << A * v << endl << endl;++cout << "Finally, V * D * V^(-1) = " << endl+ << ces.eigenvectors() * ces.eigenvalues().asDiagonal() * ces.eigenvectors().inverse() << endl;
+ eigen3/doc/snippets/ComplexEigenSolver_eigenvalues.cpp view
@@ -0,0 +1,4 @@+MatrixXcf ones = MatrixXcf::Ones(3,3);+ComplexEigenSolver<MatrixXcf> ces(ones, /* computeEigenvectors = */ false);+cout << "The eigenvalues of the 3x3 matrix of ones are:" + << endl << ces.eigenvalues() << endl;
+ eigen3/doc/snippets/ComplexEigenSolver_eigenvectors.cpp view
@@ -0,0 +1,4 @@+MatrixXcf ones = MatrixXcf::Ones(3,3);+ComplexEigenSolver<MatrixXcf> ces(ones);+cout << "The first eigenvector of the 3x3 matrix of ones is:" + << endl << ces.eigenvectors().col(1) << endl;
+ eigen3/doc/snippets/ComplexSchur_compute.cpp view
@@ -0,0 +1,6 @@+MatrixXcf A = MatrixXcf::Random(4,4);+ComplexSchur<MatrixXcf> schur(4);+schur.compute(A);+cout << "The matrix T in the decomposition of A is:" << endl << schur.matrixT() << endl;+schur.compute(A.inverse());+cout << "The matrix T in the decomposition of A^(-1) is:" << endl << schur.matrixT() << endl;
+ eigen3/doc/snippets/ComplexSchur_matrixT.cpp view
@@ -0,0 +1,4 @@+MatrixXcf A = MatrixXcf::Random(4,4);+cout << "Here is a random 4x4 matrix, A:" << endl << A << endl << endl;+ComplexSchur<MatrixXcf> schurOfA(A, false); // false means do not compute U+cout << "The triangular matrix T is:" << endl << schurOfA.matrixT() << endl;
+ eigen3/doc/snippets/ComplexSchur_matrixU.cpp view
@@ -0,0 +1,4 @@+MatrixXcf A = MatrixXcf::Random(4,4);+cout << "Here is a random 4x4 matrix, A:" << endl << A << endl << endl;+ComplexSchur<MatrixXcf> schurOfA(A);+cout << "The unitary matrix U is:" << endl << schurOfA.matrixU() << endl;
+ eigen3/doc/snippets/Cwise_abs.cpp view
@@ -0,0 +1,2 @@+Array3d v(1,-2,-3);+cout << v.abs() << endl;
+ eigen3/doc/snippets/Cwise_abs2.cpp view
@@ -0,0 +1,2 @@+Array3d v(1,-2,-3);+cout << v.abs2() << endl;
+ eigen3/doc/snippets/Cwise_acos.cpp view
@@ -0,0 +1,2 @@+Array3d v(0, sqrt(2.)/2, 1);+cout << v.acos() << endl;
+ eigen3/doc/snippets/Cwise_asin.cpp view
@@ -0,0 +1,2 @@+Array3d v(0, sqrt(2.)/2, 1);+cout << v.asin() << endl;
+ eigen3/doc/snippets/Cwise_boolean_and.cpp view
@@ -0,0 +1,2 @@+Array3d v(-1,2,1), w(-3,2,3);+cout << ((v<w) && (v<0)) << endl;
+ eigen3/doc/snippets/Cwise_boolean_or.cpp view
@@ -0,0 +1,2 @@+Array3d v(-1,2,1), w(-3,2,3);+cout << ((v<w) || (v<0)) << endl;
+ eigen3/doc/snippets/Cwise_cos.cpp view
@@ -0,0 +1,2 @@+Array3d v(M_PI, M_PI/2, M_PI/3);+cout << v.cos() << endl;
+ eigen3/doc/snippets/Cwise_cube.cpp view
@@ -0,0 +1,2 @@+Array3d v(2,3,4);+cout << v.cube() << endl;
+ eigen3/doc/snippets/Cwise_equal_equal.cpp view
@@ -0,0 +1,2 @@+Array3d v(1,2,3), w(3,2,1);+cout << (v==w) << endl;
+ eigen3/doc/snippets/Cwise_exp.cpp view
@@ -0,0 +1,2 @@+Array3d v(1,2,3);+cout << v.exp() << endl;
+ eigen3/doc/snippets/Cwise_greater.cpp view
@@ -0,0 +1,2 @@+Array3d v(1,2,3), w(3,2,1);+cout << (v>w) << endl;
+ eigen3/doc/snippets/Cwise_greater_equal.cpp view
@@ -0,0 +1,2 @@+Array3d v(1,2,3), w(3,2,1);+cout << (v>=w) << endl;
+ eigen3/doc/snippets/Cwise_inverse.cpp view
@@ -0,0 +1,2 @@+Array3d v(2,3,4);+cout << v.inverse() << endl;
+ eigen3/doc/snippets/Cwise_less.cpp view
@@ -0,0 +1,2 @@+Array3d v(1,2,3), w(3,2,1);+cout << (v<w) << endl;
+ eigen3/doc/snippets/Cwise_less_equal.cpp view
@@ -0,0 +1,2 @@+Array3d v(1,2,3), w(3,2,1);+cout << (v<=w) << endl;
+ eigen3/doc/snippets/Cwise_log.cpp view
@@ -0,0 +1,2 @@+Array3d v(1,2,3);+cout << v.log() << endl;
+ eigen3/doc/snippets/Cwise_max.cpp view
@@ -0,0 +1,2 @@+Array3d v(2,3,4), w(4,2,3);+cout << v.max(w) << endl;
+ eigen3/doc/snippets/Cwise_min.cpp view
@@ -0,0 +1,2 @@+Array3d v(2,3,4), w(4,2,3);+cout << v.min(w) << endl;
+ eigen3/doc/snippets/Cwise_minus.cpp view
@@ -0,0 +1,2 @@+Array3d v(1,2,3);+cout << v-5 << endl;
+ eigen3/doc/snippets/Cwise_minus_equal.cpp view
@@ -0,0 +1,3 @@+Array3d v(1,2,3);+v -= 5;+cout << v << endl;
+ eigen3/doc/snippets/Cwise_not_equal.cpp view
@@ -0,0 +1,2 @@+Array3d v(1,2,3), w(3,2,1);+cout << (v!=w) << endl;
+ eigen3/doc/snippets/Cwise_plus.cpp view
@@ -0,0 +1,2 @@+Array3d v(1,2,3);+cout << v+5 << endl;
+ eigen3/doc/snippets/Cwise_plus_equal.cpp view
@@ -0,0 +1,3 @@+Array3d v(1,2,3);+v += 5;+cout << v << endl;
+ eigen3/doc/snippets/Cwise_pow.cpp view
@@ -0,0 +1,2 @@+Array3d v(8,27,64);+cout << v.pow(0.333333) << endl;
+ eigen3/doc/snippets/Cwise_product.cpp view
@@ -0,0 +1,4 @@+Array33i a = Array33i::Random(), b = Array33i::Random();+Array33i c = a * b;+cout << "a:\n" << a << "\nb:\n" << b << "\nc:\n" << c << endl;+
+ eigen3/doc/snippets/Cwise_quotient.cpp view
@@ -0,0 +1,2 @@+Array3d v(2,3,4), w(4,2,3);+cout << v/w << endl;
+ eigen3/doc/snippets/Cwise_sin.cpp view
@@ -0,0 +1,2 @@+Array3d v(M_PI, M_PI/2, M_PI/3);+cout << v.sin() << endl;
+ eigen3/doc/snippets/Cwise_slash_equal.cpp view
@@ -0,0 +1,3 @@+Array3d v(3,2,4), w(5,4,2);+v /= w;+cout << v << endl;
+ eigen3/doc/snippets/Cwise_sqrt.cpp view
@@ -0,0 +1,2 @@+Array3d v(1,2,4);+cout << v.sqrt() << endl;
+ eigen3/doc/snippets/Cwise_square.cpp view
@@ -0,0 +1,2 @@+Array3d v(2,3,4);+cout << v.square() << endl;
+ eigen3/doc/snippets/Cwise_tan.cpp view
@@ -0,0 +1,2 @@+Array3d v(M_PI, M_PI/2, M_PI/3);+cout << v.tan() << endl;
+ eigen3/doc/snippets/Cwise_times_equal.cpp view
@@ -0,0 +1,3 @@+Array3d v(1,2,3), w(2,3,0);+v *= w;+cout << v << endl;
+ eigen3/doc/snippets/DenseBase_LinSpaced.cpp view
@@ -0,0 +1,2 @@+cout << VectorXi::LinSpaced(4,7,10).transpose() << endl;+cout << VectorXd::LinSpaced(5,0.0,1.0).transpose() << endl;
+ eigen3/doc/snippets/DenseBase_LinSpaced_seq.cpp view
@@ -0,0 +1,2 @@+cout << VectorXi::LinSpaced(Sequential,4,7,10).transpose() << endl;+cout << VectorXd::LinSpaced(Sequential,5,0.0,1.0).transpose() << endl;
+ eigen3/doc/snippets/DenseBase_setLinSpaced.cpp view
@@ -0,0 +1,3 @@+VectorXf v;+v.setLinSpaced(5,0.5f,1.5f);+cout << v << endl;
+ eigen3/doc/snippets/DirectionWise_replicate.cpp view
@@ -0,0 +1,4 @@+MatrixXi m = MatrixXi::Random(2,3);+cout << "Here is the matrix m:" << endl << m << endl;+cout << "m.colwise().replicate<3>() = ..." << endl;+cout << m.colwise().replicate<3>() << endl;
+ eigen3/doc/snippets/DirectionWise_replicate_int.cpp view
@@ -0,0 +1,4 @@+Vector3i v = Vector3i::Random();+cout << "Here is the vector v:" << endl << v << endl;+cout << "v.rowwise().replicate(5) = ..." << endl;+cout << v.rowwise().replicate(5) << endl;
+ eigen3/doc/snippets/EigenSolver_EigenSolver_MatrixType.cpp view
@@ -0,0 +1,16 @@+MatrixXd A = MatrixXd::Random(6,6);+cout << "Here is a random 6x6 matrix, A:" << endl << A << endl << endl;++EigenSolver<MatrixXd> es(A);+cout << "The eigenvalues of A are:" << endl << es.eigenvalues() << endl;+cout << "The matrix of eigenvectors, V, is:" << endl << es.eigenvectors() << endl << endl;++complex<double> lambda = es.eigenvalues()[0];+cout << "Consider the first eigenvalue, lambda = " << lambda << endl;+VectorXcd v = es.eigenvectors().col(0);+cout << "If v is the corresponding eigenvector, then lambda * v = " << endl << lambda * v << endl;+cout << "... and A * v = " << endl << A.cast<complex<double> >() * v << endl << endl;++MatrixXcd D = es.eigenvalues().asDiagonal();+MatrixXcd V = es.eigenvectors();+cout << "Finally, V * D * V^(-1) = " << endl << V * D * V.inverse() << endl;
+ eigen3/doc/snippets/EigenSolver_compute.cpp view
@@ -0,0 +1,6 @@+EigenSolver<MatrixXf> es;+MatrixXf A = MatrixXf::Random(4,4);+es.compute(A, /* computeEigenvectors = */ false);+cout << "The eigenvalues of A are: " << es.eigenvalues().transpose() << endl;+es.compute(A + MatrixXf::Identity(4,4), false); // re-use es to compute eigenvalues of A+I+cout << "The eigenvalues of A+I are: " << es.eigenvalues().transpose() << endl;
+ eigen3/doc/snippets/EigenSolver_eigenvalues.cpp view
@@ -0,0 +1,4 @@+MatrixXd ones = MatrixXd::Ones(3,3);+EigenSolver<MatrixXd> es(ones, false);+cout << "The eigenvalues of the 3x3 matrix of ones are:" + << endl << es.eigenvalues() << endl;
+ eigen3/doc/snippets/EigenSolver_eigenvectors.cpp view
@@ -0,0 +1,4 @@+MatrixXd ones = MatrixXd::Ones(3,3);+EigenSolver<MatrixXd> es(ones);+cout << "The first eigenvector of the 3x3 matrix of ones is:" + << endl << es.eigenvectors().col(1) << endl;
+ eigen3/doc/snippets/EigenSolver_pseudoEigenvectors.cpp view
@@ -0,0 +1,9 @@+MatrixXd A = MatrixXd::Random(6,6);+cout << "Here is a random 6x6 matrix, A:" << endl << A << endl << endl;++EigenSolver<MatrixXd> es(A);+MatrixXd D = es.pseudoEigenvalueMatrix();+MatrixXd V = es.pseudoEigenvectors();+cout << "The pseudo-eigenvalue matrix D is:" << endl << D << endl;+cout << "The pseudo-eigenvector matrix V is:" << endl << V << endl;+cout << "Finally, V * D * V^(-1) = " << endl << V * D * V.inverse() << endl;
+ eigen3/doc/snippets/FullPivHouseholderQR_solve.cpp view
@@ -0,0 +1,8 @@+Matrix3f m = Matrix3f::Random();+Matrix3f y = Matrix3f::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the matrix y:" << endl << y << endl;+Matrix3f x;+x = m.fullPivHouseholderQr().solve(y);+assert(y.isApprox(m*x));+cout << "Here is a solution x to the equation mx=y:" << endl << x << endl;
+ eigen3/doc/snippets/FullPivLU_image.cpp view
@@ -0,0 +1,9 @@+Matrix3d m;+m << 1,1,0,+ 1,3,2,+ 0,1,1;+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Notice that the middle column is the sum of the two others, so the "+ << "columns are linearly dependent." << endl;+cout << "Here is a matrix whose columns have the same span but are linearly independent:"+ << endl << m.fullPivLu().image(m) << endl;
+ eigen3/doc/snippets/FullPivLU_kernel.cpp view
@@ -0,0 +1,7 @@+MatrixXf m = MatrixXf::Random(3,5);+cout << "Here is the matrix m:" << endl << m << endl;+MatrixXf ker = m.fullPivLu().kernel();+cout << "Here is a matrix whose columns form a basis of the kernel of m:"+ << endl << ker << endl;+cout << "By definition of the kernel, m*ker is zero:"+ << endl << m*ker << endl;
+ eigen3/doc/snippets/FullPivLU_solve.cpp view
@@ -0,0 +1,11 @@+Matrix<float,2,3> m = Matrix<float,2,3>::Random();+Matrix2f y = Matrix2f::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the matrix y:" << endl << y << endl;+Matrix<float,3,2> x = m.fullPivLu().solve(y);+if((m*x).isApprox(y))+{+ cout << "Here is a solution x to the equation mx=y:" << endl << x << endl;+}+else+ cout << "The equation mx=y does not have any solution." << endl;
+ eigen3/doc/snippets/GeneralizedEigenSolver.cpp view
@@ -0,0 +1,7 @@+GeneralizedEigenSolver<MatrixXf> ges;+MatrixXf A = MatrixXf::Random(4,4);+MatrixXf B = MatrixXf::Random(4,4);+ges.compute(A, B);+cout << "The (complex) numerators of the generalzied eigenvalues are: " << ges.alphas().transpose() << endl;+cout << "The (real) denominatore of the generalzied eigenvalues are: " << ges.betas().transpose() << endl;+cout << "The (complex) generalzied eigenvalues are (alphas./beta): " << ges.eigenvalues().transpose() << endl;
+ eigen3/doc/snippets/HessenbergDecomposition_compute.cpp view
@@ -0,0 +1,6 @@+MatrixXcf A = MatrixXcf::Random(4,4);+HessenbergDecomposition<MatrixXcf> hd(4);+hd.compute(A);+cout << "The matrix H in the decomposition of A is:" << endl << hd.matrixH() << endl;+hd.compute(2*A); // re-use hd to compute and store decomposition of 2A+cout << "The matrix H in the decomposition of 2A is:" << endl << hd.matrixH() << endl;
+ eigen3/doc/snippets/HessenbergDecomposition_matrixH.cpp view
@@ -0,0 +1,8 @@+Matrix4f A = MatrixXf::Random(4,4);+cout << "Here is a random 4x4 matrix:" << endl << A << endl;+HessenbergDecomposition<MatrixXf> hessOfA(A);+MatrixXf H = hessOfA.matrixH();+cout << "The Hessenberg matrix H is:" << endl << H << endl;+MatrixXf Q = hessOfA.matrixQ();+cout << "The orthogonal matrix Q is:" << endl << Q << endl;+cout << "Q H Q^T is:" << endl << Q * H * Q.transpose() << endl;
+ eigen3/doc/snippets/HessenbergDecomposition_packedMatrix.cpp view
@@ -0,0 +1,9 @@+Matrix4d A = Matrix4d::Random(4,4);+cout << "Here is a random 4x4 matrix:" << endl << A << endl;+HessenbergDecomposition<Matrix4d> hessOfA(A);+Matrix4d pm = hessOfA.packedMatrix();+cout << "The packed matrix M is:" << endl << pm << endl;+cout << "The upper Hessenberg part corresponds to the matrix H, which is:" + << endl << hessOfA.matrixH() << endl;+Vector3d hc = hessOfA.householderCoefficients();+cout << "The vector of Householder coefficients is:" << endl << hc << endl;
+ eigen3/doc/snippets/HouseholderQR_householderQ.cpp view
@@ -0,0 +1,7 @@+MatrixXf A(MatrixXf::Random(5,3)), thinQ(MatrixXf::Identity(5,3)), Q;+A.setRandom();+HouseholderQR<MatrixXf> qr(A);+Q = qr.householderQ();+thinQ = qr.householderQ() * thinQ;+std::cout << "The complete unitary matrix Q is:\n" << Q << "\n\n";+std::cout << "The thin matrix Q is:\n" << thinQ << "\n\n";
+ eigen3/doc/snippets/HouseholderQR_solve.cpp view
@@ -0,0 +1,9 @@+typedef Matrix<float,3,3> Matrix3x3;+Matrix3x3 m = Matrix3x3::Random();+Matrix3f y = Matrix3f::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the matrix y:" << endl << y << endl;+Matrix3f x;+x = m.householderQr().solve(y);+assert(y.isApprox(m*x));+cout << "Here is a solution x to the equation mx=y:" << endl << x << endl;
+ eigen3/doc/snippets/HouseholderSequence_HouseholderSequence.cpp view
@@ -0,0 +1,31 @@+Matrix3d v = Matrix3d::Random();+cout << "The matrix v is:" << endl;+cout << v << endl;++Vector3d v0(1, v(1,0), v(2,0));+cout << "The first Householder vector is: v_0 = " << v0.transpose() << endl;+Vector3d v1(0, 1, v(2,1));+cout << "The second Householder vector is: v_1 = " << v1.transpose() << endl;+Vector3d v2(0, 0, 1);+cout << "The third Householder vector is: v_2 = " << v2.transpose() << endl;++Vector3d h = Vector3d::Random();+cout << "The Householder coefficients are: h = " << h.transpose() << endl;++Matrix3d H0 = Matrix3d::Identity() - h(0) * v0 * v0.adjoint();+cout << "The first Householder reflection is represented by H_0 = " << endl;+cout << H0 << endl;+Matrix3d H1 = Matrix3d::Identity() - h(1) * v1 * v1.adjoint();+cout << "The second Householder reflection is represented by H_1 = " << endl;+cout << H1 << endl;+Matrix3d H2 = Matrix3d::Identity() - h(2) * v2 * v2.adjoint();+cout << "The third Householder reflection is represented by H_2 = " << endl;+cout << H2 << endl;+cout << "Their product is H_0 H_1 H_2 = " << endl;+cout << H0 * H1 * H2 << endl;++HouseholderSequence<Matrix3d, Vector3d> hhSeq(v, h);+Matrix3d hhSeqAsMatrix(hhSeq);+cout << "If we construct a HouseholderSequence from v and h" << endl;+cout << "and convert it to a matrix, we get:" << endl;+cout << hhSeqAsMatrix << endl;
+ eigen3/doc/snippets/IOFormat.cpp view
@@ -0,0 +1,14 @@+std::string sep = "\n----------------------------------------\n";+Matrix3d m1;+m1 << 1.111111, 2, 3.33333, 4, 5, 6, 7, 8.888888, 9;++IOFormat CommaInitFmt(StreamPrecision, DontAlignCols, ", ", ", ", "", "", " << ", ";");+IOFormat CleanFmt(4, 0, ", ", "\n", "[", "]");+IOFormat OctaveFmt(StreamPrecision, 0, ", ", ";\n", "", "", "[", "]");+IOFormat HeavyFmt(FullPrecision, 0, ", ", ";\n", "[", "]", "[", "]");++std::cout << m1 << sep;+std::cout << m1.format(CommaInitFmt) << sep;+std::cout << m1.format(CleanFmt) << sep;+std::cout << m1.format(OctaveFmt) << sep;+std::cout << m1.format(HeavyFmt) << sep;
+ eigen3/doc/snippets/JacobiSVD_basic.cpp view
@@ -0,0 +1,9 @@+MatrixXf m = MatrixXf::Random(3,2);+cout << "Here is the matrix m:" << endl << m << endl;+JacobiSVD<MatrixXf> svd(m, ComputeThinU | ComputeThinV);+cout << "Its singular values are:" << endl << svd.singularValues() << endl;+cout << "Its left singular vectors are the columns of the thin U matrix:" << endl << svd.matrixU() << endl;+cout << "Its right singular vectors are the columns of the thin V matrix:" << endl << svd.matrixV() << endl;+Vector3f rhs(1, 0, 0);+cout << "Now consider this rhs vector:" << endl << rhs << endl;+cout << "A least-squares solution of m*x = rhs is:" << endl << svd.solve(rhs) << endl;
+ eigen3/doc/snippets/Jacobi_makeGivens.cpp view
@@ -0,0 +1,6 @@+Vector2f v = Vector2f::Random();+JacobiRotation<float> G;+G.makeGivens(v.x(), v.y());+cout << "Here is the vector v:" << endl << v << endl;+v.applyOnTheLeft(0, 1, G.adjoint());+cout << "Here is the vector J' * v:" << endl << v << endl;
+ eigen3/doc/snippets/Jacobi_makeJacobi.cpp view
@@ -0,0 +1,8 @@+Matrix2f m = Matrix2f::Random();+m = (m + m.adjoint()).eval();+JacobiRotation<float> J;+J.makeJacobi(m, 0, 1);+cout << "Here is the matrix m:" << endl << m << endl;+m.applyOnTheLeft(0, 1, J.adjoint());+m.applyOnTheRight(0, 1, J);+cout << "Here is the matrix J' * m * J:" << endl << m << endl;
+ eigen3/doc/snippets/LLT_example.cpp view
@@ -0,0 +1,12 @@+MatrixXd A(3,3);+A << 4,-1,2, -1,6,0, 2,0,5;+cout << "The matrix A is" << endl << A << endl;++LLT<MatrixXd> lltOfA(A); // compute the Cholesky decomposition of A+MatrixXd L = lltOfA.matrixL(); // retrieve factor L in the decomposition+// The previous two lines can also be written as "L = A.llt().matrixL()"++cout << "The Cholesky factor L is" << endl << L << endl;+cout << "To check this, let us compute L * L.transpose()" << endl;+cout << L * L.transpose() << endl;+cout << "This should equal the matrix A" << endl;
+ eigen3/doc/snippets/LLT_solve.cpp view
@@ -0,0 +1,8 @@+typedef Matrix<float,Dynamic,2> DataMatrix;+// let's generate some samples on the 3D plane of equation z = 2x+3y (with some noise)+DataMatrix samples = DataMatrix::Random(12,2);+VectorXf elevations = 2*samples.col(0) + 3*samples.col(1) + VectorXf::Random(12)*0.1;+// and let's solve samples * [x y]^T = elevations in least square sense:+Matrix<float,2,1> xy+ = (samples.adjoint() * samples).llt().solve((samples.adjoint()*elevations));+cout << xy << endl;
+ eigen3/doc/snippets/Map_general_stride.cpp view
@@ -0,0 +1,5 @@+int array[24];+for(int i = 0; i < 24; ++i) array[i] = i;+cout << Map<MatrixXi, 0, Stride<Dynamic,2> >+ (array, 3, 3, Stride<Dynamic,2>(8, 2))+ << endl;
+ eigen3/doc/snippets/Map_inner_stride.cpp view
@@ -0,0 +1,5 @@+int array[12];+for(int i = 0; i < 12; ++i) array[i] = i;+cout << Map<VectorXi, 0, InnerStride<2> >+ (array, 6) // the inner stride has already been passed as template parameter+ << endl;
+ eigen3/doc/snippets/Map_outer_stride.cpp view
@@ -0,0 +1,3 @@+int array[12];+for(int i = 0; i < 12; ++i) array[i] = i;+cout << Map<MatrixXi, 0, OuterStride<> >(array, 3, 3, OuterStride<>(4)) << endl;
+ eigen3/doc/snippets/Map_placement_new.cpp view
@@ -0,0 +1,5 @@+int data[] = {1,2,3,4,5,6,7,8,9};+Map<RowVectorXi> v(data,4);+cout << "The mapped vector v is: " << v << "\n";+new (&v) Map<RowVectorXi>(data+4,5);+cout << "Now v is: " << v << "\n";
+ eigen3/doc/snippets/Map_simple.cpp view
@@ -0,0 +1,3 @@+int array[9];+for(int i = 0; i < 9; ++i) array[i] = i;+cout << Map<Matrix3i>(array) << endl;
+ eigen3/doc/snippets/MatrixBase_adjoint.cpp view
@@ -0,0 +1,3 @@+Matrix2cf m = Matrix2cf::Random();+cout << "Here is the 2x2 complex matrix m:" << endl << m << endl;+cout << "Here is the adjoint of m:" << endl << m.adjoint() << endl;
+ eigen3/doc/snippets/MatrixBase_all.cpp view
@@ -0,0 +1,7 @@+Vector3f boxMin(Vector3f::Zero()), boxMax(Vector3f::Ones());+Vector3f p0 = Vector3f::Random(), p1 = Vector3f::Random().cwiseAbs();+// let's check if p0 and p1 are inside the axis aligned box defined by the corners boxMin,boxMax:+cout << "Is (" << p0.transpose() << ") inside the box: "+ << ((boxMin.array()<p0.array()).all() && (boxMax.array()>p0.array()).all()) << endl;+cout << "Is (" << p1.transpose() << ") inside the box: "+ << ((boxMin.array()<p1.array()).all() && (boxMax.array()>p1.array()).all()) << endl;
+ eigen3/doc/snippets/MatrixBase_applyOnTheLeft.cpp view
@@ -0,0 +1,7 @@+Matrix3f A = Matrix3f::Random(3,3), B;+B << 0,1,0, + 0,0,1, + 1,0,0;+cout << "At start, A = " << endl << A << endl;+A.applyOnTheLeft(B); +cout << "After applyOnTheLeft, A = " << endl << A << endl;
+ eigen3/doc/snippets/MatrixBase_applyOnTheRight.cpp view
@@ -0,0 +1,9 @@+Matrix3f A = Matrix3f::Random(3,3), B;+B << 0,1,0, + 0,0,1, + 1,0,0;+cout << "At start, A = " << endl << A << endl;+A *= B;+cout << "After A *= B, A = " << endl << A << endl;+A.applyOnTheRight(B); // equivalent to A *= B+cout << "After applyOnTheRight, A = " << endl << A << endl;
+ eigen3/doc/snippets/MatrixBase_array.cpp view
@@ -0,0 +1,4 @@+Vector3d v(1,2,3);+v.array() += 3;+v.array() -= 2;+cout << v << endl;
+ eigen3/doc/snippets/MatrixBase_array_const.cpp view
@@ -0,0 +1,4 @@+Vector3d v(-1,2,-3);+cout << "the absolute values:" << endl << v.array().abs() << endl;+cout << "the absolute values plus one:" << endl << v.array().abs()+1 << endl;+cout << "sum of the squares: " << v.array().square().sum() << endl;
+ eigen3/doc/snippets/MatrixBase_asDiagonal.cpp view
@@ -0,0 +1,1 @@+cout << Matrix3i(Vector3i(2,5,6).asDiagonal()) << endl;
+ eigen3/doc/snippets/MatrixBase_block_int_int.cpp view
@@ -0,0 +1,5 @@+Matrix4i m = Matrix4i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is m.block<2,2>(1,1):" << endl << m.block<2,2>(1,1) << endl;+m.block<2,2>(1,1).setZero();+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_block_int_int_int_int.cpp view
@@ -0,0 +1,5 @@+Matrix4i m = Matrix4i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is m.block(1, 1, 2, 2):" << endl << m.block(1, 1, 2, 2) << endl;+m.block(1, 1, 2, 2).setZero();+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_bottomLeftCorner_int_int.cpp view
@@ -0,0 +1,6 @@+Matrix4i m = Matrix4i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is m.bottomLeftCorner(2, 2):" << endl;+cout << m.bottomLeftCorner(2, 2) << endl;+m.bottomLeftCorner(2, 2).setZero();+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_bottomRightCorner_int_int.cpp view
@@ -0,0 +1,6 @@+Matrix4i m = Matrix4i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is m.bottomRightCorner(2, 2):" << endl;+cout << m.bottomRightCorner(2, 2) << endl;+m.bottomRightCorner(2, 2).setZero();+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_bottomRows_int.cpp view
@@ -0,0 +1,6 @@+Array44i a = Array44i::Random();+cout << "Here is the array a:" << endl << a << endl;+cout << "Here is a.bottomRows(2):" << endl;+cout << a.bottomRows(2) << endl;+a.bottomRows(2).setZero();+cout << "Now the array a is:" << endl << a << endl;
+ eigen3/doc/snippets/MatrixBase_cast.cpp view
@@ -0,0 +1,3 @@+Matrix2d md = Matrix2d::Identity() * 0.45;+Matrix2f mf = Matrix2f::Identity();+cout << md + mf.cast<double>() << endl;
+ eigen3/doc/snippets/MatrixBase_col.cpp view
@@ -0,0 +1,3 @@+Matrix3d m = Matrix3d::Identity();+m.col(1) = Vector3d(4,5,6);+cout << m << endl;
+ eigen3/doc/snippets/MatrixBase_colwise.cpp view
@@ -0,0 +1,5 @@+Matrix3d m = Matrix3d::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the sum of each column:" << endl << m.colwise().sum() << endl;+cout << "Here is the maximum absolute value of each column:"+ << endl << m.cwiseAbs().colwise().maxCoeff() << endl;
+ eigen3/doc/snippets/MatrixBase_computeInverseAndDetWithCheck.cpp view
@@ -0,0 +1,13 @@+Matrix3d m = Matrix3d::Random();+cout << "Here is the matrix m:" << endl << m << endl;+Matrix3d inverse;+bool invertible;+double determinant;+m.computeInverseAndDetWithCheck(inverse,determinant,invertible);+cout << "Its determinant is " << determinant << endl;+if(invertible) {+ cout << "It is invertible, and its inverse is:" << endl << inverse << endl;+}+else {+ cout << "It is not invertible." << endl;+}
+ eigen3/doc/snippets/MatrixBase_computeInverseWithCheck.cpp view
@@ -0,0 +1,11 @@+Matrix3d m = Matrix3d::Random();+cout << "Here is the matrix m:" << endl << m << endl;+Matrix3d inverse;+bool invertible;+m.computeInverseWithCheck(inverse,invertible);+if(invertible) {+ cout << "It is invertible, and its inverse is:" << endl << inverse << endl;+}+else {+ cout << "It is not invertible." << endl;+}
+ eigen3/doc/snippets/MatrixBase_cwiseAbs.cpp view
@@ -0,0 +1,4 @@+MatrixXd m(2,3);+m << 2, -4, 6, + -5, 1, 0;+cout << m.cwiseAbs() << endl;
+ eigen3/doc/snippets/MatrixBase_cwiseAbs2.cpp view
@@ -0,0 +1,4 @@+MatrixXd m(2,3);+m << 2, -4, 6, + -5, 1, 0;+cout << m.cwiseAbs2() << endl;
+ eigen3/doc/snippets/MatrixBase_cwiseEqual.cpp view
@@ -0,0 +1,7 @@+MatrixXi m(2,2);+m << 1, 0,+ 1, 1;+cout << "Comparing m with identity matrix:" << endl;+cout << m.cwiseEqual(MatrixXi::Identity(2,2)) << endl;+int count = m.cwiseEqual(MatrixXi::Identity(2,2)).count();+cout << "Number of coefficients that are equal: " << count << endl;
+ eigen3/doc/snippets/MatrixBase_cwiseInverse.cpp view
@@ -0,0 +1,4 @@+MatrixXd m(2,3);+m << 2, 0.5, 1, + 3, 0.25, 1;+cout << m.cwiseInverse() << endl;
+ eigen3/doc/snippets/MatrixBase_cwiseMax.cpp view
@@ -0,0 +1,2 @@+Vector3d v(2,3,4), w(4,2,3);+cout << v.cwiseMax(w) << endl;
+ eigen3/doc/snippets/MatrixBase_cwiseMin.cpp view
@@ -0,0 +1,2 @@+Vector3d v(2,3,4), w(4,2,3);+cout << v.cwiseMin(w) << endl;
+ eigen3/doc/snippets/MatrixBase_cwiseNotEqual.cpp view
@@ -0,0 +1,7 @@+MatrixXi m(2,2);+m << 1, 0,+ 1, 1;+cout << "Comparing m with identity matrix:" << endl;+cout << m.cwiseNotEqual(MatrixXi::Identity(2,2)) << endl;+int count = m.cwiseNotEqual(MatrixXi::Identity(2,2)).count();+cout << "Number of coefficients that are not equal: " << count << endl;
+ eigen3/doc/snippets/MatrixBase_cwiseProduct.cpp view
@@ -0,0 +1,4 @@+Matrix3i a = Matrix3i::Random(), b = Matrix3i::Random();+Matrix3i c = a.cwiseProduct(b);+cout << "a:\n" << a << "\nb:\n" << b << "\nc:\n" << c << endl;+
+ eigen3/doc/snippets/MatrixBase_cwiseQuotient.cpp view
@@ -0,0 +1,2 @@+Vector3d v(2,3,4), w(4,2,3);+cout << v.cwiseQuotient(w) << endl;
+ eigen3/doc/snippets/MatrixBase_cwiseSqrt.cpp view
@@ -0,0 +1,2 @@+Vector3d v(1,2,4);+cout << v.cwiseSqrt() << endl;
+ eigen3/doc/snippets/MatrixBase_diagonal.cpp view
@@ -0,0 +1,4 @@+Matrix3i m = Matrix3i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here are the coefficients on the main diagonal of m:" << endl+ << m.diagonal() << endl;
+ eigen3/doc/snippets/MatrixBase_diagonal_int.cpp view
@@ -0,0 +1,5 @@+Matrix4i m = Matrix4i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here are the coefficients on the 1st super-diagonal and 2nd sub-diagonal of m:" << endl+ << m.diagonal(1).transpose() << endl+ << m.diagonal(-2).transpose() << endl;
+ eigen3/doc/snippets/MatrixBase_diagonal_template_int.cpp view
@@ -0,0 +1,5 @@+Matrix4i m = Matrix4i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here are the coefficients on the 1st super-diagonal and 2nd sub-diagonal of m:" << endl+ << m.diagonal<1>().transpose() << endl+ << m.diagonal<-2>().transpose() << endl;
+ eigen3/doc/snippets/MatrixBase_eigenvalues.cpp view
@@ -0,0 +1,3 @@+MatrixXd ones = MatrixXd::Ones(3,3);+VectorXcd eivals = ones.eigenvalues();+cout << "The eigenvalues of the 3x3 matrix of ones are:" << endl << eivals << endl;
+ eigen3/doc/snippets/MatrixBase_end_int.cpp view
@@ -0,0 +1,5 @@+RowVector4i v = RowVector4i::Random();+cout << "Here is the vector v:" << endl << v << endl;+cout << "Here is v.tail(2):" << endl << v.tail(2) << endl;+v.tail(2).setZero();+cout << "Now the vector v is:" << endl << v << endl;
+ eigen3/doc/snippets/MatrixBase_eval.cpp view
@@ -0,0 +1,12 @@+Matrix2f M = Matrix2f::Random();+Matrix2f m;+m = M;+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Now we want to copy a column into a row." << endl;+cout << "If we do m.col(1) = m.row(0), then m becomes:" << endl;+m.col(1) = m.row(0);+cout << m << endl << "which is wrong!" << endl;+cout << "Now let us instead do m.col(1) = m.row(0).eval(). Then m becomes" << endl;+m = M;+m.col(1) = m.row(0).eval();+cout << m << endl << "which is right." << endl;
+ eigen3/doc/snippets/MatrixBase_extract.cpp view
@@ -0,0 +1,13 @@+#ifndef _MSC_VER+ #warning deprecated+#endif+/* deprecated+Matrix3i m = Matrix3i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the upper-triangular matrix extracted from m:" << endl+ << m.part<Eigen::UpperTriangular>() << endl;+cout << "Here is the strictly-upper-triangular matrix extracted from m:" << endl+ << m.part<Eigen::StrictlyUpperTriangular>() << endl;+cout << "Here is the unit-lower-triangular matrix extracted from m:" << endl+ << m.part<Eigen::UnitLowerTriangular>() << endl;+*/
+ eigen3/doc/snippets/MatrixBase_fixedBlock_int_int.cpp view
@@ -0,0 +1,5 @@+Matrix4d m = Vector4d(1,2,3,4).asDiagonal();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is m.fixed<2, 2>(2, 2):" << endl << m.block<2, 2>(2, 2) << endl;+m.block<2, 2>(2, 0) = m.block<2, 2>(2, 2);+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_identity.cpp view
@@ -0,0 +1,1 @@+cout << Matrix<double, 3, 4>::Identity() << endl;
+ eigen3/doc/snippets/MatrixBase_identity_int_int.cpp view
@@ -0,0 +1,1 @@+cout << MatrixXd::Identity(4, 3) << endl;
+ eigen3/doc/snippets/MatrixBase_inverse.cpp view
@@ -0,0 +1,3 @@+Matrix3d m = Matrix3d::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Its inverse is:" << endl << m.inverse() << endl;
+ eigen3/doc/snippets/MatrixBase_isDiagonal.cpp view
@@ -0,0 +1,6 @@+Matrix3d m = 10000 * Matrix3d::Identity();+m(0,2) = 1;+cout << "Here's the matrix m:" << endl << m << endl;+cout << "m.isDiagonal() returns: " << m.isDiagonal() << endl;+cout << "m.isDiagonal(1e-3) returns: " << m.isDiagonal(1e-3) << endl;+
+ eigen3/doc/snippets/MatrixBase_isIdentity.cpp view
@@ -0,0 +1,5 @@+Matrix3d m = Matrix3d::Identity();+m(0,2) = 1e-4;+cout << "Here's the matrix m:" << endl << m << endl;+cout << "m.isIdentity() returns: " << m.isIdentity() << endl;+cout << "m.isIdentity(1e-3) returns: " << m.isIdentity(1e-3) << endl;
+ eigen3/doc/snippets/MatrixBase_isOnes.cpp view
@@ -0,0 +1,5 @@+Matrix3d m = Matrix3d::Ones();+m(0,2) += 1e-4;+cout << "Here's the matrix m:" << endl << m << endl;+cout << "m.isOnes() returns: " << m.isOnes() << endl;+cout << "m.isOnes(1e-3) returns: " << m.isOnes(1e-3) << endl;
+ eigen3/doc/snippets/MatrixBase_isOrthogonal.cpp view
@@ -0,0 +1,6 @@+Vector3d v(1,0,0);+Vector3d w(1e-4,0,1);+cout << "Here's the vector v:" << endl << v << endl;+cout << "Here's the vector w:" << endl << w << endl;+cout << "v.isOrthogonal(w) returns: " << v.isOrthogonal(w) << endl;+cout << "v.isOrthogonal(w,1e-3) returns: " << v.isOrthogonal(w,1e-3) << endl;
+ eigen3/doc/snippets/MatrixBase_isUnitary.cpp view
@@ -0,0 +1,5 @@+Matrix3d m = Matrix3d::Identity();+m(0,2) = 1e-4;+cout << "Here's the matrix m:" << endl << m << endl;+cout << "m.isUnitary() returns: " << m.isUnitary() << endl;+cout << "m.isUnitary(1e-3) returns: " << m.isUnitary(1e-3) << endl;
+ eigen3/doc/snippets/MatrixBase_isZero.cpp view
@@ -0,0 +1,5 @@+Matrix3d m = Matrix3d::Zero();+m(0,2) = 1e-4;+cout << "Here's the matrix m:" << endl << m << endl;+cout << "m.isZero() returns: " << m.isZero() << endl;+cout << "m.isZero(1e-3) returns: " << m.isZero(1e-3) << endl;
+ eigen3/doc/snippets/MatrixBase_leftCols_int.cpp view
@@ -0,0 +1,6 @@+Array44i a = Array44i::Random();+cout << "Here is the array a:" << endl << a << endl;+cout << "Here is a.leftCols(2):" << endl;+cout << a.leftCols(2) << endl;+a.leftCols(2).setZero();+cout << "Now the array a is:" << endl << a << endl;
+ eigen3/doc/snippets/MatrixBase_marked.cpp view
@@ -0,0 +1,14 @@+#ifndef _MSC_VER+ #warning deprecated+#endif+/*+Matrix3d m = Matrix3d::Zero();+m.part<Eigen::UpperTriangular>().setOnes();+cout << "Here is the matrix m:" << endl << m << endl;+Matrix3d n = Matrix3d::Ones();+n.part<Eigen::LowerTriangular>() *= 2;+cout << "Here is the matrix n:" << endl << n << endl;+cout << "And now here is m.inverse()*n, taking advantage of the fact that"+ " m is upper-triangular:" << endl+ << m.marked<Eigen::UpperTriangular>().solveTriangular(n);+*/
+ eigen3/doc/snippets/MatrixBase_noalias.cpp view
@@ -0,0 +1,3 @@+Matrix2d a, b, c; a << 1,2,3,4; b << 5,6,7,8;+c.noalias() = a * b; // this computes the product directly to c+cout << c << endl;
+ eigen3/doc/snippets/MatrixBase_ones.cpp view
@@ -0,0 +1,2 @@+cout << Matrix2d::Ones() << endl;+cout << 6 * RowVector4i::Ones() << endl;
+ eigen3/doc/snippets/MatrixBase_ones_int.cpp view
@@ -0,0 +1,2 @@+cout << 6 * RowVectorXi::Ones(4) << endl;+cout << VectorXf::Ones(2) << endl;
+ eigen3/doc/snippets/MatrixBase_ones_int_int.cpp view
@@ -0,0 +1,1 @@+cout << MatrixXi::Ones(2,3) << endl;
+ eigen3/doc/snippets/MatrixBase_operatorNorm.cpp view
@@ -0,0 +1,3 @@+MatrixXd ones = MatrixXd::Ones(3,3);+cout << "The operator norm of the 3x3 matrix of ones is "+ << ones.operatorNorm() << endl;
+ eigen3/doc/snippets/MatrixBase_part.cpp view
@@ -0,0 +1,13 @@+#ifndef _MSC_VER+ #warning deprecated+#endif+/*+Matrix3d m = Matrix3d::Zero();+m.part<Eigen::StrictlyUpperTriangular>().setOnes();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "And let us now compute m*m.adjoint() in a very optimized way" << endl+ << "taking advantage of the symmetry." << endl;+Matrix3d n;+n.part<Eigen::SelfAdjoint>() = (m*m.adjoint()).lazy();+cout << "The result is:" << endl << n << endl;+*/
+ eigen3/doc/snippets/MatrixBase_prod.cpp view
@@ -0,0 +1,3 @@+Matrix3d m = Matrix3d::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the product of all the coefficients:" << endl << m.prod() << endl;
+ eigen3/doc/snippets/MatrixBase_random.cpp view
@@ -0,0 +1,1 @@+cout << 100 * Matrix2i::Random() << endl;
+ eigen3/doc/snippets/MatrixBase_random_int.cpp view
@@ -0,0 +1,1 @@+cout << VectorXi::Random(2) << endl;
+ eigen3/doc/snippets/MatrixBase_random_int_int.cpp view
@@ -0,0 +1,1 @@+cout << MatrixXi::Random(2,3) << endl;
+ eigen3/doc/snippets/MatrixBase_replicate.cpp view
@@ -0,0 +1,4 @@+MatrixXi m = MatrixXi::Random(2,3);+cout << "Here is the matrix m:" << endl << m << endl;+cout << "m.replicate<3,2>() = ..." << endl;+cout << m.replicate<3,2>() << endl;
+ eigen3/doc/snippets/MatrixBase_replicate_int_int.cpp view
@@ -0,0 +1,4 @@+Vector3i v = Vector3i::Random();+cout << "Here is the vector v:" << endl << v << endl;+cout << "v.replicate(2,5) = ..." << endl;+cout << v.replicate(2,5) << endl;
+ eigen3/doc/snippets/MatrixBase_reverse.cpp view
@@ -0,0 +1,8 @@+MatrixXi m = MatrixXi::Random(3,4);+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the reverse of m:" << endl << m.reverse() << endl;+cout << "Here is the coefficient (1,0) in the reverse of m:" << endl+ << m.reverse()(1,0) << endl;+cout << "Let us overwrite this coefficient with the value 4." << endl;+m.reverse()(1,0) = 4;+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_rightCols_int.cpp view
@@ -0,0 +1,6 @@+Array44i a = Array44i::Random();+cout << "Here is the array a:" << endl << a << endl;+cout << "Here is a.rightCols(2):" << endl;+cout << a.rightCols(2) << endl;+a.rightCols(2).setZero();+cout << "Now the array a is:" << endl << a << endl;
+ eigen3/doc/snippets/MatrixBase_row.cpp view
@@ -0,0 +1,3 @@+Matrix3d m = Matrix3d::Identity();+m.row(1) = Vector3d(4,5,6);+cout << m << endl;
+ eigen3/doc/snippets/MatrixBase_rowwise.cpp view
@@ -0,0 +1,5 @@+Matrix3d m = Matrix3d::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the sum of each row:" << endl << m.rowwise().sum() << endl;+cout << "Here is the maximum absolute value of each row:"+ << endl << m.cwiseAbs().rowwise().maxCoeff() << endl;
+ eigen3/doc/snippets/MatrixBase_segment_int_int.cpp view
@@ -0,0 +1,5 @@+RowVector4i v = RowVector4i::Random();+cout << "Here is the vector v:" << endl << v << endl;+cout << "Here is v.segment(1, 2):" << endl << v.segment(1, 2) << endl;+v.segment(1, 2).setZero();+cout << "Now the vector v is:" << endl << v << endl;
+ eigen3/doc/snippets/MatrixBase_select.cpp view
@@ -0,0 +1,6 @@+MatrixXi m(3, 3);+m << 1, 2, 3,+ 4, 5, 6,+ 7, 8, 9;+m = (m.array() >= 5).select(-m, m);+cout << m << endl;
+ eigen3/doc/snippets/MatrixBase_set.cpp view
@@ -0,0 +1,13 @@+Matrix3i m1;+m1 << 1, 2, 3,+ 4, 5, 6,+ 7, 8, 9;+cout << m1 << endl << endl;+Matrix3i m2 = Matrix3i::Identity();+m2.block(0,0, 2,2) << 10, 11, 12, 13;+cout << m2 << endl << endl;+Vector2i v1;+v1 << 14, 15;+m2 << v1.transpose(), 16,+ v1, m1.block(1,1,2,2);+cout << m2 << endl;
+ eigen3/doc/snippets/MatrixBase_setIdentity.cpp view
@@ -0,0 +1,3 @@+Matrix4i m = Matrix4i::Zero();+m.block<3,3>(1,0).setIdentity();+cout << m << endl;
+ eigen3/doc/snippets/MatrixBase_setOnes.cpp view
@@ -0,0 +1,3 @@+Matrix4i m = Matrix4i::Random();+m.row(1).setOnes();+cout << m << endl;
+ eigen3/doc/snippets/MatrixBase_setRandom.cpp view
@@ -0,0 +1,3 @@+Matrix4i m = Matrix4i::Zero();+m.col(1).setRandom();+cout << m << endl;
+ eigen3/doc/snippets/MatrixBase_setZero.cpp view
@@ -0,0 +1,3 @@+Matrix4i m = Matrix4i::Random();+m.row(1).setZero();+cout << m << endl;
+ eigen3/doc/snippets/MatrixBase_start_int.cpp view
@@ -0,0 +1,5 @@+RowVector4i v = RowVector4i::Random();+cout << "Here is the vector v:" << endl << v << endl;+cout << "Here is v.head(2):" << endl << v.head(2) << endl;+v.head(2).setZero();+cout << "Now the vector v is:" << endl << v << endl;
+ eigen3/doc/snippets/MatrixBase_template_int_bottomRows.cpp view
@@ -0,0 +1,6 @@+Array44i a = Array44i::Random();+cout << "Here is the array a:" << endl << a << endl;+cout << "Here is a.bottomRows<2>():" << endl;+cout << a.bottomRows<2>() << endl;+a.bottomRows<2>().setZero();+cout << "Now the array a is:" << endl << a << endl;
+ eigen3/doc/snippets/MatrixBase_template_int_end.cpp view
@@ -0,0 +1,5 @@+RowVector4i v = RowVector4i::Random();+cout << "Here is the vector v:" << endl << v << endl;+cout << "Here is v.tail(2):" << endl << v.tail<2>() << endl;+v.tail<2>().setZero();+cout << "Now the vector v is:" << endl << v << endl;
+ eigen3/doc/snippets/MatrixBase_template_int_int_block_int_int_int_int.cpp view
@@ -0,0 +1,5 @@+Matrix4i m = Matrix4i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the block:" << endl << m.block<2, Dynamic>(1, 1, 2, 3) << endl;+m.block<2, Dynamic>(1, 1, 2, 3).setZero();+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_template_int_int_bottomLeftCorner.cpp view
@@ -0,0 +1,6 @@+Matrix4i m = Matrix4i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is m.bottomLeftCorner<2,2>():" << endl;+cout << m.bottomLeftCorner<2,2>() << endl;+m.bottomLeftCorner<2,2>().setZero();+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_template_int_int_bottomLeftCorner_int_int.cpp view
@@ -0,0 +1,6 @@+Matrix4i m = Matrix4i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is m.bottomLeftCorner<2,Dynamic>(2,2):" << endl;+cout << m.bottomLeftCorner<2,Dynamic>(2,2) << endl;+m.bottomLeftCorner<2,Dynamic>(2,2).setZero();+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_template_int_int_bottomRightCorner.cpp view
@@ -0,0 +1,6 @@+Matrix4i m = Matrix4i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is m.bottomRightCorner<2,2>():" << endl;+cout << m.bottomRightCorner<2,2>() << endl;+m.bottomRightCorner<2,2>().setZero();+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_template_int_int_bottomRightCorner_int_int.cpp view
@@ -0,0 +1,6 @@+Matrix4i m = Matrix4i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is m.bottomRightCorner<2,Dynamic>(2,2):" << endl;+cout << m.bottomRightCorner<2,Dynamic>(2,2) << endl;+m.bottomRightCorner<2,Dynamic>(2,2).setZero();+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_template_int_int_topLeftCorner.cpp view
@@ -0,0 +1,6 @@+Matrix4i m = Matrix4i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is m.topLeftCorner<2,2>():" << endl;+cout << m.topLeftCorner<2,2>() << endl;+m.topLeftCorner<2,2>().setZero();+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_template_int_int_topLeftCorner_int_int.cpp view
@@ -0,0 +1,6 @@+Matrix4i m = Matrix4i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is m.topLeftCorner<2,Dynamic>(2,2):" << endl;+cout << m.topLeftCorner<2,Dynamic>(2,2) << endl;+m.topLeftCorner<2,Dynamic>(2,2).setZero();+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_template_int_int_topRightCorner.cpp view
@@ -0,0 +1,6 @@+Matrix4i m = Matrix4i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is m.topRightCorner<2,2>():" << endl;+cout << m.topRightCorner<2,2>() << endl;+m.topRightCorner<2,2>().setZero();+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_template_int_int_topRightCorner_int_int.cpp view
@@ -0,0 +1,6 @@+Matrix4i m = Matrix4i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is m.topRightCorner<2,Dynamic>(2,2):" << endl;+cout << m.topRightCorner<2,Dynamic>(2,2) << endl;+m.topRightCorner<2,Dynamic>(2,2).setZero();+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_template_int_leftCols.cpp view
@@ -0,0 +1,6 @@+Array44i a = Array44i::Random();+cout << "Here is the array a:" << endl << a << endl;+cout << "Here is a.leftCols<2>():" << endl;+cout << a.leftCols<2>() << endl;+a.leftCols<2>().setZero();+cout << "Now the array a is:" << endl << a << endl;
+ eigen3/doc/snippets/MatrixBase_template_int_rightCols.cpp view
@@ -0,0 +1,6 @@+Array44i a = Array44i::Random();+cout << "Here is the array a:" << endl << a << endl;+cout << "Here is a.rightCols<2>():" << endl;+cout << a.rightCols<2>() << endl;+a.rightCols<2>().setZero();+cout << "Now the array a is:" << endl << a << endl;
+ eigen3/doc/snippets/MatrixBase_template_int_segment.cpp view
@@ -0,0 +1,5 @@+RowVector4i v = RowVector4i::Random();+cout << "Here is the vector v:" << endl << v << endl;+cout << "Here is v.segment<2>(1):" << endl << v.segment<2>(1) << endl;+v.segment<2>(2).setZero();+cout << "Now the vector v is:" << endl << v << endl;
+ eigen3/doc/snippets/MatrixBase_template_int_start.cpp view
@@ -0,0 +1,5 @@+RowVector4i v = RowVector4i::Random();+cout << "Here is the vector v:" << endl << v << endl;+cout << "Here is v.head(2):" << endl << v.head<2>() << endl;+v.head<2>().setZero();+cout << "Now the vector v is:" << endl << v << endl;
+ eigen3/doc/snippets/MatrixBase_template_int_topRows.cpp view
@@ -0,0 +1,6 @@+Array44i a = Array44i::Random();+cout << "Here is the array a:" << endl << a << endl;+cout << "Here is a.topRows<2>():" << endl;+cout << a.topRows<2>() << endl;+a.topRows<2>().setZero();+cout << "Now the array a is:" << endl << a << endl;
+ eigen3/doc/snippets/MatrixBase_topLeftCorner_int_int.cpp view
@@ -0,0 +1,6 @@+Matrix4i m = Matrix4i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is m.topLeftCorner(2, 2):" << endl;+cout << m.topLeftCorner(2, 2) << endl;+m.topLeftCorner(2, 2).setZero();+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_topRightCorner_int_int.cpp view
@@ -0,0 +1,6 @@+Matrix4i m = Matrix4i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is m.topRightCorner(2, 2):" << endl;+cout << m.topRightCorner(2, 2) << endl;+m.topRightCorner(2, 2).setZero();+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_topRows_int.cpp view
@@ -0,0 +1,6 @@+Array44i a = Array44i::Random();+cout << "Here is the array a:" << endl << a << endl;+cout << "Here is a.topRows(2):" << endl;+cout << a.topRows(2) << endl;+a.topRows(2).setZero();+cout << "Now the array a is:" << endl << a << endl;
+ eigen3/doc/snippets/MatrixBase_transpose.cpp view
@@ -0,0 +1,8 @@+Matrix2i m = Matrix2i::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the transpose of m:" << endl << m.transpose() << endl;+cout << "Here is the coefficient (1,0) in the transpose of m:" << endl+ << m.transpose()(1,0) << endl;+cout << "Let us overwrite this coefficient with the value 0." << endl;+m.transpose()(1,0) = 0;+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/MatrixBase_zero.cpp view
@@ -0,0 +1,2 @@+cout << Matrix2d::Zero() << endl;+cout << RowVector4i::Zero() << endl;
+ eigen3/doc/snippets/MatrixBase_zero_int.cpp view
@@ -0,0 +1,2 @@+cout << RowVectorXi::Zero(4) << endl;+cout << VectorXf::Zero(2) << endl;
+ eigen3/doc/snippets/MatrixBase_zero_int_int.cpp view
@@ -0,0 +1,1 @@+cout << MatrixXi::Zero(2,3) << endl;
+ eigen3/doc/snippets/Matrix_resize_NoChange_int.cpp view
@@ -0,0 +1,3 @@+MatrixXd m(3,4);+m.resize(NoChange, 5);+cout << "m: " << m.rows() << " rows, " << m.cols() << " cols" << endl;
+ eigen3/doc/snippets/Matrix_resize_int.cpp view
@@ -0,0 +1,6 @@+VectorXd v(10);+v.resize(3);+RowVector3d w;+w.resize(3); // this is legal, but has no effect+cout << "v: " << v.rows() << " rows, " << v.cols() << " cols" << endl;+cout << "w: " << w.rows() << " rows, " << w.cols() << " cols" << endl;
+ eigen3/doc/snippets/Matrix_resize_int_NoChange.cpp view
@@ -0,0 +1,3 @@+MatrixXd m(3,4);+m.resize(5, NoChange);+cout << "m: " << m.rows() << " rows, " << m.cols() << " cols" << endl;
+ eigen3/doc/snippets/Matrix_resize_int_int.cpp view
@@ -0,0 +1,9 @@+MatrixXd m(2,3);+m << 1,2,3,4,5,6;+cout << "here's the 2x3 matrix m:" << endl << m << endl;+cout << "let's resize m to 3x2. This is a conservative resizing because 2*3==3*2." << endl;+m.resize(3,2);+cout << "here's the 3x2 matrix m:" << endl << m << endl;+cout << "now let's resize m to size 2x2. This is NOT a conservative resizing, so it becomes uninitialized:" << endl;+m.resize(2,2);+cout << m << endl;
+ eigen3/doc/snippets/Matrix_setConstant_int.cpp view
@@ -0,0 +1,3 @@+VectorXf v;+v.setConstant(3, 5);+cout << v << endl;
+ eigen3/doc/snippets/Matrix_setConstant_int_int.cpp view
@@ -0,0 +1,3 @@+MatrixXf m;+m.setConstant(3, 3, 5);+cout << m << endl;
+ eigen3/doc/snippets/Matrix_setIdentity_int_int.cpp view
@@ -0,0 +1,3 @@+MatrixXf m;+m.setIdentity(3, 3);+cout << m << endl;
+ eigen3/doc/snippets/Matrix_setOnes_int.cpp view
@@ -0,0 +1,3 @@+VectorXf v;+v.setOnes(3);+cout << v << endl;
+ eigen3/doc/snippets/Matrix_setOnes_int_int.cpp view
@@ -0,0 +1,3 @@+MatrixXf m;+m.setOnes(3, 3);+cout << m << endl;
+ eigen3/doc/snippets/Matrix_setRandom_int.cpp view
@@ -0,0 +1,3 @@+VectorXf v;+v.setRandom(3);+cout << v << endl;
+ eigen3/doc/snippets/Matrix_setRandom_int_int.cpp view
@@ -0,0 +1,3 @@+MatrixXf m;+m.setRandom(3, 3);+cout << m << endl;
+ eigen3/doc/snippets/Matrix_setZero_int.cpp view
@@ -0,0 +1,3 @@+VectorXf v;+v.setZero(3);+cout << v << endl;
+ eigen3/doc/snippets/Matrix_setZero_int_int.cpp view
@@ -0,0 +1,3 @@+MatrixXf m;+m.setZero(3, 3);+cout << m << endl;
+ eigen3/doc/snippets/PartialPivLU_solve.cpp view
@@ -0,0 +1,7 @@+MatrixXd A = MatrixXd::Random(3,3);+MatrixXd B = MatrixXd::Random(3,2);+cout << "Here is the invertible matrix A:" << endl << A << endl;+cout << "Here is the matrix B:" << endl << B << endl;+MatrixXd X = A.lu().solve(B);+cout << "Here is the (unique) solution X to the equation AX=B:" << endl << X << endl;+cout << "Relative error: " << (A*X-B).norm() / B.norm() << endl;
+ eigen3/doc/snippets/PartialRedux_count.cpp view
@@ -0,0 +1,3 @@+Matrix3d m = Matrix3d::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the count of elements larger or equal than 0.5 of each row:" << endl << (m.array() >= 0.5).rowwise().count() << endl;
+ eigen3/doc/snippets/PartialRedux_maxCoeff.cpp view
@@ -0,0 +1,3 @@+Matrix3d m = Matrix3d::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the maximum of each column:" << endl << m.colwise().maxCoeff() << endl;
+ eigen3/doc/snippets/PartialRedux_minCoeff.cpp view
@@ -0,0 +1,3 @@+Matrix3d m = Matrix3d::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the minimum of each column:" << endl << m.colwise().minCoeff() << endl;
+ eigen3/doc/snippets/PartialRedux_norm.cpp view
@@ -0,0 +1,3 @@+Matrix3d m = Matrix3d::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the norm of each column:" << endl << m.colwise().norm() << endl;
+ eigen3/doc/snippets/PartialRedux_prod.cpp view
@@ -0,0 +1,3 @@+Matrix3d m = Matrix3d::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the product of each row:" << endl << m.rowwise().prod() << endl;
+ eigen3/doc/snippets/PartialRedux_squaredNorm.cpp view
@@ -0,0 +1,3 @@+Matrix3d m = Matrix3d::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the square norm of each row:" << endl << m.rowwise().squaredNorm() << endl;
+ eigen3/doc/snippets/PartialRedux_sum.cpp view
@@ -0,0 +1,3 @@+Matrix3d m = Matrix3d::Random();+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the sum of each row:" << endl << m.rowwise().sum() << endl;
+ eigen3/doc/snippets/RealQZ_compute.cpp view
@@ -0,0 +1,17 @@+MatrixXf A = MatrixXf::Random(4,4);+MatrixXf B = MatrixXf::Random(4,4);+RealQZ<MatrixXf> qz(4); // preallocate space for 4x4 matrices+qz.compute(A,B); // A = Q S Z, B = Q T Z++// print original matrices and result of decomposition+cout << "A:\n" << A << "\n" << "B:\n" << B << "\n";+cout << "S:\n" << qz.matrixS() << "\n" << "T:\n" << qz.matrixT() << "\n";+cout << "Q:\n" << qz.matrixQ() << "\n" << "Z:\n" << qz.matrixZ() << "\n";++// verify precision+cout << "\nErrors:"+ << "\n|A-QSZ|: " << (A-qz.matrixQ()*qz.matrixS()*qz.matrixZ()).norm()+ << ", |B-QTZ|: " << (B-qz.matrixQ()*qz.matrixT()*qz.matrixZ()).norm()+ << "\n|QQ* - I|: " << (qz.matrixQ()*qz.matrixQ().adjoint() - MatrixXf::Identity(4,4)).norm()+ << ", |ZZ* - I|: " << (qz.matrixZ()*qz.matrixZ().adjoint() - MatrixXf::Identity(4,4)).norm()+ << "\n";
+ eigen3/doc/snippets/RealSchur_RealSchur_MatrixType.cpp view
@@ -0,0 +1,10 @@+MatrixXd A = MatrixXd::Random(6,6);+cout << "Here is a random 6x6 matrix, A:" << endl << A << endl << endl;++RealSchur<MatrixXd> schur(A);+cout << "The orthogonal matrix U is:" << endl << schur.matrixU() << endl;+cout << "The quasi-triangular matrix T is:" << endl << schur.matrixT() << endl << endl;++MatrixXd U = schur.matrixU();+MatrixXd T = schur.matrixT();+cout << "U * T * U^T = " << endl << U * T * U.transpose() << endl;
+ eigen3/doc/snippets/RealSchur_compute.cpp view
@@ -0,0 +1,6 @@+MatrixXf A = MatrixXf::Random(4,4);+RealSchur<MatrixXf> schur(4);+schur.compute(A, /* computeU = */ false);+cout << "The matrix T in the decomposition of A is:" << endl << schur.matrixT() << endl;+schur.compute(A.inverse(), /* computeU = */ false);+cout << "The matrix T in the decomposition of A^(-1) is:" << endl << schur.matrixT() << endl;
+ eigen3/doc/snippets/SelfAdjointEigenSolver_SelfAdjointEigenSolver.cpp view
@@ -0,0 +1,7 @@+SelfAdjointEigenSolver<Matrix4f> es;+Matrix4f X = Matrix4f::Random(4,4);+Matrix4f A = X + X.transpose();+es.compute(A);+cout << "The eigenvalues of A are: " << es.eigenvalues().transpose() << endl;+es.compute(A + Matrix4f::Identity(4,4)); // re-use es to compute eigenvalues of A+I+cout << "The eigenvalues of A+I are: " << es.eigenvalues().transpose() << endl;
+ eigen3/doc/snippets/SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType.cpp view
@@ -0,0 +1,17 @@+MatrixXd X = MatrixXd::Random(5,5);+MatrixXd A = X + X.transpose();+cout << "Here is a random symmetric 5x5 matrix, A:" << endl << A << endl << endl;++SelfAdjointEigenSolver<MatrixXd> es(A);+cout << "The eigenvalues of A are:" << endl << es.eigenvalues() << endl;+cout << "The matrix of eigenvectors, V, is:" << endl << es.eigenvectors() << endl << endl;++double lambda = es.eigenvalues()[0];+cout << "Consider the first eigenvalue, lambda = " << lambda << endl;+VectorXd v = es.eigenvectors().col(0);+cout << "If v is the corresponding eigenvector, then lambda * v = " << endl << lambda * v << endl;+cout << "... and A * v = " << endl << A * v << endl << endl;++MatrixXd D = es.eigenvalues().asDiagonal();+MatrixXd V = es.eigenvectors();+cout << "Finally, V * D * V^(-1) = " << endl << V * D * V.inverse() << endl;
+ eigen3/doc/snippets/SelfAdjointEigenSolver_SelfAdjointEigenSolver_MatrixType2.cpp view
@@ -0,0 +1,16 @@+MatrixXd X = MatrixXd::Random(5,5);+MatrixXd A = X + X.transpose();+cout << "Here is a random symmetric matrix, A:" << endl << A << endl;+X = MatrixXd::Random(5,5);+MatrixXd B = X * X.transpose();+cout << "and a random postive-definite matrix, B:" << endl << B << endl << endl;++GeneralizedSelfAdjointEigenSolver<MatrixXd> es(A,B);+cout << "The eigenvalues of the pencil (A,B) are:" << endl << es.eigenvalues() << endl;+cout << "The matrix of eigenvectors, V, is:" << endl << es.eigenvectors() << endl << endl;++double lambda = es.eigenvalues()[0];+cout << "Consider the first eigenvalue, lambda = " << lambda << endl;+VectorXd v = es.eigenvectors().col(0);+cout << "If v is the corresponding eigenvector, then A * v = " << endl << A * v << endl;+cout << "... and lambda * B * v = " << endl << lambda * B * v << endl << endl;
+ eigen3/doc/snippets/SelfAdjointEigenSolver_compute_MatrixType.cpp view
@@ -0,0 +1,7 @@+SelfAdjointEigenSolver<MatrixXf> es(4);+MatrixXf X = MatrixXf::Random(4,4);+MatrixXf A = X + X.transpose();+es.compute(A);+cout << "The eigenvalues of A are: " << es.eigenvalues().transpose() << endl;+es.compute(A + MatrixXf::Identity(4,4)); // re-use es to compute eigenvalues of A+I+cout << "The eigenvalues of A+I are: " << es.eigenvalues().transpose() << endl;
+ eigen3/doc/snippets/SelfAdjointEigenSolver_compute_MatrixType2.cpp view
@@ -0,0 +1,9 @@+MatrixXd X = MatrixXd::Random(5,5);+MatrixXd A = X * X.transpose();+X = MatrixXd::Random(5,5);+MatrixXd B = X * X.transpose();++GeneralizedSelfAdjointEigenSolver<MatrixXd> es(A,B,EigenvaluesOnly);+cout << "The eigenvalues of the pencil (A,B) are:" << endl << es.eigenvalues() << endl;+es.compute(B,A,false);+cout << "The eigenvalues of the pencil (B,A) are:" << endl << es.eigenvalues() << endl;
+ eigen3/doc/snippets/SelfAdjointEigenSolver_eigenvalues.cpp view
@@ -0,0 +1,4 @@+MatrixXd ones = MatrixXd::Ones(3,3);+SelfAdjointEigenSolver<MatrixXd> es(ones);+cout << "The eigenvalues of the 3x3 matrix of ones are:" + << endl << es.eigenvalues() << endl;
+ eigen3/doc/snippets/SelfAdjointEigenSolver_eigenvectors.cpp view
@@ -0,0 +1,4 @@+MatrixXd ones = MatrixXd::Ones(3,3);+SelfAdjointEigenSolver<MatrixXd> es(ones);+cout << "The first eigenvector of the 3x3 matrix of ones is:" + << endl << es.eigenvectors().col(1) << endl;
+ eigen3/doc/snippets/SelfAdjointEigenSolver_operatorInverseSqrt.cpp view
@@ -0,0 +1,9 @@+MatrixXd X = MatrixXd::Random(4,4);+MatrixXd A = X * X.transpose();+cout << "Here is a random positive-definite matrix, A:" << endl << A << endl << endl;++SelfAdjointEigenSolver<MatrixXd> es(A);+cout << "The inverse square root of A is: " << endl;+cout << es.operatorInverseSqrt() << endl;+cout << "We can also compute it with operatorSqrt() and inverse(). That yields: " << endl;+cout << es.operatorSqrt().inverse() << endl;
+ eigen3/doc/snippets/SelfAdjointEigenSolver_operatorSqrt.cpp view
@@ -0,0 +1,8 @@+MatrixXd X = MatrixXd::Random(4,4);+MatrixXd A = X * X.transpose();+cout << "Here is a random positive-definite matrix, A:" << endl << A << endl << endl;++SelfAdjointEigenSolver<MatrixXd> es(A);+MatrixXd sqrtA = es.operatorSqrt();+cout << "The square root of A is: " << endl << sqrtA << endl;+cout << "If we square this, we get: " << endl << sqrtA*sqrtA << endl;
+ eigen3/doc/snippets/SelfAdjointView_eigenvalues.cpp view
@@ -0,0 +1,3 @@+MatrixXd ones = MatrixXd::Ones(3,3);+VectorXd eivals = ones.selfadjointView<Lower>().eigenvalues();+cout << "The eigenvalues of the 3x3 matrix of ones are:" << endl << eivals << endl;
+ eigen3/doc/snippets/SelfAdjointView_operatorNorm.cpp view
@@ -0,0 +1,3 @@+MatrixXd ones = MatrixXd::Ones(3,3);+cout << "The operator norm of the 3x3 matrix of ones is "+ << ones.selfadjointView<Lower>().operatorNorm() << endl;
+ eigen3/doc/snippets/TopicAliasing_block.cpp view
@@ -0,0 +1,7 @@+MatrixXi mat(3,3); +mat << 1, 2, 3, 4, 5, 6, 7, 8, 9;+cout << "Here is the matrix mat:\n" << mat << endl;++// This assignment shows the aliasing problem+mat.bottomRightCorner(2,2) = mat.topLeftCorner(2,2);+cout << "After the assignment, mat = \n" << mat << endl;
+ eigen3/doc/snippets/TopicAliasing_block_correct.cpp view
@@ -0,0 +1,7 @@+MatrixXi mat(3,3); +mat << 1, 2, 3, 4, 5, 6, 7, 8, 9;+cout << "Here is the matrix mat:\n" << mat << endl;++// The eval() solves the aliasing problem+mat.bottomRightCorner(2,2) = mat.topLeftCorner(2,2).eval();+cout << "After the assignment, mat = \n" << mat << endl;
+ eigen3/doc/snippets/TopicAliasing_cwise.cpp view
@@ -0,0 +1,20 @@+MatrixXf mat(2,2); +mat << 1, 2, 4, 7;+cout << "Here is the matrix mat:\n" << mat << endl << endl;++mat = 2 * mat;+cout << "After 'mat = 2 * mat', mat = \n" << mat << endl << endl;+++mat = mat - MatrixXf::Identity(2,2);+cout << "After the subtraction, it becomes\n" << mat << endl << endl;+++ArrayXXf arr = mat;+arr = arr.square();+cout << "After squaring, it becomes\n" << arr << endl << endl;++// Combining all operations in one statement:+mat << 1, 2, 4, 7;+mat = (2 * mat - MatrixXf::Identity(2,2)).array().square();+cout << "Doing everything at once yields\n" << mat << endl << endl;
+ eigen3/doc/snippets/TopicAliasing_mult1.cpp view
@@ -0,0 +1,4 @@+MatrixXf matA(2,2); +matA << 2, 0, 0, 2;+matA = matA * matA;+cout << matA;
+ eigen3/doc/snippets/TopicAliasing_mult2.cpp view
@@ -0,0 +1,10 @@+MatrixXf matA(2,2), matB(2,2); +matA << 2, 0, 0, 2;++// Simple but not quite as efficient+matB = matA * matA;+cout << matB << endl << endl;++// More complicated but also more efficient+matB.noalias() = matA * matA;+cout << matB;
+ eigen3/doc/snippets/TopicAliasing_mult3.cpp view
@@ -0,0 +1,4 @@+MatrixXf matA(2,2); +matA << 2, 0, 0, 2;+matA.noalias() = matA * matA;+cout << matA;
+ eigen3/doc/snippets/TopicStorageOrders_example.cpp view
@@ -0,0 +1,18 @@+Matrix<int, 3, 4, ColMajor> Acolmajor;+Acolmajor << 8, 2, 2, 9,+ 9, 1, 4, 4,+ 3, 5, 4, 5;+cout << "The matrix A:" << endl;+cout << Acolmajor << endl << endl; ++cout << "In memory (column-major):" << endl;+for (int i = 0; i < Acolmajor.size(); i++)+ cout << *(Acolmajor.data() + i) << " ";+cout << endl << endl;++Matrix<int, 3, 4, RowMajor> Arowmajor = Acolmajor;+cout << "In memory (row-major):" << endl;+for (int i = 0; i < Arowmajor.size(); i++)+ cout << *(Arowmajor.data() + i) << " ";+cout << endl;+
+ eigen3/doc/snippets/Tridiagonalization_Tridiagonalization_MatrixType.cpp view
@@ -0,0 +1,9 @@+MatrixXd X = MatrixXd::Random(5,5);+MatrixXd A = X + X.transpose();+cout << "Here is a random symmetric 5x5 matrix:" << endl << A << endl << endl;+Tridiagonalization<MatrixXd> triOfA(A);+MatrixXd Q = triOfA.matrixQ();+cout << "The orthogonal matrix Q is:" << endl << Q << endl;+MatrixXd T = triOfA.matrixT();+cout << "The tridiagonal matrix T is:" << endl << T << endl << endl;+cout << "Q * T * Q^T = " << endl << Q * T * Q.transpose() << endl;
+ eigen3/doc/snippets/Tridiagonalization_compute.cpp view
@@ -0,0 +1,9 @@+Tridiagonalization<MatrixXf> tri;+MatrixXf X = MatrixXf::Random(4,4);+MatrixXf A = X + X.transpose();+tri.compute(A);+cout << "The matrix T in the tridiagonal decomposition of A is: " << endl;+cout << tri.matrixT() << endl;+tri.compute(2*A); // re-use tri to compute eigenvalues of 2A+cout << "The matrix T in the tridiagonal decomposition of 2A is: " << endl;+cout << tri.matrixT() << endl;
+ eigen3/doc/snippets/Tridiagonalization_decomposeInPlace.cpp view
@@ -0,0 +1,10 @@+MatrixXd X = MatrixXd::Random(5,5);+MatrixXd A = X + X.transpose();+cout << "Here is a random symmetric 5x5 matrix:" << endl << A << endl << endl;++VectorXd diag(5);+VectorXd subdiag(4);+internal::tridiagonalization_inplace(A, diag, subdiag, true);+cout << "The orthogonal matrix Q is:" << endl << A << endl;+cout << "The diagonal of the tridiagonal matrix T is:" << endl << diag << endl;+cout << "The subdiagonal of the tridiagonal matrix T is:" << endl << subdiag << endl;
+ eigen3/doc/snippets/Tridiagonalization_diagonal.cpp view
@@ -0,0 +1,13 @@+MatrixXcd X = MatrixXcd::Random(4,4);+MatrixXcd A = X + X.adjoint();+cout << "Here is a random self-adjoint 4x4 matrix:" << endl << A << endl << endl;++Tridiagonalization<MatrixXcd> triOfA(A);+MatrixXd T = triOfA.matrixT();+cout << "The tridiagonal matrix T is:" << endl << T << endl << endl;++cout << "We can also extract the diagonals of T directly ..." << endl;+VectorXd diag = triOfA.diagonal();+cout << "The diagonal is:" << endl << diag << endl; +VectorXd subdiag = triOfA.subDiagonal();+cout << "The subdiagonal is:" << endl << subdiag << endl;
+ eigen3/doc/snippets/Tridiagonalization_householderCoefficients.cpp view
@@ -0,0 +1,6 @@+Matrix4d X = Matrix4d::Random(4,4);+Matrix4d A = X + X.transpose();+cout << "Here is a random symmetric 4x4 matrix:" << endl << A << endl;+Tridiagonalization<Matrix4d> triOfA(A);+Vector3d hc = triOfA.householderCoefficients();+cout << "The vector of Householder coefficients is:" << endl << hc << endl;
+ eigen3/doc/snippets/Tridiagonalization_packedMatrix.cpp view
@@ -0,0 +1,8 @@+Matrix4d X = Matrix4d::Random(4,4);+Matrix4d A = X + X.transpose();+cout << "Here is a random symmetric 4x4 matrix:" << endl << A << endl;+Tridiagonalization<Matrix4d> triOfA(A);+Matrix4d pm = triOfA.packedMatrix();+cout << "The packed matrix M is:" << endl << pm << endl;+cout << "The diagonal and subdiagonal corresponds to the matrix T, which is:" + << endl << triOfA.matrixT() << endl;
+ eigen3/doc/snippets/Tutorial_AdvancedInitialization_Block.cpp view
@@ -0,0 +1,5 @@+MatrixXf matA(2, 2);+matA << 1, 2, 3, 4;+MatrixXf matB(4, 4);+matB << matA, matA/10, matA/10, matA;+std::cout << matB << std::endl;
+ eigen3/doc/snippets/Tutorial_AdvancedInitialization_CommaTemporary.cpp view
@@ -0,0 +1,4 @@+MatrixXf mat = MatrixXf::Random(2, 3);+std::cout << mat << std::endl << std::endl;+mat = (MatrixXf(2,2) << 0, 1, 1, 0).finished() * mat;+std::cout << mat << std::endl;
+ eigen3/doc/snippets/Tutorial_AdvancedInitialization_Join.cpp view
@@ -0,0 +1,11 @@+RowVectorXd vec1(3);+vec1 << 1, 2, 3;+std::cout << "vec1 = " << vec1 << std::endl;++RowVectorXd vec2(4);+vec2 << 1, 4, 9, 16;;+std::cout << "vec2 = " << vec2 << std::endl;++RowVectorXd joined(7);+joined << vec1, vec2;+std::cout << "joined = " << joined << std::endl;
+ eigen3/doc/snippets/Tutorial_AdvancedInitialization_LinSpaced.cpp view
@@ -0,0 +1,7 @@+ArrayXXf table(10, 4);+table.col(0) = ArrayXf::LinSpaced(10, 0, 90);+table.col(1) = M_PI / 180 * table.col(0);+table.col(2) = table.col(1).sin();+table.col(3) = table.col(1).cos();+std::cout << " Degrees Radians Sine Cosine\n";+std::cout << table << std::endl;
+ eigen3/doc/snippets/Tutorial_AdvancedInitialization_ThreeWays.cpp view
@@ -0,0 +1,20 @@+const int size = 6;+MatrixXd mat1(size, size);+mat1.topLeftCorner(size/2, size/2) = MatrixXd::Zero(size/2, size/2);+mat1.topRightCorner(size/2, size/2) = MatrixXd::Identity(size/2, size/2);+mat1.bottomLeftCorner(size/2, size/2) = MatrixXd::Identity(size/2, size/2);+mat1.bottomRightCorner(size/2, size/2) = MatrixXd::Zero(size/2, size/2);+std::cout << mat1 << std::endl << std::endl;++MatrixXd mat2(size, size);+mat2.topLeftCorner(size/2, size/2).setZero();+mat2.topRightCorner(size/2, size/2).setIdentity();+mat2.bottomLeftCorner(size/2, size/2).setIdentity();+mat2.bottomRightCorner(size/2, size/2).setZero();+std::cout << mat2 << std::endl << std::endl;++MatrixXd mat3(size, size);+mat3 << MatrixXd::Zero(size/2, size/2), MatrixXd::Identity(size/2, size/2),+ MatrixXd::Identity(size/2, size/2), MatrixXd::Zero(size/2, size/2);+std::cout << mat3 << std::endl;+
+ eigen3/doc/snippets/Tutorial_AdvancedInitialization_Zero.cpp view
@@ -0,0 +1,13 @@+std::cout << "A fixed-size array:\n";+Array33f a1 = Array33f::Zero();+std::cout << a1 << "\n\n";+++std::cout << "A one-dimensional dynamic-size array:\n";+ArrayXf a2 = ArrayXf::Zero(3);+std::cout << a2 << "\n\n";+++std::cout << "A two-dimensional dynamic-size array:\n";+ArrayXXf a3 = ArrayXXf::Zero(3, 4);+std::cout << a3 << "\n";
+ eigen3/doc/snippets/Tutorial_Map_rowmajor.cpp view
@@ -0,0 +1,7 @@+int array[8];+for(int i = 0; i < 8; ++i) array[i] = i;+cout << "Column-major:\n" << Map<Matrix<int,2,4> >(array) << endl;+cout << "Row-major:\n" << Map<Matrix<int,2,4,RowMajor> >(array) << endl;+cout << "Row-major using stride:\n" <<+ Map<Matrix<int,2,4>, Unaligned, Stride<1,4> >(array) << endl;+
+ eigen3/doc/snippets/Tutorial_Map_using.cpp view
@@ -0,0 +1,21 @@+typedef Matrix<float,1,Dynamic> MatrixType;+typedef Map<MatrixType> MapType;+typedef Map<const MatrixType> MapTypeConst; // a read-only map+const int n_dims = 5;+ +MatrixType m1(n_dims), m2(n_dims);+m1.setRandom();+m2.setRandom();+float *p = &m2(0); // get the address storing the data for m2+MapType m2map(p,m2.size()); // m2map shares data with m2+MapTypeConst m2mapconst(p,m2.size()); // a read-only accessor for m2++cout << "m1: " << m1 << endl;+cout << "m2: " << m2 << endl;+cout << "Squared euclidean distance: " << (m1-m2).squaredNorm() << endl;+cout << "Squared euclidean distance, using map: " <<+ (m1-m2map).squaredNorm() << endl;+m2map(3) = 7; // this will change m2, since they share the same array+cout << "Updated m2: " << m2 << endl;+cout << "m2 coefficient 2, constant accessor: " << m2mapconst(2) << endl;+/* m2mapconst(2) = 5; */ // this yields a compile-time error
+ eigen3/doc/snippets/Tutorial_commainit_01.cpp view
@@ -0,0 +1,5 @@+Matrix3f m;+m << 1, 2, 3,+ 4, 5, 6,+ 7, 8, 9;+std::cout << m;
+ eigen3/doc/snippets/Tutorial_commainit_01b.cpp view
@@ -0,0 +1,5 @@+Matrix3f m;+m.row(0) << 1, 2, 3;+m.block(1,0,2,2) << 4, 5, 7, 8;+m.col(2).tail(2) << 6, 9; +std::cout << m;
+ eigen3/doc/snippets/Tutorial_commainit_02.cpp view
@@ -0,0 +1,7 @@+int rows=5, cols=5;+MatrixXf m(rows,cols);+m << (Matrix3f() << 1, 2, 3, 4, 5, 6, 7, 8, 9).finished(),+ MatrixXf::Zero(3,cols-3),+ MatrixXf::Zero(rows-3,3),+ MatrixXf::Identity(rows-3,cols-3);+cout << m;
+ eigen3/doc/snippets/Tutorial_solve_matrix_inverse.cpp view
@@ -0,0 +1,6 @@+Matrix3f A;+Vector3f b;+A << 1,2,3, 4,5,6, 7,8,10;+b << 3, 3, 4;+Vector3f x = A.inverse() * b;+cout << "The solution is:" << endl << x << endl;
+ eigen3/doc/snippets/Tutorial_solve_multiple_rhs.cpp view
@@ -0,0 +1,10 @@+Matrix3f A(3,3);+A << 1,2,3, 4,5,6, 7,8,10;+Matrix<float,3,2> B;+B << 3,1, 3,1, 4,1;+Matrix<float,3,2> X;+X = A.fullPivLu().solve(B);+cout << "The solution with right-hand side (3,3,4) is:" << endl;+cout << X.col(0) << endl;+cout << "The solution with right-hand side (1,1,1) is:" << endl;+cout << X.col(1) << endl;
+ eigen3/doc/snippets/Tutorial_solve_reuse_decomposition.cpp view
@@ -0,0 +1,13 @@+Matrix3f A(3,3);+A << 1,2,3, 4,5,6, 7,8,10;+PartialPivLU<Matrix3f> luOfA(A); // compute LU decomposition of A+Vector3f b;+b << 3,3,4;+Vector3f x;+x = luOfA.solve(b);+cout << "The solution with right-hand side (3,3,4) is:" << endl;+cout << x << endl;+b << 1,1,1;+x = luOfA.solve(b);+cout << "The solution with right-hand side (1,1,1) is:" << endl;+cout << x << endl;
+ eigen3/doc/snippets/Tutorial_solve_singular.cpp view
@@ -0,0 +1,9 @@+Matrix3f A;+Vector3f b;+A << 1,2,3, 4,5,6, 7,8,9;+b << 3, 3, 4;+cout << "Here is the matrix A:" << endl << A << endl;+cout << "Here is the vector b:" << endl << b << endl;+Vector3f x;+x = A.lu().solve(b);+cout << "The solution is:" << endl << x << endl;
+ eigen3/doc/snippets/Tutorial_solve_triangular.cpp view
@@ -0,0 +1,8 @@+Matrix3f A;+Vector3f b;+A << 1,2,3, 0,5,6, 0,0,10;+b << 3, 3, 4;+cout << "Here is the matrix A:" << endl << A << endl;+cout << "Here is the vector b:" << endl << b << endl;+Vector3f x = A.triangularView<Upper>().solve(b);+cout << "The solution is:" << endl << x << endl;
+ eigen3/doc/snippets/Tutorial_solve_triangular_inplace.cpp view
@@ -0,0 +1,6 @@+Matrix3f A;+Vector3f b;+A << 1,2,3, 0,5,6, 0,0,10;+b << 3, 3, 4;+A.triangularView<Upper>().solveInPlace(b);+cout << "The solution is:" << endl << b << endl;
+ eigen3/doc/snippets/Vectorwise_reverse.cpp view
@@ -0,0 +1,10 @@+MatrixXi m = MatrixXi::Random(3,4);+cout << "Here is the matrix m:" << endl << m << endl;+cout << "Here is the rowwise reverse of m:" << endl << m.rowwise().reverse() << endl;+cout << "Here is the colwise reverse of m:" << endl << m.colwise().reverse() << endl;++cout << "Here is the coefficient (1,0) in the rowise reverse of m:" << endl+<< m.rowwise().reverse()(1,0) << endl;+cout << "Let us overwrite this coefficient with the value 4." << endl;+//m.colwise().reverse()(1,0) = 4;+cout << "Now the matrix m is:" << endl << m << endl;
+ eigen3/doc/snippets/class_FullPivLU.cpp view
@@ -0,0 +1,16 @@+typedef Matrix<double, 5, 3> Matrix5x3;+typedef Matrix<double, 5, 5> Matrix5x5;+Matrix5x3 m = Matrix5x3::Random();+cout << "Here is the matrix m:" << endl << m << endl;+Eigen::FullPivLU<Matrix5x3> lu(m);+cout << "Here is, up to permutations, its LU decomposition matrix:"+ << endl << lu.matrixLU() << endl;+cout << "Here is the L part:" << endl;+Matrix5x5 l = Matrix5x5::Identity();+l.block<5,3>(0,0).triangularView<StrictlyLower>() = lu.matrixLU();+cout << l << endl;+cout << "Here is the U part:" << endl;+Matrix5x3 u = lu.matrixLU().triangularView<Upper>();+cout << u << endl;+cout << "Let us now reconstruct the original matrix m:" << endl;+cout << lu.permutationP().inverse() * l * u * lu.permutationQ().inverse() << endl;
+ eigen3/doc/snippets/compile_snippet.cpp.in view
@@ -0,0 +1,12 @@+#include <Eigen/Dense>+#include <iostream>++using namespace Eigen;+using namespace std;++int main(int, char**)+{+ cout.precision(3);+ ${snippet_source_code}+ return 0;+}
+ eigen3/doc/snippets/tut_arithmetic_redux_minmax.cpp view
@@ -0,0 +1,12 @@+ Matrix3f m = Matrix3f::Random();+ std::ptrdiff_t i, j;+ float minOfM = m.minCoeff(&i,&j);+ cout << "Here is the matrix m:\n" << m << endl;+ cout << "Its minimum coefficient (" << minOfM + << ") is at position (" << i << "," << j << ")\n\n";++ RowVector4i v = RowVector4i::Random();+ int maxOfV = v.maxCoeff(&i);+ cout << "Here is the vector v: " << v << endl;+ cout << "Its maximum coefficient (" << maxOfV + << ") is at position " << i << endl;
+ eigen3/doc/snippets/tut_arithmetic_transpose_aliasing.cpp view
@@ -0,0 +1,5 @@+Matrix2i a; a << 1, 2, 3, 4;+cout << "Here is the matrix a:\n" << a << endl;++a = a.transpose(); // !!! do NOT do this !!!+cout << "and the result of the aliasing effect:\n" << a << endl;
+ eigen3/doc/snippets/tut_arithmetic_transpose_conjugate.cpp view
@@ -0,0 +1,12 @@+MatrixXcf a = MatrixXcf::Random(2,2);+cout << "Here is the matrix a\n" << a << endl;++cout << "Here is the matrix a^T\n" << a.transpose() << endl;+++cout << "Here is the conjugate of a\n" << a.conjugate() << endl;+++cout << "Here is the matrix a^*\n" << a.adjoint() << endl;++
+ eigen3/doc/snippets/tut_arithmetic_transpose_inplace.cpp view
@@ -0,0 +1,6 @@+MatrixXf a(2,3); a << 1, 2, 3, 4, 5, 6;+cout << "Here is the initial matrix a:\n" << a << endl;+++a.transposeInPlace();+cout << "and after being transposed:\n" << a << endl;
+ eigen3/doc/snippets/tut_matrix_assignment_resizing.cpp view
@@ -0,0 +1,5 @@+MatrixXf a(2,2);+std::cout << "a is of size " << a.rows() << "x" << a.cols() << std::endl;+MatrixXf b(3,3);+a = b;+std::cout << "a is now of size " << a.rows() << "x" << a.cols() << std::endl;
+ eigen3/doc/special_examples/CMakeLists.txt view
@@ -0,0 +1,21 @@+if(NOT EIGEN_TEST_NOQT)+ find_package(Qt4)+ if(QT4_FOUND)+ include(${QT_USE_FILE})+ endif()+endif(NOT EIGEN_TEST_NOQT)++if(QT4_FOUND)+ add_executable(Tutorial_sparse_example Tutorial_sparse_example.cpp Tutorial_sparse_example_details.cpp)+ target_link_libraries(Tutorial_sparse_example ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY})++ add_custom_command(+ TARGET Tutorial_sparse_example+ POST_BUILD+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/../html/+ COMMAND Tutorial_sparse_example ARGS ${CMAKE_CURRENT_BINARY_DIR}/../html/Tutorial_sparse_example.jpeg+ )++ add_dependencies(all_examples Tutorial_sparse_example)+endif(QT4_FOUND)+
+ eigen3/doc/special_examples/Tutorial_sparse_example.cpp view
@@ -0,0 +1,32 @@+#include <Eigen/Sparse>+#include <vector>++typedef Eigen::SparseMatrix<double> SpMat; // declares a column-major sparse matrix type of double+typedef Eigen::Triplet<double> T;++void buildProblem(std::vector<T>& coefficients, Eigen::VectorXd& b, int n);+void saveAsBitmap(const Eigen::VectorXd& x, int n, const char* filename);++int main(int argc, char** argv)+{+ int n = 300; // size of the image+ int m = n*n; // number of unknows (=number of pixels)++ // Assembly:+ std::vector<T> coefficients; // list of non-zeros coefficients+ Eigen::VectorXd b(m); // the right hand side-vector resulting from the constraints+ buildProblem(coefficients, b, n);++ SpMat A(m,m);+ A.setFromTriplets(coefficients.begin(), coefficients.end());++ // Solving:+ Eigen::SimplicialCholesky<SpMat> chol(A); // performs a Cholesky factorization of A+ Eigen::VectorXd x = chol.solve(b); // use the factorization to solve for the given right hand side++ // Export the result to a file:+ saveAsBitmap(x, n, argv[1]);++ return 0;+}+
+ eigen3/doc/special_examples/Tutorial_sparse_example_details.cpp view
@@ -0,0 +1,44 @@+#include <Eigen/Sparse>+#include <vector>+#include <QImage>++typedef Eigen::SparseMatrix<double> SpMat; // declares a column-major sparse matrix type of double+typedef Eigen::Triplet<double> T;++void insertCoefficient(int id, int i, int j, double w, std::vector<T>& coeffs,+ Eigen::VectorXd& b, const Eigen::VectorXd& boundary)+{+ int n = boundary.size();+ int id1 = i+j*n;++ if(i==-1 || i==n) b(id) -= w * boundary(j); // constrained coefficient+ else if(j==-1 || j==n) b(id) -= w * boundary(i); // constrained coefficient+ else coeffs.push_back(T(id,id1,w)); // unknown coefficient+}++void buildProblem(std::vector<T>& coefficients, Eigen::VectorXd& b, int n)+{+ b.setZero();+ Eigen::ArrayXd boundary = Eigen::ArrayXd::LinSpaced(n, 0,M_PI).sin().pow(2);+ for(int j=0; j<n; ++j)+ {+ for(int i=0; i<n; ++i)+ {+ int id = i+j*n;+ insertCoefficient(id, i-1,j, -1, coefficients, b, boundary);+ insertCoefficient(id, i+1,j, -1, coefficients, b, boundary);+ insertCoefficient(id, i,j-1, -1, coefficients, b, boundary);+ insertCoefficient(id, i,j+1, -1, coefficients, b, boundary);+ insertCoefficient(id, i,j, 4, coefficients, b, boundary);+ }+ }+}++void saveAsBitmap(const Eigen::VectorXd& x, int n, const char* filename)+{+ Eigen::Array<unsigned char,Eigen::Dynamic,Eigen::Dynamic> bits = (x*255).cast<unsigned char>();+ QImage img(bits.data(), n,n,QImage::Format_Indexed8);+ img.setColorCount(256);+ for(int i=0;i<256;i++) img.setColor(i,qRgb(i,i,i));+ img.save(filename);+}
+ eigen3/doc/tutorial.cpp view
@@ -0,0 +1,62 @@+#include <Eigen/Array>++int main(int argc, char *argv[])+{+ std::cout.precision(2);++ // demo static functions+ Eigen::Matrix3f m3 = Eigen::Matrix3f::Random();+ Eigen::Matrix4f m4 = Eigen::Matrix4f::Identity();++ std::cout << "*** Step 1 ***\nm3:\n" << m3 << "\nm4:\n" << m4 << std::endl;++ // demo non-static set... functions+ m4.setZero();+ m3.diagonal().setOnes();+ + std::cout << "*** Step 2 ***\nm3:\n" << m3 << "\nm4:\n" << m4 << std::endl;++ // demo fixed-size block() expression as lvalue and as rvalue+ m4.block<3,3>(0,1) = m3;+ m3.row(2) = m4.block<1,3>(2,0);++ std::cout << "*** Step 3 ***\nm3:\n" << m3 << "\nm4:\n" << m4 << std::endl;++ // demo dynamic-size block()+ {+ int rows = 3, cols = 3;+ m4.block(0,1,3,3).setIdentity();+ std::cout << "*** Step 4 ***\nm4:\n" << m4 << std::endl;+ }++ // demo vector blocks+ m4.diagonal().block(1,2).setOnes();+ std::cout << "*** Step 5 ***\nm4.diagonal():\n" << m4.diagonal() << std::endl;+ std::cout << "m4.diagonal().start(3)\n" << m4.diagonal().start(3) << std::endl;++ // demo coeff-wise operations+ m4 = m4.cwise()*m4;+ m3 = m3.cwise().cos();+ std::cout << "*** Step 6 ***\nm3:\n" << m3 << "\nm4:\n" << m4 << std::endl;++ // sums of coefficients+ std::cout << "*** Step 7 ***\n m4.sum(): " << m4.sum() << std::endl;+ std::cout << "m4.col(2).sum(): " << m4.col(2).sum() << std::endl;+ std::cout << "m4.colwise().sum():\n" << m4.colwise().sum() << std::endl;+ std::cout << "m4.rowwise().sum():\n" << m4.rowwise().sum() << std::endl;++ // demo intelligent auto-evaluation+ m4 = m4 * m4; // auto-evaluates so no aliasing problem (performance penalty is low)+ Eigen::Matrix4f other = (m4 * m4).lazy(); // forces lazy evaluation+ m4 = m4 + m4; // here Eigen goes for lazy evaluation, as with most expressions+ m4 = -m4 + m4 + 5 * m4; // same here, Eigen chooses lazy evaluation for all that.+ m4 = m4 * (m4 + m4); // here Eigen chooses to first evaluate m4 + m4 into a temporary.+ // indeed, here it is an optimization to cache this intermediate result.+ m3 = m3 * m4.block<3,3>(1,1); // here Eigen chooses NOT to evaluate block() into a temporary+ // because accessing coefficients of that block expression is not more costly than accessing+ // coefficients of a plain matrix.+ m4 = m4 * m4.transpose(); // same here, lazy evaluation of the transpose.+ m4 = m4 * m4.transpose().eval(); // forces immediate evaluation of the transpose++ std::cout << "*** Step 8 ***\nm3:\n" << m3 << "\nm4:\n" << m4 << std::endl;+}
+ eigen3/eigen3.pc.in view
@@ -0,0 +1,6 @@+Name: Eigen3+Description: A C++ template library for linear algebra: vectors, matrices, and related algorithms+Requires:+Version: ${EIGEN_VERSION_NUMBER}+Libs:+Cflags: -I${INCLUDE_INSTALL_DIR}
+ eigen3/failtest/CMakeLists.txt view
@@ -0,0 +1,54 @@+message(STATUS "Running the failtests")++ei_add_failtest("failtest_sanity_check")++ei_add_failtest("block_nonconst_ctor_on_const_xpr_0")+ei_add_failtest("block_nonconst_ctor_on_const_xpr_1")+ei_add_failtest("block_nonconst_ctor_on_const_xpr_2")+ei_add_failtest("transpose_nonconst_ctor_on_const_xpr")+ei_add_failtest("diagonal_nonconst_ctor_on_const_xpr")++ei_add_failtest("const_qualified_block_method_retval_0")+ei_add_failtest("const_qualified_block_method_retval_1")+ei_add_failtest("const_qualified_transpose_method_retval")+ei_add_failtest("const_qualified_diagonal_method_retval")++ei_add_failtest("map_nonconst_ctor_on_const_ptr_0")+ei_add_failtest("map_nonconst_ctor_on_const_ptr_1")+ei_add_failtest("map_nonconst_ctor_on_const_ptr_2")+ei_add_failtest("map_nonconst_ctor_on_const_ptr_3")+ei_add_failtest("map_nonconst_ctor_on_const_ptr_4")++ei_add_failtest("map_on_const_type_actually_const_0")+ei_add_failtest("map_on_const_type_actually_const_1")+ei_add_failtest("block_on_const_type_actually_const_0")+ei_add_failtest("block_on_const_type_actually_const_1")+ei_add_failtest("transpose_on_const_type_actually_const")+ei_add_failtest("diagonal_on_const_type_actually_const")++ei_add_failtest("ref_1")+ei_add_failtest("ref_2")+ei_add_failtest("ref_3")+ei_add_failtest("ref_4")+ei_add_failtest("ref_5")++ei_add_failtest("partialpivlu_int")+ei_add_failtest("fullpivlu_int")+ei_add_failtest("llt_int")+ei_add_failtest("ldlt_int")+ei_add_failtest("qr_int")+ei_add_failtest("colpivqr_int")+ei_add_failtest("fullpivqr_int")+ei_add_failtest("jacobisvd_int")+ei_add_failtest("eigensolver_int")+ei_add_failtest("eigensolver_cplx")++if (EIGEN_FAILTEST_FAILURE_COUNT)+ message(FATAL_ERROR+ "${EIGEN_FAILTEST_FAILURE_COUNT} out of ${EIGEN_FAILTEST_COUNT} failtests FAILED. "+ "To debug these failures, manually compile these programs in ${CMAKE_CURRENT_SOURCE_DIR}, "+ "with and without #define EIGEN_SHOULD_FAIL_TO_BUILD.")+else()+ message(STATUS "Failtest SUCCESS: all ${EIGEN_FAILTEST_COUNT} failtests passed.")+ message(STATUS "")+endif()
+ eigen3/failtest/block_nonconst_ctor_on_const_xpr_0.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(CV_QUALIFIER Matrix3d &m){+ Block<Matrix3d,3,3> b(m,0,0);+}++int main() {}
+ eigen3/failtest/block_nonconst_ctor_on_const_xpr_1.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(CV_QUALIFIER Matrix3d &m){+ Block<Matrix3d> b(m,0,0,3,3);+}++int main() {}
+ eigen3/failtest/block_nonconst_ctor_on_const_xpr_2.cpp view
@@ -0,0 +1,16 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(CV_QUALIFIER Matrix3d &m){+ // row/column constructor+ Block<Matrix3d,3,1> b(m,0);+}++int main() {}
+ eigen3/failtest/block_on_const_type_actually_const_0.cpp view
@@ -0,0 +1,16 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(){+ Matrix3f m;+ Block<CV_QUALIFIER Matrix3f>(m, 0, 0, 3, 3).coeffRef(0, 0) = 1.0f;+}++int main() {}
+ eigen3/failtest/block_on_const_type_actually_const_1.cpp view
@@ -0,0 +1,16 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(){+ MatrixXf m;+ Block<CV_QUALIFIER MatrixXf, 3, 3>(m, 0, 0).coeffRef(0, 0) = 1.0f;+}++int main() {}
+ eigen3/failtest/colpivqr_int.cpp view
@@ -0,0 +1,14 @@+#include "../Eigen/QR"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define SCALAR int+#else+#define SCALAR float+#endif++using namespace Eigen;++int main()+{+ ColPivHouseholderQR<Matrix<SCALAR,Dynamic,Dynamic> > qr(Matrix<SCALAR,Dynamic,Dynamic>::Random(10,10));+}
+ eigen3/failtest/const_qualified_block_method_retval_0.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(CV_QUALIFIER Matrix3d &m){+ Block<Matrix3d,3,3> b(m.block<3,3>(0,0));+}++int main() {}
+ eigen3/failtest/const_qualified_block_method_retval_1.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(CV_QUALIFIER Matrix3d &m){+ Block<Matrix3d> b(m.block(0,0,3,3));+}++int main() {}
+ eigen3/failtest/const_qualified_diagonal_method_retval.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(CV_QUALIFIER Matrix3d &m){+ Diagonal<Matrix3d> b(m.diagonal());+}++int main() {}
+ eigen3/failtest/const_qualified_transpose_method_retval.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(CV_QUALIFIER Matrix3d &m){+ Transpose<Matrix3d> b(m.transpose());+}++int main() {}
+ eigen3/failtest/diagonal_nonconst_ctor_on_const_xpr.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(CV_QUALIFIER Matrix3d &m){+ Diagonal<Matrix3d> d(m);+}++int main() {}
+ eigen3/failtest/diagonal_on_const_type_actually_const.cpp view
@@ -0,0 +1,16 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(){+ MatrixXf m;+ Diagonal<CV_QUALIFIER MatrixXf>(m).coeffRef(0) = 1.0f;+}++int main() {}
+ eigen3/failtest/eigensolver_cplx.cpp view
@@ -0,0 +1,14 @@+#include "../Eigen/Eigenvalues"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define SCALAR std::complex<double>+#else+#define SCALAR float+#endif++using namespace Eigen;++int main()+{+ EigenSolver<Matrix<SCALAR,Dynamic,Dynamic> > eig(Matrix<SCALAR,Dynamic,Dynamic>::Random(10,10));+}
+ eigen3/failtest/eigensolver_int.cpp view
@@ -0,0 +1,14 @@+#include "../Eigen/Eigenvalues"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define SCALAR int+#else+#define SCALAR float+#endif++using namespace Eigen;++int main()+{+ EigenSolver<Matrix<SCALAR,Dynamic,Dynamic> > eig(Matrix<SCALAR,Dynamic,Dynamic>::Random(10,10));+}
+ eigen3/failtest/failtest_sanity_check.cpp view
@@ -0,0 +1,5 @@+#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+This is just some text that won't compile as a C++ file, as a basic sanity check for failtest.+#else+int main() {}+#endif
+ eigen3/failtest/fullpivlu_int.cpp view
@@ -0,0 +1,14 @@+#include "../Eigen/LU"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define SCALAR int+#else+#define SCALAR float+#endif++using namespace Eigen;++int main()+{+ FullPivLU<Matrix<SCALAR,Dynamic,Dynamic> > lu(Matrix<SCALAR,Dynamic,Dynamic>::Random(10,10));+}
+ eigen3/failtest/fullpivqr_int.cpp view
@@ -0,0 +1,14 @@+#include "../Eigen/QR"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define SCALAR int+#else+#define SCALAR float+#endif++using namespace Eigen;++int main()+{+ FullPivHouseholderQR<Matrix<SCALAR,Dynamic,Dynamic> > qr(Matrix<SCALAR,Dynamic,Dynamic>::Random(10,10));+}
+ eigen3/failtest/jacobisvd_int.cpp view
@@ -0,0 +1,14 @@+#include "../Eigen/SVD"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define SCALAR int+#else+#define SCALAR float+#endif++using namespace Eigen;++int main()+{+ JacobiSVD<Matrix<SCALAR,Dynamic,Dynamic> > qr(Matrix<SCALAR,Dynamic,Dynamic>::Random(10,10));+}
+ eigen3/failtest/ldlt_int.cpp view
@@ -0,0 +1,14 @@+#include "../Eigen/Cholesky"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define SCALAR int+#else+#define SCALAR float+#endif++using namespace Eigen;++int main()+{+ LDLT<Matrix<SCALAR,Dynamic,Dynamic> > ldlt(Matrix<SCALAR,Dynamic,Dynamic>::Random(10,10));+}
+ eigen3/failtest/llt_int.cpp view
@@ -0,0 +1,14 @@+#include "../Eigen/Cholesky"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define SCALAR int+#else+#define SCALAR float+#endif++using namespace Eigen;++int main()+{+ LLT<Matrix<SCALAR,Dynamic,Dynamic> > llt(Matrix<SCALAR,Dynamic,Dynamic>::Random(10,10));+}
+ eigen3/failtest/map_nonconst_ctor_on_const_ptr_0.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(CV_QUALIFIER float *ptr){+ Map<Matrix3f> m(ptr);+}++int main() {}
+ eigen3/failtest/map_nonconst_ctor_on_const_ptr_1.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(CV_QUALIFIER float *ptr, DenseIndex size){+ Map<ArrayXf> m(ptr, size);+}++int main() {}
+ eigen3/failtest/map_nonconst_ctor_on_const_ptr_2.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(CV_QUALIFIER float *ptr, DenseIndex rows, DenseIndex cols){+ Map<MatrixXf> m(ptr, rows, cols);+}++int main() {}
+ eigen3/failtest/map_nonconst_ctor_on_const_ptr_3.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(CV_QUALIFIER float *ptr, DenseIndex rows, DenseIndex cols){+ Map<MatrixXf, Aligned, InnerStride<2> > m(ptr, rows, cols, InnerStride<2>());+}++int main() {}
+ eigen3/failtest/map_nonconst_ctor_on_const_ptr_4.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER+#else+#define CV_QUALIFIER const+#endif++using namespace Eigen;++void foo(const float *ptr, DenseIndex rows, DenseIndex cols){+ Map<CV_QUALIFIER MatrixXf, Unaligned, OuterStride<> > m(ptr, rows, cols, OuterStride<>(2));+}++int main() {}
+ eigen3/failtest/map_on_const_type_actually_const_0.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(float *ptr){+ Map<CV_QUALIFIER MatrixXf>(ptr, 1, 1).coeffRef(0,0) = 1.0f;+}++int main() {}
+ eigen3/failtest/map_on_const_type_actually_const_1.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(float *ptr){+ Map<CV_QUALIFIER Vector3f>(ptr).coeffRef(0) = 1.0f;+}++int main() {}
+ eigen3/failtest/partialpivlu_int.cpp view
@@ -0,0 +1,14 @@+#include "../Eigen/LU"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define SCALAR int+#else+#define SCALAR float+#endif++using namespace Eigen;++int main()+{+ PartialPivLU<Matrix<SCALAR,Dynamic,Dynamic> > lu(Matrix<SCALAR,Dynamic,Dynamic>::Random(10,10));+}
+ eigen3/failtest/qr_int.cpp view
@@ -0,0 +1,14 @@+#include "../Eigen/QR"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define SCALAR int+#else+#define SCALAR float+#endif++using namespace Eigen;++int main()+{+ HouseholderQR<Matrix<SCALAR,Dynamic,Dynamic> > qr(Matrix<SCALAR,Dynamic,Dynamic>::Random(10,10));+}
+ eigen3/failtest/ref_1.cpp view
@@ -0,0 +1,18 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void call_ref(Ref<VectorXf> a) { }++int main()+{+ VectorXf a(10);+ CV_QUALIFIER VectorXf& ac(a);+ call_ref(ac);+}
+ eigen3/failtest/ref_2.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++using namespace Eigen;++void call_ref(Ref<VectorXf> a) { }++int main()+{+ MatrixXf A(10,10);+#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+ call_ref(A.row(3));+#else+ call_ref(A.col(3));+#endif+}
+ eigen3/failtest/ref_3.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++using namespace Eigen;++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+void call_ref(Ref<VectorXf> a) { }+#else+void call_ref(const Ref<const VectorXf> &a) { }+#endif++int main()+{+ VectorXf a(10);+ call_ref(a+a);+}
+ eigen3/failtest/ref_4.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++using namespace Eigen;++void call_ref(Ref<MatrixXf,0,OuterStride<> > a) {}++int main()+{+ MatrixXf A(10,10);+#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+ call_ref(A.transpose());+#else+ call_ref(A);+#endif+}
+ eigen3/failtest/ref_5.cpp view
@@ -0,0 +1,16 @@+#include "../Eigen/Core"++using namespace Eigen;++void call_ref(Ref<VectorXf> a) { }++int main()+{+ VectorXf a(10);+ DenseBase<VectorXf> &ac(a);+#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+ call_ref(ac);+#else+ call_ref(ac.derived());+#endif+}
+ eigen3/failtest/transpose_nonconst_ctor_on_const_xpr.cpp view
@@ -0,0 +1,15 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(CV_QUALIFIER Matrix3d &m){+ Transpose<Matrix3d> t(m);+}++int main() {}
+ eigen3/failtest/transpose_on_const_type_actually_const.cpp view
@@ -0,0 +1,16 @@+#include "../Eigen/Core"++#ifdef EIGEN_SHOULD_FAIL_TO_BUILD+#define CV_QUALIFIER const+#else+#define CV_QUALIFIER+#endif++using namespace Eigen;++void foo(){+ MatrixXf m;+ Transpose<CV_QUALIFIER MatrixXf>(m).coeffRef(0, 0) = 1.0f;+}++int main() {}
+ eigen3/lapack/CMakeLists.txt view
@@ -0,0 +1,449 @@++project(EigenLapack CXX)++include("../cmake/language_support.cmake")++workaround_9220(Fortran EIGEN_Fortran_COMPILER_WORKS)++if(EIGEN_Fortran_COMPILER_WORKS)+ enable_language(Fortran OPTIONAL)+ if(NOT CMAKE_Fortran_COMPILER)+ set(EIGEN_Fortran_COMPILER_WORKS OFF)+ endif()+endif()++add_custom_target(lapack)+include_directories(../blas)++set(EigenLapack_SRCS+single.cpp double.cpp complex_single.cpp complex_double.cpp ../blas/xerbla.cpp+)++if(EIGEN_Fortran_COMPILER_WORKS)++set(EigenLapack_SRCS ${EigenLapack_SRCS}+ slarft.f dlarft.f clarft.f zlarft.f+ slarfb.f dlarfb.f clarfb.f zlarfb.f+ slarfg.f dlarfg.f clarfg.f zlarfg.f+ slarf.f dlarf.f clarf.f zlarf.f+ sladiv.f dladiv.f cladiv.f zladiv.f+ ilaslr.f iladlr.f ilaclr.f ilazlr.f+ ilaslc.f iladlc.f ilaclc.f ilazlc.f+ dlapy2.f dlapy3.f slapy2.f slapy3.f+ clacgv.f zlacgv.f+ slamch.f dlamch.f+ second_NONE.f dsecnd_NONE.f+)++option(EIGEN_ENABLE_LAPACK_TESTS OFF "Enbale the Lapack unit tests")++if(EIGEN_ENABLE_LAPACK_TESTS)++ get_filename_component(eigen_full_path_to_reference_lapack "./reference/" ABSOLUTE)+ if(NOT EXISTS ${eigen_full_path_to_reference_lapack})+ # Download lapack and install sources and testing at the right place+ message(STATUS "Download lapack_addons_3.4.1.tgz...")+ + file(DOWNLOAD "http://downloads.tuxfamily.org/eigen/lapack_addons_3.4.1.tgz"+ "${CMAKE_CURRENT_SOURCE_DIR}/lapack_addons_3.4.1.tgz"+ INACTIVITY_TIMEOUT 15+ TIMEOUT 240+ STATUS download_status+ EXPECTED_MD5 5758ce55afcf79da98de8b9de1615ad5+ SHOW_PROGRESS)+ + message(STATUS ${download_status})+ list(GET download_status 0 download_status_num)+ set(download_status_num 0)+ if(download_status_num EQUAL 0)+ message(STATUS "Setup lapack reference and lapack unit tests")+ execute_process(COMMAND tar xzf "lapack_addons_3.4.1.tgz" WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})+ else()+ message(STATUS "Download of lapack_addons_3.4.1.tgz failed, LAPACK unit tests wont be enabled")+ set(EIGEN_ENABLE_LAPACK_TESTS false)+ endif()+ + endif()+ + get_filename_component(eigen_full_path_to_reference_lapack "./reference/" ABSOLUTE)+ if(EXISTS ${eigen_full_path_to_reference_lapack})+ set(EigenLapack_funcfilenames+ ssyev.f dsyev.f csyev.f zsyev.f+ spotrf.f dpotrf.f cpotrf.f zpotrf.f+ spotrs.f dpotrs.f cpotrs.f zpotrs.f+ sgetrf.f dgetrf.f cgetrf.f zgetrf.f+ sgetrs.f dgetrs.f cgetrs.f zgetrs.f)+ + FILE(GLOB ReferenceLapack_SRCS0 RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "reference/*.f")+ foreach(filename1 IN LISTS ReferenceLapack_SRCS0)+ string(REPLACE "reference/" "" filename ${filename1})+ list(FIND EigenLapack_SRCS ${filename} id1)+ list(FIND EigenLapack_funcfilenames ${filename} id2)+ if((id1 EQUAL -1) AND (id2 EQUAL -1))+ set(ReferenceLapack_SRCS ${ReferenceLapack_SRCS} reference/${filename})+ endif()+ endforeach()+ endif()+ + +endif(EIGEN_ENABLE_LAPACK_TESTS)++endif(EIGEN_Fortran_COMPILER_WORKS)++add_library(eigen_lapack_static ${EigenLapack_SRCS} ${ReferenceLapack_SRCS})+add_library(eigen_lapack SHARED ${EigenLapack_SRCS})++target_link_libraries(eigen_lapack eigen_blas)++if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)+ target_link_libraries(eigen_lapack_static ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})+ target_link_libraries(eigen_lapack ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})+endif()++add_dependencies(lapack eigen_lapack eigen_lapack_static)++install(TARGETS eigen_lapack eigen_lapack_static+ RUNTIME DESTINATION bin+ LIBRARY DESTINATION lib+ ARCHIVE DESTINATION lib)++ + +get_filename_component(eigen_full_path_to_testing_lapack "./testing/" ABSOLUTE)+if(EXISTS ${eigen_full_path_to_testing_lapack})+ + # The following comes from lapack/TESTING/CMakeLists.txt+ # Get Python+ find_package(PythonInterp)+ message(STATUS "Looking for Python found - ${PYTHONINTERP_FOUND}")+ if (PYTHONINTERP_FOUND)+ message(STATUS "Using Python version ${PYTHON_VERSION_STRING}")+ endif()++ set(LAPACK_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})+ set(LAPACK_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})+ set(BUILD_SINGLE true)+ set(BUILD_DOUBLE true)+ set(BUILD_COMPLEX true)+ set(BUILD_COMPLEX16E true)+ + if(MSVC_VERSION)+# string(REPLACE "/STACK:10000000" "/STACK:900000000000000000"+# CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")+ string(REGEX REPLACE "(.*)/STACK:(.*) (.*)" "\\1/STACK:900000000000000000 \\3"+ CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")+ endif()+ add_subdirectory(testing/MATGEN)+ add_subdirectory(testing/LIN)+ add_subdirectory(testing/EIG)+ macro(add_lapack_test output input target)+ set(TEST_INPUT "${LAPACK_SOURCE_DIR}/testing/${input}")+ set(TEST_OUTPUT "${LAPACK_BINARY_DIR}/testing/${output}")+ get_target_property(TEST_LOC ${target} LOCATION)+ string(REPLACE "." "_" input_name ${input})+ set(testName "${target}_${input_name}")+ if(EXISTS "${TEST_INPUT}")+ add_test(LAPACK-${testName} "${CMAKE_COMMAND}"+ -DTEST=${TEST_LOC}+ -DINPUT=${TEST_INPUT} + -DOUTPUT=${TEST_OUTPUT} + -DINTDIR=${CMAKE_CFG_INTDIR}+ -P "${LAPACK_SOURCE_DIR}/testing/runtest.cmake")+ endif()+ endmacro(add_lapack_test)++ if (BUILD_SINGLE)+ add_lapack_test(stest.out stest.in xlintsts)+ #+ # ======== SINGLE RFP LIN TESTS ========================+ add_lapack_test(stest_rfp.out stest_rfp.in xlintstrfs)+ #+ #+ # ======== SINGLE EIG TESTS ===========================+ #++ add_lapack_test(snep.out nep.in xeigtsts)+++ add_lapack_test(ssep.out sep.in xeigtsts)+++ add_lapack_test(ssvd.out svd.in xeigtsts)+++ add_lapack_test(sec.out sec.in xeigtsts)+++ add_lapack_test(sed.out sed.in xeigtsts)+++ add_lapack_test(sgg.out sgg.in xeigtsts)+++ add_lapack_test(sgd.out sgd.in xeigtsts)+++ add_lapack_test(ssb.out ssb.in xeigtsts)+++ add_lapack_test(ssg.out ssg.in xeigtsts)+++ add_lapack_test(sbal.out sbal.in xeigtsts)+++ add_lapack_test(sbak.out sbak.in xeigtsts)+++ add_lapack_test(sgbal.out sgbal.in xeigtsts)+++ add_lapack_test(sgbak.out sgbak.in xeigtsts)+++ add_lapack_test(sbb.out sbb.in xeigtsts)+++ add_lapack_test(sglm.out glm.in xeigtsts)+++ add_lapack_test(sgqr.out gqr.in xeigtsts)+++ add_lapack_test(sgsv.out gsv.in xeigtsts)+++ add_lapack_test(scsd.out csd.in xeigtsts)+++ add_lapack_test(slse.out lse.in xeigtsts)+ endif()++ if (BUILD_DOUBLE)+ #+ # ======== DOUBLE LIN TESTS ===========================+ add_lapack_test(dtest.out dtest.in xlintstd)+ #+ # ======== DOUBLE RFP LIN TESTS ========================+ add_lapack_test(dtest_rfp.out dtest_rfp.in xlintstrfd)+ #+ # ======== DOUBLE EIG TESTS ===========================++ add_lapack_test(dnep.out nep.in xeigtstd)+++ add_lapack_test(dsep.out sep.in xeigtstd)+++ add_lapack_test(dsvd.out svd.in xeigtstd)+++ add_lapack_test(dec.out dec.in xeigtstd)+++ add_lapack_test(ded.out ded.in xeigtstd)+++ add_lapack_test(dgg.out dgg.in xeigtstd)+++ add_lapack_test(dgd.out dgd.in xeigtstd)+++ add_lapack_test(dsb.out dsb.in xeigtstd)+++ add_lapack_test(dsg.out dsg.in xeigtstd)+++ add_lapack_test(dbal.out dbal.in xeigtstd)+++ add_lapack_test(dbak.out dbak.in xeigtstd)+++ add_lapack_test(dgbal.out dgbal.in xeigtstd)+++ add_lapack_test(dgbak.out dgbak.in xeigtstd)+++ add_lapack_test(dbb.out dbb.in xeigtstd)+++ add_lapack_test(dglm.out glm.in xeigtstd)+++ add_lapack_test(dgqr.out gqr.in xeigtstd)+++ add_lapack_test(dgsv.out gsv.in xeigtstd)+++ add_lapack_test(dcsd.out csd.in xeigtstd)+++ add_lapack_test(dlse.out lse.in xeigtstd)+ endif()++ if (BUILD_COMPLEX)+ add_lapack_test(ctest.out ctest.in xlintstc)+ #+ # ======== COMPLEX RFP LIN TESTS ========================+ add_lapack_test(ctest_rfp.out ctest_rfp.in xlintstrfc)+ #+ # ======== COMPLEX EIG TESTS ===========================++ add_lapack_test(cnep.out nep.in xeigtstc)+++ add_lapack_test(csep.out sep.in xeigtstc)+++ add_lapack_test(csvd.out svd.in xeigtstc)+++ add_lapack_test(cec.out cec.in xeigtstc)+++ add_lapack_test(ced.out ced.in xeigtstc)+++ add_lapack_test(cgg.out cgg.in xeigtstc)+++ add_lapack_test(cgd.out cgd.in xeigtstc)+++ add_lapack_test(csb.out csb.in xeigtstc)+++ add_lapack_test(csg.out csg.in xeigtstc)+++ add_lapack_test(cbal.out cbal.in xeigtstc)+++ add_lapack_test(cbak.out cbak.in xeigtstc)+++ add_lapack_test(cgbal.out cgbal.in xeigtstc)+++ add_lapack_test(cgbak.out cgbak.in xeigtstc)+++ add_lapack_test(cbb.out cbb.in xeigtstc)+++ add_lapack_test(cglm.out glm.in xeigtstc)+++ add_lapack_test(cgqr.out gqr.in xeigtstc)+++ add_lapack_test(cgsv.out gsv.in xeigtstc)+++ add_lapack_test(ccsd.out csd.in xeigtstc)+++ add_lapack_test(clse.out lse.in xeigtstc)+ endif()++ if (BUILD_COMPLEX16)+ #+ # ======== COMPLEX16 LIN TESTS ========================+ add_lapack_test(ztest.out ztest.in xlintstz)+ #+ # ======== COMPLEX16 RFP LIN TESTS ========================+ add_lapack_test(ztest_rfp.out ztest_rfp.in xlintstrfz)+ #+ # ======== COMPLEX16 EIG TESTS ===========================++ add_lapack_test(znep.out nep.in xeigtstz)+++ add_lapack_test(zsep.out sep.in xeigtstz)+++ add_lapack_test(zsvd.out svd.in xeigtstz)+++ add_lapack_test(zec.out zec.in xeigtstz)+++ add_lapack_test(zed.out zed.in xeigtstz)+++ add_lapack_test(zgg.out zgg.in xeigtstz)+++ add_lapack_test(zgd.out zgd.in xeigtstz)+++ add_lapack_test(zsb.out zsb.in xeigtstz)+++ add_lapack_test(zsg.out zsg.in xeigtstz)+++ add_lapack_test(zbal.out zbal.in xeigtstz)+++ add_lapack_test(zbak.out zbak.in xeigtstz)+++ add_lapack_test(zgbal.out zgbal.in xeigtstz)+++ add_lapack_test(zgbak.out zgbak.in xeigtstz)+++ add_lapack_test(zbb.out zbb.in xeigtstz)+++ add_lapack_test(zglm.out glm.in xeigtstz)+++ add_lapack_test(zgqr.out gqr.in xeigtstz)+++ add_lapack_test(zgsv.out gsv.in xeigtstz)+++ add_lapack_test(zcsd.out csd.in xeigtstz)+++ add_lapack_test(zlse.out lse.in xeigtstz)+ endif()+++ if (BUILD_SIMPLE)+ if (BUILD_DOUBLE)+ #+ # ======== SINGLE-DOUBLE PROTO LIN TESTS ==============+ add_lapack_test(dstest.out dstest.in xlintstds)+ endif()+ endif()+++ if (BUILD_COMPLEX)+ if (BUILD_COMPLEX16)+ #+ # ======== COMPLEX-COMPLEX16 LIN TESTS ========================+ add_lapack_test(zctest.out zctest.in xlintstzc)+ endif()+ endif()++ # ==============================================================================++ execute_process(COMMAND ${CMAKE_COMMAND} -E copy ${LAPACK_SOURCE_DIR}/testing/lapack_testing.py ${LAPACK_BINARY_DIR})+ add_test(+ NAME LAPACK_Test_Summary+ WORKING_DIRECTORY ${LAPACK_BINARY_DIR}+ COMMAND ${PYTHON_EXECUTABLE} "lapack_testing.py"+ )++endif()+
+ eigen3/lapack/cholesky.cpp view
@@ -0,0 +1,72 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010-2011 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "lapack_common.h"+#include <Eigen/Cholesky>++// POTRF computes the Cholesky factorization of a real symmetric positive definite matrix A.+EIGEN_LAPACK_FUNC(potrf,(char* uplo, int *n, RealScalar *pa, int *lda, int *info))+{+ *info = 0;+ if(UPLO(*uplo)==INVALID) *info = -1;+ else if(*n<0) *info = -2;+ else if(*lda<std::max(1,*n)) *info = -4;+ if(*info!=0)+ {+ int e = -*info;+ return xerbla_(SCALAR_SUFFIX_UP"POTRF", &e, 6);+ }++ Scalar* a = reinterpret_cast<Scalar*>(pa);+ MatrixType A(a,*n,*n,*lda);+ int ret;+ if(UPLO(*uplo)==UP) ret = int(internal::llt_inplace<Scalar, Upper>::blocked(A));+ else ret = int(internal::llt_inplace<Scalar, Lower>::blocked(A));++ if(ret>=0)+ *info = ret+1;+ + return 0;+}++// POTRS solves a system of linear equations A*X = B with a symmetric+// positive definite matrix A using the Cholesky factorization+// A = U**T*U or A = L*L**T computed by DPOTRF.+EIGEN_LAPACK_FUNC(potrs,(char* uplo, int *n, int *nrhs, RealScalar *pa, int *lda, RealScalar *pb, int *ldb, int *info))+{+ *info = 0;+ if(UPLO(*uplo)==INVALID) *info = -1;+ else if(*n<0) *info = -2;+ else if(*nrhs<0) *info = -3;+ else if(*lda<std::max(1,*n)) *info = -5;+ else if(*ldb<std::max(1,*n)) *info = -7;+ if(*info!=0)+ {+ int e = -*info;+ return xerbla_(SCALAR_SUFFIX_UP"POTRS", &e, 6);+ }++ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* b = reinterpret_cast<Scalar*>(pb);+ MatrixType A(a,*n,*n,*lda);+ MatrixType B(b,*n,*nrhs,*ldb);++ if(UPLO(*uplo)==UP)+ {+ A.triangularView<Upper>().adjoint().solveInPlace(B);+ A.triangularView<Upper>().solveInPlace(B);+ }+ else+ {+ A.triangularView<Lower>().solveInPlace(B);+ A.triangularView<Lower>().adjoint().solveInPlace(B);+ }++ return 0;+}
+ eigen3/lapack/clacgv.f view
@@ -0,0 +1,116 @@+*> \brief \b CLACGV+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download CLACGV + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/clacgv.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/clacgv.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/clacgv.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE CLACGV( N, X, INCX )+* +* .. Scalar Arguments ..+* INTEGER INCX, N+* ..+* .. Array Arguments ..+* COMPLEX X( * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> CLACGV conjugates a complex vector of length N.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The length of the vector X. N >= 0.+*> \endverbatim+*>+*> \param[in,out] X+*> \verbatim+*> X is COMPLEX array, dimension+*> (1+(N-1)*abs(INCX))+*> On entry, the vector of length N to be conjugated.+*> On exit, X is overwritten with conjg(X).+*> \endverbatim+*>+*> \param[in] INCX+*> \verbatim+*> INCX is INTEGER+*> The spacing between successive elements of X.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup complexOTHERauxiliary+*+* =====================================================================+ SUBROUTINE CLACGV( N, X, INCX )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ INTEGER INCX, N+* ..+* .. Array Arguments ..+ COMPLEX X( * )+* ..+*+* =====================================================================+*+* .. Local Scalars ..+ INTEGER I, IOFF+* ..+* .. Intrinsic Functions ..+ INTRINSIC CONJG+* ..+* .. Executable Statements ..+*+ IF( INCX.EQ.1 ) THEN+ DO 10 I = 1, N+ X( I ) = CONJG( X( I ) )+ 10 CONTINUE+ ELSE+ IOFF = 1+ IF( INCX.LT.0 )+ $ IOFF = 1 - ( N-1 )*INCX+ DO 20 I = 1, N+ X( IOFF ) = CONJG( X( IOFF ) )+ IOFF = IOFF + INCX+ 20 CONTINUE+ END IF+ RETURN+*+* End of CLACGV+*+ END
+ eigen3/lapack/cladiv.f view
@@ -0,0 +1,97 @@+*> \brief \b CLADIV+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download CLADIV + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cladiv.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cladiv.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cladiv.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* COMPLEX FUNCTION CLADIV( X, Y )+* +* .. Scalar Arguments ..+* COMPLEX X, Y+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> CLADIV := X / Y, where X and Y are complex. The computation of X / Y+*> will not overflow on an intermediary step unless the results+*> overflows.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] X+*> \verbatim+*> X is COMPLEX+*> \endverbatim+*>+*> \param[in] Y+*> \verbatim+*> Y is COMPLEX+*> The complex scalars X and Y.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup complexOTHERauxiliary+*+* =====================================================================+ COMPLEX FUNCTION CLADIV( X, Y )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ COMPLEX X, Y+* ..+*+* =====================================================================+*+* .. Local Scalars ..+ REAL ZI, ZR+* ..+* .. External Subroutines ..+ EXTERNAL SLADIV+* ..+* .. Intrinsic Functions ..+ INTRINSIC AIMAG, CMPLX, REAL+* ..+* .. Executable Statements ..+*+ CALL SLADIV( REAL( X ), AIMAG( X ), REAL( Y ), AIMAG( Y ), ZR,+ $ ZI )+ CLADIV = CMPLX( ZR, ZI )+*+ RETURN+*+* End of CLADIV+*+ END
+ eigen3/lapack/clarf.f view
@@ -0,0 +1,232 @@+*> \brief \b CLARF+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download CLARF + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/clarf.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/clarf.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/clarf.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE CLARF( SIDE, M, N, V, INCV, TAU, C, LDC, WORK )+* +* .. Scalar Arguments ..+* CHARACTER SIDE+* INTEGER INCV, LDC, M, N+* COMPLEX TAU+* ..+* .. Array Arguments ..+* COMPLEX C( LDC, * ), V( * ), WORK( * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> CLARF applies a complex elementary reflector H to a complex M-by-N+*> matrix C, from either the left or the right. H is represented in the+*> form+*>+*> H = I - tau * v * v**H+*>+*> where tau is a complex scalar and v is a complex vector.+*>+*> If tau = 0, then H is taken to be the unit matrix.+*>+*> To apply H**H (the conjugate transpose of H), supply conjg(tau) instead+*> tau.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] SIDE+*> \verbatim+*> SIDE is CHARACTER*1+*> = 'L': form H * C+*> = 'R': form C * H+*> \endverbatim+*>+*> \param[in] M+*> \verbatim+*> M is INTEGER+*> The number of rows of the matrix C.+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The number of columns of the matrix C.+*> \endverbatim+*>+*> \param[in] V+*> \verbatim+*> V is COMPLEX array, dimension+*> (1 + (M-1)*abs(INCV)) if SIDE = 'L'+*> or (1 + (N-1)*abs(INCV)) if SIDE = 'R'+*> The vector v in the representation of H. V is not used if+*> TAU = 0.+*> \endverbatim+*>+*> \param[in] INCV+*> \verbatim+*> INCV is INTEGER+*> The increment between elements of v. INCV <> 0.+*> \endverbatim+*>+*> \param[in] TAU+*> \verbatim+*> TAU is COMPLEX+*> The value tau in the representation of H.+*> \endverbatim+*>+*> \param[in,out] C+*> \verbatim+*> C is COMPLEX array, dimension (LDC,N)+*> On entry, the M-by-N matrix C.+*> On exit, C is overwritten by the matrix H * C if SIDE = 'L',+*> or C * H if SIDE = 'R'.+*> \endverbatim+*>+*> \param[in] LDC+*> \verbatim+*> LDC is INTEGER+*> The leading dimension of the array C. LDC >= max(1,M).+*> \endverbatim+*>+*> \param[out] WORK+*> \verbatim+*> WORK is COMPLEX array, dimension+*> (N) if SIDE = 'L'+*> or (M) if SIDE = 'R'+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup complexOTHERauxiliary+*+* =====================================================================+ SUBROUTINE CLARF( SIDE, M, N, V, INCV, TAU, C, LDC, WORK )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ CHARACTER SIDE+ INTEGER INCV, LDC, M, N+ COMPLEX TAU+* ..+* .. Array Arguments ..+ COMPLEX C( LDC, * ), V( * ), WORK( * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ COMPLEX ONE, ZERO+ PARAMETER ( ONE = ( 1.0E+0, 0.0E+0 ),+ $ ZERO = ( 0.0E+0, 0.0E+0 ) )+* ..+* .. Local Scalars ..+ LOGICAL APPLYLEFT+ INTEGER I, LASTV, LASTC+* ..+* .. External Subroutines ..+ EXTERNAL CGEMV, CGERC+* ..+* .. External Functions ..+ LOGICAL LSAME+ INTEGER ILACLR, ILACLC+ EXTERNAL LSAME, ILACLR, ILACLC+* ..+* .. Executable Statements ..+*+ APPLYLEFT = LSAME( SIDE, 'L' )+ LASTV = 0+ LASTC = 0+ IF( TAU.NE.ZERO ) THEN+! Set up variables for scanning V. LASTV begins pointing to the end+! of V.+ IF( APPLYLEFT ) THEN+ LASTV = M+ ELSE+ LASTV = N+ END IF+ IF( INCV.GT.0 ) THEN+ I = 1 + (LASTV-1) * INCV+ ELSE+ I = 1+ END IF+! Look for the last non-zero row in V.+ DO WHILE( LASTV.GT.0 .AND. V( I ).EQ.ZERO )+ LASTV = LASTV - 1+ I = I - INCV+ END DO+ IF( APPLYLEFT ) THEN+! Scan for the last non-zero column in C(1:lastv,:).+ LASTC = ILACLC(LASTV, N, C, LDC)+ ELSE+! Scan for the last non-zero row in C(:,1:lastv).+ LASTC = ILACLR(M, LASTV, C, LDC)+ END IF+ END IF+! Note that lastc.eq.0 renders the BLAS operations null; no special+! case is needed at this level.+ IF( APPLYLEFT ) THEN+*+* Form H * C+*+ IF( LASTV.GT.0 ) THEN+*+* w(1:lastc,1) := C(1:lastv,1:lastc)**H * v(1:lastv,1)+*+ CALL CGEMV( 'Conjugate transpose', LASTV, LASTC, ONE,+ $ C, LDC, V, INCV, ZERO, WORK, 1 )+*+* C(1:lastv,1:lastc) := C(...) - v(1:lastv,1) * w(1:lastc,1)**H+*+ CALL CGERC( LASTV, LASTC, -TAU, V, INCV, WORK, 1, C, LDC )+ END IF+ ELSE+*+* Form C * H+*+ IF( LASTV.GT.0 ) THEN+*+* w(1:lastc,1) := C(1:lastc,1:lastv) * v(1:lastv,1)+*+ CALL CGEMV( 'No transpose', LASTC, LASTV, ONE, C, LDC,+ $ V, INCV, ZERO, WORK, 1 )+*+* C(1:lastc,1:lastv) := C(...) - w(1:lastc,1) * v(1:lastv,1)**H+*+ CALL CGERC( LASTC, LASTV, -TAU, WORK, 1, V, INCV, C, LDC )+ END IF+ END IF+ RETURN+*+* End of CLARF+*+ END
+ eigen3/lapack/clarfb.f view
@@ -0,0 +1,771 @@+*> \brief \b CLARFB+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download CLARFB + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/clarfb.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/clarfb.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/clarfb.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE CLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV,+* T, LDT, C, LDC, WORK, LDWORK )+* +* .. Scalar Arguments ..+* CHARACTER DIRECT, SIDE, STOREV, TRANS+* INTEGER K, LDC, LDT, LDV, LDWORK, M, N+* ..+* .. Array Arguments ..+* COMPLEX C( LDC, * ), T( LDT, * ), V( LDV, * ),+* $ WORK( LDWORK, * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> CLARFB applies a complex block reflector H or its transpose H**H to a+*> complex M-by-N matrix C, from either the left or the right.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] SIDE+*> \verbatim+*> SIDE is CHARACTER*1+*> = 'L': apply H or H**H from the Left+*> = 'R': apply H or H**H from the Right+*> \endverbatim+*>+*> \param[in] TRANS+*> \verbatim+*> TRANS is CHARACTER*1+*> = 'N': apply H (No transpose)+*> = 'C': apply H**H (Conjugate transpose)+*> \endverbatim+*>+*> \param[in] DIRECT+*> \verbatim+*> DIRECT is CHARACTER*1+*> Indicates how H is formed from a product of elementary+*> reflectors+*> = 'F': H = H(1) H(2) . . . H(k) (Forward)+*> = 'B': H = H(k) . . . H(2) H(1) (Backward)+*> \endverbatim+*>+*> \param[in] STOREV+*> \verbatim+*> STOREV is CHARACTER*1+*> Indicates how the vectors which define the elementary+*> reflectors are stored:+*> = 'C': Columnwise+*> = 'R': Rowwise+*> \endverbatim+*>+*> \param[in] M+*> \verbatim+*> M is INTEGER+*> The number of rows of the matrix C.+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The number of columns of the matrix C.+*> \endverbatim+*>+*> \param[in] K+*> \verbatim+*> K is INTEGER+*> The order of the matrix T (= the number of elementary+*> reflectors whose product defines the block reflector).+*> \endverbatim+*>+*> \param[in] V+*> \verbatim+*> V is COMPLEX array, dimension+*> (LDV,K) if STOREV = 'C'+*> (LDV,M) if STOREV = 'R' and SIDE = 'L'+*> (LDV,N) if STOREV = 'R' and SIDE = 'R'+*> The matrix V. See Further Details.+*> \endverbatim+*>+*> \param[in] LDV+*> \verbatim+*> LDV is INTEGER+*> The leading dimension of the array V.+*> If STOREV = 'C' and SIDE = 'L', LDV >= max(1,M);+*> if STOREV = 'C' and SIDE = 'R', LDV >= max(1,N);+*> if STOREV = 'R', LDV >= K.+*> \endverbatim+*>+*> \param[in] T+*> \verbatim+*> T is COMPLEX array, dimension (LDT,K)+*> The triangular K-by-K matrix T in the representation of the+*> block reflector.+*> \endverbatim+*>+*> \param[in] LDT+*> \verbatim+*> LDT is INTEGER+*> The leading dimension of the array T. LDT >= K.+*> \endverbatim+*>+*> \param[in,out] C+*> \verbatim+*> C is COMPLEX array, dimension (LDC,N)+*> On entry, the M-by-N matrix C.+*> On exit, C is overwritten by H*C or H**H*C or C*H or C*H**H.+*> \endverbatim+*>+*> \param[in] LDC+*> \verbatim+*> LDC is INTEGER+*> The leading dimension of the array C. LDC >= max(1,M).+*> \endverbatim+*>+*> \param[out] WORK+*> \verbatim+*> WORK is COMPLEX array, dimension (LDWORK,K)+*> \endverbatim+*>+*> \param[in] LDWORK+*> \verbatim+*> LDWORK is INTEGER+*> The leading dimension of the array WORK.+*> If SIDE = 'L', LDWORK >= max(1,N);+*> if SIDE = 'R', LDWORK >= max(1,M).+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup complexOTHERauxiliary+*+*> \par Further Details:+* =====================+*>+*> \verbatim+*>+*> The shape of the matrix V and the storage of the vectors which define+*> the H(i) is best illustrated by the following example with n = 5 and+*> k = 3. The elements equal to 1 are not stored; the corresponding+*> array elements are modified but restored on exit. The rest of the+*> array is not used.+*>+*> DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R':+*>+*> V = ( 1 ) V = ( 1 v1 v1 v1 v1 )+*> ( v1 1 ) ( 1 v2 v2 v2 )+*> ( v1 v2 1 ) ( 1 v3 v3 )+*> ( v1 v2 v3 )+*> ( v1 v2 v3 )+*>+*> DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R':+*>+*> V = ( v1 v2 v3 ) V = ( v1 v1 1 )+*> ( v1 v2 v3 ) ( v2 v2 v2 1 )+*> ( 1 v2 v3 ) ( v3 v3 v3 v3 1 )+*> ( 1 v3 )+*> ( 1 )+*> \endverbatim+*>+* =====================================================================+ SUBROUTINE CLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV,+ $ T, LDT, C, LDC, WORK, LDWORK )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ CHARACTER DIRECT, SIDE, STOREV, TRANS+ INTEGER K, LDC, LDT, LDV, LDWORK, M, N+* ..+* .. Array Arguments ..+ COMPLEX C( LDC, * ), T( LDT, * ), V( LDV, * ),+ $ WORK( LDWORK, * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ COMPLEX ONE+ PARAMETER ( ONE = ( 1.0E+0, 0.0E+0 ) )+* ..+* .. Local Scalars ..+ CHARACTER TRANST+ INTEGER I, J, LASTV, LASTC+* ..+* .. External Functions ..+ LOGICAL LSAME+ INTEGER ILACLR, ILACLC+ EXTERNAL LSAME, ILACLR, ILACLC+* ..+* .. External Subroutines ..+ EXTERNAL CCOPY, CGEMM, CLACGV, CTRMM+* ..+* .. Intrinsic Functions ..+ INTRINSIC CONJG+* ..+* .. Executable Statements ..+*+* Quick return if possible+*+ IF( M.LE.0 .OR. N.LE.0 )+ $ RETURN+*+ IF( LSAME( TRANS, 'N' ) ) THEN+ TRANST = 'C'+ ELSE+ TRANST = 'N'+ END IF+*+ IF( LSAME( STOREV, 'C' ) ) THEN+*+ IF( LSAME( DIRECT, 'F' ) ) THEN+*+* Let V = ( V1 ) (first K rows)+* ( V2 )+* where V1 is unit lower triangular.+*+ IF( LSAME( SIDE, 'L' ) ) THEN+*+* Form H * C or H**H * C where C = ( C1 )+* ( C2 )+*+ LASTV = MAX( K, ILACLR( M, K, V, LDV ) )+ LASTC = ILACLC( LASTV, N, C, LDC )+*+* W := C**H * V = (C1**H * V1 + C2**H * V2) (stored in WORK)+*+* W := C1**H+*+ DO 10 J = 1, K+ CALL CCOPY( LASTC, C( J, 1 ), LDC, WORK( 1, J ), 1 )+ CALL CLACGV( LASTC, WORK( 1, J ), 1 )+ 10 CONTINUE+*+* W := W * V1+*+ CALL CTRMM( 'Right', 'Lower', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C2**H *V2+*+ CALL CGEMM( 'Conjugate transpose', 'No transpose',+ $ LASTC, K, LASTV-K, ONE, C( K+1, 1 ), LDC,+ $ V( K+1, 1 ), LDV, ONE, WORK, LDWORK )+ END IF+*+* W := W * T**H or W * T+*+ CALL CTRMM( 'Right', 'Upper', TRANST, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - V * W**H+*+ IF( M.GT.K ) THEN+*+* C2 := C2 - V2 * W**H+*+ CALL CGEMM( 'No transpose', 'Conjugate transpose',+ $ LASTV-K, LASTC, K, -ONE, V( K+1, 1 ), LDV,+ $ WORK, LDWORK, ONE, C( K+1, 1 ), LDC )+ END IF+*+* W := W * V1**H+*+ CALL CTRMM( 'Right', 'Lower', 'Conjugate transpose',+ $ 'Unit', LASTC, K, ONE, V, LDV, WORK, LDWORK )+*+* C1 := C1 - W**H+*+ DO 30 J = 1, K+ DO 20 I = 1, LASTC+ C( J, I ) = C( J, I ) - CONJG( WORK( I, J ) )+ 20 CONTINUE+ 30 CONTINUE+*+ ELSE IF( LSAME( SIDE, 'R' ) ) THEN+*+* Form C * H or C * H**H where C = ( C1 C2 )+*+ LASTV = MAX( K, ILACLR( N, K, V, LDV ) )+ LASTC = ILACLR( M, LASTV, C, LDC )+*+* W := C * V = (C1*V1 + C2*V2) (stored in WORK)+*+* W := C1+*+ DO 40 J = 1, K+ CALL CCOPY( LASTC, C( 1, J ), 1, WORK( 1, J ), 1 )+ 40 CONTINUE+*+* W := W * V1+*+ CALL CTRMM( 'Right', 'Lower', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C2 * V2+*+ CALL CGEMM( 'No transpose', 'No transpose',+ $ LASTC, K, LASTV-K,+ $ ONE, C( 1, K+1 ), LDC, V( K+1, 1 ), LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T or W * T**H+*+ CALL CTRMM( 'Right', 'Upper', TRANS, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - W * V**H+*+ IF( LASTV.GT.K ) THEN+*+* C2 := C2 - W * V2**H+*+ CALL CGEMM( 'No transpose', 'Conjugate transpose',+ $ LASTC, LASTV-K, K,+ $ -ONE, WORK, LDWORK, V( K+1, 1 ), LDV,+ $ ONE, C( 1, K+1 ), LDC )+ END IF+*+* W := W * V1**H+*+ CALL CTRMM( 'Right', 'Lower', 'Conjugate transpose',+ $ 'Unit', LASTC, K, ONE, V, LDV, WORK, LDWORK )+*+* C1 := C1 - W+*+ DO 60 J = 1, K+ DO 50 I = 1, LASTC+ C( I, J ) = C( I, J ) - WORK( I, J )+ 50 CONTINUE+ 60 CONTINUE+ END IF+*+ ELSE+*+* Let V = ( V1 )+* ( V2 ) (last K rows)+* where V2 is unit upper triangular.+*+ IF( LSAME( SIDE, 'L' ) ) THEN+*+* Form H * C or H**H * C where C = ( C1 )+* ( C2 )+*+ LASTV = MAX( K, ILACLR( M, K, V, LDV ) )+ LASTC = ILACLC( LASTV, N, C, LDC )+*+* W := C**H * V = (C1**H * V1 + C2**H * V2) (stored in WORK)+*+* W := C2**H+*+ DO 70 J = 1, K+ CALL CCOPY( LASTC, C( LASTV-K+J, 1 ), LDC,+ $ WORK( 1, J ), 1 )+ CALL CLACGV( LASTC, WORK( 1, J ), 1 )+ 70 CONTINUE+*+* W := W * V2+*+ CALL CTRMM( 'Right', 'Upper', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,+ $ WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C1**H*V1+*+ CALL CGEMM( 'Conjugate transpose', 'No transpose',+ $ LASTC, K, LASTV-K, ONE, C, LDC, V, LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T**H or W * T+*+ CALL CTRMM( 'Right', 'Lower', TRANST, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - V * W**H+*+ IF( LASTV.GT.K ) THEN+*+* C1 := C1 - V1 * W**H+*+ CALL CGEMM( 'No transpose', 'Conjugate transpose',+ $ LASTV-K, LASTC, K, -ONE, V, LDV, WORK, LDWORK,+ $ ONE, C, LDC )+ END IF+*+* W := W * V2**H+*+ CALL CTRMM( 'Right', 'Upper', 'Conjugate transpose',+ $ 'Unit', LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,+ $ WORK, LDWORK )+*+* C2 := C2 - W**H+*+ DO 90 J = 1, K+ DO 80 I = 1, LASTC+ C( LASTV-K+J, I ) = C( LASTV-K+J, I ) -+ $ CONJG( WORK( I, J ) )+ 80 CONTINUE+ 90 CONTINUE+*+ ELSE IF( LSAME( SIDE, 'R' ) ) THEN+*+* Form C * H or C * H**H where C = ( C1 C2 )+*+ LASTV = MAX( K, ILACLR( N, K, V, LDV ) )+ LASTC = ILACLR( M, LASTV, C, LDC )+*+* W := C * V = (C1*V1 + C2*V2) (stored in WORK)+*+* W := C2+*+ DO 100 J = 1, K+ CALL CCOPY( LASTC, C( 1, LASTV-K+J ), 1,+ $ WORK( 1, J ), 1 )+ 100 CONTINUE+*+* W := W * V2+*+ CALL CTRMM( 'Right', 'Upper', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,+ $ WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C1 * V1+*+ CALL CGEMM( 'No transpose', 'No transpose',+ $ LASTC, K, LASTV-K,+ $ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )+ END IF+*+* W := W * T or W * T**H+*+ CALL CTRMM( 'Right', 'Lower', TRANS, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - W * V**H+*+ IF( LASTV.GT.K ) THEN+*+* C1 := C1 - W * V1**H+*+ CALL CGEMM( 'No transpose', 'Conjugate transpose',+ $ LASTC, LASTV-K, K, -ONE, WORK, LDWORK, V, LDV,+ $ ONE, C, LDC )+ END IF+*+* W := W * V2**H+*+ CALL CTRMM( 'Right', 'Upper', 'Conjugate transpose',+ $ 'Unit', LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,+ $ WORK, LDWORK )+*+* C2 := C2 - W+*+ DO 120 J = 1, K+ DO 110 I = 1, LASTC+ C( I, LASTV-K+J ) = C( I, LASTV-K+J )+ $ - WORK( I, J )+ 110 CONTINUE+ 120 CONTINUE+ END IF+ END IF+*+ ELSE IF( LSAME( STOREV, 'R' ) ) THEN+*+ IF( LSAME( DIRECT, 'F' ) ) THEN+*+* Let V = ( V1 V2 ) (V1: first K columns)+* where V1 is unit upper triangular.+*+ IF( LSAME( SIDE, 'L' ) ) THEN+*+* Form H * C or H**H * C where C = ( C1 )+* ( C2 )+*+ LASTV = MAX( K, ILACLC( K, M, V, LDV ) )+ LASTC = ILACLC( LASTV, N, C, LDC )+*+* W := C**H * V**H = (C1**H * V1**H + C2**H * V2**H) (stored in WORK)+*+* W := C1**H+*+ DO 130 J = 1, K+ CALL CCOPY( LASTC, C( J, 1 ), LDC, WORK( 1, J ), 1 )+ CALL CLACGV( LASTC, WORK( 1, J ), 1 )+ 130 CONTINUE+*+* W := W * V1**H+*+ CALL CTRMM( 'Right', 'Upper', 'Conjugate transpose',+ $ 'Unit', LASTC, K, ONE, V, LDV, WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C2**H*V2**H+*+ CALL CGEMM( 'Conjugate transpose',+ $ 'Conjugate transpose', LASTC, K, LASTV-K,+ $ ONE, C( K+1, 1 ), LDC, V( 1, K+1 ), LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T**H or W * T+*+ CALL CTRMM( 'Right', 'Upper', TRANST, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - V**H * W**H+*+ IF( LASTV.GT.K ) THEN+*+* C2 := C2 - V2**H * W**H+*+ CALL CGEMM( 'Conjugate transpose',+ $ 'Conjugate transpose', LASTV-K, LASTC, K,+ $ -ONE, V( 1, K+1 ), LDV, WORK, LDWORK,+ $ ONE, C( K+1, 1 ), LDC )+ END IF+*+* W := W * V1+*+ CALL CTRMM( 'Right', 'Upper', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+*+* C1 := C1 - W**H+*+ DO 150 J = 1, K+ DO 140 I = 1, LASTC+ C( J, I ) = C( J, I ) - CONJG( WORK( I, J ) )+ 140 CONTINUE+ 150 CONTINUE+*+ ELSE IF( LSAME( SIDE, 'R' ) ) THEN+*+* Form C * H or C * H**H where C = ( C1 C2 )+*+ LASTV = MAX( K, ILACLC( K, N, V, LDV ) )+ LASTC = ILACLR( M, LASTV, C, LDC )+*+* W := C * V**H = (C1*V1**H + C2*V2**H) (stored in WORK)+*+* W := C1+*+ DO 160 J = 1, K+ CALL CCOPY( LASTC, C( 1, J ), 1, WORK( 1, J ), 1 )+ 160 CONTINUE+*+* W := W * V1**H+*+ CALL CTRMM( 'Right', 'Upper', 'Conjugate transpose',+ $ 'Unit', LASTC, K, ONE, V, LDV, WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C2 * V2**H+*+ CALL CGEMM( 'No transpose', 'Conjugate transpose',+ $ LASTC, K, LASTV-K, ONE, C( 1, K+1 ), LDC,+ $ V( 1, K+1 ), LDV, ONE, WORK, LDWORK )+ END IF+*+* W := W * T or W * T**H+*+ CALL CTRMM( 'Right', 'Upper', TRANS, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - W * V+*+ IF( LASTV.GT.K ) THEN+*+* C2 := C2 - W * V2+*+ CALL CGEMM( 'No transpose', 'No transpose',+ $ LASTC, LASTV-K, K,+ $ -ONE, WORK, LDWORK, V( 1, K+1 ), LDV,+ $ ONE, C( 1, K+1 ), LDC )+ END IF+*+* W := W * V1+*+ CALL CTRMM( 'Right', 'Upper', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+*+* C1 := C1 - W+*+ DO 180 J = 1, K+ DO 170 I = 1, LASTC+ C( I, J ) = C( I, J ) - WORK( I, J )+ 170 CONTINUE+ 180 CONTINUE+*+ END IF+*+ ELSE+*+* Let V = ( V1 V2 ) (V2: last K columns)+* where V2 is unit lower triangular.+*+ IF( LSAME( SIDE, 'L' ) ) THEN+*+* Form H * C or H**H * C where C = ( C1 )+* ( C2 )+*+ LASTV = MAX( K, ILACLC( K, M, V, LDV ) )+ LASTC = ILACLC( LASTV, N, C, LDC )+*+* W := C**H * V**H = (C1**H * V1**H + C2**H * V2**H) (stored in WORK)+*+* W := C2**H+*+ DO 190 J = 1, K+ CALL CCOPY( LASTC, C( LASTV-K+J, 1 ), LDC,+ $ WORK( 1, J ), 1 )+ CALL CLACGV( LASTC, WORK( 1, J ), 1 )+ 190 CONTINUE+*+* W := W * V2**H+*+ CALL CTRMM( 'Right', 'Lower', 'Conjugate transpose',+ $ 'Unit', LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,+ $ WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C1**H * V1**H+*+ CALL CGEMM( 'Conjugate transpose',+ $ 'Conjugate transpose', LASTC, K, LASTV-K,+ $ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )+ END IF+*+* W := W * T**H or W * T+*+ CALL CTRMM( 'Right', 'Lower', TRANST, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - V**H * W**H+*+ IF( LASTV.GT.K ) THEN+*+* C1 := C1 - V1**H * W**H+*+ CALL CGEMM( 'Conjugate transpose',+ $ 'Conjugate transpose', LASTV-K, LASTC, K,+ $ -ONE, V, LDV, WORK, LDWORK, ONE, C, LDC )+ END IF+*+* W := W * V2+*+ CALL CTRMM( 'Right', 'Lower', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,+ $ WORK, LDWORK )+*+* C2 := C2 - W**H+*+ DO 210 J = 1, K+ DO 200 I = 1, LASTC+ C( LASTV-K+J, I ) = C( LASTV-K+J, I ) -+ $ CONJG( WORK( I, J ) )+ 200 CONTINUE+ 210 CONTINUE+*+ ELSE IF( LSAME( SIDE, 'R' ) ) THEN+*+* Form C * H or C * H**H where C = ( C1 C2 )+*+ LASTV = MAX( K, ILACLC( K, N, V, LDV ) )+ LASTC = ILACLR( M, LASTV, C, LDC )+*+* W := C * V**H = (C1*V1**H + C2*V2**H) (stored in WORK)+*+* W := C2+*+ DO 220 J = 1, K+ CALL CCOPY( LASTC, C( 1, LASTV-K+J ), 1,+ $ WORK( 1, J ), 1 )+ 220 CONTINUE+*+* W := W * V2**H+*+ CALL CTRMM( 'Right', 'Lower', 'Conjugate transpose',+ $ 'Unit', LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,+ $ WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C1 * V1**H+*+ CALL CGEMM( 'No transpose', 'Conjugate transpose',+ $ LASTC, K, LASTV-K, ONE, C, LDC, V, LDV, ONE,+ $ WORK, LDWORK )+ END IF+*+* W := W * T or W * T**H+*+ CALL CTRMM( 'Right', 'Lower', TRANS, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - W * V+*+ IF( LASTV.GT.K ) THEN+*+* C1 := C1 - W * V1+*+ CALL CGEMM( 'No transpose', 'No transpose',+ $ LASTC, LASTV-K, K, -ONE, WORK, LDWORK, V, LDV,+ $ ONE, C, LDC )+ END IF+*+* W := W * V2+*+ CALL CTRMM( 'Right', 'Lower', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,+ $ WORK, LDWORK )+*+* C1 := C1 - W+*+ DO 240 J = 1, K+ DO 230 I = 1, LASTC+ C( I, LASTV-K+J ) = C( I, LASTV-K+J )+ $ - WORK( I, J )+ 230 CONTINUE+ 240 CONTINUE+*+ END IF+*+ END IF+ END IF+*+ RETURN+*+* End of CLARFB+*+ END
+ eigen3/lapack/clarfg.f view
@@ -0,0 +1,203 @@+*> \brief \b CLARFG+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download CLARFG + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/clarfg.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/clarfg.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/clarfg.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE CLARFG( N, ALPHA, X, INCX, TAU )+* +* .. Scalar Arguments ..+* INTEGER INCX, N+* COMPLEX ALPHA, TAU+* ..+* .. Array Arguments ..+* COMPLEX X( * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> CLARFG generates a complex elementary reflector H of order n, such+*> that+*>+*> H**H * ( alpha ) = ( beta ), H**H * H = I.+*> ( x ) ( 0 )+*>+*> where alpha and beta are scalars, with beta real, and x is an+*> (n-1)-element complex vector. H is represented in the form+*>+*> H = I - tau * ( 1 ) * ( 1 v**H ) ,+*> ( v )+*>+*> where tau is a complex scalar and v is a complex (n-1)-element+*> vector. Note that H is not hermitian.+*>+*> If the elements of x are all zero and alpha is real, then tau = 0+*> and H is taken to be the unit matrix.+*>+*> Otherwise 1 <= real(tau) <= 2 and abs(tau-1) <= 1 .+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The order of the elementary reflector.+*> \endverbatim+*>+*> \param[in,out] ALPHA+*> \verbatim+*> ALPHA is COMPLEX+*> On entry, the value alpha.+*> On exit, it is overwritten with the value beta.+*> \endverbatim+*>+*> \param[in,out] X+*> \verbatim+*> X is COMPLEX array, dimension+*> (1+(N-2)*abs(INCX))+*> On entry, the vector x.+*> On exit, it is overwritten with the vector v.+*> \endverbatim+*>+*> \param[in] INCX+*> \verbatim+*> INCX is INTEGER+*> The increment between elements of X. INCX > 0.+*> \endverbatim+*>+*> \param[out] TAU+*> \verbatim+*> TAU is COMPLEX+*> The value tau.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup complexOTHERauxiliary+*+* =====================================================================+ SUBROUTINE CLARFG( N, ALPHA, X, INCX, TAU )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ INTEGER INCX, N+ COMPLEX ALPHA, TAU+* ..+* .. Array Arguments ..+ COMPLEX X( * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ REAL ONE, ZERO+ PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 )+* ..+* .. Local Scalars ..+ INTEGER J, KNT+ REAL ALPHI, ALPHR, BETA, RSAFMN, SAFMIN, XNORM+* ..+* .. External Functions ..+ REAL SCNRM2, SLAMCH, SLAPY3+ COMPLEX CLADIV+ EXTERNAL SCNRM2, SLAMCH, SLAPY3, CLADIV+* ..+* .. Intrinsic Functions ..+ INTRINSIC ABS, AIMAG, CMPLX, REAL, SIGN+* ..+* .. External Subroutines ..+ EXTERNAL CSCAL, CSSCAL+* ..+* .. Executable Statements ..+*+ IF( N.LE.0 ) THEN+ TAU = ZERO+ RETURN+ END IF+*+ XNORM = SCNRM2( N-1, X, INCX )+ ALPHR = REAL( ALPHA )+ ALPHI = AIMAG( ALPHA )+*+ IF( XNORM.EQ.ZERO .AND. ALPHI.EQ.ZERO ) THEN+*+* H = I+*+ TAU = ZERO+ ELSE+*+* general case+*+ BETA = -SIGN( SLAPY3( ALPHR, ALPHI, XNORM ), ALPHR )+ SAFMIN = SLAMCH( 'S' ) / SLAMCH( 'E' )+ RSAFMN = ONE / SAFMIN+*+ KNT = 0+ IF( ABS( BETA ).LT.SAFMIN ) THEN+*+* XNORM, BETA may be inaccurate; scale X and recompute them+*+ 10 CONTINUE+ KNT = KNT + 1+ CALL CSSCAL( N-1, RSAFMN, X, INCX )+ BETA = BETA*RSAFMN+ ALPHI = ALPHI*RSAFMN+ ALPHR = ALPHR*RSAFMN+ IF( ABS( BETA ).LT.SAFMIN )+ $ GO TO 10+*+* New BETA is at most 1, at least SAFMIN+*+ XNORM = SCNRM2( N-1, X, INCX )+ ALPHA = CMPLX( ALPHR, ALPHI )+ BETA = -SIGN( SLAPY3( ALPHR, ALPHI, XNORM ), ALPHR )+ END IF+ TAU = CMPLX( ( BETA-ALPHR ) / BETA, -ALPHI / BETA )+ ALPHA = CLADIV( CMPLX( ONE ), ALPHA-BETA )+ CALL CSCAL( N-1, ALPHA, X, INCX )+*+* If ALPHA is subnormal, it may lose relative accuracy+*+ DO 20 J = 1, KNT+ BETA = BETA*SAFMIN+ 20 CONTINUE+ ALPHA = BETA+ END IF+*+ RETURN+*+* End of CLARFG+*+ END
+ eigen3/lapack/clarft.f view
@@ -0,0 +1,328 @@+*> \brief \b CLARFT+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download CLARFT + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/clarft.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/clarft.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/clarft.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE CLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )+* +* .. Scalar Arguments ..+* CHARACTER DIRECT, STOREV+* INTEGER K, LDT, LDV, N+* ..+* .. Array Arguments ..+* COMPLEX T( LDT, * ), TAU( * ), V( LDV, * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> CLARFT forms the triangular factor T of a complex block reflector H+*> of order n, which is defined as a product of k elementary reflectors.+*>+*> If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;+*>+*> If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.+*>+*> If STOREV = 'C', the vector which defines the elementary reflector+*> H(i) is stored in the i-th column of the array V, and+*>+*> H = I - V * T * V**H+*>+*> If STOREV = 'R', the vector which defines the elementary reflector+*> H(i) is stored in the i-th row of the array V, and+*>+*> H = I - V**H * T * V+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] DIRECT+*> \verbatim+*> DIRECT is CHARACTER*1+*> Specifies the order in which the elementary reflectors are+*> multiplied to form the block reflector:+*> = 'F': H = H(1) H(2) . . . H(k) (Forward)+*> = 'B': H = H(k) . . . H(2) H(1) (Backward)+*> \endverbatim+*>+*> \param[in] STOREV+*> \verbatim+*> STOREV is CHARACTER*1+*> Specifies how the vectors which define the elementary+*> reflectors are stored (see also Further Details):+*> = 'C': columnwise+*> = 'R': rowwise+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The order of the block reflector H. N >= 0.+*> \endverbatim+*>+*> \param[in] K+*> \verbatim+*> K is INTEGER+*> The order of the triangular factor T (= the number of+*> elementary reflectors). K >= 1.+*> \endverbatim+*>+*> \param[in] V+*> \verbatim+*> V is COMPLEX array, dimension+*> (LDV,K) if STOREV = 'C'+*> (LDV,N) if STOREV = 'R'+*> The matrix V. See further details.+*> \endverbatim+*>+*> \param[in] LDV+*> \verbatim+*> LDV is INTEGER+*> The leading dimension of the array V.+*> If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.+*> \endverbatim+*>+*> \param[in] TAU+*> \verbatim+*> TAU is COMPLEX array, dimension (K)+*> TAU(i) must contain the scalar factor of the elementary+*> reflector H(i).+*> \endverbatim+*>+*> \param[out] T+*> \verbatim+*> T is COMPLEX array, dimension (LDT,K)+*> The k by k triangular factor T of the block reflector.+*> If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is+*> lower triangular. The rest of the array is not used.+*> \endverbatim+*>+*> \param[in] LDT+*> \verbatim+*> LDT is INTEGER+*> The leading dimension of the array T. LDT >= K.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date April 2012+*+*> \ingroup complexOTHERauxiliary+*+*> \par Further Details:+* =====================+*>+*> \verbatim+*>+*> The shape of the matrix V and the storage of the vectors which define+*> the H(i) is best illustrated by the following example with n = 5 and+*> k = 3. The elements equal to 1 are not stored.+*>+*> DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R':+*>+*> V = ( 1 ) V = ( 1 v1 v1 v1 v1 )+*> ( v1 1 ) ( 1 v2 v2 v2 )+*> ( v1 v2 1 ) ( 1 v3 v3 )+*> ( v1 v2 v3 )+*> ( v1 v2 v3 )+*>+*> DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R':+*>+*> V = ( v1 v2 v3 ) V = ( v1 v1 1 )+*> ( v1 v2 v3 ) ( v2 v2 v2 1 )+*> ( 1 v2 v3 ) ( v3 v3 v3 v3 1 )+*> ( 1 v3 )+*> ( 1 )+*> \endverbatim+*>+* =====================================================================+ SUBROUTINE CLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )+*+* -- LAPACK auxiliary routine (version 3.4.1) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* April 2012+*+* .. Scalar Arguments ..+ CHARACTER DIRECT, STOREV+ INTEGER K, LDT, LDV, N+* ..+* .. Array Arguments ..+ COMPLEX T( LDT, * ), TAU( * ), V( LDV, * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ COMPLEX ONE, ZERO+ PARAMETER ( ONE = ( 1.0E+0, 0.0E+0 ),+ $ ZERO = ( 0.0E+0, 0.0E+0 ) )+* ..+* .. Local Scalars ..+ INTEGER I, J, PREVLASTV, LASTV+* ..+* .. External Subroutines ..+ EXTERNAL CGEMV, CLACGV, CTRMV+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. Executable Statements ..+*+* Quick return if possible+*+ IF( N.EQ.0 )+ $ RETURN+*+ IF( LSAME( DIRECT, 'F' ) ) THEN+ PREVLASTV = N+ DO I = 1, K+ PREVLASTV = MAX( PREVLASTV, I )+ IF( TAU( I ).EQ.ZERO ) THEN+*+* H(i) = I+*+ DO J = 1, I+ T( J, I ) = ZERO+ END DO+ ELSE+*+* general case+*+ IF( LSAME( STOREV, 'C' ) ) THEN+* Skip any trailing zeros.+ DO LASTV = N, I+1, -1+ IF( V( LASTV, I ).NE.ZERO ) EXIT+ END DO+ DO J = 1, I-1+ T( J, I ) = -TAU( I ) * CONJG( V( I , J ) )+ END DO + J = MIN( LASTV, PREVLASTV )+*+* T(1:i-1,i) := - tau(i) * V(i:j,1:i-1)**H * V(i:j,i)+*+ CALL CGEMV( 'Conjugate transpose', J-I, I-1,+ $ -TAU( I ), V( I+1, 1 ), LDV, + $ V( I+1, I ), 1,+ $ ONE, T( 1, I ), 1 )+ ELSE+* Skip any trailing zeros.+ DO LASTV = N, I+1, -1+ IF( V( I, LASTV ).NE.ZERO ) EXIT+ END DO+ DO J = 1, I-1+ T( J, I ) = -TAU( I ) * V( J , I )+ END DO + J = MIN( LASTV, PREVLASTV )+*+* T(1:i-1,i) := - tau(i) * V(1:i-1,i:j) * V(i,i:j)**H+*+ CALL CGEMM( 'N', 'C', I-1, 1, J-I, -TAU( I ),+ $ V( 1, I+1 ), LDV, V( I, I+1 ), LDV,+ $ ONE, T( 1, I ), LDT ) + END IF+*+* T(1:i-1,i) := T(1:i-1,1:i-1) * T(1:i-1,i)+*+ CALL CTRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T,+ $ LDT, T( 1, I ), 1 )+ T( I, I ) = TAU( I )+ IF( I.GT.1 ) THEN+ PREVLASTV = MAX( PREVLASTV, LASTV )+ ELSE+ PREVLASTV = LASTV+ END IF+ END IF+ END DO+ ELSE+ PREVLASTV = 1+ DO I = K, 1, -1+ IF( TAU( I ).EQ.ZERO ) THEN+*+* H(i) = I+*+ DO J = I, K+ T( J, I ) = ZERO+ END DO+ ELSE+*+* general case+*+ IF( I.LT.K ) THEN+ IF( LSAME( STOREV, 'C' ) ) THEN+* Skip any leading zeros.+ DO LASTV = 1, I-1+ IF( V( LASTV, I ).NE.ZERO ) EXIT+ END DO+ DO J = I+1, K+ T( J, I ) = -TAU( I ) * CONJG( V( N-K+I , J ) )+ END DO + J = MAX( LASTV, PREVLASTV )+*+* T(i+1:k,i) = -tau(i) * V(j:n-k+i,i+1:k)**H * V(j:n-k+i,i)+*+ CALL CGEMV( 'Conjugate transpose', N-K+I-J, K-I,+ $ -TAU( I ), V( J, I+1 ), LDV, V( J, I ),+ $ 1, ONE, T( I+1, I ), 1 )+ ELSE+* Skip any leading zeros.+ DO LASTV = 1, I-1+ IF( V( I, LASTV ).NE.ZERO ) EXIT+ END DO+ DO J = I+1, K+ T( J, I ) = -TAU( I ) * V( J, N-K+I )+ END DO + J = MAX( LASTV, PREVLASTV )+*+* T(i+1:k,i) = -tau(i) * V(i+1:k,j:n-k+i) * V(i,j:n-k+i)**H+*+ CALL CGEMM( 'N', 'C', K-I, 1, N-K+I-J, -TAU( I ),+ $ V( I+1, J ), LDV, V( I, J ), LDV,+ $ ONE, T( I+1, I ), LDT ) + END IF+*+* T(i+1:k,i) := T(i+1:k,i+1:k) * T(i+1:k,i)+*+ CALL CTRMV( 'Lower', 'No transpose', 'Non-unit', K-I,+ $ T( I+1, I+1 ), LDT, T( I+1, I ), 1 )+ IF( I.GT.1 ) THEN+ PREVLASTV = MIN( PREVLASTV, LASTV )+ ELSE+ PREVLASTV = LASTV+ END IF+ END IF+ T( I, I ) = TAU( I )+ END IF+ END DO+ END IF+ RETURN+*+* End of CLARFT+*+ END
+ eigen3/lapack/complex_double.cpp view
@@ -0,0 +1,17 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009-2011 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define SCALAR std::complex<double>+#define SCALAR_SUFFIX z+#define SCALAR_SUFFIX_UP "Z"+#define REAL_SCALAR_SUFFIX d+#define ISCOMPLEX 1++#include "cholesky.cpp"+#include "lu.cpp"
+ eigen3/lapack/complex_single.cpp view
@@ -0,0 +1,17 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009-2011 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define SCALAR std::complex<float>+#define SCALAR_SUFFIX c+#define SCALAR_SUFFIX_UP "C"+#define REAL_SCALAR_SUFFIX s+#define ISCOMPLEX 1++#include "cholesky.cpp"+#include "lu.cpp"
+ eigen3/lapack/dladiv.f view
@@ -0,0 +1,128 @@+*> \brief \b DLADIV+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download DLADIV + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dladiv.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dladiv.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dladiv.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE DLADIV( A, B, C, D, P, Q )+* +* .. Scalar Arguments ..+* DOUBLE PRECISION A, B, C, D, P, Q+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> DLADIV performs complex division in real arithmetic+*>+*> a + i*b+*> p + i*q = ---------+*> c + i*d+*>+*> The algorithm is due to Robert L. Smith and can be found+*> in D. Knuth, The art of Computer Programming, Vol.2, p.195+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] A+*> \verbatim+*> A is DOUBLE PRECISION+*> \endverbatim+*>+*> \param[in] B+*> \verbatim+*> B is DOUBLE PRECISION+*> \endverbatim+*>+*> \param[in] C+*> \verbatim+*> C is DOUBLE PRECISION+*> \endverbatim+*>+*> \param[in] D+*> \verbatim+*> D is DOUBLE PRECISION+*> The scalars a, b, c, and d in the above expression.+*> \endverbatim+*>+*> \param[out] P+*> \verbatim+*> P is DOUBLE PRECISION+*> \endverbatim+*>+*> \param[out] Q+*> \verbatim+*> Q is DOUBLE PRECISION+*> The scalars p and q in the above expression.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup auxOTHERauxiliary+*+* =====================================================================+ SUBROUTINE DLADIV( A, B, C, D, P, Q )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ DOUBLE PRECISION A, B, C, D, P, Q+* ..+*+* =====================================================================+*+* .. Local Scalars ..+ DOUBLE PRECISION E, F+* ..+* .. Intrinsic Functions ..+ INTRINSIC ABS+* ..+* .. Executable Statements ..+*+ IF( ABS( D ).LT.ABS( C ) ) THEN+ E = D / C+ F = C + D*E+ P = ( A+B*E ) / F+ Q = ( B-A*E ) / F+ ELSE+ E = C / D+ F = D + C*E+ P = ( B+A*E ) / F+ Q = ( -A+B*E ) / F+ END IF+*+ RETURN+*+* End of DLADIV+*+ END
+ eigen3/lapack/dlamch.f view
@@ -0,0 +1,189 @@+*> \brief \b DLAMCH+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+* Definition:+* ===========+*+* DOUBLE PRECISION FUNCTION DLAMCH( CMACH )+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> DLAMCH determines double precision machine parameters.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] CMACH+*> \verbatim+*> Specifies the value to be returned by DLAMCH:+*> = 'E' or 'e', DLAMCH := eps+*> = 'S' or 's , DLAMCH := sfmin+*> = 'B' or 'b', DLAMCH := base+*> = 'P' or 'p', DLAMCH := eps*base+*> = 'N' or 'n', DLAMCH := t+*> = 'R' or 'r', DLAMCH := rnd+*> = 'M' or 'm', DLAMCH := emin+*> = 'U' or 'u', DLAMCH := rmin+*> = 'L' or 'l', DLAMCH := emax+*> = 'O' or 'o', DLAMCH := rmax+*> where+*> eps = relative machine precision+*> sfmin = safe minimum, such that 1/sfmin does not overflow+*> base = base of the machine+*> prec = eps*base+*> t = number of (base) digits in the mantissa+*> rnd = 1.0 when rounding occurs in addition, 0.0 otherwise+*> emin = minimum exponent before (gradual) underflow+*> rmin = underflow threshold - base**(emin-1)+*> emax = largest exponent before overflow+*> rmax = overflow threshold - (base**emax)*(1-eps)+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup auxOTHERauxiliary+*+* =====================================================================+ DOUBLE PRECISION FUNCTION DLAMCH( CMACH )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ CHARACTER CMACH+* ..+*+* =====================================================================+*+* .. Parameters ..+ DOUBLE PRECISION ONE, ZERO+ PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )+* ..+* .. Local Scalars ..+ DOUBLE PRECISION RND, EPS, SFMIN, SMALL, RMACH+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. Intrinsic Functions ..+ INTRINSIC DIGITS, EPSILON, HUGE, MAXEXPONENT,+ $ MINEXPONENT, RADIX, TINY+* ..+* .. Executable Statements ..+*+*+* Assume rounding, not chopping. Always.+*+ RND = ONE+*+ IF( ONE.EQ.RND ) THEN+ EPS = EPSILON(ZERO) * 0.5+ ELSE+ EPS = EPSILON(ZERO)+ END IF+*+ IF( LSAME( CMACH, 'E' ) ) THEN+ RMACH = EPS+ ELSE IF( LSAME( CMACH, 'S' ) ) THEN+ SFMIN = TINY(ZERO)+ SMALL = ONE / HUGE(ZERO)+ IF( SMALL.GE.SFMIN ) THEN+*+* Use SMALL plus a bit, to avoid the possibility of rounding+* causing overflow when computing 1/sfmin.+*+ SFMIN = SMALL*( ONE+EPS )+ END IF+ RMACH = SFMIN+ ELSE IF( LSAME( CMACH, 'B' ) ) THEN+ RMACH = RADIX(ZERO)+ ELSE IF( LSAME( CMACH, 'P' ) ) THEN+ RMACH = EPS * RADIX(ZERO)+ ELSE IF( LSAME( CMACH, 'N' ) ) THEN+ RMACH = DIGITS(ZERO)+ ELSE IF( LSAME( CMACH, 'R' ) ) THEN+ RMACH = RND+ ELSE IF( LSAME( CMACH, 'M' ) ) THEN+ RMACH = MINEXPONENT(ZERO)+ ELSE IF( LSAME( CMACH, 'U' ) ) THEN+ RMACH = tiny(zero)+ ELSE IF( LSAME( CMACH, 'L' ) ) THEN+ RMACH = MAXEXPONENT(ZERO)+ ELSE IF( LSAME( CMACH, 'O' ) ) THEN+ RMACH = HUGE(ZERO)+ ELSE+ RMACH = ZERO+ END IF+*+ DLAMCH = RMACH+ RETURN+*+* End of DLAMCH+*+ END+************************************************************************+*> \brief \b DLAMC3+*> \details+*> \b Purpose:+*> \verbatim+*> DLAMC3 is intended to force A and B to be stored prior to doing+*> the addition of A and B , for use in situations where optimizers+*> might hold one of these in a register.+*> \endverbatim+*> \author LAPACK is a software package provided by Univ. of Tennessee, Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..+*> \date November 2011+*> \ingroup auxOTHERauxiliary+*>+*> \param[in] A+*> \verbatim+*> A is a DOUBLE PRECISION+*> \endverbatim+*>+*> \param[in] B+*> \verbatim+*> B is a DOUBLE PRECISION+*> The values A and B.+*> \endverbatim+*>+ DOUBLE PRECISION FUNCTION DLAMC3( A, B )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..+* November 2010+*+* .. Scalar Arguments ..+ DOUBLE PRECISION A, B+* ..+* =====================================================================+*+* .. Executable Statements ..+*+ DLAMC3 = A + B+*+ RETURN+*+* End of DLAMC3+*+ END+*+************************************************************************
+ eigen3/lapack/dlapy2.f view
@@ -0,0 +1,104 @@+*> \brief \b DLAPY2+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download DLAPY2 + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlapy2.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlapy2.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlapy2.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* DOUBLE PRECISION FUNCTION DLAPY2( X, Y )+* +* .. Scalar Arguments ..+* DOUBLE PRECISION X, Y+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> DLAPY2 returns sqrt(x**2+y**2), taking care not to cause unnecessary+*> overflow.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] X+*> \verbatim+*> X is DOUBLE PRECISION+*> \endverbatim+*>+*> \param[in] Y+*> \verbatim+*> Y is DOUBLE PRECISION+*> X and Y specify the values x and y.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup auxOTHERauxiliary+*+* =====================================================================+ DOUBLE PRECISION FUNCTION DLAPY2( X, Y )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ DOUBLE PRECISION X, Y+* ..+*+* =====================================================================+*+* .. Parameters ..+ DOUBLE PRECISION ZERO+ PARAMETER ( ZERO = 0.0D0 )+ DOUBLE PRECISION ONE+ PARAMETER ( ONE = 1.0D0 )+* ..+* .. Local Scalars ..+ DOUBLE PRECISION W, XABS, YABS, Z+* ..+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, MIN, SQRT+* ..+* .. Executable Statements ..+*+ XABS = ABS( X )+ YABS = ABS( Y )+ W = MAX( XABS, YABS )+ Z = MIN( XABS, YABS )+ IF( Z.EQ.ZERO ) THEN+ DLAPY2 = W+ ELSE+ DLAPY2 = W*SQRT( ONE+( Z / W )**2 )+ END IF+ RETURN+*+* End of DLAPY2+*+ END
+ eigen3/lapack/dlapy3.f view
@@ -0,0 +1,111 @@+*> \brief \b DLAPY3+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download DLAPY3 + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlapy3.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlapy3.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlapy3.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* DOUBLE PRECISION FUNCTION DLAPY3( X, Y, Z )+* +* .. Scalar Arguments ..+* DOUBLE PRECISION X, Y, Z+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> DLAPY3 returns sqrt(x**2+y**2+z**2), taking care not to cause+*> unnecessary overflow.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] X+*> \verbatim+*> X is DOUBLE PRECISION+*> \endverbatim+*>+*> \param[in] Y+*> \verbatim+*> Y is DOUBLE PRECISION+*> \endverbatim+*>+*> \param[in] Z+*> \verbatim+*> Z is DOUBLE PRECISION+*> X, Y and Z specify the values x, y and z.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup auxOTHERauxiliary+*+* =====================================================================+ DOUBLE PRECISION FUNCTION DLAPY3( X, Y, Z )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ DOUBLE PRECISION X, Y, Z+* ..+*+* =====================================================================+*+* .. Parameters ..+ DOUBLE PRECISION ZERO+ PARAMETER ( ZERO = 0.0D0 )+* ..+* .. Local Scalars ..+ DOUBLE PRECISION W, XABS, YABS, ZABS+* ..+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, SQRT+* ..+* .. Executable Statements ..+*+ XABS = ABS( X )+ YABS = ABS( Y )+ ZABS = ABS( Z )+ W = MAX( XABS, YABS, ZABS )+ IF( W.EQ.ZERO ) THEN+* W can be zero for max(0,nan,0)+* adding all three entries together will make sure+* NaN will not disappear.+ DLAPY3 = XABS + YABS + ZABS+ ELSE+ DLAPY3 = W*SQRT( ( XABS / W )**2+( YABS / W )**2++ $ ( ZABS / W )**2 )+ END IF+ RETURN+*+* End of DLAPY3+*+ END
+ eigen3/lapack/dlarf.f view
@@ -0,0 +1,227 @@+*> \brief \b DLARF+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download DLARF + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarf.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarf.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarf.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE DLARF( SIDE, M, N, V, INCV, TAU, C, LDC, WORK )+* +* .. Scalar Arguments ..+* CHARACTER SIDE+* INTEGER INCV, LDC, M, N+* DOUBLE PRECISION TAU+* ..+* .. Array Arguments ..+* DOUBLE PRECISION C( LDC, * ), V( * ), WORK( * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> DLARF applies a real elementary reflector H to a real m by n matrix+*> C, from either the left or the right. H is represented in the form+*>+*> H = I - tau * v * v**T+*>+*> where tau is a real scalar and v is a real vector.+*>+*> If tau = 0, then H is taken to be the unit matrix.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] SIDE+*> \verbatim+*> SIDE is CHARACTER*1+*> = 'L': form H * C+*> = 'R': form C * H+*> \endverbatim+*>+*> \param[in] M+*> \verbatim+*> M is INTEGER+*> The number of rows of the matrix C.+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The number of columns of the matrix C.+*> \endverbatim+*>+*> \param[in] V+*> \verbatim+*> V is DOUBLE PRECISION array, dimension+*> (1 + (M-1)*abs(INCV)) if SIDE = 'L'+*> or (1 + (N-1)*abs(INCV)) if SIDE = 'R'+*> The vector v in the representation of H. V is not used if+*> TAU = 0.+*> \endverbatim+*>+*> \param[in] INCV+*> \verbatim+*> INCV is INTEGER+*> The increment between elements of v. INCV <> 0.+*> \endverbatim+*>+*> \param[in] TAU+*> \verbatim+*> TAU is DOUBLE PRECISION+*> The value tau in the representation of H.+*> \endverbatim+*>+*> \param[in,out] C+*> \verbatim+*> C is DOUBLE PRECISION array, dimension (LDC,N)+*> On entry, the m by n matrix C.+*> On exit, C is overwritten by the matrix H * C if SIDE = 'L',+*> or C * H if SIDE = 'R'.+*> \endverbatim+*>+*> \param[in] LDC+*> \verbatim+*> LDC is INTEGER+*> The leading dimension of the array C. LDC >= max(1,M).+*> \endverbatim+*>+*> \param[out] WORK+*> \verbatim+*> WORK is DOUBLE PRECISION array, dimension+*> (N) if SIDE = 'L'+*> or (M) if SIDE = 'R'+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup doubleOTHERauxiliary+*+* =====================================================================+ SUBROUTINE DLARF( SIDE, M, N, V, INCV, TAU, C, LDC, WORK )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ CHARACTER SIDE+ INTEGER INCV, LDC, M, N+ DOUBLE PRECISION TAU+* ..+* .. Array Arguments ..+ DOUBLE PRECISION C( LDC, * ), V( * ), WORK( * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ DOUBLE PRECISION ONE, ZERO+ PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )+* ..+* .. Local Scalars ..+ LOGICAL APPLYLEFT+ INTEGER I, LASTV, LASTC+* ..+* .. External Subroutines ..+ EXTERNAL DGEMV, DGER+* ..+* .. External Functions ..+ LOGICAL LSAME+ INTEGER ILADLR, ILADLC+ EXTERNAL LSAME, ILADLR, ILADLC+* ..+* .. Executable Statements ..+*+ APPLYLEFT = LSAME( SIDE, 'L' )+ LASTV = 0+ LASTC = 0+ IF( TAU.NE.ZERO ) THEN+! Set up variables for scanning V. LASTV begins pointing to the end+! of V.+ IF( APPLYLEFT ) THEN+ LASTV = M+ ELSE+ LASTV = N+ END IF+ IF( INCV.GT.0 ) THEN+ I = 1 + (LASTV-1) * INCV+ ELSE+ I = 1+ END IF+! Look for the last non-zero row in V.+ DO WHILE( LASTV.GT.0 .AND. V( I ).EQ.ZERO )+ LASTV = LASTV - 1+ I = I - INCV+ END DO+ IF( APPLYLEFT ) THEN+! Scan for the last non-zero column in C(1:lastv,:).+ LASTC = ILADLC(LASTV, N, C, LDC)+ ELSE+! Scan for the last non-zero row in C(:,1:lastv).+ LASTC = ILADLR(M, LASTV, C, LDC)+ END IF+ END IF+! Note that lastc.eq.0 renders the BLAS operations null; no special+! case is needed at this level.+ IF( APPLYLEFT ) THEN+*+* Form H * C+*+ IF( LASTV.GT.0 ) THEN+*+* w(1:lastc,1) := C(1:lastv,1:lastc)**T * v(1:lastv,1)+*+ CALL DGEMV( 'Transpose', LASTV, LASTC, ONE, C, LDC, V, INCV,+ $ ZERO, WORK, 1 )+*+* C(1:lastv,1:lastc) := C(...) - v(1:lastv,1) * w(1:lastc,1)**T+*+ CALL DGER( LASTV, LASTC, -TAU, V, INCV, WORK, 1, C, LDC )+ END IF+ ELSE+*+* Form C * H+*+ IF( LASTV.GT.0 ) THEN+*+* w(1:lastc,1) := C(1:lastc,1:lastv) * v(1:lastv,1)+*+ CALL DGEMV( 'No transpose', LASTC, LASTV, ONE, C, LDC,+ $ V, INCV, ZERO, WORK, 1 )+*+* C(1:lastc,1:lastv) := C(...) - w(1:lastc,1) * v(1:lastv,1)**T+*+ CALL DGER( LASTC, LASTV, -TAU, WORK, 1, V, INCV, C, LDC )+ END IF+ END IF+ RETURN+*+* End of DLARF+*+ END
+ eigen3/lapack/dlarfb.f view
@@ -0,0 +1,762 @@+*> \brief \b DLARFB+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download DLARFB + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarfb.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarfb.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarfb.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE DLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV,+* T, LDT, C, LDC, WORK, LDWORK )+* +* .. Scalar Arguments ..+* CHARACTER DIRECT, SIDE, STOREV, TRANS+* INTEGER K, LDC, LDT, LDV, LDWORK, M, N+* ..+* .. Array Arguments ..+* DOUBLE PRECISION C( LDC, * ), T( LDT, * ), V( LDV, * ),+* $ WORK( LDWORK, * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> DLARFB applies a real block reflector H or its transpose H**T to a+*> real m by n matrix C, from either the left or the right.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] SIDE+*> \verbatim+*> SIDE is CHARACTER*1+*> = 'L': apply H or H**T from the Left+*> = 'R': apply H or H**T from the Right+*> \endverbatim+*>+*> \param[in] TRANS+*> \verbatim+*> TRANS is CHARACTER*1+*> = 'N': apply H (No transpose)+*> = 'T': apply H**T (Transpose)+*> \endverbatim+*>+*> \param[in] DIRECT+*> \verbatim+*> DIRECT is CHARACTER*1+*> Indicates how H is formed from a product of elementary+*> reflectors+*> = 'F': H = H(1) H(2) . . . H(k) (Forward)+*> = 'B': H = H(k) . . . H(2) H(1) (Backward)+*> \endverbatim+*>+*> \param[in] STOREV+*> \verbatim+*> STOREV is CHARACTER*1+*> Indicates how the vectors which define the elementary+*> reflectors are stored:+*> = 'C': Columnwise+*> = 'R': Rowwise+*> \endverbatim+*>+*> \param[in] M+*> \verbatim+*> M is INTEGER+*> The number of rows of the matrix C.+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The number of columns of the matrix C.+*> \endverbatim+*>+*> \param[in] K+*> \verbatim+*> K is INTEGER+*> The order of the matrix T (= the number of elementary+*> reflectors whose product defines the block reflector).+*> \endverbatim+*>+*> \param[in] V+*> \verbatim+*> V is DOUBLE PRECISION array, dimension+*> (LDV,K) if STOREV = 'C'+*> (LDV,M) if STOREV = 'R' and SIDE = 'L'+*> (LDV,N) if STOREV = 'R' and SIDE = 'R'+*> The matrix V. See Further Details.+*> \endverbatim+*>+*> \param[in] LDV+*> \verbatim+*> LDV is INTEGER+*> The leading dimension of the array V.+*> If STOREV = 'C' and SIDE = 'L', LDV >= max(1,M);+*> if STOREV = 'C' and SIDE = 'R', LDV >= max(1,N);+*> if STOREV = 'R', LDV >= K.+*> \endverbatim+*>+*> \param[in] T+*> \verbatim+*> T is DOUBLE PRECISION array, dimension (LDT,K)+*> The triangular k by k matrix T in the representation of the+*> block reflector.+*> \endverbatim+*>+*> \param[in] LDT+*> \verbatim+*> LDT is INTEGER+*> The leading dimension of the array T. LDT >= K.+*> \endverbatim+*>+*> \param[in,out] C+*> \verbatim+*> C is DOUBLE PRECISION array, dimension (LDC,N)+*> On entry, the m by n matrix C.+*> On exit, C is overwritten by H*C or H**T*C or C*H or C*H**T.+*> \endverbatim+*>+*> \param[in] LDC+*> \verbatim+*> LDC is INTEGER+*> The leading dimension of the array C. LDC >= max(1,M).+*> \endverbatim+*>+*> \param[out] WORK+*> \verbatim+*> WORK is DOUBLE PRECISION array, dimension (LDWORK,K)+*> \endverbatim+*>+*> \param[in] LDWORK+*> \verbatim+*> LDWORK is INTEGER+*> The leading dimension of the array WORK.+*> If SIDE = 'L', LDWORK >= max(1,N);+*> if SIDE = 'R', LDWORK >= max(1,M).+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup doubleOTHERauxiliary+*+*> \par Further Details:+* =====================+*>+*> \verbatim+*>+*> The shape of the matrix V and the storage of the vectors which define+*> the H(i) is best illustrated by the following example with n = 5 and+*> k = 3. The elements equal to 1 are not stored; the corresponding+*> array elements are modified but restored on exit. The rest of the+*> array is not used.+*>+*> DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R':+*>+*> V = ( 1 ) V = ( 1 v1 v1 v1 v1 )+*> ( v1 1 ) ( 1 v2 v2 v2 )+*> ( v1 v2 1 ) ( 1 v3 v3 )+*> ( v1 v2 v3 )+*> ( v1 v2 v3 )+*>+*> DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R':+*>+*> V = ( v1 v2 v3 ) V = ( v1 v1 1 )+*> ( v1 v2 v3 ) ( v2 v2 v2 1 )+*> ( 1 v2 v3 ) ( v3 v3 v3 v3 1 )+*> ( 1 v3 )+*> ( 1 )+*> \endverbatim+*>+* =====================================================================+ SUBROUTINE DLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV,+ $ T, LDT, C, LDC, WORK, LDWORK )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ CHARACTER DIRECT, SIDE, STOREV, TRANS+ INTEGER K, LDC, LDT, LDV, LDWORK, M, N+* ..+* .. Array Arguments ..+ DOUBLE PRECISION C( LDC, * ), T( LDT, * ), V( LDV, * ),+ $ WORK( LDWORK, * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ DOUBLE PRECISION ONE+ PARAMETER ( ONE = 1.0D+0 )+* ..+* .. Local Scalars ..+ CHARACTER TRANST+ INTEGER I, J, LASTV, LASTC+* ..+* .. External Functions ..+ LOGICAL LSAME+ INTEGER ILADLR, ILADLC+ EXTERNAL LSAME, ILADLR, ILADLC+* ..+* .. External Subroutines ..+ EXTERNAL DCOPY, DGEMM, DTRMM+* ..+* .. Executable Statements ..+*+* Quick return if possible+*+ IF( M.LE.0 .OR. N.LE.0 )+ $ RETURN+*+ IF( LSAME( TRANS, 'N' ) ) THEN+ TRANST = 'T'+ ELSE+ TRANST = 'N'+ END IF+*+ IF( LSAME( STOREV, 'C' ) ) THEN+*+ IF( LSAME( DIRECT, 'F' ) ) THEN+*+* Let V = ( V1 ) (first K rows)+* ( V2 )+* where V1 is unit lower triangular.+*+ IF( LSAME( SIDE, 'L' ) ) THEN+*+* Form H * C or H**T * C where C = ( C1 )+* ( C2 )+*+ LASTV = MAX( K, ILADLR( M, K, V, LDV ) )+ LASTC = ILADLC( LASTV, N, C, LDC )+*+* W := C**T * V = (C1**T * V1 + C2**T * V2) (stored in WORK)+*+* W := C1**T+*+ DO 10 J = 1, K+ CALL DCOPY( LASTC, C( J, 1 ), LDC, WORK( 1, J ), 1 )+ 10 CONTINUE+*+* W := W * V1+*+ CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C2**T *V2+*+ CALL DGEMM( 'Transpose', 'No transpose',+ $ LASTC, K, LASTV-K,+ $ ONE, C( K+1, 1 ), LDC, V( K+1, 1 ), LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T**T or W * T+*+ CALL DTRMM( 'Right', 'Upper', TRANST, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - V * W**T+*+ IF( LASTV.GT.K ) THEN+*+* C2 := C2 - V2 * W**T+*+ CALL DGEMM( 'No transpose', 'Transpose',+ $ LASTV-K, LASTC, K,+ $ -ONE, V( K+1, 1 ), LDV, WORK, LDWORK, ONE,+ $ C( K+1, 1 ), LDC )+ END IF+*+* W := W * V1**T+*+ CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+*+* C1 := C1 - W**T+*+ DO 30 J = 1, K+ DO 20 I = 1, LASTC+ C( J, I ) = C( J, I ) - WORK( I, J )+ 20 CONTINUE+ 30 CONTINUE+*+ ELSE IF( LSAME( SIDE, 'R' ) ) THEN+*+* Form C * H or C * H**T where C = ( C1 C2 )+*+ LASTV = MAX( K, ILADLR( N, K, V, LDV ) )+ LASTC = ILADLR( M, LASTV, C, LDC )+*+* W := C * V = (C1*V1 + C2*V2) (stored in WORK)+*+* W := C1+*+ DO 40 J = 1, K+ CALL DCOPY( LASTC, C( 1, J ), 1, WORK( 1, J ), 1 )+ 40 CONTINUE+*+* W := W * V1+*+ CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C2 * V2+*+ CALL DGEMM( 'No transpose', 'No transpose',+ $ LASTC, K, LASTV-K,+ $ ONE, C( 1, K+1 ), LDC, V( K+1, 1 ), LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T or W * T**T+*+ CALL DTRMM( 'Right', 'Upper', TRANS, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - W * V**T+*+ IF( LASTV.GT.K ) THEN+*+* C2 := C2 - W * V2**T+*+ CALL DGEMM( 'No transpose', 'Transpose',+ $ LASTC, LASTV-K, K,+ $ -ONE, WORK, LDWORK, V( K+1, 1 ), LDV, ONE,+ $ C( 1, K+1 ), LDC )+ END IF+*+* W := W * V1**T+*+ CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+*+* C1 := C1 - W+*+ DO 60 J = 1, K+ DO 50 I = 1, LASTC+ C( I, J ) = C( I, J ) - WORK( I, J )+ 50 CONTINUE+ 60 CONTINUE+ END IF+*+ ELSE+*+* Let V = ( V1 )+* ( V2 ) (last K rows)+* where V2 is unit upper triangular.+*+ IF( LSAME( SIDE, 'L' ) ) THEN+*+* Form H * C or H**T * C where C = ( C1 )+* ( C2 )+*+ LASTV = MAX( K, ILADLR( M, K, V, LDV ) )+ LASTC = ILADLC( LASTV, N, C, LDC )+*+* W := C**T * V = (C1**T * V1 + C2**T * V2) (stored in WORK)+*+* W := C2**T+*+ DO 70 J = 1, K+ CALL DCOPY( LASTC, C( LASTV-K+J, 1 ), LDC,+ $ WORK( 1, J ), 1 )+ 70 CONTINUE+*+* W := W * V2+*+ CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,+ $ WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C1**T*V1+*+ CALL DGEMM( 'Transpose', 'No transpose',+ $ LASTC, K, LASTV-K, ONE, C, LDC, V, LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T**T or W * T+*+ CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - V * W**T+*+ IF( LASTV.GT.K ) THEN+*+* C1 := C1 - V1 * W**T+*+ CALL DGEMM( 'No transpose', 'Transpose',+ $ LASTV-K, LASTC, K, -ONE, V, LDV, WORK, LDWORK,+ $ ONE, C, LDC )+ END IF+*+* W := W * V2**T+*+ CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit',+ $ LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,+ $ WORK, LDWORK )+*+* C2 := C2 - W**T+*+ DO 90 J = 1, K+ DO 80 I = 1, LASTC+ C( LASTV-K+J, I ) = C( LASTV-K+J, I ) - WORK(I, J)+ 80 CONTINUE+ 90 CONTINUE+*+ ELSE IF( LSAME( SIDE, 'R' ) ) THEN+*+* Form C * H or C * H**T where C = ( C1 C2 )+*+ LASTV = MAX( K, ILADLR( N, K, V, LDV ) )+ LASTC = ILADLR( M, LASTV, C, LDC )+*+* W := C * V = (C1*V1 + C2*V2) (stored in WORK)+*+* W := C2+*+ DO 100 J = 1, K+ CALL DCOPY( LASTC, C( 1, N-K+J ), 1, WORK( 1, J ), 1 )+ 100 CONTINUE+*+* W := W * V2+*+ CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,+ $ WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C1 * V1+*+ CALL DGEMM( 'No transpose', 'No transpose',+ $ LASTC, K, LASTV-K, ONE, C, LDC, V, LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T or W * T**T+*+ CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - W * V**T+*+ IF( LASTV.GT.K ) THEN+*+* C1 := C1 - W * V1**T+*+ CALL DGEMM( 'No transpose', 'Transpose',+ $ LASTC, LASTV-K, K, -ONE, WORK, LDWORK, V, LDV,+ $ ONE, C, LDC )+ END IF+*+* W := W * V2**T+*+ CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit',+ $ LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,+ $ WORK, LDWORK )+*+* C2 := C2 - W+*+ DO 120 J = 1, K+ DO 110 I = 1, LASTC+ C( I, LASTV-K+J ) = C( I, LASTV-K+J ) - WORK(I, J)+ 110 CONTINUE+ 120 CONTINUE+ END IF+ END IF+*+ ELSE IF( LSAME( STOREV, 'R' ) ) THEN+*+ IF( LSAME( DIRECT, 'F' ) ) THEN+*+* Let V = ( V1 V2 ) (V1: first K columns)+* where V1 is unit upper triangular.+*+ IF( LSAME( SIDE, 'L' ) ) THEN+*+* Form H * C or H**T * C where C = ( C1 )+* ( C2 )+*+ LASTV = MAX( K, ILADLC( K, M, V, LDV ) )+ LASTC = ILADLC( LASTV, N, C, LDC )+*+* W := C**T * V**T = (C1**T * V1**T + C2**T * V2**T) (stored in WORK)+*+* W := C1**T+*+ DO 130 J = 1, K+ CALL DCOPY( LASTC, C( J, 1 ), LDC, WORK( 1, J ), 1 )+ 130 CONTINUE+*+* W := W * V1**T+*+ CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C2**T*V2**T+*+ CALL DGEMM( 'Transpose', 'Transpose',+ $ LASTC, K, LASTV-K,+ $ ONE, C( K+1, 1 ), LDC, V( 1, K+1 ), LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T**T or W * T+*+ CALL DTRMM( 'Right', 'Upper', TRANST, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - V**T * W**T+*+ IF( LASTV.GT.K ) THEN+*+* C2 := C2 - V2**T * W**T+*+ CALL DGEMM( 'Transpose', 'Transpose',+ $ LASTV-K, LASTC, K,+ $ -ONE, V( 1, K+1 ), LDV, WORK, LDWORK,+ $ ONE, C( K+1, 1 ), LDC )+ END IF+*+* W := W * V1+*+ CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+*+* C1 := C1 - W**T+*+ DO 150 J = 1, K+ DO 140 I = 1, LASTC+ C( J, I ) = C( J, I ) - WORK( I, J )+ 140 CONTINUE+ 150 CONTINUE+*+ ELSE IF( LSAME( SIDE, 'R' ) ) THEN+*+* Form C * H or C * H**T where C = ( C1 C2 )+*+ LASTV = MAX( K, ILADLC( K, N, V, LDV ) )+ LASTC = ILADLR( M, LASTV, C, LDC )+*+* W := C * V**T = (C1*V1**T + C2*V2**T) (stored in WORK)+*+* W := C1+*+ DO 160 J = 1, K+ CALL DCOPY( LASTC, C( 1, J ), 1, WORK( 1, J ), 1 )+ 160 CONTINUE+*+* W := W * V1**T+*+ CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C2 * V2**T+*+ CALL DGEMM( 'No transpose', 'Transpose',+ $ LASTC, K, LASTV-K,+ $ ONE, C( 1, K+1 ), LDC, V( 1, K+1 ), LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T or W * T**T+*+ CALL DTRMM( 'Right', 'Upper', TRANS, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - W * V+*+ IF( LASTV.GT.K ) THEN+*+* C2 := C2 - W * V2+*+ CALL DGEMM( 'No transpose', 'No transpose',+ $ LASTC, LASTV-K, K,+ $ -ONE, WORK, LDWORK, V( 1, K+1 ), LDV,+ $ ONE, C( 1, K+1 ), LDC )+ END IF+*+* W := W * V1+*+ CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+*+* C1 := C1 - W+*+ DO 180 J = 1, K+ DO 170 I = 1, LASTC+ C( I, J ) = C( I, J ) - WORK( I, J )+ 170 CONTINUE+ 180 CONTINUE+*+ END IF+*+ ELSE+*+* Let V = ( V1 V2 ) (V2: last K columns)+* where V2 is unit lower triangular.+*+ IF( LSAME( SIDE, 'L' ) ) THEN+*+* Form H * C or H**T * C where C = ( C1 )+* ( C2 )+*+ LASTV = MAX( K, ILADLC( K, M, V, LDV ) )+ LASTC = ILADLC( LASTV, N, C, LDC )+*+* W := C**T * V**T = (C1**T * V1**T + C2**T * V2**T) (stored in WORK)+*+* W := C2**T+*+ DO 190 J = 1, K+ CALL DCOPY( LASTC, C( LASTV-K+J, 1 ), LDC,+ $ WORK( 1, J ), 1 )+ 190 CONTINUE+*+* W := W * V2**T+*+ CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit',+ $ LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,+ $ WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C1**T * V1**T+*+ CALL DGEMM( 'Transpose', 'Transpose',+ $ LASTC, K, LASTV-K, ONE, C, LDC, V, LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T**T or W * T+*+ CALL DTRMM( 'Right', 'Lower', TRANST, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - V**T * W**T+*+ IF( LASTV.GT.K ) THEN+*+* C1 := C1 - V1**T * W**T+*+ CALL DGEMM( 'Transpose', 'Transpose',+ $ LASTV-K, LASTC, K, -ONE, V, LDV, WORK, LDWORK,+ $ ONE, C, LDC )+ END IF+*+* W := W * V2+*+ CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,+ $ WORK, LDWORK )+*+* C2 := C2 - W**T+*+ DO 210 J = 1, K+ DO 200 I = 1, LASTC+ C( LASTV-K+J, I ) = C( LASTV-K+J, I ) - WORK(I, J)+ 200 CONTINUE+ 210 CONTINUE+*+ ELSE IF( LSAME( SIDE, 'R' ) ) THEN+*+* Form C * H or C * H**T where C = ( C1 C2 )+*+ LASTV = MAX( K, ILADLC( K, N, V, LDV ) )+ LASTC = ILADLR( M, LASTV, C, LDC )+*+* W := C * V**T = (C1*V1**T + C2*V2**T) (stored in WORK)+*+* W := C2+*+ DO 220 J = 1, K+ CALL DCOPY( LASTC, C( 1, LASTV-K+J ), 1,+ $ WORK( 1, J ), 1 )+ 220 CONTINUE+*+* W := W * V2**T+*+ CALL DTRMM( 'Right', 'Lower', 'Transpose', 'Unit',+ $ LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,+ $ WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C1 * V1**T+*+ CALL DGEMM( 'No transpose', 'Transpose',+ $ LASTC, K, LASTV-K, ONE, C, LDC, V, LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T or W * T**T+*+ CALL DTRMM( 'Right', 'Lower', TRANS, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - W * V+*+ IF( LASTV.GT.K ) THEN+*+* C1 := C1 - W * V1+*+ CALL DGEMM( 'No transpose', 'No transpose',+ $ LASTC, LASTV-K, K, -ONE, WORK, LDWORK, V, LDV,+ $ ONE, C, LDC )+ END IF+*+* W := W * V2+*+ CALL DTRMM( 'Right', 'Lower', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,+ $ WORK, LDWORK )+*+* C1 := C1 - W+*+ DO 240 J = 1, K+ DO 230 I = 1, LASTC+ C( I, LASTV-K+J ) = C( I, LASTV-K+J ) - WORK(I, J)+ 230 CONTINUE+ 240 CONTINUE+*+ END IF+*+ END IF+ END IF+*+ RETURN+*+* End of DLARFB+*+ END
+ eigen3/lapack/dlarfg.f view
@@ -0,0 +1,196 @@+*> \brief \b DLARFG+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download DLARFG + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarfg.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarfg.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarfg.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE DLARFG( N, ALPHA, X, INCX, TAU )+* +* .. Scalar Arguments ..+* INTEGER INCX, N+* DOUBLE PRECISION ALPHA, TAU+* ..+* .. Array Arguments ..+* DOUBLE PRECISION X( * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> DLARFG generates a real elementary reflector H of order n, such+*> that+*>+*> H * ( alpha ) = ( beta ), H**T * H = I.+*> ( x ) ( 0 )+*>+*> where alpha and beta are scalars, and x is an (n-1)-element real+*> vector. H is represented in the form+*>+*> H = I - tau * ( 1 ) * ( 1 v**T ) ,+*> ( v )+*>+*> where tau is a real scalar and v is a real (n-1)-element+*> vector.+*>+*> If the elements of x are all zero, then tau = 0 and H is taken to be+*> the unit matrix.+*>+*> Otherwise 1 <= tau <= 2.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The order of the elementary reflector.+*> \endverbatim+*>+*> \param[in,out] ALPHA+*> \verbatim+*> ALPHA is DOUBLE PRECISION+*> On entry, the value alpha.+*> On exit, it is overwritten with the value beta.+*> \endverbatim+*>+*> \param[in,out] X+*> \verbatim+*> X is DOUBLE PRECISION array, dimension+*> (1+(N-2)*abs(INCX))+*> On entry, the vector x.+*> On exit, it is overwritten with the vector v.+*> \endverbatim+*>+*> \param[in] INCX+*> \verbatim+*> INCX is INTEGER+*> The increment between elements of X. INCX > 0.+*> \endverbatim+*>+*> \param[out] TAU+*> \verbatim+*> TAU is DOUBLE PRECISION+*> The value tau.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup doubleOTHERauxiliary+*+* =====================================================================+ SUBROUTINE DLARFG( N, ALPHA, X, INCX, TAU )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ INTEGER INCX, N+ DOUBLE PRECISION ALPHA, TAU+* ..+* .. Array Arguments ..+ DOUBLE PRECISION X( * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ DOUBLE PRECISION ONE, ZERO+ PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )+* ..+* .. Local Scalars ..+ INTEGER J, KNT+ DOUBLE PRECISION BETA, RSAFMN, SAFMIN, XNORM+* ..+* .. External Functions ..+ DOUBLE PRECISION DLAMCH, DLAPY2, DNRM2+ EXTERNAL DLAMCH, DLAPY2, DNRM2+* ..+* .. Intrinsic Functions ..+ INTRINSIC ABS, SIGN+* ..+* .. External Subroutines ..+ EXTERNAL DSCAL+* ..+* .. Executable Statements ..+*+ IF( N.LE.1 ) THEN+ TAU = ZERO+ RETURN+ END IF+*+ XNORM = DNRM2( N-1, X, INCX )+*+ IF( XNORM.EQ.ZERO ) THEN+*+* H = I+*+ TAU = ZERO+ ELSE+*+* general case+*+ BETA = -SIGN( DLAPY2( ALPHA, XNORM ), ALPHA )+ SAFMIN = DLAMCH( 'S' ) / DLAMCH( 'E' )+ KNT = 0+ IF( ABS( BETA ).LT.SAFMIN ) THEN+*+* XNORM, BETA may be inaccurate; scale X and recompute them+*+ RSAFMN = ONE / SAFMIN+ 10 CONTINUE+ KNT = KNT + 1+ CALL DSCAL( N-1, RSAFMN, X, INCX )+ BETA = BETA*RSAFMN+ ALPHA = ALPHA*RSAFMN+ IF( ABS( BETA ).LT.SAFMIN )+ $ GO TO 10+*+* New BETA is at most 1, at least SAFMIN+*+ XNORM = DNRM2( N-1, X, INCX )+ BETA = -SIGN( DLAPY2( ALPHA, XNORM ), ALPHA )+ END IF+ TAU = ( BETA-ALPHA ) / BETA+ CALL DSCAL( N-1, ONE / ( ALPHA-BETA ), X, INCX )+*+* If ALPHA is subnormal, it may lose relative accuracy+*+ DO 20 J = 1, KNT+ BETA = BETA*SAFMIN+ 20 CONTINUE+ ALPHA = BETA+ END IF+*+ RETURN+*+* End of DLARFG+*+ END
+ eigen3/lapack/dlarft.f view
@@ -0,0 +1,326 @@+*> \brief \b DLARFT+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download DLARFT + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dlarft.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dlarft.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dlarft.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE DLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )+* +* .. Scalar Arguments ..+* CHARACTER DIRECT, STOREV+* INTEGER K, LDT, LDV, N+* ..+* .. Array Arguments ..+* DOUBLE PRECISION T( LDT, * ), TAU( * ), V( LDV, * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> DLARFT forms the triangular factor T of a real block reflector H+*> of order n, which is defined as a product of k elementary reflectors.+*>+*> If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;+*>+*> If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.+*>+*> If STOREV = 'C', the vector which defines the elementary reflector+*> H(i) is stored in the i-th column of the array V, and+*>+*> H = I - V * T * V**T+*>+*> If STOREV = 'R', the vector which defines the elementary reflector+*> H(i) is stored in the i-th row of the array V, and+*>+*> H = I - V**T * T * V+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] DIRECT+*> \verbatim+*> DIRECT is CHARACTER*1+*> Specifies the order in which the elementary reflectors are+*> multiplied to form the block reflector:+*> = 'F': H = H(1) H(2) . . . H(k) (Forward)+*> = 'B': H = H(k) . . . H(2) H(1) (Backward)+*> \endverbatim+*>+*> \param[in] STOREV+*> \verbatim+*> STOREV is CHARACTER*1+*> Specifies how the vectors which define the elementary+*> reflectors are stored (see also Further Details):+*> = 'C': columnwise+*> = 'R': rowwise+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The order of the block reflector H. N >= 0.+*> \endverbatim+*>+*> \param[in] K+*> \verbatim+*> K is INTEGER+*> The order of the triangular factor T (= the number of+*> elementary reflectors). K >= 1.+*> \endverbatim+*>+*> \param[in] V+*> \verbatim+*> V is DOUBLE PRECISION array, dimension+*> (LDV,K) if STOREV = 'C'+*> (LDV,N) if STOREV = 'R'+*> The matrix V. See further details.+*> \endverbatim+*>+*> \param[in] LDV+*> \verbatim+*> LDV is INTEGER+*> The leading dimension of the array V.+*> If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.+*> \endverbatim+*>+*> \param[in] TAU+*> \verbatim+*> TAU is DOUBLE PRECISION array, dimension (K)+*> TAU(i) must contain the scalar factor of the elementary+*> reflector H(i).+*> \endverbatim+*>+*> \param[out] T+*> \verbatim+*> T is DOUBLE PRECISION array, dimension (LDT,K)+*> The k by k triangular factor T of the block reflector.+*> If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is+*> lower triangular. The rest of the array is not used.+*> \endverbatim+*>+*> \param[in] LDT+*> \verbatim+*> LDT is INTEGER+*> The leading dimension of the array T. LDT >= K.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date April 2012+*+*> \ingroup doubleOTHERauxiliary+*+*> \par Further Details:+* =====================+*>+*> \verbatim+*>+*> The shape of the matrix V and the storage of the vectors which define+*> the H(i) is best illustrated by the following example with n = 5 and+*> k = 3. The elements equal to 1 are not stored.+*>+*> DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R':+*>+*> V = ( 1 ) V = ( 1 v1 v1 v1 v1 )+*> ( v1 1 ) ( 1 v2 v2 v2 )+*> ( v1 v2 1 ) ( 1 v3 v3 )+*> ( v1 v2 v3 )+*> ( v1 v2 v3 )+*>+*> DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R':+*>+*> V = ( v1 v2 v3 ) V = ( v1 v1 1 )+*> ( v1 v2 v3 ) ( v2 v2 v2 1 )+*> ( 1 v2 v3 ) ( v3 v3 v3 v3 1 )+*> ( 1 v3 )+*> ( 1 )+*> \endverbatim+*>+* =====================================================================+ SUBROUTINE DLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )+*+* -- LAPACK auxiliary routine (version 3.4.1) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* April 2012+*+* .. Scalar Arguments ..+ CHARACTER DIRECT, STOREV+ INTEGER K, LDT, LDV, N+* ..+* .. Array Arguments ..+ DOUBLE PRECISION T( LDT, * ), TAU( * ), V( LDV, * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ DOUBLE PRECISION ONE, ZERO+ PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )+* ..+* .. Local Scalars ..+ INTEGER I, J, PREVLASTV, LASTV+* ..+* .. External Subroutines ..+ EXTERNAL DGEMV, DTRMV+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. Executable Statements ..+*+* Quick return if possible+*+ IF( N.EQ.0 )+ $ RETURN+*+ IF( LSAME( DIRECT, 'F' ) ) THEN+ PREVLASTV = N+ DO I = 1, K+ PREVLASTV = MAX( I, PREVLASTV )+ IF( TAU( I ).EQ.ZERO ) THEN+*+* H(i) = I+*+ DO J = 1, I+ T( J, I ) = ZERO+ END DO+ ELSE+*+* general case+*+ IF( LSAME( STOREV, 'C' ) ) THEN+* Skip any trailing zeros.+ DO LASTV = N, I+1, -1+ IF( V( LASTV, I ).NE.ZERO ) EXIT+ END DO+ DO J = 1, I-1+ T( J, I ) = -TAU( I ) * V( I , J )+ END DO + J = MIN( LASTV, PREVLASTV )+*+* T(1:i-1,i) := - tau(i) * V(i:j,1:i-1)**T * V(i:j,i)+*+ CALL DGEMV( 'Transpose', J-I, I-1, -TAU( I ), + $ V( I+1, 1 ), LDV, V( I+1, I ), 1, ONE, + $ T( 1, I ), 1 )+ ELSE+* Skip any trailing zeros.+ DO LASTV = N, I+1, -1+ IF( V( I, LASTV ).NE.ZERO ) EXIT+ END DO+ DO J = 1, I-1+ T( J, I ) = -TAU( I ) * V( J , I )+ END DO + J = MIN( LASTV, PREVLASTV )+*+* T(1:i-1,i) := - tau(i) * V(1:i-1,i:j) * V(i,i:j)**T+*+ CALL DGEMV( 'No transpose', I-1, J-I, -TAU( I ),+ $ V( 1, I+1 ), LDV, V( I, I+1 ), LDV, ONE,+ $ T( 1, I ), 1 )+ END IF+*+* T(1:i-1,i) := T(1:i-1,1:i-1) * T(1:i-1,i)+*+ CALL DTRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T,+ $ LDT, T( 1, I ), 1 )+ T( I, I ) = TAU( I )+ IF( I.GT.1 ) THEN+ PREVLASTV = MAX( PREVLASTV, LASTV )+ ELSE+ PREVLASTV = LASTV+ END IF+ END IF+ END DO+ ELSE+ PREVLASTV = 1+ DO I = K, 1, -1+ IF( TAU( I ).EQ.ZERO ) THEN+*+* H(i) = I+*+ DO J = I, K+ T( J, I ) = ZERO+ END DO+ ELSE+*+* general case+*+ IF( I.LT.K ) THEN+ IF( LSAME( STOREV, 'C' ) ) THEN+* Skip any leading zeros.+ DO LASTV = 1, I-1+ IF( V( LASTV, I ).NE.ZERO ) EXIT+ END DO+ DO J = I+1, K+ T( J, I ) = -TAU( I ) * V( N-K+I , J )+ END DO + J = MAX( LASTV, PREVLASTV )+*+* T(i+1:k,i) = -tau(i) * V(j:n-k+i,i+1:k)**T * V(j:n-k+i,i)+*+ CALL DGEMV( 'Transpose', N-K+I-J, K-I, -TAU( I ),+ $ V( J, I+1 ), LDV, V( J, I ), 1, ONE,+ $ T( I+1, I ), 1 )+ ELSE+* Skip any leading zeros.+ DO LASTV = 1, I-1+ IF( V( I, LASTV ).NE.ZERO ) EXIT+ END DO+ DO J = I+1, K+ T( J, I ) = -TAU( I ) * V( J, N-K+I )+ END DO + J = MAX( LASTV, PREVLASTV )+*+* T(i+1:k,i) = -tau(i) * V(i+1:k,j:n-k+i) * V(i,j:n-k+i)**T+*+ CALL DGEMV( 'No transpose', K-I, N-K+I-J,+ $ -TAU( I ), V( I+1, J ), LDV, V( I, J ), LDV,+ $ ONE, T( I+1, I ), 1 )+ END IF+*+* T(i+1:k,i) := T(i+1:k,i+1:k) * T(i+1:k,i)+*+ CALL DTRMV( 'Lower', 'No transpose', 'Non-unit', K-I,+ $ T( I+1, I+1 ), LDT, T( I+1, I ), 1 )+ IF( I.GT.1 ) THEN+ PREVLASTV = MIN( PREVLASTV, LASTV )+ ELSE+ PREVLASTV = LASTV+ END IF+ END IF+ T( I, I ) = TAU( I )+ END IF+ END DO+ END IF+ RETURN+*+* End of DLARFT+*+ END
+ eigen3/lapack/double.cpp view
@@ -0,0 +1,17 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009-2011 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define SCALAR double+#define SCALAR_SUFFIX d+#define SCALAR_SUFFIX_UP "D"+#define ISCOMPLEX 0++#include "cholesky.cpp"+#include "lu.cpp"+#include "eigenvalues.cpp"
+ eigen3/lapack/dsecnd_NONE.f view
@@ -0,0 +1,52 @@+*> \brief \b DSECND returns nothing+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+* Definition:+* ===========+*+* DOUBLE PRECISION FUNCTION DSECND( )+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> DSECND returns nothing instead of returning the user time for a process in seconds.+*> If you are using that routine, it means that neither EXTERNAL ETIME,+*> EXTERNAL ETIME_, INTERNAL ETIME, INTERNAL CPU_TIME is available on+*> your machine.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup auxOTHERauxiliary+*+* =====================================================================+ DOUBLE PRECISION FUNCTION DSECND( )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* =====================================================================+*+ DSECND = 0.0D+0+ RETURN+*+* End of DSECND+*+ END
+ eigen3/lapack/eigenvalues.cpp view
@@ -0,0 +1,79 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "common.h"+#include <Eigen/Eigenvalues>++// computes an LU factorization of a general M-by-N matrix A using partial pivoting with row interchanges+EIGEN_LAPACK_FUNC(syev,(char *jobz, char *uplo, int* n, Scalar* a, int *lda, Scalar* w, Scalar* /*work*/, int* lwork, int *info))+{+ // TODO exploit the work buffer+ bool query_size = *lwork==-1;+ + *info = 0;+ if(*jobz!='N' && *jobz!='V') *info = -1;+ else if(UPLO(*uplo)==INVALID) *info = -2;+ else if(*n<0) *info = -3;+ else if(*lda<std::max(1,*n)) *info = -5;+ else if((!query_size) && *lwork<std::max(1,3**n-1)) *info = -8;+ +// if(*info==0)+// {+// int nb = ILAENV( 1, 'SSYTRD', UPLO, N, -1, -1, -1 )+// LWKOPT = MAX( 1, ( NB+2 )*N )+// WORK( 1 ) = LWKOPT+// *+// IF( LWORK.LT.MAX( 1, 3*N-1 ) .AND. .NOT.LQUERY )+// $ INFO = -8+// END IF+// *+// IF( INFO.NE.0 ) THEN+// CALL XERBLA( 'SSYEV ', -INFO )+// RETURN+// ELSE IF( LQUERY ) THEN+// RETURN+// END IF+ + if(*info!=0)+ {+ int e = -*info;+ return xerbla_(SCALAR_SUFFIX_UP"SYEV ", &e, 6);+ }+ + if(query_size)+ {+ *lwork = 0;+ return 0;+ }+ + if(*n==0)+ return 0;+ + PlainMatrixType mat(*n,*n);+ if(UPLO(*uplo)==UP) mat = matrix(a,*n,*n,*lda).adjoint();+ else mat = matrix(a,*n,*n,*lda);+ + bool computeVectors = *jobz=='V' || *jobz=='v';+ SelfAdjointEigenSolver<PlainMatrixType> eig(mat,computeVectors?ComputeEigenvectors:EigenvaluesOnly);+ + if(eig.info()==NoConvergence)+ {+ vector(w,*n).setZero();+ if(computeVectors)+ matrix(a,*n,*n,*lda).setIdentity();+ //*info = 1;+ return 0;+ }+ + vector(w,*n) = eig.eigenvalues();+ if(computeVectors)+ matrix(a,*n,*n,*lda) = eig.eigenvectors();+ + return 0;+}
+ eigen3/lapack/ilaclc.f view
@@ -0,0 +1,118 @@+*> \brief \b ILACLC+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download ILACLC + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ilaclc.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ilaclc.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ilaclc.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* INTEGER FUNCTION ILACLC( M, N, A, LDA )+* +* .. Scalar Arguments ..+* INTEGER M, N, LDA+* ..+* .. Array Arguments ..+* COMPLEX A( LDA, * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> ILACLC scans A for its last non-zero column.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] M+*> \verbatim+*> M is INTEGER+*> The number of rows of the matrix A.+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The number of columns of the matrix A.+*> \endverbatim+*>+*> \param[in] A+*> \verbatim+*> A is COMPLEX array, dimension (LDA,N)+*> The m by n matrix A.+*> \endverbatim+*>+*> \param[in] LDA+*> \verbatim+*> LDA is INTEGER+*> The leading dimension of the array A. LDA >= max(1,M).+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup complexOTHERauxiliary+*+* =====================================================================+ INTEGER FUNCTION ILACLC( M, N, A, LDA )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ INTEGER M, N, LDA+* ..+* .. Array Arguments ..+ COMPLEX A( LDA, * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ COMPLEX ZERO+ PARAMETER ( ZERO = (0.0E+0, 0.0E+0) )+* ..+* .. Local Scalars ..+ INTEGER I+* ..+* .. Executable Statements ..+*+* Quick test for the common case where one corner is non-zero.+ IF( N.EQ.0 ) THEN+ ILACLC = N+ ELSE IF( A(1, N).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN+ ILACLC = N+ ELSE+* Now scan each column from the end, returning with the first non-zero.+ DO ILACLC = N, 1, -1+ DO I = 1, M+ IF( A(I, ILACLC).NE.ZERO ) RETURN+ END DO+ END DO+ END IF+ RETURN+ END
+ eigen3/lapack/ilaclr.f view
@@ -0,0 +1,121 @@+*> \brief \b ILACLR+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download ILACLR + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ilaclr.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ilaclr.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ilaclr.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* INTEGER FUNCTION ILACLR( M, N, A, LDA )+* +* .. Scalar Arguments ..+* INTEGER M, N, LDA+* ..+* .. Array Arguments ..+* COMPLEX A( LDA, * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> ILACLR scans A for its last non-zero row.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] M+*> \verbatim+*> M is INTEGER+*> The number of rows of the matrix A.+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The number of columns of the matrix A.+*> \endverbatim+*>+*> \param[in] A+*> \verbatim+*> A is array, dimension (LDA,N)+*> The m by n matrix A.+*> \endverbatim+*>+*> \param[in] LDA+*> \verbatim+*> LDA is INTEGER+*> The leading dimension of the array A. LDA >= max(1,M).+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date April 2012+*+*> \ingroup complexOTHERauxiliary+*+* =====================================================================+ INTEGER FUNCTION ILACLR( M, N, A, LDA )+*+* -- LAPACK auxiliary routine (version 3.4.1) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* April 2012+*+* .. Scalar Arguments ..+ INTEGER M, N, LDA+* ..+* .. Array Arguments ..+ COMPLEX A( LDA, * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ COMPLEX ZERO+ PARAMETER ( ZERO = (0.0E+0, 0.0E+0) )+* ..+* .. Local Scalars ..+ INTEGER I, J+* ..+* .. Executable Statements ..+*+* Quick test for the common case where one corner is non-zero.+ IF( M.EQ.0 ) THEN+ ILACLR = M+ ELSE IF( A(M, 1).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN+ ILACLR = M+ ELSE+* Scan up each column tracking the last zero row seen.+ ILACLR = 0+ DO J = 1, N+ I=M+ DO WHILE((A(MAX(I,1),J).EQ.ZERO).AND.(I.GE.1))+ I=I-1+ ENDDO+ ILACLR = MAX( ILACLR, I )+ END DO+ END IF+ RETURN+ END
+ eigen3/lapack/iladlc.f view
@@ -0,0 +1,118 @@+*> \brief \b ILADLC+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download ILADLC + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/iladlc.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/iladlc.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/iladlc.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* INTEGER FUNCTION ILADLC( M, N, A, LDA )+* +* .. Scalar Arguments ..+* INTEGER M, N, LDA+* ..+* .. Array Arguments ..+* DOUBLE PRECISION A( LDA, * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> ILADLC scans A for its last non-zero column.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] M+*> \verbatim+*> M is INTEGER+*> The number of rows of the matrix A.+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The number of columns of the matrix A.+*> \endverbatim+*>+*> \param[in] A+*> \verbatim+*> A is DOUBLE PRECISION array, dimension (LDA,N)+*> The m by n matrix A.+*> \endverbatim+*>+*> \param[in] LDA+*> \verbatim+*> LDA is INTEGER+*> The leading dimension of the array A. LDA >= max(1,M).+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup auxOTHERauxiliary+*+* =====================================================================+ INTEGER FUNCTION ILADLC( M, N, A, LDA )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ INTEGER M, N, LDA+* ..+* .. Array Arguments ..+ DOUBLE PRECISION A( LDA, * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ DOUBLE PRECISION ZERO+ PARAMETER ( ZERO = 0.0D+0 )+* ..+* .. Local Scalars ..+ INTEGER I+* ..+* .. Executable Statements ..+*+* Quick test for the common case where one corner is non-zero.+ IF( N.EQ.0 ) THEN+ ILADLC = N+ ELSE IF( A(1, N).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN+ ILADLC = N+ ELSE+* Now scan each column from the end, returning with the first non-zero.+ DO ILADLC = N, 1, -1+ DO I = 1, M+ IF( A(I, ILADLC).NE.ZERO ) RETURN+ END DO+ END DO+ END IF+ RETURN+ END
+ eigen3/lapack/iladlr.f view
@@ -0,0 +1,121 @@+*> \brief \b ILADLR+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download ILADLR + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/iladlr.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/iladlr.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/iladlr.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* INTEGER FUNCTION ILADLR( M, N, A, LDA )+* +* .. Scalar Arguments ..+* INTEGER M, N, LDA+* ..+* .. Array Arguments ..+* DOUBLE PRECISION A( LDA, * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> ILADLR scans A for its last non-zero row.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] M+*> \verbatim+*> M is INTEGER+*> The number of rows of the matrix A.+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The number of columns of the matrix A.+*> \endverbatim+*>+*> \param[in] A+*> \verbatim+*> A is DOUBLE PRECISION array, dimension (LDA,N)+*> The m by n matrix A.+*> \endverbatim+*>+*> \param[in] LDA+*> \verbatim+*> LDA is INTEGER+*> The leading dimension of the array A. LDA >= max(1,M).+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date April 2012+*+*> \ingroup auxOTHERauxiliary+*+* =====================================================================+ INTEGER FUNCTION ILADLR( M, N, A, LDA )+*+* -- LAPACK auxiliary routine (version 3.4.1) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* April 2012+*+* .. Scalar Arguments ..+ INTEGER M, N, LDA+* ..+* .. Array Arguments ..+ DOUBLE PRECISION A( LDA, * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ DOUBLE PRECISION ZERO+ PARAMETER ( ZERO = 0.0D+0 )+* ..+* .. Local Scalars ..+ INTEGER I, J+* ..+* .. Executable Statements ..+*+* Quick test for the common case where one corner is non-zero.+ IF( M.EQ.0 ) THEN+ ILADLR = M+ ELSE IF( A(M, 1).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN+ ILADLR = M+ ELSE+* Scan up each column tracking the last zero row seen.+ ILADLR = 0+ DO J = 1, N+ I=M+ DO WHILE((A(MAX(I,1),J).EQ.ZERO).AND.(I.GE.1))+ I=I-1+ ENDDO+ ILADLR = MAX( ILADLR, I )+ END DO+ END IF+ RETURN+ END
+ eigen3/lapack/ilaslc.f view
@@ -0,0 +1,118 @@+*> \brief \b ILASLC+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download ILASLC + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ilaslc.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ilaslc.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ilaslc.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* INTEGER FUNCTION ILASLC( M, N, A, LDA )+* +* .. Scalar Arguments ..+* INTEGER M, N, LDA+* ..+* .. Array Arguments ..+* REAL A( LDA, * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> ILASLC scans A for its last non-zero column.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] M+*> \verbatim+*> M is INTEGER+*> The number of rows of the matrix A.+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The number of columns of the matrix A.+*> \endverbatim+*>+*> \param[in] A+*> \verbatim+*> A is REAL array, dimension (LDA,N)+*> The m by n matrix A.+*> \endverbatim+*>+*> \param[in] LDA+*> \verbatim+*> LDA is INTEGER+*> The leading dimension of the array A. LDA >= max(1,M).+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup realOTHERauxiliary+*+* =====================================================================+ INTEGER FUNCTION ILASLC( M, N, A, LDA )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ INTEGER M, N, LDA+* ..+* .. Array Arguments ..+ REAL A( LDA, * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ REAL ZERO+ PARAMETER ( ZERO = 0.0D+0 )+* ..+* .. Local Scalars ..+ INTEGER I+* ..+* .. Executable Statements ..+*+* Quick test for the common case where one corner is non-zero.+ IF( N.EQ.0 ) THEN+ ILASLC = N+ ELSE IF( A(1, N).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN+ ILASLC = N+ ELSE+* Now scan each column from the end, returning with the first non-zero.+ DO ILASLC = N, 1, -1+ DO I = 1, M+ IF( A(I, ILASLC).NE.ZERO ) RETURN+ END DO+ END DO+ END IF+ RETURN+ END
+ eigen3/lapack/ilaslr.f view
@@ -0,0 +1,121 @@+*> \brief \b ILASLR+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download ILASLR + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ilaslr.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ilaslr.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ilaslr.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* INTEGER FUNCTION ILASLR( M, N, A, LDA )+* +* .. Scalar Arguments ..+* INTEGER M, N, LDA+* ..+* .. Array Arguments ..+* REAL A( LDA, * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> ILASLR scans A for its last non-zero row.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] M+*> \verbatim+*> M is INTEGER+*> The number of rows of the matrix A.+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The number of columns of the matrix A.+*> \endverbatim+*>+*> \param[in] A+*> \verbatim+*> A is REAL array, dimension (LDA,N)+*> The m by n matrix A.+*> \endverbatim+*>+*> \param[in] LDA+*> \verbatim+*> LDA is INTEGER+*> The leading dimension of the array A. LDA >= max(1,M).+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date April 2012+*+*> \ingroup realOTHERauxiliary+*+* =====================================================================+ INTEGER FUNCTION ILASLR( M, N, A, LDA )+*+* -- LAPACK auxiliary routine (version 3.4.1) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* April 2012+*+* .. Scalar Arguments ..+ INTEGER M, N, LDA+* ..+* .. Array Arguments ..+ REAL A( LDA, * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ REAL ZERO+ PARAMETER ( ZERO = 0.0E+0 )+* ..+* .. Local Scalars ..+ INTEGER I, J+* ..+* .. Executable Statements ..+*+* Quick test for the common case where one corner is non-zero.+ IF( M.EQ.0 ) THEN+ ILASLR = M+ ELSEIF( A(M, 1).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN+ ILASLR = M+ ELSE+* Scan up each column tracking the last zero row seen.+ ILASLR = 0+ DO J = 1, N+ I=M+ DO WHILE((A(MAX(I,1),J).EQ.ZERO).AND.(I.GE.1))+ I=I-1+ ENDDO+ ILASLR = MAX( ILASLR, I )+ END DO+ END IF+ RETURN+ END
+ eigen3/lapack/ilazlc.f view
@@ -0,0 +1,118 @@+*> \brief \b ILAZLC+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download ILAZLC + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ilazlc.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ilazlc.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ilazlc.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* INTEGER FUNCTION ILAZLC( M, N, A, LDA )+* +* .. Scalar Arguments ..+* INTEGER M, N, LDA+* ..+* .. Array Arguments ..+* COMPLEX*16 A( LDA, * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> ILAZLC scans A for its last non-zero column.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] M+*> \verbatim+*> M is INTEGER+*> The number of rows of the matrix A.+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The number of columns of the matrix A.+*> \endverbatim+*>+*> \param[in] A+*> \verbatim+*> A is COMPLEX*16 array, dimension (LDA,N)+*> The m by n matrix A.+*> \endverbatim+*>+*> \param[in] LDA+*> \verbatim+*> LDA is INTEGER+*> The leading dimension of the array A. LDA >= max(1,M).+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup complex16OTHERauxiliary+*+* =====================================================================+ INTEGER FUNCTION ILAZLC( M, N, A, LDA )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ INTEGER M, N, LDA+* ..+* .. Array Arguments ..+ COMPLEX*16 A( LDA, * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ COMPLEX*16 ZERO+ PARAMETER ( ZERO = (0.0D+0, 0.0D+0) )+* ..+* .. Local Scalars ..+ INTEGER I+* ..+* .. Executable Statements ..+*+* Quick test for the common case where one corner is non-zero.+ IF( N.EQ.0 ) THEN+ ILAZLC = N+ ELSE IF( A(1, N).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN+ ILAZLC = N+ ELSE+* Now scan each column from the end, returning with the first non-zero.+ DO ILAZLC = N, 1, -1+ DO I = 1, M+ IF( A(I, ILAZLC).NE.ZERO ) RETURN+ END DO+ END DO+ END IF+ RETURN+ END
+ eigen3/lapack/ilazlr.f view
@@ -0,0 +1,121 @@+*> \brief \b ILAZLR+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download ILAZLR + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ilazlr.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ilazlr.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ilazlr.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* INTEGER FUNCTION ILAZLR( M, N, A, LDA )+* +* .. Scalar Arguments ..+* INTEGER M, N, LDA+* ..+* .. Array Arguments ..+* COMPLEX*16 A( LDA, * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> ILAZLR scans A for its last non-zero row.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] M+*> \verbatim+*> M is INTEGER+*> The number of rows of the matrix A.+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The number of columns of the matrix A.+*> \endverbatim+*>+*> \param[in] A+*> \verbatim+*> A is COMPLEX*16 array, dimension (LDA,N)+*> The m by n matrix A.+*> \endverbatim+*>+*> \param[in] LDA+*> \verbatim+*> LDA is INTEGER+*> The leading dimension of the array A. LDA >= max(1,M).+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date April 2012+*+*> \ingroup complex16OTHERauxiliary+*+* =====================================================================+ INTEGER FUNCTION ILAZLR( M, N, A, LDA )+*+* -- LAPACK auxiliary routine (version 3.4.1) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* April 2012+*+* .. Scalar Arguments ..+ INTEGER M, N, LDA+* ..+* .. Array Arguments ..+ COMPLEX*16 A( LDA, * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ COMPLEX*16 ZERO+ PARAMETER ( ZERO = (0.0D+0, 0.0D+0) )+* ..+* .. Local Scalars ..+ INTEGER I, J+* ..+* .. Executable Statements ..+*+* Quick test for the common case where one corner is non-zero.+ IF( M.EQ.0 ) THEN+ ILAZLR = M+ ELSE IF( A(M, 1).NE.ZERO .OR. A(M, N).NE.ZERO ) THEN+ ILAZLR = M+ ELSE+* Scan up each column tracking the last zero row seen.+ ILAZLR = 0+ DO J = 1, N+ I=M+ DO WHILE((A(MAX(I,1),J).EQ.ZERO).AND.(I.GE.1))+ I=I-1+ ENDDO+ ILAZLR = MAX( ILAZLR, I )+ END DO+ END IF+ RETURN+ END
+ eigen3/lapack/lapack_common.h view
@@ -0,0 +1,23 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010-2011 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_LAPACK_COMMON_H+#define EIGEN_LAPACK_COMMON_H++#include "../blas/common.h"++#define EIGEN_LAPACK_FUNC(FUNC,ARGLIST) \+ extern "C" { int EIGEN_BLAS_FUNC(FUNC) ARGLIST; } \+ int EIGEN_BLAS_FUNC(FUNC) ARGLIST++typedef Eigen::Map<Eigen::Transpositions<Eigen::Dynamic,Eigen::Dynamic,int> > PivotsType;++++#endif // EIGEN_LAPACK_COMMON_H
+ eigen3/lapack/lu.cpp view
@@ -0,0 +1,89 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010-2011 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "common.h"+#include <Eigen/LU>++// computes an LU factorization of a general M-by-N matrix A using partial pivoting with row interchanges+EIGEN_LAPACK_FUNC(getrf,(int *m, int *n, RealScalar *pa, int *lda, int *ipiv, int *info))+{+ *info = 0;+ if(*m<0) *info = -1;+ else if(*n<0) *info = -2;+ else if(*lda<std::max(1,*m)) *info = -4;+ if(*info!=0)+ {+ int e = -*info;+ return xerbla_(SCALAR_SUFFIX_UP"GETRF", &e, 6);+ }++ if(*m==0 || *n==0)+ return 0;++ Scalar* a = reinterpret_cast<Scalar*>(pa);+ int nb_transpositions;+ int ret = int(Eigen::internal::partial_lu_impl<Scalar,ColMajor,int>+ ::blocked_lu(*m, *n, a, *lda, ipiv, nb_transpositions));++ for(int i=0; i<std::min(*m,*n); ++i)+ ipiv[i]++;++ if(ret>=0)+ *info = ret+1;++ return 0;+}++//GETRS solves a system of linear equations+// A * X = B or A' * X = B+// with a general N-by-N matrix A using the LU factorization computed by GETRF+EIGEN_LAPACK_FUNC(getrs,(char *trans, int *n, int *nrhs, RealScalar *pa, int *lda, int *ipiv, RealScalar *pb, int *ldb, int *info))+{+ *info = 0;+ if(OP(*trans)==INVALID) *info = -1;+ else if(*n<0) *info = -2;+ else if(*nrhs<0) *info = -3;+ else if(*lda<std::max(1,*n)) *info = -5;+ else if(*ldb<std::max(1,*n)) *info = -8;+ if(*info!=0)+ {+ int e = -*info;+ return xerbla_(SCALAR_SUFFIX_UP"GETRS", &e, 6);+ }++ Scalar* a = reinterpret_cast<Scalar*>(pa);+ Scalar* b = reinterpret_cast<Scalar*>(pb);+ MatrixType lu(a,*n,*n,*lda);+ MatrixType B(b,*n,*nrhs,*ldb);++ for(int i=0; i<*n; ++i)+ ipiv[i]--;+ if(OP(*trans)==NOTR)+ {+ B = PivotsType(ipiv,*n) * B;+ lu.triangularView<UnitLower>().solveInPlace(B);+ lu.triangularView<Upper>().solveInPlace(B);+ }+ else if(OP(*trans)==TR)+ {+ lu.triangularView<Upper>().transpose().solveInPlace(B);+ lu.triangularView<UnitLower>().transpose().solveInPlace(B);+ B = PivotsType(ipiv,*n).transpose() * B;+ }+ else if(OP(*trans)==ADJ)+ {+ lu.triangularView<Upper>().adjoint().solveInPlace(B);+ lu.triangularView<UnitLower>().adjoint().solveInPlace(B);+ B = PivotsType(ipiv,*n).transpose() * B;+ }+ for(int i=0; i<*n; ++i)+ ipiv[i]++;++ return 0;+}
+ eigen3/lapack/second_NONE.f view
@@ -0,0 +1,52 @@+*> \brief \b SECOND returns nothing+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+* Definition:+* ===========+*+* REAL FUNCTION SECOND( )+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> SECOND returns nothing instead of returning the user time for a process in seconds.+*> If you are using that routine, it means that neither EXTERNAL ETIME,+*> EXTERNAL ETIME_, INTERNAL ETIME, INTERNAL CPU_TIME is available on+*> your machine.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup auxOTHERauxiliary+*+* =====================================================================+ REAL FUNCTION SECOND( )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* =====================================================================+*+ SECOND = 0.0E+0+ RETURN+*+* End of SECOND+*+ END
+ eigen3/lapack/single.cpp view
@@ -0,0 +1,17 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009-2011 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define SCALAR float+#define SCALAR_SUFFIX s+#define SCALAR_SUFFIX_UP "S"+#define ISCOMPLEX 0++#include "cholesky.cpp"+#include "lu.cpp"+#include "eigenvalues.cpp"
+ eigen3/lapack/sladiv.f view
@@ -0,0 +1,128 @@+*> \brief \b SLADIV+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download SLADIV + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/sladiv.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/sladiv.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/sladiv.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE SLADIV( A, B, C, D, P, Q )+* +* .. Scalar Arguments ..+* REAL A, B, C, D, P, Q+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> SLADIV performs complex division in real arithmetic+*>+*> a + i*b+*> p + i*q = ---------+*> c + i*d+*>+*> The algorithm is due to Robert L. Smith and can be found+*> in D. Knuth, The art of Computer Programming, Vol.2, p.195+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] A+*> \verbatim+*> A is REAL+*> \endverbatim+*>+*> \param[in] B+*> \verbatim+*> B is REAL+*> \endverbatim+*>+*> \param[in] C+*> \verbatim+*> C is REAL+*> \endverbatim+*>+*> \param[in] D+*> \verbatim+*> D is REAL+*> The scalars a, b, c, and d in the above expression.+*> \endverbatim+*>+*> \param[out] P+*> \verbatim+*> P is REAL+*> \endverbatim+*>+*> \param[out] Q+*> \verbatim+*> Q is REAL+*> The scalars p and q in the above expression.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup auxOTHERauxiliary+*+* =====================================================================+ SUBROUTINE SLADIV( A, B, C, D, P, Q )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ REAL A, B, C, D, P, Q+* ..+*+* =====================================================================+*+* .. Local Scalars ..+ REAL E, F+* ..+* .. Intrinsic Functions ..+ INTRINSIC ABS+* ..+* .. Executable Statements ..+*+ IF( ABS( D ).LT.ABS( C ) ) THEN+ E = D / C+ F = C + D*E+ P = ( A+B*E ) / F+ Q = ( B-A*E ) / F+ ELSE+ E = C / D+ F = D + C*E+ P = ( B+A*E ) / F+ Q = ( -A+B*E ) / F+ END IF+*+ RETURN+*+* End of SLADIV+*+ END
+ eigen3/lapack/slamch.f view
@@ -0,0 +1,192 @@+*> \brief \b SLAMCH+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+* Definition:+* ===========+*+* REAL FUNCTION SLAMCH( CMACH )+*+* .. Scalar Arguments ..+* CHARACTER CMACH+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> SLAMCH determines single precision machine parameters.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] CMACH+*> \verbatim+*> Specifies the value to be returned by SLAMCH:+*> = 'E' or 'e', SLAMCH := eps+*> = 'S' or 's , SLAMCH := sfmin+*> = 'B' or 'b', SLAMCH := base+*> = 'P' or 'p', SLAMCH := eps*base+*> = 'N' or 'n', SLAMCH := t+*> = 'R' or 'r', SLAMCH := rnd+*> = 'M' or 'm', SLAMCH := emin+*> = 'U' or 'u', SLAMCH := rmin+*> = 'L' or 'l', SLAMCH := emax+*> = 'O' or 'o', SLAMCH := rmax+*> where+*> eps = relative machine precision+*> sfmin = safe minimum, such that 1/sfmin does not overflow+*> base = base of the machine+*> prec = eps*base+*> t = number of (base) digits in the mantissa+*> rnd = 1.0 when rounding occurs in addition, 0.0 otherwise+*> emin = minimum exponent before (gradual) underflow+*> rmin = underflow threshold - base**(emin-1)+*> emax = largest exponent before overflow+*> rmax = overflow threshold - (base**emax)*(1-eps)+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup auxOTHERauxiliary+*+* =====================================================================+ REAL FUNCTION SLAMCH( CMACH )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ CHARACTER CMACH+* ..+*+* =====================================================================+*+* .. Parameters ..+ REAL ONE, ZERO+ PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 )+* ..+* .. Local Scalars ..+ REAL RND, EPS, SFMIN, SMALL, RMACH+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. Intrinsic Functions ..+ INTRINSIC DIGITS, EPSILON, HUGE, MAXEXPONENT,+ $ MINEXPONENT, RADIX, TINY+* ..+* .. Executable Statements ..+*+*+* Assume rounding, not chopping. Always.+*+ RND = ONE+*+ IF( ONE.EQ.RND ) THEN+ EPS = EPSILON(ZERO) * 0.5+ ELSE+ EPS = EPSILON(ZERO)+ END IF+*+ IF( LSAME( CMACH, 'E' ) ) THEN+ RMACH = EPS+ ELSE IF( LSAME( CMACH, 'S' ) ) THEN+ SFMIN = TINY(ZERO)+ SMALL = ONE / HUGE(ZERO)+ IF( SMALL.GE.SFMIN ) THEN+*+* Use SMALL plus a bit, to avoid the possibility of rounding+* causing overflow when computing 1/sfmin.+*+ SFMIN = SMALL*( ONE+EPS )+ END IF+ RMACH = SFMIN+ ELSE IF( LSAME( CMACH, 'B' ) ) THEN+ RMACH = RADIX(ZERO)+ ELSE IF( LSAME( CMACH, 'P' ) ) THEN+ RMACH = EPS * RADIX(ZERO)+ ELSE IF( LSAME( CMACH, 'N' ) ) THEN+ RMACH = DIGITS(ZERO)+ ELSE IF( LSAME( CMACH, 'R' ) ) THEN+ RMACH = RND+ ELSE IF( LSAME( CMACH, 'M' ) ) THEN+ RMACH = MINEXPONENT(ZERO)+ ELSE IF( LSAME( CMACH, 'U' ) ) THEN+ RMACH = tiny(zero)+ ELSE IF( LSAME( CMACH, 'L' ) ) THEN+ RMACH = MAXEXPONENT(ZERO)+ ELSE IF( LSAME( CMACH, 'O' ) ) THEN+ RMACH = HUGE(ZERO)+ ELSE+ RMACH = ZERO+ END IF+*+ SLAMCH = RMACH+ RETURN+*+* End of SLAMCH+*+ END+************************************************************************+*> \brief \b SLAMC3+*> \details+*> \b Purpose:+*> \verbatim+*> SLAMC3 is intended to force A and B to be stored prior to doing+*> the addition of A and B , for use in situations where optimizers+*> might hold one of these in a register.+*> \endverbatim+*> \author LAPACK is a software package provided by Univ. of Tennessee, Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..+*> \date November 2011+*> \ingroup auxOTHERauxiliary+*>+*> \param[in] A+*> \verbatim+*> \endverbatim+*>+*> \param[in] B+*> \verbatim+*> The values A and B.+*> \endverbatim+*>+*+ REAL FUNCTION SLAMC3( A, B )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..+* November 2010+*+* .. Scalar Arguments ..+ REAL A, B+* ..+* =====================================================================+*+* .. Executable Statements ..+*+ SLAMC3 = A + B+*+ RETURN+*+* End of SLAMC3+*+ END+*+************************************************************************
+ eigen3/lapack/slapy2.f view
@@ -0,0 +1,104 @@+*> \brief \b SLAPY2+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download SLAPY2 + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/slapy2.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/slapy2.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/slapy2.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* REAL FUNCTION SLAPY2( X, Y )+* +* .. Scalar Arguments ..+* REAL X, Y+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> SLAPY2 returns sqrt(x**2+y**2), taking care not to cause unnecessary+*> overflow.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] X+*> \verbatim+*> X is REAL+*> \endverbatim+*>+*> \param[in] Y+*> \verbatim+*> Y is REAL+*> X and Y specify the values x and y.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup auxOTHERauxiliary+*+* =====================================================================+ REAL FUNCTION SLAPY2( X, Y )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ REAL X, Y+* ..+*+* =====================================================================+*+* .. Parameters ..+ REAL ZERO+ PARAMETER ( ZERO = 0.0E0 )+ REAL ONE+ PARAMETER ( ONE = 1.0E0 )+* ..+* .. Local Scalars ..+ REAL W, XABS, YABS, Z+* ..+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, MIN, SQRT+* ..+* .. Executable Statements ..+*+ XABS = ABS( X )+ YABS = ABS( Y )+ W = MAX( XABS, YABS )+ Z = MIN( XABS, YABS )+ IF( Z.EQ.ZERO ) THEN+ SLAPY2 = W+ ELSE+ SLAPY2 = W*SQRT( ONE+( Z / W )**2 )+ END IF+ RETURN+*+* End of SLAPY2+*+ END
+ eigen3/lapack/slapy3.f view
@@ -0,0 +1,111 @@+*> \brief \b SLAPY3+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download SLAPY3 + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/slapy3.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/slapy3.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/slapy3.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* REAL FUNCTION SLAPY3( X, Y, Z )+* +* .. Scalar Arguments ..+* REAL X, Y, Z+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> SLAPY3 returns sqrt(x**2+y**2+z**2), taking care not to cause+*> unnecessary overflow.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] X+*> \verbatim+*> X is REAL+*> \endverbatim+*>+*> \param[in] Y+*> \verbatim+*> Y is REAL+*> \endverbatim+*>+*> \param[in] Z+*> \verbatim+*> Z is REAL+*> X, Y and Z specify the values x, y and z.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup auxOTHERauxiliary+*+* =====================================================================+ REAL FUNCTION SLAPY3( X, Y, Z )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ REAL X, Y, Z+* ..+*+* =====================================================================+*+* .. Parameters ..+ REAL ZERO+ PARAMETER ( ZERO = 0.0E0 )+* ..+* .. Local Scalars ..+ REAL W, XABS, YABS, ZABS+* ..+* .. Intrinsic Functions ..+ INTRINSIC ABS, MAX, SQRT+* ..+* .. Executable Statements ..+*+ XABS = ABS( X )+ YABS = ABS( Y )+ ZABS = ABS( Z )+ W = MAX( XABS, YABS, ZABS )+ IF( W.EQ.ZERO ) THEN+* W can be zero for max(0,nan,0)+* adding all three entries together will make sure+* NaN will not disappear.+ SLAPY3 = XABS + YABS + ZABS+ ELSE+ SLAPY3 = W*SQRT( ( XABS / W )**2+( YABS / W )**2++ $ ( ZABS / W )**2 )+ END IF+ RETURN+*+* End of SLAPY3+*+ END
+ eigen3/lapack/slarf.f view
@@ -0,0 +1,227 @@+*> \brief \b SLARF+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download SLARF + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/slarf.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/slarf.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/slarf.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE SLARF( SIDE, M, N, V, INCV, TAU, C, LDC, WORK )+* +* .. Scalar Arguments ..+* CHARACTER SIDE+* INTEGER INCV, LDC, M, N+* REAL TAU+* ..+* .. Array Arguments ..+* REAL C( LDC, * ), V( * ), WORK( * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> SLARF applies a real elementary reflector H to a real m by n matrix+*> C, from either the left or the right. H is represented in the form+*>+*> H = I - tau * v * v**T+*>+*> where tau is a real scalar and v is a real vector.+*>+*> If tau = 0, then H is taken to be the unit matrix.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] SIDE+*> \verbatim+*> SIDE is CHARACTER*1+*> = 'L': form H * C+*> = 'R': form C * H+*> \endverbatim+*>+*> \param[in] M+*> \verbatim+*> M is INTEGER+*> The number of rows of the matrix C.+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The number of columns of the matrix C.+*> \endverbatim+*>+*> \param[in] V+*> \verbatim+*> V is REAL array, dimension+*> (1 + (M-1)*abs(INCV)) if SIDE = 'L'+*> or (1 + (N-1)*abs(INCV)) if SIDE = 'R'+*> The vector v in the representation of H. V is not used if+*> TAU = 0.+*> \endverbatim+*>+*> \param[in] INCV+*> \verbatim+*> INCV is INTEGER+*> The increment between elements of v. INCV <> 0.+*> \endverbatim+*>+*> \param[in] TAU+*> \verbatim+*> TAU is REAL+*> The value tau in the representation of H.+*> \endverbatim+*>+*> \param[in,out] C+*> \verbatim+*> C is REAL array, dimension (LDC,N)+*> On entry, the m by n matrix C.+*> On exit, C is overwritten by the matrix H * C if SIDE = 'L',+*> or C * H if SIDE = 'R'.+*> \endverbatim+*>+*> \param[in] LDC+*> \verbatim+*> LDC is INTEGER+*> The leading dimension of the array C. LDC >= max(1,M).+*> \endverbatim+*>+*> \param[out] WORK+*> \verbatim+*> WORK is REAL array, dimension+*> (N) if SIDE = 'L'+*> or (M) if SIDE = 'R'+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup realOTHERauxiliary+*+* =====================================================================+ SUBROUTINE SLARF( SIDE, M, N, V, INCV, TAU, C, LDC, WORK )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ CHARACTER SIDE+ INTEGER INCV, LDC, M, N+ REAL TAU+* ..+* .. Array Arguments ..+ REAL C( LDC, * ), V( * ), WORK( * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ REAL ONE, ZERO+ PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 )+* ..+* .. Local Scalars ..+ LOGICAL APPLYLEFT+ INTEGER I, LASTV, LASTC+* ..+* .. External Subroutines ..+ EXTERNAL SGEMV, SGER+* ..+* .. External Functions ..+ LOGICAL LSAME+ INTEGER ILASLR, ILASLC+ EXTERNAL LSAME, ILASLR, ILASLC+* ..+* .. Executable Statements ..+*+ APPLYLEFT = LSAME( SIDE, 'L' )+ LASTV = 0+ LASTC = 0+ IF( TAU.NE.ZERO ) THEN+! Set up variables for scanning V. LASTV begins pointing to the end+! of V.+ IF( APPLYLEFT ) THEN+ LASTV = M+ ELSE+ LASTV = N+ END IF+ IF( INCV.GT.0 ) THEN+ I = 1 + (LASTV-1) * INCV+ ELSE+ I = 1+ END IF+! Look for the last non-zero row in V.+ DO WHILE( LASTV.GT.0 .AND. V( I ).EQ.ZERO )+ LASTV = LASTV - 1+ I = I - INCV+ END DO+ IF( APPLYLEFT ) THEN+! Scan for the last non-zero column in C(1:lastv,:).+ LASTC = ILASLC(LASTV, N, C, LDC)+ ELSE+! Scan for the last non-zero row in C(:,1:lastv).+ LASTC = ILASLR(M, LASTV, C, LDC)+ END IF+ END IF+! Note that lastc.eq.0 renders the BLAS operations null; no special+! case is needed at this level.+ IF( APPLYLEFT ) THEN+*+* Form H * C+*+ IF( LASTV.GT.0 ) THEN+*+* w(1:lastc,1) := C(1:lastv,1:lastc)**T * v(1:lastv,1)+*+ CALL SGEMV( 'Transpose', LASTV, LASTC, ONE, C, LDC, V, INCV,+ $ ZERO, WORK, 1 )+*+* C(1:lastv,1:lastc) := C(...) - v(1:lastv,1) * w(1:lastc,1)**T+*+ CALL SGER( LASTV, LASTC, -TAU, V, INCV, WORK, 1, C, LDC )+ END IF+ ELSE+*+* Form C * H+*+ IF( LASTV.GT.0 ) THEN+*+* w(1:lastc,1) := C(1:lastc,1:lastv) * v(1:lastv,1)+*+ CALL SGEMV( 'No transpose', LASTC, LASTV, ONE, C, LDC,+ $ V, INCV, ZERO, WORK, 1 )+*+* C(1:lastc,1:lastv) := C(...) - w(1:lastc,1) * v(1:lastv,1)**T+*+ CALL SGER( LASTC, LASTV, -TAU, WORK, 1, V, INCV, C, LDC )+ END IF+ END IF+ RETURN+*+* End of SLARF+*+ END
+ eigen3/lapack/slarfb.f view
@@ -0,0 +1,763 @@+*> \brief \b SLARFB+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download SLARFB + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/slarfb.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/slarfb.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/slarfb.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE SLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV,+* T, LDT, C, LDC, WORK, LDWORK )+* +* .. Scalar Arguments ..+* CHARACTER DIRECT, SIDE, STOREV, TRANS+* INTEGER K, LDC, LDT, LDV, LDWORK, M, N+* ..+* .. Array Arguments ..+* REAL C( LDC, * ), T( LDT, * ), V( LDV, * ),+* $ WORK( LDWORK, * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> SLARFB applies a real block reflector H or its transpose H**T to a+*> real m by n matrix C, from either the left or the right.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] SIDE+*> \verbatim+*> SIDE is CHARACTER*1+*> = 'L': apply H or H**T from the Left+*> = 'R': apply H or H**T from the Right+*> \endverbatim+*>+*> \param[in] TRANS+*> \verbatim+*> TRANS is CHARACTER*1+*> = 'N': apply H (No transpose)+*> = 'T': apply H**T (Transpose)+*> \endverbatim+*>+*> \param[in] DIRECT+*> \verbatim+*> DIRECT is CHARACTER*1+*> Indicates how H is formed from a product of elementary+*> reflectors+*> = 'F': H = H(1) H(2) . . . H(k) (Forward)+*> = 'B': H = H(k) . . . H(2) H(1) (Backward)+*> \endverbatim+*>+*> \param[in] STOREV+*> \verbatim+*> STOREV is CHARACTER*1+*> Indicates how the vectors which define the elementary+*> reflectors are stored:+*> = 'C': Columnwise+*> = 'R': Rowwise+*> \endverbatim+*>+*> \param[in] M+*> \verbatim+*> M is INTEGER+*> The number of rows of the matrix C.+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The number of columns of the matrix C.+*> \endverbatim+*>+*> \param[in] K+*> \verbatim+*> K is INTEGER+*> The order of the matrix T (= the number of elementary+*> reflectors whose product defines the block reflector).+*> \endverbatim+*>+*> \param[in] V+*> \verbatim+*> V is REAL array, dimension+*> (LDV,K) if STOREV = 'C'+*> (LDV,M) if STOREV = 'R' and SIDE = 'L'+*> (LDV,N) if STOREV = 'R' and SIDE = 'R'+*> The matrix V. See Further Details.+*> \endverbatim+*>+*> \param[in] LDV+*> \verbatim+*> LDV is INTEGER+*> The leading dimension of the array V.+*> If STOREV = 'C' and SIDE = 'L', LDV >= max(1,M);+*> if STOREV = 'C' and SIDE = 'R', LDV >= max(1,N);+*> if STOREV = 'R', LDV >= K.+*> \endverbatim+*>+*> \param[in] T+*> \verbatim+*> T is REAL array, dimension (LDT,K)+*> The triangular k by k matrix T in the representation of the+*> block reflector.+*> \endverbatim+*>+*> \param[in] LDT+*> \verbatim+*> LDT is INTEGER+*> The leading dimension of the array T. LDT >= K.+*> \endverbatim+*>+*> \param[in,out] C+*> \verbatim+*> C is REAL array, dimension (LDC,N)+*> On entry, the m by n matrix C.+*> On exit, C is overwritten by H*C or H**T*C or C*H or C*H**T.+*> \endverbatim+*>+*> \param[in] LDC+*> \verbatim+*> LDC is INTEGER+*> The leading dimension of the array C. LDC >= max(1,M).+*> \endverbatim+*>+*> \param[out] WORK+*> \verbatim+*> WORK is REAL array, dimension (LDWORK,K)+*> \endverbatim+*>+*> \param[in] LDWORK+*> \verbatim+*> LDWORK is INTEGER+*> The leading dimension of the array WORK.+*> If SIDE = 'L', LDWORK >= max(1,N);+*> if SIDE = 'R', LDWORK >= max(1,M).+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup realOTHERauxiliary+*+*> \par Further Details:+* =====================+*>+*> \verbatim+*>+*> The shape of the matrix V and the storage of the vectors which define+*> the H(i) is best illustrated by the following example with n = 5 and+*> k = 3. The elements equal to 1 are not stored; the corresponding+*> array elements are modified but restored on exit. The rest of the+*> array is not used.+*>+*> DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R':+*>+*> V = ( 1 ) V = ( 1 v1 v1 v1 v1 )+*> ( v1 1 ) ( 1 v2 v2 v2 )+*> ( v1 v2 1 ) ( 1 v3 v3 )+*> ( v1 v2 v3 )+*> ( v1 v2 v3 )+*>+*> DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R':+*>+*> V = ( v1 v2 v3 ) V = ( v1 v1 1 )+*> ( v1 v2 v3 ) ( v2 v2 v2 1 )+*> ( 1 v2 v3 ) ( v3 v3 v3 v3 1 )+*> ( 1 v3 )+*> ( 1 )+*> \endverbatim+*>+* =====================================================================+ SUBROUTINE SLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV,+ $ T, LDT, C, LDC, WORK, LDWORK )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ CHARACTER DIRECT, SIDE, STOREV, TRANS+ INTEGER K, LDC, LDT, LDV, LDWORK, M, N+* ..+* .. Array Arguments ..+ REAL C( LDC, * ), T( LDT, * ), V( LDV, * ),+ $ WORK( LDWORK, * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ REAL ONE+ PARAMETER ( ONE = 1.0E+0 )+* ..+* .. Local Scalars ..+ CHARACTER TRANST+ INTEGER I, J, LASTV, LASTC+* ..+* .. External Functions ..+ LOGICAL LSAME+ INTEGER ILASLR, ILASLC+ EXTERNAL LSAME, ILASLR, ILASLC+* ..+* .. External Subroutines ..+ EXTERNAL SCOPY, SGEMM, STRMM+* ..+* .. Executable Statements ..+*+* Quick return if possible+*+ IF( M.LE.0 .OR. N.LE.0 )+ $ RETURN+*+ IF( LSAME( TRANS, 'N' ) ) THEN+ TRANST = 'T'+ ELSE+ TRANST = 'N'+ END IF+*+ IF( LSAME( STOREV, 'C' ) ) THEN+*+ IF( LSAME( DIRECT, 'F' ) ) THEN+*+* Let V = ( V1 ) (first K rows)+* ( V2 )+* where V1 is unit lower triangular.+*+ IF( LSAME( SIDE, 'L' ) ) THEN+*+* Form H * C or H**T * C where C = ( C1 )+* ( C2 )+*+ LASTV = MAX( K, ILASLR( M, K, V, LDV ) )+ LASTC = ILASLC( LASTV, N, C, LDC )+*+* W := C**T * V = (C1**T * V1 + C2**T * V2) (stored in WORK)+*+* W := C1**T+*+ DO 10 J = 1, K+ CALL SCOPY( LASTC, C( J, 1 ), LDC, WORK( 1, J ), 1 )+ 10 CONTINUE+*+* W := W * V1+*+ CALL STRMM( 'Right', 'Lower', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C2**T *V2+*+ CALL SGEMM( 'Transpose', 'No transpose',+ $ LASTC, K, LASTV-K,+ $ ONE, C( K+1, 1 ), LDC, V( K+1, 1 ), LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T**T or W * T+*+ CALL STRMM( 'Right', 'Upper', TRANST, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - V * W**T+*+ IF( LASTV.GT.K ) THEN+*+* C2 := C2 - V2 * W**T+*+ CALL SGEMM( 'No transpose', 'Transpose',+ $ LASTV-K, LASTC, K,+ $ -ONE, V( K+1, 1 ), LDV, WORK, LDWORK, ONE,+ $ C( K+1, 1 ), LDC )+ END IF+*+* W := W * V1**T+*+ CALL STRMM( 'Right', 'Lower', 'Transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+*+* C1 := C1 - W**T+*+ DO 30 J = 1, K+ DO 20 I = 1, LASTC+ C( J, I ) = C( J, I ) - WORK( I, J )+ 20 CONTINUE+ 30 CONTINUE+*+ ELSE IF( LSAME( SIDE, 'R' ) ) THEN+*+* Form C * H or C * H**T where C = ( C1 C2 )+*+ LASTV = MAX( K, ILASLR( N, K, V, LDV ) )+ LASTC = ILASLR( M, LASTV, C, LDC )+*+* W := C * V = (C1*V1 + C2*V2) (stored in WORK)+*+* W := C1+*+ DO 40 J = 1, K+ CALL SCOPY( LASTC, C( 1, J ), 1, WORK( 1, J ), 1 )+ 40 CONTINUE+*+* W := W * V1+*+ CALL STRMM( 'Right', 'Lower', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C2 * V2+*+ CALL SGEMM( 'No transpose', 'No transpose',+ $ LASTC, K, LASTV-K,+ $ ONE, C( 1, K+1 ), LDC, V( K+1, 1 ), LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T or W * T**T+*+ CALL STRMM( 'Right', 'Upper', TRANS, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - W * V**T+*+ IF( LASTV.GT.K ) THEN+*+* C2 := C2 - W * V2**T+*+ CALL SGEMM( 'No transpose', 'Transpose',+ $ LASTC, LASTV-K, K,+ $ -ONE, WORK, LDWORK, V( K+1, 1 ), LDV, ONE,+ $ C( 1, K+1 ), LDC )+ END IF+*+* W := W * V1**T+*+ CALL STRMM( 'Right', 'Lower', 'Transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+*+* C1 := C1 - W+*+ DO 60 J = 1, K+ DO 50 I = 1, LASTC+ C( I, J ) = C( I, J ) - WORK( I, J )+ 50 CONTINUE+ 60 CONTINUE+ END IF+*+ ELSE+*+* Let V = ( V1 )+* ( V2 ) (last K rows)+* where V2 is unit upper triangular.+*+ IF( LSAME( SIDE, 'L' ) ) THEN+*+* Form H * C or H**T * C where C = ( C1 )+* ( C2 )+*+ LASTV = MAX( K, ILASLR( M, K, V, LDV ) )+ LASTC = ILASLC( LASTV, N, C, LDC )+*+* W := C**T * V = (C1**T * V1 + C2**T * V2) (stored in WORK)+*+* W := C2**T+*+ DO 70 J = 1, K+ CALL SCOPY( LASTC, C( LASTV-K+J, 1 ), LDC,+ $ WORK( 1, J ), 1 )+ 70 CONTINUE+*+* W := W * V2+*+ CALL STRMM( 'Right', 'Upper', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,+ $ WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C1**T*V1+*+ CALL SGEMM( 'Transpose', 'No transpose',+ $ LASTC, K, LASTV-K, ONE, C, LDC, V, LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T**T or W * T+*+ CALL STRMM( 'Right', 'Lower', TRANST, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - V * W**T+*+ IF( LASTV.GT.K ) THEN+*+* C1 := C1 - V1 * W**T+*+ CALL SGEMM( 'No transpose', 'Transpose',+ $ LASTV-K, LASTC, K, -ONE, V, LDV, WORK, LDWORK,+ $ ONE, C, LDC )+ END IF+*+* W := W * V2**T+*+ CALL STRMM( 'Right', 'Upper', 'Transpose', 'Unit',+ $ LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,+ $ WORK, LDWORK )+*+* C2 := C2 - W**T+*+ DO 90 J = 1, K+ DO 80 I = 1, LASTC+ C( LASTV-K+J, I ) = C( LASTV-K+J, I ) - WORK(I, J)+ 80 CONTINUE+ 90 CONTINUE+*+ ELSE IF( LSAME( SIDE, 'R' ) ) THEN+*+* Form C * H or C * H**T where C = ( C1 C2 )+*+ LASTV = MAX( K, ILASLR( N, K, V, LDV ) )+ LASTC = ILASLR( M, LASTV, C, LDC )+*+* W := C * V = (C1*V1 + C2*V2) (stored in WORK)+*+* W := C2+*+ DO 100 J = 1, K+ CALL SCOPY( LASTC, C( 1, N-K+J ), 1, WORK( 1, J ), 1 )+ 100 CONTINUE+*+* W := W * V2+*+ CALL STRMM( 'Right', 'Upper', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,+ $ WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C1 * V1+*+ CALL SGEMM( 'No transpose', 'No transpose',+ $ LASTC, K, LASTV-K, ONE, C, LDC, V, LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T or W * T**T+*+ CALL STRMM( 'Right', 'Lower', TRANS, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - W * V**T+*+ IF( LASTV.GT.K ) THEN+*+* C1 := C1 - W * V1**T+*+ CALL SGEMM( 'No transpose', 'Transpose',+ $ LASTC, LASTV-K, K, -ONE, WORK, LDWORK, V, LDV,+ $ ONE, C, LDC )+ END IF+*+* W := W * V2**T+*+ CALL STRMM( 'Right', 'Upper', 'Transpose', 'Unit',+ $ LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,+ $ WORK, LDWORK )+*+* C2 := C2 - W+*+ DO 120 J = 1, K+ DO 110 I = 1, LASTC+ C( I, LASTV-K+J ) = C( I, LASTV-K+J ) - WORK(I, J)+ 110 CONTINUE+ 120 CONTINUE+ END IF+ END IF+*+ ELSE IF( LSAME( STOREV, 'R' ) ) THEN+*+ IF( LSAME( DIRECT, 'F' ) ) THEN+*+* Let V = ( V1 V2 ) (V1: first K columns)+* where V1 is unit upper triangular.+*+ IF( LSAME( SIDE, 'L' ) ) THEN+*+* Form H * C or H**T * C where C = ( C1 )+* ( C2 )+*+ LASTV = MAX( K, ILASLC( K, M, V, LDV ) )+ LASTC = ILASLC( LASTV, N, C, LDC )+*+* W := C**T * V**T = (C1**T * V1**T + C2**T * V2**T) (stored in WORK)+*+* W := C1**T+*+ DO 130 J = 1, K+ CALL SCOPY( LASTC, C( J, 1 ), LDC, WORK( 1, J ), 1 )+ 130 CONTINUE+*+* W := W * V1**T+*+ CALL STRMM( 'Right', 'Upper', 'Transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C2**T*V2**T+*+ CALL SGEMM( 'Transpose', 'Transpose',+ $ LASTC, K, LASTV-K,+ $ ONE, C( K+1, 1 ), LDC, V( 1, K+1 ), LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T**T or W * T+*+ CALL STRMM( 'Right', 'Upper', TRANST, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - V**T * W**T+*+ IF( LASTV.GT.K ) THEN+*+* C2 := C2 - V2**T * W**T+*+ CALL SGEMM( 'Transpose', 'Transpose',+ $ LASTV-K, LASTC, K,+ $ -ONE, V( 1, K+1 ), LDV, WORK, LDWORK,+ $ ONE, C( K+1, 1 ), LDC )+ END IF+*+* W := W * V1+*+ CALL STRMM( 'Right', 'Upper', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+*+* C1 := C1 - W**T+*+ DO 150 J = 1, K+ DO 140 I = 1, LASTC+ C( J, I ) = C( J, I ) - WORK( I, J )+ 140 CONTINUE+ 150 CONTINUE+*+ ELSE IF( LSAME( SIDE, 'R' ) ) THEN+*+* Form C * H or C * H**T where C = ( C1 C2 )+*+ LASTV = MAX( K, ILASLC( K, N, V, LDV ) )+ LASTC = ILASLR( M, LASTV, C, LDC )+*+* W := C * V**T = (C1*V1**T + C2*V2**T) (stored in WORK)+*+* W := C1+*+ DO 160 J = 1, K+ CALL SCOPY( LASTC, C( 1, J ), 1, WORK( 1, J ), 1 )+ 160 CONTINUE+*+* W := W * V1**T+*+ CALL STRMM( 'Right', 'Upper', 'Transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C2 * V2**T+*+ CALL SGEMM( 'No transpose', 'Transpose',+ $ LASTC, K, LASTV-K,+ $ ONE, C( 1, K+1 ), LDC, V( 1, K+1 ), LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T or W * T**T+*+ CALL STRMM( 'Right', 'Upper', TRANS, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - W * V+*+ IF( LASTV.GT.K ) THEN+*+* C2 := C2 - W * V2+*+ CALL SGEMM( 'No transpose', 'No transpose',+ $ LASTC, LASTV-K, K,+ $ -ONE, WORK, LDWORK, V( 1, K+1 ), LDV,+ $ ONE, C( 1, K+1 ), LDC )+ END IF+*+* W := W * V1+*+ CALL STRMM( 'Right', 'Upper', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+*+* C1 := C1 - W+*+ DO 180 J = 1, K+ DO 170 I = 1, LASTC+ C( I, J ) = C( I, J ) - WORK( I, J )+ 170 CONTINUE+ 180 CONTINUE+*+ END IF+*+ ELSE+*+* Let V = ( V1 V2 ) (V2: last K columns)+* where V2 is unit lower triangular.+*+ IF( LSAME( SIDE, 'L' ) ) THEN+*+* Form H * C or H**T * C where C = ( C1 )+* ( C2 )+*+ LASTV = MAX( K, ILASLC( K, M, V, LDV ) )+ LASTC = ILASLC( LASTV, N, C, LDC )+*+* W := C**T * V**T = (C1**T * V1**T + C2**T * V2**T) (stored in WORK)+*+* W := C2**T+*+ DO 190 J = 1, K+ CALL SCOPY( LASTC, C( LASTV-K+J, 1 ), LDC,+ $ WORK( 1, J ), 1 )+ 190 CONTINUE+*+* W := W * V2**T+*+ CALL STRMM( 'Right', 'Lower', 'Transpose', 'Unit',+ $ LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,+ $ WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C1**T * V1**T+*+ CALL SGEMM( 'Transpose', 'Transpose',+ $ LASTC, K, LASTV-K, ONE, C, LDC, V, LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T**T or W * T+*+ CALL STRMM( 'Right', 'Lower', TRANST, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - V**T * W**T+*+ IF( LASTV.GT.K ) THEN+*+* C1 := C1 - V1**T * W**T+*+ CALL SGEMM( 'Transpose', 'Transpose',+ $ LASTV-K, LASTC, K, -ONE, V, LDV, WORK, LDWORK,+ $ ONE, C, LDC )+ END IF+*+* W := W * V2+*+ CALL STRMM( 'Right', 'Lower', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,+ $ WORK, LDWORK )+*+* C2 := C2 - W**T+*+ DO 210 J = 1, K+ DO 200 I = 1, LASTC+ C( LASTV-K+J, I ) = C( LASTV-K+J, I ) - WORK(I, J)+ 200 CONTINUE+ 210 CONTINUE+*+ ELSE IF( LSAME( SIDE, 'R' ) ) THEN+*+* Form C * H or C * H**T where C = ( C1 C2 )+*+ LASTV = MAX( K, ILASLC( K, N, V, LDV ) )+ LASTC = ILASLR( M, LASTV, C, LDC )+*+* W := C * V**T = (C1*V1**T + C2*V2**T) (stored in WORK)+*+* W := C2+*+ DO 220 J = 1, K+ CALL SCOPY( LASTC, C( 1, LASTV-K+J ), 1,+ $ WORK( 1, J ), 1 )+ 220 CONTINUE+*+* W := W * V2**T+*+ CALL STRMM( 'Right', 'Lower', 'Transpose', 'Unit',+ $ LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,+ $ WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C1 * V1**T+*+ CALL SGEMM( 'No transpose', 'Transpose',+ $ LASTC, K, LASTV-K, ONE, C, LDC, V, LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T or W * T**T+*+ CALL STRMM( 'Right', 'Lower', TRANS, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - W * V+*+ IF( LASTV.GT.K ) THEN+*+* C1 := C1 - W * V1+*+ CALL SGEMM( 'No transpose', 'No transpose',+ $ LASTC, LASTV-K, K, -ONE, WORK, LDWORK, V, LDV,+ $ ONE, C, LDC )+ END IF+*+* W := W * V2+*+ CALL STRMM( 'Right', 'Lower', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,+ $ WORK, LDWORK )+*+* C1 := C1 - W+*+ DO 240 J = 1, K+ DO 230 I = 1, LASTC+ C( I, LASTV-K+J ) = C( I, LASTV-K+J )+ $ - WORK( I, J )+ 230 CONTINUE+ 240 CONTINUE+*+ END IF+*+ END IF+ END IF+*+ RETURN+*+* End of SLARFB+*+ END
+ eigen3/lapack/slarfg.f view
@@ -0,0 +1,196 @@+*> \brief \b SLARFG+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download SLARFG + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/slarfg.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/slarfg.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/slarfg.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE SLARFG( N, ALPHA, X, INCX, TAU )+* +* .. Scalar Arguments ..+* INTEGER INCX, N+* REAL ALPHA, TAU+* ..+* .. Array Arguments ..+* REAL X( * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> SLARFG generates a real elementary reflector H of order n, such+*> that+*>+*> H * ( alpha ) = ( beta ), H**T * H = I.+*> ( x ) ( 0 )+*>+*> where alpha and beta are scalars, and x is an (n-1)-element real+*> vector. H is represented in the form+*>+*> H = I - tau * ( 1 ) * ( 1 v**T ) ,+*> ( v )+*>+*> where tau is a real scalar and v is a real (n-1)-element+*> vector.+*>+*> If the elements of x are all zero, then tau = 0 and H is taken to be+*> the unit matrix.+*>+*> Otherwise 1 <= tau <= 2.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The order of the elementary reflector.+*> \endverbatim+*>+*> \param[in,out] ALPHA+*> \verbatim+*> ALPHA is REAL+*> On entry, the value alpha.+*> On exit, it is overwritten with the value beta.+*> \endverbatim+*>+*> \param[in,out] X+*> \verbatim+*> X is REAL array, dimension+*> (1+(N-2)*abs(INCX))+*> On entry, the vector x.+*> On exit, it is overwritten with the vector v.+*> \endverbatim+*>+*> \param[in] INCX+*> \verbatim+*> INCX is INTEGER+*> The increment between elements of X. INCX > 0.+*> \endverbatim+*>+*> \param[out] TAU+*> \verbatim+*> TAU is REAL+*> The value tau.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup realOTHERauxiliary+*+* =====================================================================+ SUBROUTINE SLARFG( N, ALPHA, X, INCX, TAU )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ INTEGER INCX, N+ REAL ALPHA, TAU+* ..+* .. Array Arguments ..+ REAL X( * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ REAL ONE, ZERO+ PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 )+* ..+* .. Local Scalars ..+ INTEGER J, KNT+ REAL BETA, RSAFMN, SAFMIN, XNORM+* ..+* .. External Functions ..+ REAL SLAMCH, SLAPY2, SNRM2+ EXTERNAL SLAMCH, SLAPY2, SNRM2+* ..+* .. Intrinsic Functions ..+ INTRINSIC ABS, SIGN+* ..+* .. External Subroutines ..+ EXTERNAL SSCAL+* ..+* .. Executable Statements ..+*+ IF( N.LE.1 ) THEN+ TAU = ZERO+ RETURN+ END IF+*+ XNORM = SNRM2( N-1, X, INCX )+*+ IF( XNORM.EQ.ZERO ) THEN+*+* H = I+*+ TAU = ZERO+ ELSE+*+* general case+*+ BETA = -SIGN( SLAPY2( ALPHA, XNORM ), ALPHA )+ SAFMIN = SLAMCH( 'S' ) / SLAMCH( 'E' )+ KNT = 0+ IF( ABS( BETA ).LT.SAFMIN ) THEN+*+* XNORM, BETA may be inaccurate; scale X and recompute them+*+ RSAFMN = ONE / SAFMIN+ 10 CONTINUE+ KNT = KNT + 1+ CALL SSCAL( N-1, RSAFMN, X, INCX )+ BETA = BETA*RSAFMN+ ALPHA = ALPHA*RSAFMN+ IF( ABS( BETA ).LT.SAFMIN )+ $ GO TO 10+*+* New BETA is at most 1, at least SAFMIN+*+ XNORM = SNRM2( N-1, X, INCX )+ BETA = -SIGN( SLAPY2( ALPHA, XNORM ), ALPHA )+ END IF+ TAU = ( BETA-ALPHA ) / BETA+ CALL SSCAL( N-1, ONE / ( ALPHA-BETA ), X, INCX )+*+* If ALPHA is subnormal, it may lose relative accuracy+*+ DO 20 J = 1, KNT+ BETA = BETA*SAFMIN+ 20 CONTINUE+ ALPHA = BETA+ END IF+*+ RETURN+*+* End of SLARFG+*+ END
+ eigen3/lapack/slarft.f view
@@ -0,0 +1,326 @@+*> \brief \b SLARFT+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download SLARFT + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/slarft.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/slarft.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/slarft.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE SLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )+* +* .. Scalar Arguments ..+* CHARACTER DIRECT, STOREV+* INTEGER K, LDT, LDV, N+* ..+* .. Array Arguments ..+* REAL T( LDT, * ), TAU( * ), V( LDV, * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> SLARFT forms the triangular factor T of a real block reflector H+*> of order n, which is defined as a product of k elementary reflectors.+*>+*> If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;+*>+*> If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.+*>+*> If STOREV = 'C', the vector which defines the elementary reflector+*> H(i) is stored in the i-th column of the array V, and+*>+*> H = I - V * T * V**T+*>+*> If STOREV = 'R', the vector which defines the elementary reflector+*> H(i) is stored in the i-th row of the array V, and+*>+*> H = I - V**T * T * V+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] DIRECT+*> \verbatim+*> DIRECT is CHARACTER*1+*> Specifies the order in which the elementary reflectors are+*> multiplied to form the block reflector:+*> = 'F': H = H(1) H(2) . . . H(k) (Forward)+*> = 'B': H = H(k) . . . H(2) H(1) (Backward)+*> \endverbatim+*>+*> \param[in] STOREV+*> \verbatim+*> STOREV is CHARACTER*1+*> Specifies how the vectors which define the elementary+*> reflectors are stored (see also Further Details):+*> = 'C': columnwise+*> = 'R': rowwise+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The order of the block reflector H. N >= 0.+*> \endverbatim+*>+*> \param[in] K+*> \verbatim+*> K is INTEGER+*> The order of the triangular factor T (= the number of+*> elementary reflectors). K >= 1.+*> \endverbatim+*>+*> \param[in] V+*> \verbatim+*> V is REAL array, dimension+*> (LDV,K) if STOREV = 'C'+*> (LDV,N) if STOREV = 'R'+*> The matrix V. See further details.+*> \endverbatim+*>+*> \param[in] LDV+*> \verbatim+*> LDV is INTEGER+*> The leading dimension of the array V.+*> If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.+*> \endverbatim+*>+*> \param[in] TAU+*> \verbatim+*> TAU is REAL array, dimension (K)+*> TAU(i) must contain the scalar factor of the elementary+*> reflector H(i).+*> \endverbatim+*>+*> \param[out] T+*> \verbatim+*> T is REAL array, dimension (LDT,K)+*> The k by k triangular factor T of the block reflector.+*> If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is+*> lower triangular. The rest of the array is not used.+*> \endverbatim+*>+*> \param[in] LDT+*> \verbatim+*> LDT is INTEGER+*> The leading dimension of the array T. LDT >= K.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date April 2012+*+*> \ingroup realOTHERauxiliary+*+*> \par Further Details:+* =====================+*>+*> \verbatim+*>+*> The shape of the matrix V and the storage of the vectors which define+*> the H(i) is best illustrated by the following example with n = 5 and+*> k = 3. The elements equal to 1 are not stored.+*>+*> DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R':+*>+*> V = ( 1 ) V = ( 1 v1 v1 v1 v1 )+*> ( v1 1 ) ( 1 v2 v2 v2 )+*> ( v1 v2 1 ) ( 1 v3 v3 )+*> ( v1 v2 v3 )+*> ( v1 v2 v3 )+*>+*> DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R':+*>+*> V = ( v1 v2 v3 ) V = ( v1 v1 1 )+*> ( v1 v2 v3 ) ( v2 v2 v2 1 )+*> ( 1 v2 v3 ) ( v3 v3 v3 v3 1 )+*> ( 1 v3 )+*> ( 1 )+*> \endverbatim+*>+* =====================================================================+ SUBROUTINE SLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )+*+* -- LAPACK auxiliary routine (version 3.4.1) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* April 2012+*+* .. Scalar Arguments ..+ CHARACTER DIRECT, STOREV+ INTEGER K, LDT, LDV, N+* ..+* .. Array Arguments ..+ REAL T( LDT, * ), TAU( * ), V( LDV, * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ REAL ONE, ZERO+ PARAMETER ( ONE = 1.0E+0, ZERO = 0.0E+0 )+* ..+* .. Local Scalars ..+ INTEGER I, J, PREVLASTV, LASTV+* ..+* .. External Subroutines ..+ EXTERNAL SGEMV, STRMV+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. Executable Statements ..+*+* Quick return if possible+*+ IF( N.EQ.0 )+ $ RETURN+*+ IF( LSAME( DIRECT, 'F' ) ) THEN+ PREVLASTV = N+ DO I = 1, K+ PREVLASTV = MAX( I, PREVLASTV )+ IF( TAU( I ).EQ.ZERO ) THEN+*+* H(i) = I+*+ DO J = 1, I+ T( J, I ) = ZERO+ END DO+ ELSE+*+* general case+*+ IF( LSAME( STOREV, 'C' ) ) THEN+* Skip any trailing zeros.+ DO LASTV = N, I+1, -1+ IF( V( LASTV, I ).NE.ZERO ) EXIT+ END DO+ DO J = 1, I-1+ T( J, I ) = -TAU( I ) * V( I , J )+ END DO + J = MIN( LASTV, PREVLASTV )+*+* T(1:i-1,i) := - tau(i) * V(i:j,1:i-1)**T * V(i:j,i)+*+ CALL SGEMV( 'Transpose', J-I, I-1, -TAU( I ),+ $ V( I+1, 1 ), LDV, V( I+1, I ), 1, ONE,+ $ T( 1, I ), 1 )+ ELSE+* Skip any trailing zeros.+ DO LASTV = N, I+1, -1+ IF( V( I, LASTV ).NE.ZERO ) EXIT+ END DO+ DO J = 1, I-1+ T( J, I ) = -TAU( I ) * V( J , I )+ END DO + J = MIN( LASTV, PREVLASTV )+*+* T(1:i-1,i) := - tau(i) * V(1:i-1,i:j) * V(i,i:j)**T+*+ CALL SGEMV( 'No transpose', I-1, J-I, -TAU( I ),+ $ V( 1, I+1 ), LDV, V( I, I+1 ), LDV, + $ ONE, T( 1, I ), 1 )+ END IF+*+* T(1:i-1,i) := T(1:i-1,1:i-1) * T(1:i-1,i)+*+ CALL STRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T,+ $ LDT, T( 1, I ), 1 )+ T( I, I ) = TAU( I )+ IF( I.GT.1 ) THEN+ PREVLASTV = MAX( PREVLASTV, LASTV )+ ELSE+ PREVLASTV = LASTV+ END IF+ END IF+ END DO+ ELSE+ PREVLASTV = 1+ DO I = K, 1, -1+ IF( TAU( I ).EQ.ZERO ) THEN+*+* H(i) = I+*+ DO J = I, K+ T( J, I ) = ZERO+ END DO+ ELSE+*+* general case+*+ IF( I.LT.K ) THEN+ IF( LSAME( STOREV, 'C' ) ) THEN+* Skip any leading zeros.+ DO LASTV = 1, I-1+ IF( V( LASTV, I ).NE.ZERO ) EXIT+ END DO+ DO J = I+1, K+ T( J, I ) = -TAU( I ) * V( N-K+I , J )+ END DO + J = MAX( LASTV, PREVLASTV )+*+* T(i+1:k,i) = -tau(i) * V(j:n-k+i,i+1:k)**T * V(j:n-k+i,i)+*+ CALL SGEMV( 'Transpose', N-K+I-J, K-I, -TAU( I ),+ $ V( J, I+1 ), LDV, V( J, I ), 1, ONE,+ $ T( I+1, I ), 1 )+ ELSE+* Skip any leading zeros.+ DO LASTV = 1, I-1+ IF( V( I, LASTV ).NE.ZERO ) EXIT+ END DO+ DO J = I+1, K+ T( J, I ) = -TAU( I ) * V( J, N-K+I )+ END DO + J = MAX( LASTV, PREVLASTV )+*+* T(i+1:k,i) = -tau(i) * V(i+1:k,j:n-k+i) * V(i,j:n-k+i)**T+*+ CALL SGEMV( 'No transpose', K-I, N-K+I-J,+ $ -TAU( I ), V( I+1, J ), LDV, V( I, J ), LDV,+ $ ONE, T( I+1, I ), 1 )+ END IF+*+* T(i+1:k,i) := T(i+1:k,i+1:k) * T(i+1:k,i)+*+ CALL STRMV( 'Lower', 'No transpose', 'Non-unit', K-I,+ $ T( I+1, I+1 ), LDT, T( I+1, I ), 1 )+ IF( I.GT.1 ) THEN+ PREVLASTV = MIN( PREVLASTV, LASTV )+ ELSE+ PREVLASTV = LASTV+ END IF+ END IF+ T( I, I ) = TAU( I )+ END IF+ END DO+ END IF+ RETURN+*+* End of SLARFT+*+ END
+ eigen3/lapack/zlacgv.f view
@@ -0,0 +1,116 @@+*> \brief \b ZLACGV+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download ZLACGV + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zlacgv.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zlacgv.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zlacgv.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE ZLACGV( N, X, INCX )+* +* .. Scalar Arguments ..+* INTEGER INCX, N+* ..+* .. Array Arguments ..+* COMPLEX*16 X( * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> ZLACGV conjugates a complex vector of length N.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The length of the vector X. N >= 0.+*> \endverbatim+*>+*> \param[in,out] X+*> \verbatim+*> X is COMPLEX*16 array, dimension+*> (1+(N-1)*abs(INCX))+*> On entry, the vector of length N to be conjugated.+*> On exit, X is overwritten with conjg(X).+*> \endverbatim+*>+*> \param[in] INCX+*> \verbatim+*> INCX is INTEGER+*> The spacing between successive elements of X.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup complex16OTHERauxiliary+*+* =====================================================================+ SUBROUTINE ZLACGV( N, X, INCX )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ INTEGER INCX, N+* ..+* .. Array Arguments ..+ COMPLEX*16 X( * )+* ..+*+* =====================================================================+*+* .. Local Scalars ..+ INTEGER I, IOFF+* ..+* .. Intrinsic Functions ..+ INTRINSIC DCONJG+* ..+* .. Executable Statements ..+*+ IF( INCX.EQ.1 ) THEN+ DO 10 I = 1, N+ X( I ) = DCONJG( X( I ) )+ 10 CONTINUE+ ELSE+ IOFF = 1+ IF( INCX.LT.0 )+ $ IOFF = 1 - ( N-1 )*INCX+ DO 20 I = 1, N+ X( IOFF ) = DCONJG( X( IOFF ) )+ IOFF = IOFF + INCX+ 20 CONTINUE+ END IF+ RETURN+*+* End of ZLACGV+*+ END
+ eigen3/lapack/zladiv.f view
@@ -0,0 +1,97 @@+*> \brief \b ZLADIV+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download ZLADIV + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zladiv.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zladiv.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zladiv.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* COMPLEX*16 FUNCTION ZLADIV( X, Y )+* +* .. Scalar Arguments ..+* COMPLEX*16 X, Y+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> ZLADIV := X / Y, where X and Y are complex. The computation of X / Y+*> will not overflow on an intermediary step unless the results+*> overflows.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] X+*> \verbatim+*> X is COMPLEX*16+*> \endverbatim+*>+*> \param[in] Y+*> \verbatim+*> Y is COMPLEX*16+*> The complex scalars X and Y.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup complex16OTHERauxiliary+*+* =====================================================================+ COMPLEX*16 FUNCTION ZLADIV( X, Y )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ COMPLEX*16 X, Y+* ..+*+* =====================================================================+*+* .. Local Scalars ..+ DOUBLE PRECISION ZI, ZR+* ..+* .. External Subroutines ..+ EXTERNAL DLADIV+* ..+* .. Intrinsic Functions ..+ INTRINSIC DBLE, DCMPLX, DIMAG+* ..+* .. Executable Statements ..+*+ CALL DLADIV( DBLE( X ), DIMAG( X ), DBLE( Y ), DIMAG( Y ), ZR,+ $ ZI )+ ZLADIV = DCMPLX( ZR, ZI )+*+ RETURN+*+* End of ZLADIV+*+ END
+ eigen3/lapack/zlarf.f view
@@ -0,0 +1,232 @@+*> \brief \b ZLARF+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download ZLARF + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zlarf.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zlarf.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zlarf.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE ZLARF( SIDE, M, N, V, INCV, TAU, C, LDC, WORK )+* +* .. Scalar Arguments ..+* CHARACTER SIDE+* INTEGER INCV, LDC, M, N+* COMPLEX*16 TAU+* ..+* .. Array Arguments ..+* COMPLEX*16 C( LDC, * ), V( * ), WORK( * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> ZLARF applies a complex elementary reflector H to a complex M-by-N+*> matrix C, from either the left or the right. H is represented in the+*> form+*>+*> H = I - tau * v * v**H+*>+*> where tau is a complex scalar and v is a complex vector.+*>+*> If tau = 0, then H is taken to be the unit matrix.+*>+*> To apply H**H, supply conjg(tau) instead+*> tau.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] SIDE+*> \verbatim+*> SIDE is CHARACTER*1+*> = 'L': form H * C+*> = 'R': form C * H+*> \endverbatim+*>+*> \param[in] M+*> \verbatim+*> M is INTEGER+*> The number of rows of the matrix C.+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The number of columns of the matrix C.+*> \endverbatim+*>+*> \param[in] V+*> \verbatim+*> V is COMPLEX*16 array, dimension+*> (1 + (M-1)*abs(INCV)) if SIDE = 'L'+*> or (1 + (N-1)*abs(INCV)) if SIDE = 'R'+*> The vector v in the representation of H. V is not used if+*> TAU = 0.+*> \endverbatim+*>+*> \param[in] INCV+*> \verbatim+*> INCV is INTEGER+*> The increment between elements of v. INCV <> 0.+*> \endverbatim+*>+*> \param[in] TAU+*> \verbatim+*> TAU is COMPLEX*16+*> The value tau in the representation of H.+*> \endverbatim+*>+*> \param[in,out] C+*> \verbatim+*> C is COMPLEX*16 array, dimension (LDC,N)+*> On entry, the M-by-N matrix C.+*> On exit, C is overwritten by the matrix H * C if SIDE = 'L',+*> or C * H if SIDE = 'R'.+*> \endverbatim+*>+*> \param[in] LDC+*> \verbatim+*> LDC is INTEGER+*> The leading dimension of the array C. LDC >= max(1,M).+*> \endverbatim+*>+*> \param[out] WORK+*> \verbatim+*> WORK is COMPLEX*16 array, dimension+*> (N) if SIDE = 'L'+*> or (M) if SIDE = 'R'+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup complex16OTHERauxiliary+*+* =====================================================================+ SUBROUTINE ZLARF( SIDE, M, N, V, INCV, TAU, C, LDC, WORK )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ CHARACTER SIDE+ INTEGER INCV, LDC, M, N+ COMPLEX*16 TAU+* ..+* .. Array Arguments ..+ COMPLEX*16 C( LDC, * ), V( * ), WORK( * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ COMPLEX*16 ONE, ZERO+ PARAMETER ( ONE = ( 1.0D+0, 0.0D+0 ),+ $ ZERO = ( 0.0D+0, 0.0D+0 ) )+* ..+* .. Local Scalars ..+ LOGICAL APPLYLEFT+ INTEGER I, LASTV, LASTC+* ..+* .. External Subroutines ..+ EXTERNAL ZGEMV, ZGERC+* ..+* .. External Functions ..+ LOGICAL LSAME+ INTEGER ILAZLR, ILAZLC+ EXTERNAL LSAME, ILAZLR, ILAZLC+* ..+* .. Executable Statements ..+*+ APPLYLEFT = LSAME( SIDE, 'L' )+ LASTV = 0+ LASTC = 0+ IF( TAU.NE.ZERO ) THEN+* Set up variables for scanning V. LASTV begins pointing to the end+* of V.+ IF( APPLYLEFT ) THEN+ LASTV = M+ ELSE+ LASTV = N+ END IF+ IF( INCV.GT.0 ) THEN+ I = 1 + (LASTV-1) * INCV+ ELSE+ I = 1+ END IF+* Look for the last non-zero row in V.+ DO WHILE( LASTV.GT.0 .AND. V( I ).EQ.ZERO )+ LASTV = LASTV - 1+ I = I - INCV+ END DO+ IF( APPLYLEFT ) THEN+* Scan for the last non-zero column in C(1:lastv,:).+ LASTC = ILAZLC(LASTV, N, C, LDC)+ ELSE+* Scan for the last non-zero row in C(:,1:lastv).+ LASTC = ILAZLR(M, LASTV, C, LDC)+ END IF+ END IF+* Note that lastc.eq.0 renders the BLAS operations null; no special+* case is needed at this level.+ IF( APPLYLEFT ) THEN+*+* Form H * C+*+ IF( LASTV.GT.0 ) THEN+*+* w(1:lastc,1) := C(1:lastv,1:lastc)**H * v(1:lastv,1)+*+ CALL ZGEMV( 'Conjugate transpose', LASTV, LASTC, ONE,+ $ C, LDC, V, INCV, ZERO, WORK, 1 )+*+* C(1:lastv,1:lastc) := C(...) - v(1:lastv,1) * w(1:lastc,1)**H+*+ CALL ZGERC( LASTV, LASTC, -TAU, V, INCV, WORK, 1, C, LDC )+ END IF+ ELSE+*+* Form C * H+*+ IF( LASTV.GT.0 ) THEN+*+* w(1:lastc,1) := C(1:lastc,1:lastv) * v(1:lastv,1)+*+ CALL ZGEMV( 'No transpose', LASTC, LASTV, ONE, C, LDC,+ $ V, INCV, ZERO, WORK, 1 )+*+* C(1:lastc,1:lastv) := C(...) - w(1:lastc,1) * v(1:lastv,1)**H+*+ CALL ZGERC( LASTC, LASTV, -TAU, WORK, 1, V, INCV, C, LDC )+ END IF+ END IF+ RETURN+*+* End of ZLARF+*+ END
+ eigen3/lapack/zlarfb.f view
@@ -0,0 +1,774 @@+*> \brief \b ZLARFB+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download ZLARFB + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zlarfb.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zlarfb.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zlarfb.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE ZLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV,+* T, LDT, C, LDC, WORK, LDWORK )+* +* .. Scalar Arguments ..+* CHARACTER DIRECT, SIDE, STOREV, TRANS+* INTEGER K, LDC, LDT, LDV, LDWORK, M, N+* ..+* .. Array Arguments ..+* COMPLEX*16 C( LDC, * ), T( LDT, * ), V( LDV, * ),+* $ WORK( LDWORK, * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> ZLARFB applies a complex block reflector H or its transpose H**H to a+*> complex M-by-N matrix C, from either the left or the right.+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] SIDE+*> \verbatim+*> SIDE is CHARACTER*1+*> = 'L': apply H or H**H from the Left+*> = 'R': apply H or H**H from the Right+*> \endverbatim+*>+*> \param[in] TRANS+*> \verbatim+*> TRANS is CHARACTER*1+*> = 'N': apply H (No transpose)+*> = 'C': apply H**H (Conjugate transpose)+*> \endverbatim+*>+*> \param[in] DIRECT+*> \verbatim+*> DIRECT is CHARACTER*1+*> Indicates how H is formed from a product of elementary+*> reflectors+*> = 'F': H = H(1) H(2) . . . H(k) (Forward)+*> = 'B': H = H(k) . . . H(2) H(1) (Backward)+*> \endverbatim+*>+*> \param[in] STOREV+*> \verbatim+*> STOREV is CHARACTER*1+*> Indicates how the vectors which define the elementary+*> reflectors are stored:+*> = 'C': Columnwise+*> = 'R': Rowwise+*> \endverbatim+*>+*> \param[in] M+*> \verbatim+*> M is INTEGER+*> The number of rows of the matrix C.+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The number of columns of the matrix C.+*> \endverbatim+*>+*> \param[in] K+*> \verbatim+*> K is INTEGER+*> The order of the matrix T (= the number of elementary+*> reflectors whose product defines the block reflector).+*> \endverbatim+*>+*> \param[in] V+*> \verbatim+*> V is COMPLEX*16 array, dimension+*> (LDV,K) if STOREV = 'C'+*> (LDV,M) if STOREV = 'R' and SIDE = 'L'+*> (LDV,N) if STOREV = 'R' and SIDE = 'R'+*> See Further Details.+*> \endverbatim+*>+*> \param[in] LDV+*> \verbatim+*> LDV is INTEGER+*> The leading dimension of the array V.+*> If STOREV = 'C' and SIDE = 'L', LDV >= max(1,M);+*> if STOREV = 'C' and SIDE = 'R', LDV >= max(1,N);+*> if STOREV = 'R', LDV >= K.+*> \endverbatim+*>+*> \param[in] T+*> \verbatim+*> T is COMPLEX*16 array, dimension (LDT,K)+*> The triangular K-by-K matrix T in the representation of the+*> block reflector.+*> \endverbatim+*>+*> \param[in] LDT+*> \verbatim+*> LDT is INTEGER+*> The leading dimension of the array T. LDT >= K.+*> \endverbatim+*>+*> \param[in,out] C+*> \verbatim+*> C is COMPLEX*16 array, dimension (LDC,N)+*> On entry, the M-by-N matrix C.+*> On exit, C is overwritten by H*C or H**H*C or C*H or C*H**H.+*> \endverbatim+*>+*> \param[in] LDC+*> \verbatim+*> LDC is INTEGER+*> The leading dimension of the array C. LDC >= max(1,M).+*> \endverbatim+*>+*> \param[out] WORK+*> \verbatim+*> WORK is COMPLEX*16 array, dimension (LDWORK,K)+*> \endverbatim+*>+*> \param[in] LDWORK+*> \verbatim+*> LDWORK is INTEGER+*> The leading dimension of the array WORK.+*> If SIDE = 'L', LDWORK >= max(1,N);+*> if SIDE = 'R', LDWORK >= max(1,M).+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup complex16OTHERauxiliary+*+*> \par Further Details:+* =====================+*>+*> \verbatim+*>+*> The shape of the matrix V and the storage of the vectors which define+*> the H(i) is best illustrated by the following example with n = 5 and+*> k = 3. The elements equal to 1 are not stored; the corresponding+*> array elements are modified but restored on exit. The rest of the+*> array is not used.+*>+*> DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R':+*>+*> V = ( 1 ) V = ( 1 v1 v1 v1 v1 )+*> ( v1 1 ) ( 1 v2 v2 v2 )+*> ( v1 v2 1 ) ( 1 v3 v3 )+*> ( v1 v2 v3 )+*> ( v1 v2 v3 )+*>+*> DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R':+*>+*> V = ( v1 v2 v3 ) V = ( v1 v1 1 )+*> ( v1 v2 v3 ) ( v2 v2 v2 1 )+*> ( 1 v2 v3 ) ( v3 v3 v3 v3 1 )+*> ( 1 v3 )+*> ( 1 )+*> \endverbatim+*>+* =====================================================================+ SUBROUTINE ZLARFB( SIDE, TRANS, DIRECT, STOREV, M, N, K, V, LDV,+ $ T, LDT, C, LDC, WORK, LDWORK )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ CHARACTER DIRECT, SIDE, STOREV, TRANS+ INTEGER K, LDC, LDT, LDV, LDWORK, M, N+* ..+* .. Array Arguments ..+ COMPLEX*16 C( LDC, * ), T( LDT, * ), V( LDV, * ),+ $ WORK( LDWORK, * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ COMPLEX*16 ONE+ PARAMETER ( ONE = ( 1.0D+0, 0.0D+0 ) )+* ..+* .. Local Scalars ..+ CHARACTER TRANST+ INTEGER I, J, LASTV, LASTC+* ..+* .. External Functions ..+ LOGICAL LSAME+ INTEGER ILAZLR, ILAZLC+ EXTERNAL LSAME, ILAZLR, ILAZLC+* ..+* .. External Subroutines ..+ EXTERNAL ZCOPY, ZGEMM, ZLACGV, ZTRMM+* ..+* .. Intrinsic Functions ..+ INTRINSIC DCONJG+* ..+* .. Executable Statements ..+*+* Quick return if possible+*+ IF( M.LE.0 .OR. N.LE.0 )+ $ RETURN+*+ IF( LSAME( TRANS, 'N' ) ) THEN+ TRANST = 'C'+ ELSE+ TRANST = 'N'+ END IF+*+ IF( LSAME( STOREV, 'C' ) ) THEN+*+ IF( LSAME( DIRECT, 'F' ) ) THEN+*+* Let V = ( V1 ) (first K rows)+* ( V2 )+* where V1 is unit lower triangular.+*+ IF( LSAME( SIDE, 'L' ) ) THEN+*+* Form H * C or H**H * C where C = ( C1 )+* ( C2 )+*+ LASTV = MAX( K, ILAZLR( M, K, V, LDV ) )+ LASTC = ILAZLC( LASTV, N, C, LDC )+*+* W := C**H * V = (C1**H * V1 + C2**H * V2) (stored in WORK)+*+* W := C1**H+*+ DO 10 J = 1, K+ CALL ZCOPY( LASTC, C( J, 1 ), LDC, WORK( 1, J ), 1 )+ CALL ZLACGV( LASTC, WORK( 1, J ), 1 )+ 10 CONTINUE+*+* W := W * V1+*+ CALL ZTRMM( 'Right', 'Lower', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C2**H *V2+*+ CALL ZGEMM( 'Conjugate transpose', 'No transpose',+ $ LASTC, K, LASTV-K, ONE, C( K+1, 1 ), LDC,+ $ V( K+1, 1 ), LDV, ONE, WORK, LDWORK )+ END IF+*+* W := W * T**H or W * T+*+ CALL ZTRMM( 'Right', 'Upper', TRANST, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - V * W**H+*+ IF( M.GT.K ) THEN+*+* C2 := C2 - V2 * W**H+*+ CALL ZGEMM( 'No transpose', 'Conjugate transpose',+ $ LASTV-K, LASTC, K,+ $ -ONE, V( K+1, 1 ), LDV, WORK, LDWORK,+ $ ONE, C( K+1, 1 ), LDC )+ END IF+*+* W := W * V1**H+*+ CALL ZTRMM( 'Right', 'Lower', 'Conjugate transpose',+ $ 'Unit', LASTC, K, ONE, V, LDV, WORK, LDWORK )+*+* C1 := C1 - W**H+*+ DO 30 J = 1, K+ DO 20 I = 1, LASTC+ C( J, I ) = C( J, I ) - DCONJG( WORK( I, J ) )+ 20 CONTINUE+ 30 CONTINUE+*+ ELSE IF( LSAME( SIDE, 'R' ) ) THEN+*+* Form C * H or C * H**H where C = ( C1 C2 )+*+ LASTV = MAX( K, ILAZLR( N, K, V, LDV ) )+ LASTC = ILAZLR( M, LASTV, C, LDC )+*+* W := C * V = (C1*V1 + C2*V2) (stored in WORK)+*+* W := C1+*+ DO 40 J = 1, K+ CALL ZCOPY( LASTC, C( 1, J ), 1, WORK( 1, J ), 1 )+ 40 CONTINUE+*+* W := W * V1+*+ CALL ZTRMM( 'Right', 'Lower', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C2 * V2+*+ CALL ZGEMM( 'No transpose', 'No transpose',+ $ LASTC, K, LASTV-K,+ $ ONE, C( 1, K+1 ), LDC, V( K+1, 1 ), LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T or W * T**H+*+ CALL ZTRMM( 'Right', 'Upper', TRANS, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - W * V**H+*+ IF( LASTV.GT.K ) THEN+*+* C2 := C2 - W * V2**H+*+ CALL ZGEMM( 'No transpose', 'Conjugate transpose',+ $ LASTC, LASTV-K, K,+ $ -ONE, WORK, LDWORK, V( K+1, 1 ), LDV,+ $ ONE, C( 1, K+1 ), LDC )+ END IF+*+* W := W * V1**H+*+ CALL ZTRMM( 'Right', 'Lower', 'Conjugate transpose',+ $ 'Unit', LASTC, K, ONE, V, LDV, WORK, LDWORK )+*+* C1 := C1 - W+*+ DO 60 J = 1, K+ DO 50 I = 1, LASTC+ C( I, J ) = C( I, J ) - WORK( I, J )+ 50 CONTINUE+ 60 CONTINUE+ END IF+*+ ELSE+*+* Let V = ( V1 )+* ( V2 ) (last K rows)+* where V2 is unit upper triangular.+*+ IF( LSAME( SIDE, 'L' ) ) THEN+*+* Form H * C or H**H * C where C = ( C1 )+* ( C2 )+*+ LASTV = MAX( K, ILAZLR( M, K, V, LDV ) )+ LASTC = ILAZLC( LASTV, N, C, LDC )+*+* W := C**H * V = (C1**H * V1 + C2**H * V2) (stored in WORK)+*+* W := C2**H+*+ DO 70 J = 1, K+ CALL ZCOPY( LASTC, C( LASTV-K+J, 1 ), LDC,+ $ WORK( 1, J ), 1 )+ CALL ZLACGV( LASTC, WORK( 1, J ), 1 )+ 70 CONTINUE+*+* W := W * V2+*+ CALL ZTRMM( 'Right', 'Upper', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,+ $ WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C1**H*V1+*+ CALL ZGEMM( 'Conjugate transpose', 'No transpose',+ $ LASTC, K, LASTV-K,+ $ ONE, C, LDC, V, LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T**H or W * T+*+ CALL ZTRMM( 'Right', 'Lower', TRANST, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - V * W**H+*+ IF( LASTV.GT.K ) THEN+*+* C1 := C1 - V1 * W**H+*+ CALL ZGEMM( 'No transpose', 'Conjugate transpose',+ $ LASTV-K, LASTC, K,+ $ -ONE, V, LDV, WORK, LDWORK,+ $ ONE, C, LDC )+ END IF+*+* W := W * V2**H+*+ CALL ZTRMM( 'Right', 'Upper', 'Conjugate transpose',+ $ 'Unit', LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,+ $ WORK, LDWORK )+*+* C2 := C2 - W**H+*+ DO 90 J = 1, K+ DO 80 I = 1, LASTC+ C( LASTV-K+J, I ) = C( LASTV-K+J, I ) -+ $ DCONJG( WORK( I, J ) )+ 80 CONTINUE+ 90 CONTINUE+*+ ELSE IF( LSAME( SIDE, 'R' ) ) THEN+*+* Form C * H or C * H**H where C = ( C1 C2 )+*+ LASTV = MAX( K, ILAZLR( N, K, V, LDV ) )+ LASTC = ILAZLR( M, LASTV, C, LDC )+*+* W := C * V = (C1*V1 + C2*V2) (stored in WORK)+*+* W := C2+*+ DO 100 J = 1, K+ CALL ZCOPY( LASTC, C( 1, LASTV-K+J ), 1,+ $ WORK( 1, J ), 1 )+ 100 CONTINUE+*+* W := W * V2+*+ CALL ZTRMM( 'Right', 'Upper', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,+ $ WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C1 * V1+*+ CALL ZGEMM( 'No transpose', 'No transpose',+ $ LASTC, K, LASTV-K,+ $ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )+ END IF+*+* W := W * T or W * T**H+*+ CALL ZTRMM( 'Right', 'Lower', TRANS, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - W * V**H+*+ IF( LASTV.GT.K ) THEN+*+* C1 := C1 - W * V1**H+*+ CALL ZGEMM( 'No transpose', 'Conjugate transpose',+ $ LASTC, LASTV-K, K, -ONE, WORK, LDWORK, V, LDV,+ $ ONE, C, LDC )+ END IF+*+* W := W * V2**H+*+ CALL ZTRMM( 'Right', 'Upper', 'Conjugate transpose',+ $ 'Unit', LASTC, K, ONE, V( LASTV-K+1, 1 ), LDV,+ $ WORK, LDWORK )+*+* C2 := C2 - W+*+ DO 120 J = 1, K+ DO 110 I = 1, LASTC+ C( I, LASTV-K+J ) = C( I, LASTV-K+J )+ $ - WORK( I, J )+ 110 CONTINUE+ 120 CONTINUE+ END IF+ END IF+*+ ELSE IF( LSAME( STOREV, 'R' ) ) THEN+*+ IF( LSAME( DIRECT, 'F' ) ) THEN+*+* Let V = ( V1 V2 ) (V1: first K columns)+* where V1 is unit upper triangular.+*+ IF( LSAME( SIDE, 'L' ) ) THEN+*+* Form H * C or H**H * C where C = ( C1 )+* ( C2 )+*+ LASTV = MAX( K, ILAZLC( K, M, V, LDV ) )+ LASTC = ILAZLC( LASTV, N, C, LDC )+*+* W := C**H * V**H = (C1**H * V1**H + C2**H * V2**H) (stored in WORK)+*+* W := C1**H+*+ DO 130 J = 1, K+ CALL ZCOPY( LASTC, C( J, 1 ), LDC, WORK( 1, J ), 1 )+ CALL ZLACGV( LASTC, WORK( 1, J ), 1 )+ 130 CONTINUE+*+* W := W * V1**H+*+ CALL ZTRMM( 'Right', 'Upper', 'Conjugate transpose',+ $ 'Unit', LASTC, K, ONE, V, LDV, WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C2**H*V2**H+*+ CALL ZGEMM( 'Conjugate transpose',+ $ 'Conjugate transpose', LASTC, K, LASTV-K,+ $ ONE, C( K+1, 1 ), LDC, V( 1, K+1 ), LDV,+ $ ONE, WORK, LDWORK )+ END IF+*+* W := W * T**H or W * T+*+ CALL ZTRMM( 'Right', 'Upper', TRANST, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - V**H * W**H+*+ IF( LASTV.GT.K ) THEN+*+* C2 := C2 - V2**H * W**H+*+ CALL ZGEMM( 'Conjugate transpose',+ $ 'Conjugate transpose', LASTV-K, LASTC, K,+ $ -ONE, V( 1, K+1 ), LDV, WORK, LDWORK,+ $ ONE, C( K+1, 1 ), LDC )+ END IF+*+* W := W * V1+*+ CALL ZTRMM( 'Right', 'Upper', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+*+* C1 := C1 - W**H+*+ DO 150 J = 1, K+ DO 140 I = 1, LASTC+ C( J, I ) = C( J, I ) - DCONJG( WORK( I, J ) )+ 140 CONTINUE+ 150 CONTINUE+*+ ELSE IF( LSAME( SIDE, 'R' ) ) THEN+*+* Form C * H or C * H**H where C = ( C1 C2 )+*+ LASTV = MAX( K, ILAZLC( K, N, V, LDV ) )+ LASTC = ILAZLR( M, LASTV, C, LDC )+*+* W := C * V**H = (C1*V1**H + C2*V2**H) (stored in WORK)+*+* W := C1+*+ DO 160 J = 1, K+ CALL ZCOPY( LASTC, C( 1, J ), 1, WORK( 1, J ), 1 )+ 160 CONTINUE+*+* W := W * V1**H+*+ CALL ZTRMM( 'Right', 'Upper', 'Conjugate transpose',+ $ 'Unit', LASTC, K, ONE, V, LDV, WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C2 * V2**H+*+ CALL ZGEMM( 'No transpose', 'Conjugate transpose',+ $ LASTC, K, LASTV-K, ONE, C( 1, K+1 ), LDC,+ $ V( 1, K+1 ), LDV, ONE, WORK, LDWORK )+ END IF+*+* W := W * T or W * T**H+*+ CALL ZTRMM( 'Right', 'Upper', TRANS, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - W * V+*+ IF( LASTV.GT.K ) THEN+*+* C2 := C2 - W * V2+*+ CALL ZGEMM( 'No transpose', 'No transpose',+ $ LASTC, LASTV-K, K,+ $ -ONE, WORK, LDWORK, V( 1, K+1 ), LDV,+ $ ONE, C( 1, K+1 ), LDC )+ END IF+*+* W := W * V1+*+ CALL ZTRMM( 'Right', 'Upper', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V, LDV, WORK, LDWORK )+*+* C1 := C1 - W+*+ DO 180 J = 1, K+ DO 170 I = 1, LASTC+ C( I, J ) = C( I, J ) - WORK( I, J )+ 170 CONTINUE+ 180 CONTINUE+*+ END IF+*+ ELSE+*+* Let V = ( V1 V2 ) (V2: last K columns)+* where V2 is unit lower triangular.+*+ IF( LSAME( SIDE, 'L' ) ) THEN+*+* Form H * C or H**H * C where C = ( C1 )+* ( C2 )+*+ LASTV = MAX( K, ILAZLC( K, M, V, LDV ) )+ LASTC = ILAZLC( LASTV, N, C, LDC )+*+* W := C**H * V**H = (C1**H * V1**H + C2**H * V2**H) (stored in WORK)+*+* W := C2**H+*+ DO 190 J = 1, K+ CALL ZCOPY( LASTC, C( LASTV-K+J, 1 ), LDC,+ $ WORK( 1, J ), 1 )+ CALL ZLACGV( LASTC, WORK( 1, J ), 1 )+ 190 CONTINUE+*+* W := W * V2**H+*+ CALL ZTRMM( 'Right', 'Lower', 'Conjugate transpose',+ $ 'Unit', LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,+ $ WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C1**H * V1**H+*+ CALL ZGEMM( 'Conjugate transpose',+ $ 'Conjugate transpose', LASTC, K, LASTV-K,+ $ ONE, C, LDC, V, LDV, ONE, WORK, LDWORK )+ END IF+*+* W := W * T**H or W * T+*+ CALL ZTRMM( 'Right', 'Lower', TRANST, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - V**H * W**H+*+ IF( LASTV.GT.K ) THEN+*+* C1 := C1 - V1**H * W**H+*+ CALL ZGEMM( 'Conjugate transpose',+ $ 'Conjugate transpose', LASTV-K, LASTC, K,+ $ -ONE, V, LDV, WORK, LDWORK, ONE, C, LDC )+ END IF+*+* W := W * V2+*+ CALL ZTRMM( 'Right', 'Lower', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,+ $ WORK, LDWORK )+*+* C2 := C2 - W**H+*+ DO 210 J = 1, K+ DO 200 I = 1, LASTC+ C( LASTV-K+J, I ) = C( LASTV-K+J, I ) -+ $ DCONJG( WORK( I, J ) )+ 200 CONTINUE+ 210 CONTINUE+*+ ELSE IF( LSAME( SIDE, 'R' ) ) THEN+*+* Form C * H or C * H**H where C = ( C1 C2 )+*+ LASTV = MAX( K, ILAZLC( K, N, V, LDV ) )+ LASTC = ILAZLR( M, LASTV, C, LDC )+*+* W := C * V**H = (C1*V1**H + C2*V2**H) (stored in WORK)+*+* W := C2+*+ DO 220 J = 1, K+ CALL ZCOPY( LASTC, C( 1, LASTV-K+J ), 1,+ $ WORK( 1, J ), 1 )+ 220 CONTINUE+*+* W := W * V2**H+*+ CALL ZTRMM( 'Right', 'Lower', 'Conjugate transpose',+ $ 'Unit', LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,+ $ WORK, LDWORK )+ IF( LASTV.GT.K ) THEN+*+* W := W + C1 * V1**H+*+ CALL ZGEMM( 'No transpose', 'Conjugate transpose',+ $ LASTC, K, LASTV-K, ONE, C, LDC, V, LDV, ONE,+ $ WORK, LDWORK )+ END IF+*+* W := W * T or W * T**H+*+ CALL ZTRMM( 'Right', 'Lower', TRANS, 'Non-unit',+ $ LASTC, K, ONE, T, LDT, WORK, LDWORK )+*+* C := C - W * V+*+ IF( LASTV.GT.K ) THEN+*+* C1 := C1 - W * V1+*+ CALL ZGEMM( 'No transpose', 'No transpose',+ $ LASTC, LASTV-K, K, -ONE, WORK, LDWORK, V, LDV,+ $ ONE, C, LDC )+ END IF+*+* W := W * V2+*+ CALL ZTRMM( 'Right', 'Lower', 'No transpose', 'Unit',+ $ LASTC, K, ONE, V( 1, LASTV-K+1 ), LDV,+ $ WORK, LDWORK )+*+* C1 := C1 - W+*+ DO 240 J = 1, K+ DO 230 I = 1, LASTC+ C( I, LASTV-K+J ) = C( I, LASTV-K+J )+ $ - WORK( I, J )+ 230 CONTINUE+ 240 CONTINUE+*+ END IF+*+ END IF+ END IF+*+ RETURN+*+* End of ZLARFB+*+ END
+ eigen3/lapack/zlarfg.f view
@@ -0,0 +1,203 @@+*> \brief \b ZLARFG+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download ZLARFG + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zlarfg.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zlarfg.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zlarfg.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE ZLARFG( N, ALPHA, X, INCX, TAU )+* +* .. Scalar Arguments ..+* INTEGER INCX, N+* COMPLEX*16 ALPHA, TAU+* ..+* .. Array Arguments ..+* COMPLEX*16 X( * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> ZLARFG generates a complex elementary reflector H of order n, such+*> that+*>+*> H**H * ( alpha ) = ( beta ), H**H * H = I.+*> ( x ) ( 0 )+*>+*> where alpha and beta are scalars, with beta real, and x is an+*> (n-1)-element complex vector. H is represented in the form+*>+*> H = I - tau * ( 1 ) * ( 1 v**H ) ,+*> ( v )+*>+*> where tau is a complex scalar and v is a complex (n-1)-element+*> vector. Note that H is not hermitian.+*>+*> If the elements of x are all zero and alpha is real, then tau = 0+*> and H is taken to be the unit matrix.+*>+*> Otherwise 1 <= real(tau) <= 2 and abs(tau-1) <= 1 .+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The order of the elementary reflector.+*> \endverbatim+*>+*> \param[in,out] ALPHA+*> \verbatim+*> ALPHA is COMPLEX*16+*> On entry, the value alpha.+*> On exit, it is overwritten with the value beta.+*> \endverbatim+*>+*> \param[in,out] X+*> \verbatim+*> X is COMPLEX*16 array, dimension+*> (1+(N-2)*abs(INCX))+*> On entry, the vector x.+*> On exit, it is overwritten with the vector v.+*> \endverbatim+*>+*> \param[in] INCX+*> \verbatim+*> INCX is INTEGER+*> The increment between elements of X. INCX > 0.+*> \endverbatim+*>+*> \param[out] TAU+*> \verbatim+*> TAU is COMPLEX*16+*> The value tau.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date November 2011+*+*> \ingroup complex16OTHERauxiliary+*+* =====================================================================+ SUBROUTINE ZLARFG( N, ALPHA, X, INCX, TAU )+*+* -- LAPACK auxiliary routine (version 3.4.0) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* November 2011+*+* .. Scalar Arguments ..+ INTEGER INCX, N+ COMPLEX*16 ALPHA, TAU+* ..+* .. Array Arguments ..+ COMPLEX*16 X( * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ DOUBLE PRECISION ONE, ZERO+ PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 )+* ..+* .. Local Scalars ..+ INTEGER J, KNT+ DOUBLE PRECISION ALPHI, ALPHR, BETA, RSAFMN, SAFMIN, XNORM+* ..+* .. External Functions ..+ DOUBLE PRECISION DLAMCH, DLAPY3, DZNRM2+ COMPLEX*16 ZLADIV+ EXTERNAL DLAMCH, DLAPY3, DZNRM2, ZLADIV+* ..+* .. Intrinsic Functions ..+ INTRINSIC ABS, DBLE, DCMPLX, DIMAG, SIGN+* ..+* .. External Subroutines ..+ EXTERNAL ZDSCAL, ZSCAL+* ..+* .. Executable Statements ..+*+ IF( N.LE.0 ) THEN+ TAU = ZERO+ RETURN+ END IF+*+ XNORM = DZNRM2( N-1, X, INCX )+ ALPHR = DBLE( ALPHA )+ ALPHI = DIMAG( ALPHA )+*+ IF( XNORM.EQ.ZERO .AND. ALPHI.EQ.ZERO ) THEN+*+* H = I+*+ TAU = ZERO+ ELSE+*+* general case+*+ BETA = -SIGN( DLAPY3( ALPHR, ALPHI, XNORM ), ALPHR )+ SAFMIN = DLAMCH( 'S' ) / DLAMCH( 'E' )+ RSAFMN = ONE / SAFMIN+*+ KNT = 0+ IF( ABS( BETA ).LT.SAFMIN ) THEN+*+* XNORM, BETA may be inaccurate; scale X and recompute them+*+ 10 CONTINUE+ KNT = KNT + 1+ CALL ZDSCAL( N-1, RSAFMN, X, INCX )+ BETA = BETA*RSAFMN+ ALPHI = ALPHI*RSAFMN+ ALPHR = ALPHR*RSAFMN+ IF( ABS( BETA ).LT.SAFMIN )+ $ GO TO 10+*+* New BETA is at most 1, at least SAFMIN+*+ XNORM = DZNRM2( N-1, X, INCX )+ ALPHA = DCMPLX( ALPHR, ALPHI )+ BETA = -SIGN( DLAPY3( ALPHR, ALPHI, XNORM ), ALPHR )+ END IF+ TAU = DCMPLX( ( BETA-ALPHR ) / BETA, -ALPHI / BETA )+ ALPHA = ZLADIV( DCMPLX( ONE ), ALPHA-BETA )+ CALL ZSCAL( N-1, ALPHA, X, INCX )+*+* If ALPHA is subnormal, it may lose relative accuracy+*+ DO 20 J = 1, KNT+ BETA = BETA*SAFMIN+ 20 CONTINUE+ ALPHA = BETA+ END IF+*+ RETURN+*+* End of ZLARFG+*+ END
+ eigen3/lapack/zlarft.f view
@@ -0,0 +1,327 @@+*> \brief \b ZLARFT+*+* =========== DOCUMENTATION ===========+*+* Online html documentation available at +* http://www.netlib.org/lapack/explore-html/ +*+*> \htmlonly+*> Download ZLARFT + dependencies +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zlarft.f"> +*> [TGZ]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zlarft.f"> +*> [ZIP]</a> +*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zlarft.f"> +*> [TXT]</a>+*> \endhtmlonly +*+* Definition:+* ===========+*+* SUBROUTINE ZLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )+* +* .. Scalar Arguments ..+* CHARACTER DIRECT, STOREV+* INTEGER K, LDT, LDV, N+* ..+* .. Array Arguments ..+* COMPLEX*16 T( LDT, * ), TAU( * ), V( LDV, * )+* ..+* +*+*> \par Purpose:+* =============+*>+*> \verbatim+*>+*> ZLARFT forms the triangular factor T of a complex block reflector H+*> of order n, which is defined as a product of k elementary reflectors.+*>+*> If DIRECT = 'F', H = H(1) H(2) . . . H(k) and T is upper triangular;+*>+*> If DIRECT = 'B', H = H(k) . . . H(2) H(1) and T is lower triangular.+*>+*> If STOREV = 'C', the vector which defines the elementary reflector+*> H(i) is stored in the i-th column of the array V, and+*>+*> H = I - V * T * V**H+*>+*> If STOREV = 'R', the vector which defines the elementary reflector+*> H(i) is stored in the i-th row of the array V, and+*>+*> H = I - V**H * T * V+*> \endverbatim+*+* Arguments:+* ==========+*+*> \param[in] DIRECT+*> \verbatim+*> DIRECT is CHARACTER*1+*> Specifies the order in which the elementary reflectors are+*> multiplied to form the block reflector:+*> = 'F': H = H(1) H(2) . . . H(k) (Forward)+*> = 'B': H = H(k) . . . H(2) H(1) (Backward)+*> \endverbatim+*>+*> \param[in] STOREV+*> \verbatim+*> STOREV is CHARACTER*1+*> Specifies how the vectors which define the elementary+*> reflectors are stored (see also Further Details):+*> = 'C': columnwise+*> = 'R': rowwise+*> \endverbatim+*>+*> \param[in] N+*> \verbatim+*> N is INTEGER+*> The order of the block reflector H. N >= 0.+*> \endverbatim+*>+*> \param[in] K+*> \verbatim+*> K is INTEGER+*> The order of the triangular factor T (= the number of+*> elementary reflectors). K >= 1.+*> \endverbatim+*>+*> \param[in] V+*> \verbatim+*> V is COMPLEX*16 array, dimension+*> (LDV,K) if STOREV = 'C'+*> (LDV,N) if STOREV = 'R'+*> The matrix V. See further details.+*> \endverbatim+*>+*> \param[in] LDV+*> \verbatim+*> LDV is INTEGER+*> The leading dimension of the array V.+*> If STOREV = 'C', LDV >= max(1,N); if STOREV = 'R', LDV >= K.+*> \endverbatim+*>+*> \param[in] TAU+*> \verbatim+*> TAU is COMPLEX*16 array, dimension (K)+*> TAU(i) must contain the scalar factor of the elementary+*> reflector H(i).+*> \endverbatim+*>+*> \param[out] T+*> \verbatim+*> T is COMPLEX*16 array, dimension (LDT,K)+*> The k by k triangular factor T of the block reflector.+*> If DIRECT = 'F', T is upper triangular; if DIRECT = 'B', T is+*> lower triangular. The rest of the array is not used.+*> \endverbatim+*>+*> \param[in] LDT+*> \verbatim+*> LDT is INTEGER+*> The leading dimension of the array T. LDT >= K.+*> \endverbatim+*+* Authors:+* ========+*+*> \author Univ. of Tennessee +*> \author Univ. of California Berkeley +*> \author Univ. of Colorado Denver +*> \author NAG Ltd. +*+*> \date April 2012+*+*> \ingroup complex16OTHERauxiliary+*+*> \par Further Details:+* =====================+*>+*> \verbatim+*>+*> The shape of the matrix V and the storage of the vectors which define+*> the H(i) is best illustrated by the following example with n = 5 and+*> k = 3. The elements equal to 1 are not stored.+*>+*> DIRECT = 'F' and STOREV = 'C': DIRECT = 'F' and STOREV = 'R':+*>+*> V = ( 1 ) V = ( 1 v1 v1 v1 v1 )+*> ( v1 1 ) ( 1 v2 v2 v2 )+*> ( v1 v2 1 ) ( 1 v3 v3 )+*> ( v1 v2 v3 )+*> ( v1 v2 v3 )+*>+*> DIRECT = 'B' and STOREV = 'C': DIRECT = 'B' and STOREV = 'R':+*>+*> V = ( v1 v2 v3 ) V = ( v1 v1 1 )+*> ( v1 v2 v3 ) ( v2 v2 v2 1 )+*> ( 1 v2 v3 ) ( v3 v3 v3 v3 1 )+*> ( 1 v3 )+*> ( 1 )+*> \endverbatim+*>+* =====================================================================+ SUBROUTINE ZLARFT( DIRECT, STOREV, N, K, V, LDV, TAU, T, LDT )+*+* -- LAPACK auxiliary routine (version 3.4.1) --+* -- LAPACK is a software package provided by Univ. of Tennessee, --+* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--+* April 2012+*+* .. Scalar Arguments ..+ CHARACTER DIRECT, STOREV+ INTEGER K, LDT, LDV, N+* ..+* .. Array Arguments ..+ COMPLEX*16 T( LDT, * ), TAU( * ), V( LDV, * )+* ..+*+* =====================================================================+*+* .. Parameters ..+ COMPLEX*16 ONE, ZERO+ PARAMETER ( ONE = ( 1.0D+0, 0.0D+0 ),+ $ ZERO = ( 0.0D+0, 0.0D+0 ) )+* ..+* .. Local Scalars ..+ INTEGER I, J, PREVLASTV, LASTV+* ..+* .. External Subroutines ..+ EXTERNAL ZGEMV, ZLACGV, ZTRMV+* ..+* .. External Functions ..+ LOGICAL LSAME+ EXTERNAL LSAME+* ..+* .. Executable Statements ..+*+* Quick return if possible+*+ IF( N.EQ.0 )+ $ RETURN+*+ IF( LSAME( DIRECT, 'F' ) ) THEN+ PREVLASTV = N+ DO I = 1, K+ PREVLASTV = MAX( PREVLASTV, I )+ IF( TAU( I ).EQ.ZERO ) THEN+*+* H(i) = I+*+ DO J = 1, I+ T( J, I ) = ZERO+ END DO+ ELSE+*+* general case+*+ IF( LSAME( STOREV, 'C' ) ) THEN+* Skip any trailing zeros.+ DO LASTV = N, I+1, -1+ IF( V( LASTV, I ).NE.ZERO ) EXIT+ END DO+ DO J = 1, I-1+ T( J, I ) = -TAU( I ) * CONJG( V( I , J ) )+ END DO + J = MIN( LASTV, PREVLASTV )+*+* T(1:i-1,i) := - tau(i) * V(i:j,1:i-1)**H * V(i:j,i)+*+ CALL ZGEMV( 'Conjugate transpose', J-I, I-1,+ $ -TAU( I ), V( I+1, 1 ), LDV, + $ V( I+1, I ), 1, ONE, T( 1, I ), 1 )+ ELSE+* Skip any trailing zeros.+ DO LASTV = N, I+1, -1+ IF( V( I, LASTV ).NE.ZERO ) EXIT+ END DO+ DO J = 1, I-1+ T( J, I ) = -TAU( I ) * V( J , I )+ END DO + J = MIN( LASTV, PREVLASTV )+*+* T(1:i-1,i) := - tau(i) * V(1:i-1,i:j) * V(i,i:j)**H+*+ CALL ZGEMM( 'N', 'C', I-1, 1, J-I, -TAU( I ),+ $ V( 1, I+1 ), LDV, V( I, I+1 ), LDV,+ $ ONE, T( 1, I ), LDT ) + END IF+*+* T(1:i-1,i) := T(1:i-1,1:i-1) * T(1:i-1,i)+*+ CALL ZTRMV( 'Upper', 'No transpose', 'Non-unit', I-1, T,+ $ LDT, T( 1, I ), 1 )+ T( I, I ) = TAU( I )+ IF( I.GT.1 ) THEN+ PREVLASTV = MAX( PREVLASTV, LASTV )+ ELSE+ PREVLASTV = LASTV+ END IF+ END IF+ END DO+ ELSE+ PREVLASTV = 1+ DO I = K, 1, -1+ IF( TAU( I ).EQ.ZERO ) THEN+*+* H(i) = I+*+ DO J = I, K+ T( J, I ) = ZERO+ END DO+ ELSE+*+* general case+*+ IF( I.LT.K ) THEN+ IF( LSAME( STOREV, 'C' ) ) THEN+* Skip any leading zeros.+ DO LASTV = 1, I-1+ IF( V( LASTV, I ).NE.ZERO ) EXIT+ END DO+ DO J = I+1, K+ T( J, I ) = -TAU( I ) * CONJG( V( N-K+I , J ) )+ END DO + J = MAX( LASTV, PREVLASTV )+*+* T(i+1:k,i) = -tau(i) * V(j:n-k+i,i+1:k)**H * V(j:n-k+i,i)+*+ CALL ZGEMV( 'Conjugate transpose', N-K+I-J, K-I,+ $ -TAU( I ), V( J, I+1 ), LDV, V( J, I ),+ $ 1, ONE, T( I+1, I ), 1 )+ ELSE+* Skip any leading zeros.+ DO LASTV = 1, I-1+ IF( V( I, LASTV ).NE.ZERO ) EXIT+ END DO+ DO J = I+1, K+ T( J, I ) = -TAU( I ) * V( J, N-K+I )+ END DO + J = MAX( LASTV, PREVLASTV )+*+* T(i+1:k,i) = -tau(i) * V(i+1:k,j:n-k+i) * V(i,j:n-k+i)**H+*+ CALL ZGEMM( 'N', 'C', K-I, 1, N-K+I-J, -TAU( I ),+ $ V( I+1, J ), LDV, V( I, J ), LDV,+ $ ONE, T( I+1, I ), LDT ) + END IF+*+* T(i+1:k,i) := T(i+1:k,i+1:k) * T(i+1:k,i)+*+ CALL ZTRMV( 'Lower', 'No transpose', 'Non-unit', K-I,+ $ T( I+1, I+1 ), LDT, T( I+1, I ), 1 )+ IF( I.GT.1 ) THEN+ PREVLASTV = MIN( PREVLASTV, LASTV )+ ELSE+ PREVLASTV = LASTV+ END IF+ END IF+ T( I, I ) = TAU( I )+ END IF+ END DO+ END IF+ RETURN+*+* End of ZLARFT+*+ END
+ eigen3/scripts/CMakeLists.txt view
@@ -0,0 +1,6 @@+get_property(EIGEN_TESTS_LIST GLOBAL PROPERTY EIGEN_TESTS_LIST)+configure_file(buildtests.in ${CMAKE_BINARY_DIR}/buildtests.sh @ONLY)++configure_file(check.in ${CMAKE_BINARY_DIR}/check.sh COPYONLY)+configure_file(debug.in ${CMAKE_BINARY_DIR}/debug.sh COPYONLY)+configure_file(release.in ${CMAKE_BINARY_DIR}/release.sh COPYONLY)
+ eigen3/scripts/buildtests.in view
@@ -0,0 +1,22 @@+#!/bin/bash++if [[ $# != 1 || $1 == *help ]]+then+ echo "usage: ./check regexp"+ echo " Builds tests matching the regexp."+ echo " The EIGEN_MAKE_ARGS environment variable allows to pass args to 'make'."+ echo " For example, to launch 5 concurrent builds, use EIGEN_MAKE_ARGS='-j5'"+ exit 0+fi++TESTSLIST="@EIGEN_TESTS_LIST@"+targets_to_make=`echo "$TESTSLIST" | egrep "$1" | xargs echo`++if [ -n "${EIGEN_MAKE_ARGS:+x}" ]+then+ make $targets_to_make ${EIGEN_MAKE_ARGS}+else+ make $targets_to_make+fi+exit $?+
+ eigen3/scripts/cdashtesting.cmake.in view
@@ -0,0 +1,49 @@++set(CTEST_SOURCE_DIRECTORY "@CMAKE_SOURCE_DIR@")+set(CTEST_BINARY_DIRECTORY "@CMAKE_BINARY_DIR@")+set(CTEST_CMAKE_GENERATOR "@CMAKE_GENERATOR@")+set(CTEST_BUILD_NAME "@BUILDNAME@")+set(CTEST_SITE "@SITE@")++set(MODEL Experimental)+if(${CTEST_SCRIPT_ARG} MATCHES Nightly)+ set(MODEL Nightly)+elseif(${CTEST_SCRIPT_ARG} MATCHES Continuous)+ set(MODEL Continuous)+endif()++find_program(CTEST_HG_COMMAND NAMES hg)+set(CTEST_UPDATE_COMMAND "${CTEST_HG_COMMAND}")++ctest_start(${MODEL} ${CTEST_SOURCE_DIRECTORY} ${CTEST_BINARY_DIRECTORY})++ctest_update(SOURCE "${CTEST_SOURCE_DIRECTORY}")+ctest_submit(PARTS Update Notes)++# to get CTEST_PROJECT_SUBPROJECTS definition:+include("${CTEST_SOURCE_DIRECTORY}/CTestConfig.cmake")++foreach(subproject ${CTEST_PROJECT_SUBPROJECTS})+ message("")+ message("Process ${subproject}")+ + set_property(GLOBAL PROPERTY SubProject ${subproject})+ set_property(GLOBAL PROPERTY Label ${subproject})++ ctest_configure(BUILD ${CTEST_BINARY_DIRECTORY} SOURCE ${CTEST_SOURCE_DIRECTORY} )+ ctest_submit(PARTS Configure)++ set(CTEST_BUILD_TARGET "Build${subproject}")+ message("Build ${CTEST_BUILD_TARGET}")+ ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}" APPEND)+ # builds target ${CTEST_BUILD_TARGET}+ ctest_submit(PARTS Build)++ ctest_test(BUILD "${CTEST_BINARY_DIRECTORY}" INCLUDE_LABEL "${subproject}" )+ # runs only tests that have a LABELS property matching "${subproject}"+ + ctest_coverage(BUILD "${CTEST_BINARY_DIRECTORY}" LABELS "${subproject}" )+ + ctest_submit(PARTS Test)+ +endforeach()
+ eigen3/scripts/check.in view
@@ -0,0 +1,21 @@+#!/bin/bash+# check : shorthand for make and ctest -R++if [[ $# != 1 || $1 == *help ]]+then+ echo "usage: ./check regexp"+ echo " Builds and runs tests matching the regexp."+ echo " The EIGEN_MAKE_ARGS environment variable allows to pass args to 'make'."+ echo " For example, to launch 5 concurrent builds, use EIGEN_MAKE_ARGS='-j5'"+ echo " The EIGEN_CTEST_ARGS environment variable allows to pass args to 'ctest'."+ echo " For example, with CTest 2.8, you can use EIGEN_CTEST_ARGS='-j5'."+ exit 0+fi++if [ -n "${EIGEN_CTEST_ARGS:+x}" ]+then+ ./buildtests.sh "$1" && ctest -R "$1" ${EIGEN_CTEST_ARGS}+else+ ./buildtests.sh "$1" && ctest -R "$1"+fi+exit $?
+ eigen3/scripts/debug.in view
@@ -0,0 +1,3 @@+#!/bin/sh++cmake -DCMAKE_BUILD_TYPE=Debug .
+ eigen3/scripts/eigen_gen_credits.cpp view
@@ -0,0 +1,232 @@+#include <string>+#include <sstream>+#include <iostream>+#include <fstream>+#include <iomanip>+#include <map>+#include <list>++using namespace std;++// this function takes a line that may contain a name and/or email address,+// and returns just the name, while fixing the "bad cases".+std::string contributor_name(const std::string& line)+{+ string result;++ // let's first take care of the case of isolated email addresses, like+ // "user@localhost.localdomain" entries+ if(line.find("markb@localhost.localdomain") != string::npos)+ {+ return "Mark Borgerding";+ }++ if(line.find("kayhman@contact.intra.cea.fr") != string::npos)+ {+ return "Guillaume Saupin";+ }++ // from there on we assume that we have a entry of the form+ // either:+ // Bla bli Blurp+ // or:+ // Bla bli Blurp <bblurp@email.com>+ + size_t position_of_email_address = line.find_first_of('<');+ if(position_of_email_address != string::npos)+ {+ // there is an e-mail address in <...>.+ + // Hauke once committed as "John Smith", fix that.+ if(line.find("hauke.heibel") != string::npos)+ result = "Hauke Heibel";+ else+ {+ // just remove the e-mail address+ result = line.substr(0, position_of_email_address);+ }+ }+ else+ {+ // there is no e-mail address in <...>.+ + if(line.find("convert-repo") != string::npos)+ result = "";+ else+ result = line;+ }++ // remove trailing spaces+ size_t length = result.length();+ while(length >= 1 && result[length-1] == ' ') result.erase(--length);++ return result;+}++// parses hg churn output to generate a contributors map.+map<string,int> contributors_map_from_churn_output(const char *filename)+{+ map<string,int> contributors_map;++ string line;+ ifstream churn_out;+ churn_out.open(filename, ios::in);+ while(!getline(churn_out,line).eof())+ {+ // remove the histograms "******" that hg churn may draw at the end of some lines+ size_t first_star = line.find_first_of('*');+ if(first_star != string::npos) line.erase(first_star);+ + // remove trailing spaces+ size_t length = line.length();+ while(length >= 1 && line[length-1] == ' ') line.erase(--length);++ // now the last space indicates where the number starts+ size_t last_space = line.find_last_of(' ');+ + // get the number (of changesets or of modified lines for each contributor)+ int number;+ istringstream(line.substr(last_space+1)) >> number;++ // get the name of the contributor+ line.erase(last_space); + string name = contributor_name(line);+ + map<string,int>::iterator it = contributors_map.find(name);+ // if new contributor, insert+ if(it == contributors_map.end())+ contributors_map.insert(pair<string,int>(name, number));+ // if duplicate, just add the number+ else+ it->second += number;+ }+ churn_out.close();++ return contributors_map;+}++// find the last name, i.e. the last word.+// for "van den Schbling" types of last names, that's not a problem, that's actually what we want.+string lastname(const string& name)+{+ size_t last_space = name.find_last_of(' ');+ if(last_space >= name.length()-1) return name;+ else return name.substr(last_space+1);+}++struct contributor+{+ string name;+ int changedlines;+ int changesets;+ string url;+ string misc;+ + contributor() : changedlines(0), changesets(0) {}+ + bool operator < (const contributor& other)+ {+ return lastname(name).compare(lastname(other.name)) < 0;+ }+};++void add_online_info_into_contributors_list(list<contributor>& contributors_list, const char *filename)+{+ string line;+ ifstream online_info;+ online_info.open(filename, ios::in);+ while(!getline(online_info,line).eof())+ {+ string hgname, realname, url, misc;+ + size_t last_bar = line.find_last_of('|');+ if(last_bar == string::npos) continue;+ if(last_bar < line.length())+ misc = line.substr(last_bar+1);+ line.erase(last_bar);+ + last_bar = line.find_last_of('|');+ if(last_bar == string::npos) continue;+ if(last_bar < line.length())+ url = line.substr(last_bar+1);+ line.erase(last_bar);++ last_bar = line.find_last_of('|');+ if(last_bar == string::npos) continue;+ if(last_bar < line.length())+ realname = line.substr(last_bar+1);+ line.erase(last_bar);++ hgname = line;+ + // remove the example line+ if(hgname.find("MercurialName") != string::npos) continue;+ + list<contributor>::iterator it;+ for(it=contributors_list.begin(); it != contributors_list.end() && it->name != hgname; ++it)+ {}+ + if(it == contributors_list.end())+ {+ contributor c;+ c.name = realname;+ c.url = url;+ c.misc = misc;+ contributors_list.push_back(c);+ }+ else+ {+ it->name = realname;+ it->url = url;+ it->misc = misc;+ }+ }+}++int main()+{+ // parse the hg churn output files+ map<string,int> contributors_map_for_changedlines = contributors_map_from_churn_output("churn-changedlines.out");+ //map<string,int> contributors_map_for_changesets = contributors_map_from_churn_output("churn-changesets.out");+ + // merge into the contributors list+ list<contributor> contributors_list;+ map<string,int>::iterator it;+ for(it=contributors_map_for_changedlines.begin(); it != contributors_map_for_changedlines.end(); ++it)+ {+ contributor c;+ c.name = it->first;+ c.changedlines = it->second;+ c.changesets = 0; //contributors_map_for_changesets.find(it->first)->second;+ contributors_list.push_back(c);+ }+ + add_online_info_into_contributors_list(contributors_list, "online-info.out");+ + contributors_list.sort();+ + cout << "{| cellpadding=\"5\"\n";+ cout << "!\n";+ cout << "! Lines changed\n";+ cout << "!\n";++ list<contributor>::iterator itc;+ int i = 0;+ for(itc=contributors_list.begin(); itc != contributors_list.end(); ++itc)+ {+ if(itc->name.length() == 0) continue;+ if(i%2) cout << "|-\n";+ else cout << "|- style=\"background:#FFFFD0\"\n";+ if(itc->url.length())+ cout << "| [" << itc->url << " " << itc->name << "]\n";+ else+ cout << "| " << itc->name << "\n";+ if(itc->changedlines)+ cout << "| " << itc->changedlines << "\n";+ else+ cout << "| (no information)\n";+ cout << "| " << itc->misc << "\n";+ i++;+ }+ cout << "|}" << endl;+}
+ eigen3/scripts/eigen_gen_docs view
@@ -0,0 +1,24 @@+#!/bin/sh++# configuration+# You should call this script with USER set as you want, else some default+# will be used+USER=${USER:-'orzel'}+UPLOAD_DIR=dox++#ulimit -v 1024000++# step 1 : build+rm build/doc/html -Rf+mkdir build -p+(cd build && cmake .. && make doc) || { echo "make failed"; exit 1; }++#step 2 : upload+# (the '/' at the end of path is very important, see rsync documentation)+rsync -az --no-p --delete build/doc/html/ $USER@ssh.tuxfamily.org:eigen/eigen.tuxfamily.org-web/htdocs/$UPLOAD_DIR/ || { echo "upload failed"; exit 1; }++#step 3 : fix the perm+ssh $USER@ssh.tuxfamily.org "chmod -R g+w /home/eigen/eigen.tuxfamily.org-web/htdocs/$UPLOAD_DIR" || { echo "perm failed"; exit 1; }++echo "Uploaded successfully"+
+ eigen3/scripts/release.in view
@@ -0,0 +1,3 @@+#!/bin/sh++cmake -DCMAKE_BUILD_TYPE=Release .
+ eigen3/scripts/relicense.py view
@@ -0,0 +1,69 @@+# This file is part of Eigen, a lightweight C++ template library+# for linear algebra.+#+# Copyright (C) 2012 Keir Mierle <mierle@gmail.com>+#+# This Source Code Form is subject to the terms of the Mozilla+# Public License v. 2.0. If a copy of the MPL was not distributed+# with this file, You can obtain one at http://mozilla.org/MPL/2.0/.+#+# Author: mierle@gmail.com (Keir Mierle)+#+# Make the long-awaited conversion to MPL.++lgpl3_header = '''+// Eigen is free software; you can redistribute it and/or+// modify it under the terms of the GNU Lesser General Public+// License as published by the Free Software Foundation; either+// version 3 of the License, or (at your option) any later version.+//+// Alternatively, you can redistribute it and/or+// modify it under the terms of the GNU General Public License as+// published by the Free Software Foundation; either version 2 of+// the License, or (at your option) any later version.+//+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the+// GNU General Public License for more details.+//+// You should have received a copy of the GNU Lesser General Public+// License and a copy of the GNU General Public License along with+// Eigen. If not, see <http://www.gnu.org/licenses/>.+'''++mpl2_header = """+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.+"""++import os+import sys++exclusions = set(['relicense.py'])++def update(text):+ if text.find(lgpl3_header) == -1:+ return text, False+ return text.replace(lgpl3_header, mpl2_header), True++rootdir = sys.argv[1]+for root, sub_folders, files in os.walk(rootdir):+ for basename in files:+ if basename in exclusions:+ print 'SKIPPED', filename+ continue+ filename = os.path.join(root, basename)+ fo = file(filename)+ text = fo.read()+ fo.close()++ text, updated = update(text)+ if updated:+ fo = file(filename, "w")+ fo.write(text)+ fo.close()+ print 'UPDATED', filename+ else:+ print ' ', filename
+ eigen3/signature_of_eigen3_matrix_library view
@@ -0,0 +1,1 @@+This file is just there as a signature to help identify directories containing Eigen3. When writing a script looking for Eigen3, just look for this file. This is especially useful to help disambiguate with Eigen2...
+ eigen3/test/CMakeLists.txt view
@@ -0,0 +1,291 @@++# generate split test header file+message(STATUS ${CMAKE_CURRENT_BINARY_DIR})+file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/split_test_helper.h "")+foreach(i RANGE 1 999)+ file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/split_test_helper.h+ "#ifdef EIGEN_TEST_PART_${i}\n"+ "#define CALL_SUBTEST_${i}(FUNC) CALL_SUBTEST(FUNC)\n"+ "#else\n"+ "#define CALL_SUBTEST_${i}(FUNC)\n"+ "#endif\n\n"+ )+endforeach()++# configure blas/lapack (use Eigen's ones)+set(BLAS_FOUND TRUE)+set(LAPACK_FOUND TRUE)+set(BLAS_LIBRARIES eigen_blas)+set(LAPACK_LIBRARIES eigen_lapack)++set(EIGEN_TEST_MATRIX_DIR "" CACHE STRING "Enable testing of realword sparse matrices contained in the specified path")+if(EIGEN_TEST_MATRIX_DIR)+ if(NOT WIN32)+ message(STATUS "Test realworld sparse matrices: ${EIGEN_TEST_MATRIX_DIR}")+ add_definitions( -DTEST_REAL_CASES="${EIGEN_TEST_MATRIX_DIR}" )+ else(NOT WIN32)+ message(STATUS "REAL CASES CAN NOT BE CURRENTLY TESTED ON WIN32")+ endif(NOT WIN32)+endif(EIGEN_TEST_MATRIX_DIR)++set(SPARSE_LIBS " ")++find_package(Cholmod)+if(CHOLMOD_FOUND AND BLAS_FOUND AND LAPACK_FOUND)+ add_definitions("-DEIGEN_CHOLMOD_SUPPORT")+ include_directories(${CHOLMOD_INCLUDES})+ set(SPARSE_LIBS ${SPARSE_LIBS} ${CHOLMOD_LIBRARIES} ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})+ set(CHOLMOD_ALL_LIBS ${CHOLMOD_LIBRARIES} ${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})+ ei_add_property(EIGEN_TESTED_BACKENDS "Cholmod, ")+else()+ ei_add_property(EIGEN_MISSING_BACKENDS "Cholmod, ")+endif()++find_package(Umfpack)+if(UMFPACK_FOUND AND BLAS_FOUND)+ add_definitions("-DEIGEN_UMFPACK_SUPPORT")+ include_directories(${UMFPACK_INCLUDES})+ set(SPARSE_LIBS ${SPARSE_LIBS} ${UMFPACK_LIBRARIES} ${BLAS_LIBRARIES})+ set(UMFPACK_ALL_LIBS ${UMFPACK_LIBRARIES} ${BLAS_LIBRARIES})+ ei_add_property(EIGEN_TESTED_BACKENDS "UmfPack, ")+else()+ ei_add_property(EIGEN_MISSING_BACKENDS "UmfPack, ")+endif()++find_package(SuperLU)+if(SUPERLU_FOUND AND BLAS_FOUND)+ add_definitions("-DEIGEN_SUPERLU_SUPPORT")+ include_directories(${SUPERLU_INCLUDES})+ set(SPARSE_LIBS ${SPARSE_LIBS} ${SUPERLU_LIBRARIES} ${BLAS_LIBRARIES})+ set(SUPERLU_ALL_LIBS ${SUPERLU_LIBRARIES} ${BLAS_LIBRARIES})+ ei_add_property(EIGEN_TESTED_BACKENDS "SuperLU, ")+else()+ ei_add_property(EIGEN_MISSING_BACKENDS "SuperLU, ")+endif()+++find_package(Pastix)+find_package(Scotch)+find_package(Metis 5.0 REQUIRED)+if(PASTIX_FOUND AND BLAS_FOUND)+ add_definitions("-DEIGEN_PASTIX_SUPPORT")+ include_directories(${PASTIX_INCLUDES})+ if(SCOTCH_FOUND)+ include_directories(${SCOTCH_INCLUDES})+ set(PASTIX_LIBRARIES ${PASTIX_LIBRARIES} ${SCOTCH_LIBRARIES})+ elseif(METIS_FOUND)+ include_directories(${METIS_INCLUDES})+ set(PASTIX_LIBRARIES ${PASTIX_LIBRARIES} ${METIS_LIBRARIES})+ else(SCOTCH_FOUND)+ ei_add_property(EIGEN_MISSING_BACKENDS "PaStiX, ")+ endif(SCOTCH_FOUND)+ set(SPARSE_LIBS ${SPARSE_LIBS} ${PASTIX_LIBRARIES} ${ORDERING_LIBRARIES} ${BLAS_LIBRARIES})+ set(PASTIX_ALL_LIBS ${PASTIX_LIBRARIES} ${BLAS_LIBRARIES})+ ei_add_property(EIGEN_TESTED_BACKENDS "PaStiX, ")+else()+ ei_add_property(EIGEN_MISSING_BACKENDS "PaStiX, ")+endif()++if(METIS_FOUND)+ add_definitions("-DEIGEN_METIS_SUPPORT")+ include_directories(${METIS_INCLUDES})+ ei_add_property(EIGEN_TESTED_BACKENDS "METIS, ")+else()+ ei_add_property(EIGEN_MISSING_BACKENDS "METIS, ")+endif()++find_package(SPQR)+if(SPQR_FOUND AND BLAS_FOUND AND LAPACK_FOUND)+ if(CHOLMOD_FOUND)+ add_definitions("-DEIGEN_SPQR_SUPPORT")+ include_directories(${SPQR_INCLUDES})+ set(SPQR_ALL_LIBS ${SPQR_LIBRARIES} ${CHOLMOD_LIBRARIES} ${LAPACK_LIBRARIES} ${BLAS_LIBRARIES})+ set(SPARSE_LIBS ${SPARSE_LIBS} ${SPQR_ALL_LIBS})+ ei_add_property(EIGEN_TESTED_BACKENDS "SPQR, ")+ else(CHOLMOD_FOUND)+ ei_add_property(EIGEN_MISSING_BACKENDS "SPQR, ")+ endif(CHOLMOD_FOUND)+endif()++option(EIGEN_TEST_NOQT "Disable Qt support in unit tests" OFF)+if(NOT EIGEN_TEST_NOQT)+ find_package(Qt4)+ if(QT4_FOUND)+ include(${QT_USE_FILE})+ ei_add_property(EIGEN_TESTED_BACKENDS "Qt4 support, ")+ else()+ ei_add_property(EIGEN_MISSING_BACKENDS "Qt4 support, ")+ endif()+endif(NOT EIGEN_TEST_NOQT)++if(TEST_LIB)+ add_definitions("-DEIGEN_EXTERN_INSTANTIATIONS=1")+endif(TEST_LIB)++set_property(GLOBAL PROPERTY EIGEN_CURRENT_SUBPROJECT "Official")+add_custom_target(BuildOfficial)++ei_add_test(meta)+ei_add_test(sizeof)+ei_add_test(dynalloc)+ei_add_test(nomalloc)+ei_add_test(first_aligned)+ei_add_test(mixingtypes)+ei_add_test(packetmath)+ei_add_test(unalignedassert)+ei_add_test(vectorization_logic)+ei_add_test(basicstuff)+ei_add_test(linearstructure)+ei_add_test(integer_types)+ei_add_test(cwiseop)+ei_add_test(unalignedcount)+ei_add_test(exceptions)+ei_add_test(redux)+ei_add_test(visitor)+ei_add_test(block)+ei_add_test(corners)+ei_add_test(product_small)+ei_add_test(product_large)+ei_add_test(product_extra)+ei_add_test(diagonalmatrices)+ei_add_test(adjoint)+ei_add_test(diagonal)+ei_add_test(miscmatrices)+ei_add_test(commainitializer)+ei_add_test(smallvectors)+ei_add_test(mapped_matrix)+ei_add_test(mapstride)+ei_add_test(mapstaticmethods)+ei_add_test(array)+ei_add_test(array_for_matrix)+ei_add_test(array_replicate)+ei_add_test(array_reverse)+ei_add_test(ref)+ei_add_test(triangular)+ei_add_test(selfadjoint)+ei_add_test(product_selfadjoint)+ei_add_test(product_symm)+ei_add_test(product_syrk)+ei_add_test(product_trmv)+ei_add_test(product_trmm)+ei_add_test(product_trsolve)+ei_add_test(product_mmtr)+ei_add_test(product_notemporary)+ei_add_test(stable_norm)+ei_add_test(bandmatrix)+ei_add_test(cholesky)+ei_add_test(lu)+ei_add_test(determinant)+ei_add_test(inverse)+ei_add_test(qr)+ei_add_test(qr_colpivoting)+ei_add_test(qr_fullpivoting)+ei_add_test(upperbidiagonalization)+ei_add_test(hessenberg)+ei_add_test(schur_real)+ei_add_test(schur_complex)+ei_add_test(eigensolver_selfadjoint)+ei_add_test(eigensolver_generic)+ei_add_test(eigensolver_complex)+ei_add_test(real_qz)+ei_add_test(eigensolver_generalized_real)+ei_add_test(jacobi)+ei_add_test(jacobisvd)+ei_add_test(geo_orthomethods)+ei_add_test(geo_homogeneous)+ei_add_test(geo_quaternion)+ei_add_test(geo_transformations)+ei_add_test(geo_eulerangles)+ei_add_test(geo_hyperplane)+ei_add_test(geo_parametrizedline)+ei_add_test(geo_alignedbox)+ei_add_test(stdvector)+ei_add_test(stdvector_overload)+ei_add_test(stdlist)+ei_add_test(stddeque)+ei_add_test(resize)+ei_add_test(sparse_vector)+ei_add_test(sparse_basic)+ei_add_test(sparse_product)+ei_add_test(sparse_solvers)+ei_add_test(umeyama)+ei_add_test(householder)+ei_add_test(swap)+ei_add_test(conservative_resize)+ei_add_test(permutationmatrices)+ei_add_test(sparse_permutations)+ei_add_test(nullary)+ei_add_test(nesting_ops "${CMAKE_CXX_FLAGS_DEBUG}")+ei_add_test(zerosized)+ei_add_test(dontalign)+ei_add_test(sizeoverflow)+ei_add_test(prec_inverse_4x4)+ei_add_test(vectorwiseop)+ei_add_test(special_numbers)++ei_add_test(simplicial_cholesky)+ei_add_test(conjugate_gradient)+ei_add_test(bicgstab)+ei_add_test(sparselu)+ei_add_test(sparseqr)++# ei_add_test(denseLM)++if(QT4_FOUND)+ ei_add_test(qtvector "" "${QT_QTCORE_LIBRARY}")+endif(QT4_FOUND)++ei_add_test(eigen2support)++if(UMFPACK_FOUND)+ ei_add_test(umfpack_support "" "${UMFPACK_ALL_LIBS}")+endif()++if(SUPERLU_FOUND)+ ei_add_test(superlu_support "" "${SUPERLU_ALL_LIBS}")+endif()++if(CHOLMOD_FOUND)+ ei_add_test(cholmod_support "" "${CHOLMOD_ALL_LIBS}")+endif()++if(PARDISO_FOUND)+ ei_add_test(pardiso_support "" "${PARDISO_ALL_LIBS}")+endif()++if(PASTIX_FOUND AND (SCOTCH_FOUND OR METIS_FOUND))+ ei_add_test(pastix_support "" "${PASTIX_ALL_LIBS}")+endif()++if(SPQR_FOUND AND CHOLMOD_FOUND)+ ei_add_test(spqr_support "" "${SPQR_ALL_LIBS}")+endif()++if(METIS_FOUND)+ei_add_test(metis_support "" "${METIS_LIBRARIES}")+endif()++string(TOLOWER "${CMAKE_CXX_COMPILER}" cmake_cxx_compiler_tolower)+if(cmake_cxx_compiler_tolower MATCHES "qcc")+ set(CXX_IS_QCC "ON")+endif()++ei_add_property(EIGEN_TESTING_SUMMARY "CXX: ${CMAKE_CXX_COMPILER}\n")+if(CMAKE_COMPILER_IS_GNUCXX AND NOT CXX_IS_QCC)+ execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version COMMAND head -n 1 OUTPUT_VARIABLE EIGEN_CXX_VERSION_STRING OUTPUT_STRIP_TRAILING_WHITESPACE)+ ei_add_property(EIGEN_TESTING_SUMMARY "CXX_VERSION: ${EIGEN_CXX_VERSION_STRING}\n")+endif()+ei_add_property(EIGEN_TESTING_SUMMARY "CXX_FLAGS: ${CMAKE_CXX_FLAGS}\n")+ei_add_property(EIGEN_TESTING_SUMMARY "Sparse lib flags: ${SPARSE_LIBS}\n")++option(EIGEN_TEST_EIGEN2 "Run whole Eigen2 test suite against EIGEN2_SUPPORT" OFF)+mark_as_advanced(EIGEN_TEST_EIGEN2)+if(EIGEN_TEST_EIGEN2)+ add_subdirectory(eigen2)+endif()+++option(EIGEN_TEST_BUILD_DOCUMENTATION "Test building the doxygen documentation" OFF)+IF(EIGEN_TEST_BUILD_DOCUMENTATION)+ add_dependencies(buildtests doc)+ENDIF()
+ eigen3/test/adjoint.cpp view
@@ -0,0 +1,160 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN_NO_STATIC_ASSERT++#include "main.h"++template<bool IsInteger> struct adjoint_specific;++template<> struct adjoint_specific<true> {+ template<typename Vec, typename Mat, typename Scalar>+ static void run(const Vec& v1, const Vec& v2, Vec& v3, const Mat& square, Scalar s1, Scalar s2) {+ VERIFY(test_isApproxWithRef((s1 * v1 + s2 * v2).dot(v3), numext::conj(s1) * v1.dot(v3) + numext::conj(s2) * v2.dot(v3), 0));+ VERIFY(test_isApproxWithRef(v3.dot(s1 * v1 + s2 * v2), s1*v3.dot(v1)+s2*v3.dot(v2), 0));+ + // check compatibility of dot and adjoint+ VERIFY(test_isApproxWithRef(v1.dot(square * v2), (square.adjoint() * v1).dot(v2), 0));+ }+};++template<> struct adjoint_specific<false> {+ template<typename Vec, typename Mat, typename Scalar>+ static void run(const Vec& v1, const Vec& v2, Vec& v3, const Mat& square, Scalar s1, Scalar s2) {+ typedef typename NumTraits<Scalar>::Real RealScalar;+ using std::abs;+ + RealScalar ref = NumTraits<Scalar>::IsInteger ? RealScalar(0) : (std::max)((s1 * v1 + s2 * v2).norm(),v3.norm());+ VERIFY(test_isApproxWithRef((s1 * v1 + s2 * v2).dot(v3), numext::conj(s1) * v1.dot(v3) + numext::conj(s2) * v2.dot(v3), ref));+ VERIFY(test_isApproxWithRef(v3.dot(s1 * v1 + s2 * v2), s1*v3.dot(v1)+s2*v3.dot(v2), ref));+ + VERIFY_IS_APPROX(v1.squaredNorm(), v1.norm() * v1.norm());+ // check normalized() and normalize()+ VERIFY_IS_APPROX(v1, v1.norm() * v1.normalized());+ v3 = v1;+ v3.normalize();+ VERIFY_IS_APPROX(v1, v1.norm() * v3);+ VERIFY_IS_APPROX(v3, v1.normalized());+ VERIFY_IS_APPROX(v3.norm(), RealScalar(1));+ + // check compatibility of dot and adjoint+ ref = NumTraits<Scalar>::IsInteger ? 0 : (std::max)((std::max)(v1.norm(),v2.norm()),(std::max)((square * v2).norm(),(square.adjoint() * v1).norm()));+ VERIFY(internal::isMuchSmallerThan(abs(v1.dot(square * v2) - (square.adjoint() * v1).dot(v2)), ref, test_precision<Scalar>()));+ + // check that Random().normalized() works: tricky as the random xpr must be evaluated by+ // normalized() in order to produce a consistent result.+ VERIFY_IS_APPROX(Vec::Random(v1.size()).normalized().norm(), RealScalar(1));+ }+};++template<typename MatrixType> void adjoint(const MatrixType& m)+{+ /* this test covers the following files:+ Transpose.h Conjugate.h Dot.h+ */+ using std::abs;+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;+ + Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols),+ square = SquareMatrixType::Random(rows, rows);+ VectorType v1 = VectorType::Random(rows),+ v2 = VectorType::Random(rows),+ v3 = VectorType::Random(rows),+ vzero = VectorType::Zero(rows);++ Scalar s1 = internal::random<Scalar>(),+ s2 = internal::random<Scalar>();++ // check basic compatibility of adjoint, transpose, conjugate+ VERIFY_IS_APPROX(m1.transpose().conjugate().adjoint(), m1);+ VERIFY_IS_APPROX(m1.adjoint().conjugate().transpose(), m1);++ // check multiplicative behavior+ VERIFY_IS_APPROX((m1.adjoint() * m2).adjoint(), m2.adjoint() * m1);+ VERIFY_IS_APPROX((s1 * m1).adjoint(), numext::conj(s1) * m1.adjoint());++ // check basic properties of dot, squaredNorm+ VERIFY_IS_APPROX(numext::conj(v1.dot(v2)), v2.dot(v1));+ VERIFY_IS_APPROX(numext::real(v1.dot(v1)), v1.squaredNorm());+ + adjoint_specific<NumTraits<Scalar>::IsInteger>::run(v1, v2, v3, square, s1, s2);+ + VERIFY_IS_MUCH_SMALLER_THAN(abs(vzero.dot(v1)), static_cast<RealScalar>(1));+ + // like in testBasicStuff, test operator() to check const-qualification+ Index r = internal::random<Index>(0, rows-1),+ c = internal::random<Index>(0, cols-1);+ VERIFY_IS_APPROX(m1.conjugate()(r,c), numext::conj(m1(r,c)));+ VERIFY_IS_APPROX(m1.adjoint()(c,r), numext::conj(m1(r,c)));++ // check inplace transpose+ m3 = m1;+ m3.transposeInPlace();+ VERIFY_IS_APPROX(m3,m1.transpose());+ m3.transposeInPlace();+ VERIFY_IS_APPROX(m3,m1);++ // check inplace adjoint+ m3 = m1;+ m3.adjointInPlace();+ VERIFY_IS_APPROX(m3,m1.adjoint());+ m3.transposeInPlace();+ VERIFY_IS_APPROX(m3,m1.conjugate());++ // check mixed dot product+ typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, 1> RealVectorType;+ RealVectorType rv1 = RealVectorType::Random(rows);+ VERIFY_IS_APPROX(v1.dot(rv1.template cast<Scalar>()), v1.dot(rv1));+ VERIFY_IS_APPROX(rv1.template cast<Scalar>().dot(v1), rv1.dot(v1));+}++void test_adjoint()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( adjoint(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( adjoint(Matrix3d()) );+ CALL_SUBTEST_3( adjoint(Matrix4f()) );+ CALL_SUBTEST_4( adjoint(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );+ CALL_SUBTEST_5( adjoint(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_6( adjoint(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ }+ // test a large static matrix only once+ CALL_SUBTEST_7( adjoint(Matrix<float, 100, 100>()) );++#ifdef EIGEN_TEST_PART_4+ {+ MatrixXcf a(10,10), b(10,10);+ VERIFY_RAISES_ASSERT(a = a.transpose());+ VERIFY_RAISES_ASSERT(a = a.transpose() + b);+ VERIFY_RAISES_ASSERT(a = b + a.transpose());+ VERIFY_RAISES_ASSERT(a = a.conjugate().transpose());+ VERIFY_RAISES_ASSERT(a = a.adjoint());+ VERIFY_RAISES_ASSERT(a = a.adjoint() + b);+ VERIFY_RAISES_ASSERT(a = b + a.adjoint());++ // no assertion should be triggered for these cases:+ a.transpose() = a.transpose();+ a.transpose() += a.transpose();+ a.transpose() += a.transpose() + b;+ a.transpose() = a.adjoint();+ a.transpose() += a.adjoint();+ a.transpose() += a.adjoint() + b;+ }+#endif+}+
+ eigen3/test/array.cpp view
@@ -0,0 +1,308 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename ArrayType> void array(const ArrayType& m)+{+ typedef typename ArrayType::Index Index;+ typedef typename ArrayType::Scalar Scalar;+ typedef Array<Scalar, ArrayType::RowsAtCompileTime, 1> ColVectorType;+ typedef Array<Scalar, 1, ArrayType::ColsAtCompileTime> RowVectorType;++ Index rows = m.rows();+ Index cols = m.cols(); ++ ArrayType m1 = ArrayType::Random(rows, cols),+ m2 = ArrayType::Random(rows, cols),+ m3(rows, cols);++ ColVectorType cv1 = ColVectorType::Random(rows);+ RowVectorType rv1 = RowVectorType::Random(cols);++ Scalar s1 = internal::random<Scalar>(),+ s2 = internal::random<Scalar>();++ // scalar addition+ VERIFY_IS_APPROX(m1 + s1, s1 + m1);+ VERIFY_IS_APPROX(m1 + s1, ArrayType::Constant(rows,cols,s1) + m1);+ VERIFY_IS_APPROX(s1 - m1, (-m1)+s1 );+ VERIFY_IS_APPROX(m1 - s1, m1 - ArrayType::Constant(rows,cols,s1));+ VERIFY_IS_APPROX(s1 - m1, ArrayType::Constant(rows,cols,s1) - m1);+ VERIFY_IS_APPROX((m1*Scalar(2)) - s2, (m1+m1) - ArrayType::Constant(rows,cols,s2) );+ m3 = m1;+ m3 += s2;+ VERIFY_IS_APPROX(m3, m1 + s2);+ m3 = m1;+ m3 -= s1;+ VERIFY_IS_APPROX(m3, m1 - s1); + + // scalar operators via Maps+ m3 = m1;+ ArrayType::Map(m1.data(), m1.rows(), m1.cols()) -= ArrayType::Map(m2.data(), m2.rows(), m2.cols());+ VERIFY_IS_APPROX(m1, m3 - m2);+ + m3 = m1;+ ArrayType::Map(m1.data(), m1.rows(), m1.cols()) += ArrayType::Map(m2.data(), m2.rows(), m2.cols());+ VERIFY_IS_APPROX(m1, m3 + m2);+ + m3 = m1;+ ArrayType::Map(m1.data(), m1.rows(), m1.cols()) *= ArrayType::Map(m2.data(), m2.rows(), m2.cols());+ VERIFY_IS_APPROX(m1, m3 * m2);+ + m3 = m1;+ m2 = ArrayType::Random(rows,cols);+ m2 = (m2==0).select(1,m2);+ ArrayType::Map(m1.data(), m1.rows(), m1.cols()) /= ArrayType::Map(m2.data(), m2.rows(), m2.cols()); + VERIFY_IS_APPROX(m1, m3 / m2);++ // reductions+ VERIFY_IS_APPROX(m1.abs().colwise().sum().sum(), m1.abs().sum());+ VERIFY_IS_APPROX(m1.abs().rowwise().sum().sum(), m1.abs().sum());+ using std::abs;+ VERIFY_IS_MUCH_SMALLER_THAN(abs(m1.colwise().sum().sum() - m1.sum()), m1.abs().sum());+ VERIFY_IS_MUCH_SMALLER_THAN(abs(m1.rowwise().sum().sum() - m1.sum()), m1.abs().sum());+ if (!internal::isMuchSmallerThan(abs(m1.sum() - (m1+m2).sum()), m1.abs().sum(), test_precision<Scalar>()))+ VERIFY_IS_NOT_APPROX(((m1+m2).rowwise().sum()).sum(), m1.sum());+ VERIFY_IS_APPROX(m1.colwise().sum(), m1.colwise().redux(internal::scalar_sum_op<Scalar>()));++ // vector-wise ops+ m3 = m1;+ VERIFY_IS_APPROX(m3.colwise() += cv1, m1.colwise() + cv1);+ m3 = m1;+ VERIFY_IS_APPROX(m3.colwise() -= cv1, m1.colwise() - cv1);+ m3 = m1;+ VERIFY_IS_APPROX(m3.rowwise() += rv1, m1.rowwise() + rv1);+ m3 = m1;+ VERIFY_IS_APPROX(m3.rowwise() -= rv1, m1.rowwise() - rv1);+}++template<typename ArrayType> void comparisons(const ArrayType& m)+{+ using std::abs;+ typedef typename ArrayType::Index Index;+ typedef typename ArrayType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;++ Index rows = m.rows();+ Index cols = m.cols();++ Index r = internal::random<Index>(0, rows-1),+ c = internal::random<Index>(0, cols-1);++ ArrayType m1 = ArrayType::Random(rows, cols),+ m2 = ArrayType::Random(rows, cols),+ m3(rows, cols); ++ VERIFY(((m1 + Scalar(1)) > m1).all());+ VERIFY(((m1 - Scalar(1)) < m1).all());+ if (rows*cols>1)+ {+ m3 = m1;+ m3(r,c) += 1;+ VERIFY(! (m1 < m3).all() );+ VERIFY(! (m1 > m3).all() );+ }+ VERIFY(!(m1 > m2 && m1 < m2).any());+ VERIFY((m1 <= m2 || m1 >= m2).all());++ // comparisons to scalar+ VERIFY( (m1 != (m1(r,c)+1) ).any() );+ VERIFY( (m1 > (m1(r,c)-1) ).any() );+ VERIFY( (m1 < (m1(r,c)+1) ).any() );+ VERIFY( (m1 == m1(r,c) ).any() );++ // test Select+ VERIFY_IS_APPROX( (m1<m2).select(m1,m2), m1.cwiseMin(m2) );+ VERIFY_IS_APPROX( (m1>m2).select(m1,m2), m1.cwiseMax(m2) );+ Scalar mid = (m1.cwiseAbs().minCoeff() + m1.cwiseAbs().maxCoeff())/Scalar(2);+ for (int j=0; j<cols; ++j)+ for (int i=0; i<rows; ++i)+ m3(i,j) = abs(m1(i,j))<mid ? 0 : m1(i,j);+ VERIFY_IS_APPROX( (m1.abs()<ArrayType::Constant(rows,cols,mid))+ .select(ArrayType::Zero(rows,cols),m1), m3);+ // shorter versions:+ VERIFY_IS_APPROX( (m1.abs()<ArrayType::Constant(rows,cols,mid))+ .select(0,m1), m3);+ VERIFY_IS_APPROX( (m1.abs()>=ArrayType::Constant(rows,cols,mid))+ .select(m1,0), m3);+ // even shorter version:+ VERIFY_IS_APPROX( (m1.abs()<mid).select(0,m1), m3);++ // count+ VERIFY(((m1.abs()+1)>RealScalar(0.1)).count() == rows*cols);++ // and/or+ VERIFY( (m1<RealScalar(0) && m1>RealScalar(0)).count() == 0);+ VERIFY( (m1<RealScalar(0) || m1>=RealScalar(0)).count() == rows*cols);+ RealScalar a = m1.abs().mean();+ VERIFY( (m1<-a || m1>a).count() == (m1.abs()>a).count());++ typedef Array<typename ArrayType::Index, Dynamic, 1> ArrayOfIndices;++ // TODO allows colwise/rowwise for array+ VERIFY_IS_APPROX(((m1.abs()+1)>RealScalar(0.1)).colwise().count(), ArrayOfIndices::Constant(cols,rows).transpose());+ VERIFY_IS_APPROX(((m1.abs()+1)>RealScalar(0.1)).rowwise().count(), ArrayOfIndices::Constant(rows, cols));+}++template<typename ArrayType> void array_real(const ArrayType& m)+{+ using std::abs;+ using std::sqrt;+ typedef typename ArrayType::Index Index;+ typedef typename ArrayType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;++ Index rows = m.rows();+ Index cols = m.cols();++ ArrayType m1 = ArrayType::Random(rows, cols),+ m2 = ArrayType::Random(rows, cols),+ m3(rows, cols);++ Scalar s1 = internal::random<Scalar>();++ // these tests are mostly to check possible compilation issues.+ VERIFY_IS_APPROX(m1.sin(), sin(m1));+ VERIFY_IS_APPROX(m1.cos(), cos(m1));+ VERIFY_IS_APPROX(m1.asin(), asin(m1));+ VERIFY_IS_APPROX(m1.acos(), acos(m1));+ VERIFY_IS_APPROX(m1.tan(), tan(m1));+ + VERIFY_IS_APPROX(cos(m1+RealScalar(3)*m2), cos((m1+RealScalar(3)*m2).eval()));++ VERIFY_IS_APPROX(m1.abs().sqrt(), sqrt(abs(m1)));+ VERIFY_IS_APPROX(m1.abs(), sqrt(numext::abs2(m1)));++ VERIFY_IS_APPROX(numext::abs2(numext::real(m1)) + numext::abs2(numext::imag(m1)), numext::abs2(m1));+ VERIFY_IS_APPROX(numext::abs2(real(m1)) + numext::abs2(imag(m1)), numext::abs2(m1));+ if(!NumTraits<Scalar>::IsComplex)+ VERIFY_IS_APPROX(numext::real(m1), m1);++ // shift argument of logarithm so that it is not zero+ Scalar smallNumber = NumTraits<Scalar>::dummy_precision();+ VERIFY_IS_APPROX((m1.abs() + smallNumber).log() , log(abs(m1) + smallNumber));++ VERIFY_IS_APPROX(m1.exp() * m2.exp(), exp(m1+m2));+ VERIFY_IS_APPROX(m1.exp(), exp(m1));+ VERIFY_IS_APPROX(m1.exp() / m2.exp(),(m1-m2).exp());++ VERIFY_IS_APPROX(m1.pow(2), m1.square());+ VERIFY_IS_APPROX(pow(m1,2), m1.square());++ ArrayType exponents = ArrayType::Constant(rows, cols, RealScalar(2));+ VERIFY_IS_APPROX(Eigen::pow(m1,exponents), m1.square());++ m3 = m1.abs();+ VERIFY_IS_APPROX(m3.pow(RealScalar(0.5)), m3.sqrt());+ VERIFY_IS_APPROX(pow(m3,RealScalar(0.5)), m3.sqrt());++ // scalar by array division+ const RealScalar tiny = sqrt(std::numeric_limits<RealScalar>::epsilon());+ s1 += Scalar(tiny);+ m1 += ArrayType::Constant(rows,cols,Scalar(tiny));+ VERIFY_IS_APPROX(s1/m1, s1 * m1.inverse());+ + // check inplace transpose+ m3 = m1;+ m3.transposeInPlace();+ VERIFY_IS_APPROX(m3,m1.transpose());+ m3.transposeInPlace();+ VERIFY_IS_APPROX(m3,m1);+}++template<typename ArrayType> void array_complex(const ArrayType& m)+{+ typedef typename ArrayType::Index Index;++ Index rows = m.rows();+ Index cols = m.cols();++ ArrayType m1 = ArrayType::Random(rows, cols),+ m2(rows, cols);++ for (Index i = 0; i < m.rows(); ++i)+ for (Index j = 0; j < m.cols(); ++j)+ m2(i,j) = sqrt(m1(i,j));++ VERIFY_IS_APPROX(m1.sqrt(), m2);+ VERIFY_IS_APPROX(m1.sqrt(), Eigen::sqrt(m1));+}++template<typename ArrayType> void min_max(const ArrayType& m)+{+ typedef typename ArrayType::Index Index;+ typedef typename ArrayType::Scalar Scalar;++ Index rows = m.rows();+ Index cols = m.cols();++ ArrayType m1 = ArrayType::Random(rows, cols);++ // min/max with array+ Scalar maxM1 = m1.maxCoeff();+ Scalar minM1 = m1.minCoeff();++ VERIFY_IS_APPROX(ArrayType::Constant(rows,cols, minM1), (m1.min)(ArrayType::Constant(rows,cols, minM1)));+ VERIFY_IS_APPROX(m1, (m1.min)(ArrayType::Constant(rows,cols, maxM1)));++ VERIFY_IS_APPROX(ArrayType::Constant(rows,cols, maxM1), (m1.max)(ArrayType::Constant(rows,cols, maxM1)));+ VERIFY_IS_APPROX(m1, (m1.max)(ArrayType::Constant(rows,cols, minM1)));++ // min/max with scalar input+ VERIFY_IS_APPROX(ArrayType::Constant(rows,cols, minM1), (m1.min)( minM1));+ VERIFY_IS_APPROX(m1, (m1.min)( maxM1));++ VERIFY_IS_APPROX(ArrayType::Constant(rows,cols, maxM1), (m1.max)( maxM1));+ VERIFY_IS_APPROX(m1, (m1.max)( minM1));++}++void test_array()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( array(Array<float, 1, 1>()) );+ CALL_SUBTEST_2( array(Array22f()) );+ CALL_SUBTEST_3( array(Array44d()) );+ CALL_SUBTEST_4( array(ArrayXXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_5( array(ArrayXXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_6( array(ArrayXXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ }+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( comparisons(Array<float, 1, 1>()) );+ CALL_SUBTEST_2( comparisons(Array22f()) );+ CALL_SUBTEST_3( comparisons(Array44d()) );+ CALL_SUBTEST_5( comparisons(ArrayXXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_6( comparisons(ArrayXXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ }+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( min_max(Array<float, 1, 1>()) );+ CALL_SUBTEST_2( min_max(Array22f()) );+ CALL_SUBTEST_3( min_max(Array44d()) );+ CALL_SUBTEST_5( min_max(ArrayXXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_6( min_max(ArrayXXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ }+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( array_real(Array<float, 1, 1>()) );+ CALL_SUBTEST_2( array_real(Array22f()) );+ CALL_SUBTEST_3( array_real(Array44d()) );+ CALL_SUBTEST_5( array_real(ArrayXXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ }+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_4( array_complex(ArrayXXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ }++ VERIFY((internal::is_same< internal::global_math_functions_filtering_base<int>::type, int >::value));+ VERIFY((internal::is_same< internal::global_math_functions_filtering_base<float>::type, float >::value));+ VERIFY((internal::is_same< internal::global_math_functions_filtering_base<Array2i>::type, ArrayBase<Array2i> >::value));+ typedef CwiseUnaryOp<internal::scalar_sum_op<double>, ArrayXd > Xpr;+ VERIFY((internal::is_same< internal::global_math_functions_filtering_base<Xpr>::type,+ ArrayBase<Xpr>+ >::value));+}
+ eigen3/test/array_for_matrix.cpp view
@@ -0,0 +1,254 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void array_for_matrix(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType;+ typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType; ++ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols);++ ColVectorType cv1 = ColVectorType::Random(rows);+ RowVectorType rv1 = RowVectorType::Random(cols);+ + Scalar s1 = internal::random<Scalar>(),+ s2 = internal::random<Scalar>();+ + // scalar addition+ VERIFY_IS_APPROX(m1.array() + s1, s1 + m1.array());+ VERIFY_IS_APPROX((m1.array() + s1).matrix(), MatrixType::Constant(rows,cols,s1) + m1);+ VERIFY_IS_APPROX(((m1*Scalar(2)).array() - s2).matrix(), (m1+m1) - MatrixType::Constant(rows,cols,s2) );+ m3 = m1;+ m3.array() += s2;+ VERIFY_IS_APPROX(m3, (m1.array() + s2).matrix());+ m3 = m1;+ m3.array() -= s1;+ VERIFY_IS_APPROX(m3, (m1.array() - s1).matrix());++ // reductions+ VERIFY_IS_MUCH_SMALLER_THAN(m1.colwise().sum().sum() - m1.sum(), m1.squaredNorm());+ VERIFY_IS_MUCH_SMALLER_THAN(m1.rowwise().sum().sum() - m1.sum(), m1.squaredNorm());+ VERIFY_IS_MUCH_SMALLER_THAN(m1.colwise().sum() + m2.colwise().sum() - (m1+m2).colwise().sum(), (m1+m2).squaredNorm());+ VERIFY_IS_MUCH_SMALLER_THAN(m1.rowwise().sum() - m2.rowwise().sum() - (m1-m2).rowwise().sum(), (m1-m2).squaredNorm());+ VERIFY_IS_APPROX(m1.colwise().sum(), m1.colwise().redux(internal::scalar_sum_op<Scalar>()));++ // vector-wise ops+ m3 = m1;+ VERIFY_IS_APPROX(m3.colwise() += cv1, m1.colwise() + cv1);+ m3 = m1;+ VERIFY_IS_APPROX(m3.colwise() -= cv1, m1.colwise() - cv1);+ m3 = m1;+ VERIFY_IS_APPROX(m3.rowwise() += rv1, m1.rowwise() + rv1);+ m3 = m1;+ VERIFY_IS_APPROX(m3.rowwise() -= rv1, m1.rowwise() - rv1);+ + // empty objects+ VERIFY_IS_APPROX(m1.block(0,0,0,cols).colwise().sum(), RowVectorType::Zero(cols));+ VERIFY_IS_APPROX(m1.block(0,0,rows,0).rowwise().prod(), ColVectorType::Ones(rows));+ + // verify the const accessors exist+ const Scalar& ref_m1 = m.matrix().array().coeffRef(0);+ const Scalar& ref_m2 = m.matrix().array().coeffRef(0,0);+ const Scalar& ref_a1 = m.array().matrix().coeffRef(0);+ const Scalar& ref_a2 = m.array().matrix().coeffRef(0,0);+ VERIFY(&ref_a1 == &ref_m1);+ VERIFY(&ref_a2 == &ref_m2);+}++template<typename MatrixType> void comparisons(const MatrixType& m)+{+ using std::abs;+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;++ Index rows = m.rows();+ Index cols = m.cols();++ Index r = internal::random<Index>(0, rows-1),+ c = internal::random<Index>(0, cols-1);++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols);++ VERIFY(((m1.array() + Scalar(1)) > m1.array()).all());+ VERIFY(((m1.array() - Scalar(1)) < m1.array()).all());+ if (rows*cols>1)+ {+ m3 = m1;+ m3(r,c) += 1;+ VERIFY(! (m1.array() < m3.array()).all() );+ VERIFY(! (m1.array() > m3.array()).all() );+ }++ // comparisons to scalar+ VERIFY( (m1.array() != (m1(r,c)+1) ).any() );+ VERIFY( (m1.array() > (m1(r,c)-1) ).any() );+ VERIFY( (m1.array() < (m1(r,c)+1) ).any() );+ VERIFY( (m1.array() == m1(r,c) ).any() );+ VERIFY( m1.cwiseEqual(m1(r,c)).any() );++ // test Select+ VERIFY_IS_APPROX( (m1.array()<m2.array()).select(m1,m2), m1.cwiseMin(m2) );+ VERIFY_IS_APPROX( (m1.array()>m2.array()).select(m1,m2), m1.cwiseMax(m2) );+ Scalar mid = (m1.cwiseAbs().minCoeff() + m1.cwiseAbs().maxCoeff())/Scalar(2);+ for (int j=0; j<cols; ++j)+ for (int i=0; i<rows; ++i)+ m3(i,j) = abs(m1(i,j))<mid ? 0 : m1(i,j);+ VERIFY_IS_APPROX( (m1.array().abs()<MatrixType::Constant(rows,cols,mid).array())+ .select(MatrixType::Zero(rows,cols),m1), m3);+ // shorter versions:+ VERIFY_IS_APPROX( (m1.array().abs()<MatrixType::Constant(rows,cols,mid).array())+ .select(0,m1), m3);+ VERIFY_IS_APPROX( (m1.array().abs()>=MatrixType::Constant(rows,cols,mid).array())+ .select(m1,0), m3);+ // even shorter version:+ VERIFY_IS_APPROX( (m1.array().abs()<mid).select(0,m1), m3);++ // count+ VERIFY(((m1.array().abs()+1)>RealScalar(0.1)).count() == rows*cols);++ typedef Matrix<typename MatrixType::Index, Dynamic, 1> VectorOfIndices;++ // TODO allows colwise/rowwise for array+ VERIFY_IS_APPROX(((m1.array().abs()+1)>RealScalar(0.1)).matrix().colwise().count(), VectorOfIndices::Constant(cols,rows).transpose());+ VERIFY_IS_APPROX(((m1.array().abs()+1)>RealScalar(0.1)).matrix().rowwise().count(), VectorOfIndices::Constant(rows, cols));+}++template<typename VectorType> void lpNorm(const VectorType& v)+{+ using std::sqrt;+ VectorType u = VectorType::Random(v.size());++ VERIFY_IS_APPROX(u.template lpNorm<Infinity>(), u.cwiseAbs().maxCoeff());+ VERIFY_IS_APPROX(u.template lpNorm<1>(), u.cwiseAbs().sum());+ VERIFY_IS_APPROX(u.template lpNorm<2>(), sqrt(u.array().abs().square().sum()));+ VERIFY_IS_APPROX(numext::pow(u.template lpNorm<5>(), typename VectorType::RealScalar(5)), u.array().abs().pow(5).sum());+}++template<typename MatrixType> void cwise_min_max(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;++ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols);++ // min/max with array+ Scalar maxM1 = m1.maxCoeff();+ Scalar minM1 = m1.minCoeff();++ VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, minM1), m1.cwiseMin(MatrixType::Constant(rows,cols, minM1)));+ VERIFY_IS_APPROX(m1, m1.cwiseMin(MatrixType::Constant(rows,cols, maxM1)));++ VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, maxM1), m1.cwiseMax(MatrixType::Constant(rows,cols, maxM1)));+ VERIFY_IS_APPROX(m1, m1.cwiseMax(MatrixType::Constant(rows,cols, minM1)));++ // min/max with scalar input+ VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, minM1), m1.cwiseMin( minM1));+ VERIFY_IS_APPROX(m1, m1.cwiseMin(maxM1));+ VERIFY_IS_APPROX(-m1, (-m1).cwiseMin(-minM1));+ VERIFY_IS_APPROX(-m1.array(), ((-m1).array().min)( -minM1));++ VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, maxM1), m1.cwiseMax( maxM1));+ VERIFY_IS_APPROX(m1, m1.cwiseMax(minM1));+ VERIFY_IS_APPROX(-m1, (-m1).cwiseMax(-maxM1));+ VERIFY_IS_APPROX(-m1.array(), ((-m1).array().max)(-maxM1));++ VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, minM1).array(), (m1.array().min)( minM1));+ VERIFY_IS_APPROX(m1.array(), (m1.array().min)( maxM1));++ VERIFY_IS_APPROX(MatrixType::Constant(rows,cols, maxM1).array(), (m1.array().max)( maxM1));+ VERIFY_IS_APPROX(m1.array(), (m1.array().max)( minM1));++}++template<typename MatrixTraits> void resize(const MatrixTraits& t)+{+ typedef typename MatrixTraits::Index Index;+ typedef typename MatrixTraits::Scalar Scalar;+ typedef Matrix<Scalar,Dynamic,Dynamic> MatrixType;+ typedef Array<Scalar,Dynamic,Dynamic> Array2DType;+ typedef Matrix<Scalar,Dynamic,1> VectorType;+ typedef Array<Scalar,Dynamic,1> Array1DType;++ Index rows = t.rows(), cols = t.cols();++ MatrixType m(rows,cols);+ VectorType v(rows);+ Array2DType a2(rows,cols);+ Array1DType a1(rows);++ m.array().resize(rows+1,cols+1);+ VERIFY(m.rows()==rows+1 && m.cols()==cols+1);+ a2.matrix().resize(rows+1,cols+1);+ VERIFY(a2.rows()==rows+1 && a2.cols()==cols+1);+ v.array().resize(cols);+ VERIFY(v.size()==cols);+ a1.matrix().resize(cols);+ VERIFY(a1.size()==cols);+}++void regression_bug_654()+{+ ArrayXf a = RowVectorXf(3);+ VectorXf v = Array<float,1,Dynamic>(3);+}++void test_array_for_matrix()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( array_for_matrix(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( array_for_matrix(Matrix2f()) );+ CALL_SUBTEST_3( array_for_matrix(Matrix4d()) );+ CALL_SUBTEST_4( array_for_matrix(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_5( array_for_matrix(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_6( array_for_matrix(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ }+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( comparisons(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( comparisons(Matrix2f()) );+ CALL_SUBTEST_3( comparisons(Matrix4d()) );+ CALL_SUBTEST_5( comparisons(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_6( comparisons(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ }+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( cwise_min_max(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( cwise_min_max(Matrix2f()) );+ CALL_SUBTEST_3( cwise_min_max(Matrix4d()) );+ CALL_SUBTEST_5( cwise_min_max(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_6( cwise_min_max(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ }+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( lpNorm(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( lpNorm(Vector2f()) );+ CALL_SUBTEST_7( lpNorm(Vector3d()) );+ CALL_SUBTEST_8( lpNorm(Vector4f()) );+ CALL_SUBTEST_5( lpNorm(VectorXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_4( lpNorm(VectorXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ }+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_4( resize(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_5( resize(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_6( resize(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ }+ CALL_SUBTEST_6( regression_bug_654() );+}
+ eigen3/test/array_replicate.cpp view
@@ -0,0 +1,69 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void replicate(const MatrixType& m)+{+ /* this test covers the following files:+ Replicate.cpp+ */+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;+ typedef Matrix<Scalar, Dynamic, Dynamic> MatrixX;+ typedef Matrix<Scalar, Dynamic, 1> VectorX;++ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols);++ VectorType v1 = VectorType::Random(rows);++ MatrixX x1, x2;+ VectorX vx1;++ int f1 = internal::random<int>(1,10),+ f2 = internal::random<int>(1,10);++ x1.resize(rows*f1,cols*f2);+ for(int j=0; j<f2; j++)+ for(int i=0; i<f1; i++)+ x1.block(i*rows,j*cols,rows,cols) = m1;+ VERIFY_IS_APPROX(x1, m1.replicate(f1,f2));++ x2.resize(2*rows,3*cols);+ x2 << m2, m2, m2,+ m2, m2, m2;+ VERIFY_IS_APPROX(x2, (m2.template replicate<2,3>()));++ x2.resize(rows,f1);+ for (int j=0; j<f1; ++j)+ x2.col(j) = v1;+ VERIFY_IS_APPROX(x2, v1.rowwise().replicate(f1));++ vx1.resize(rows*f2);+ for (int j=0; j<f2; ++j)+ vx1.segment(j*rows,rows) = v1;+ VERIFY_IS_APPROX(vx1, v1.colwise().replicate(f2));+}++void test_array_replicate()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( replicate(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( replicate(Vector2f()) );+ CALL_SUBTEST_3( replicate(Vector3d()) );+ CALL_SUBTEST_4( replicate(Vector4f()) );+ CALL_SUBTEST_5( replicate(VectorXf(16)) );+ CALL_SUBTEST_6( replicate(VectorXcd(10)) );+ }+}
+ eigen3/test/array_reverse.cpp view
@@ -0,0 +1,128 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+// Copyright (C) 2009 Ricard Marxer <email@ricardmarxer.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <iostream>++using namespace std;++template<typename MatrixType> void reverse(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ Index rows = m.rows();+ Index cols = m.cols();++ // this test relies a lot on Random.h, and there's not much more that we can do+ // to test it, hence I consider that we will have tested Random.h+ MatrixType m1 = MatrixType::Random(rows, cols);+ VectorType v1 = VectorType::Random(rows);++ MatrixType m1_r = m1.reverse();+ // Verify that MatrixBase::reverse() works+ for ( int i = 0; i < rows; i++ ) {+ for ( int j = 0; j < cols; j++ ) {+ VERIFY_IS_APPROX(m1_r(i, j), m1(rows - 1 - i, cols - 1 - j));+ }+ }++ Reverse<MatrixType> m1_rd(m1);+ // Verify that a Reverse default (in both directions) of an expression works+ for ( int i = 0; i < rows; i++ ) {+ for ( int j = 0; j < cols; j++ ) {+ VERIFY_IS_APPROX(m1_rd(i, j), m1(rows - 1 - i, cols - 1 - j));+ }+ }++ Reverse<MatrixType, BothDirections> m1_rb(m1);+ // Verify that a Reverse in both directions of an expression works+ for ( int i = 0; i < rows; i++ ) {+ for ( int j = 0; j < cols; j++ ) {+ VERIFY_IS_APPROX(m1_rb(i, j), m1(rows - 1 - i, cols - 1 - j));+ }+ }++ Reverse<MatrixType, Vertical> m1_rv(m1);+ // Verify that a Reverse in the vertical directions of an expression works+ for ( int i = 0; i < rows; i++ ) {+ for ( int j = 0; j < cols; j++ ) {+ VERIFY_IS_APPROX(m1_rv(i, j), m1(rows - 1 - i, j));+ }+ }++ Reverse<MatrixType, Horizontal> m1_rh(m1);+ // Verify that a Reverse in the horizontal directions of an expression works+ for ( int i = 0; i < rows; i++ ) {+ for ( int j = 0; j < cols; j++ ) {+ VERIFY_IS_APPROX(m1_rh(i, j), m1(i, cols - 1 - j));+ }+ }++ VectorType v1_r = v1.reverse();+ // Verify that a VectorType::reverse() of an expression works+ for ( int i = 0; i < rows; i++ ) {+ VERIFY_IS_APPROX(v1_r(i), v1(rows - 1 - i));+ }++ MatrixType m1_cr = m1.colwise().reverse();+ // Verify that PartialRedux::reverse() works (for colwise())+ for ( int i = 0; i < rows; i++ ) {+ for ( int j = 0; j < cols; j++ ) {+ VERIFY_IS_APPROX(m1_cr(i, j), m1(rows - 1 - i, j));+ }+ }++ MatrixType m1_rr = m1.rowwise().reverse();+ // Verify that PartialRedux::reverse() works (for rowwise())+ for ( int i = 0; i < rows; i++ ) {+ for ( int j = 0; j < cols; j++ ) {+ VERIFY_IS_APPROX(m1_rr(i, j), m1(i, cols - 1 - j));+ }+ }++ Scalar x = internal::random<Scalar>();++ Index r = internal::random<Index>(0, rows-1),+ c = internal::random<Index>(0, cols-1);++ m1.reverse()(r, c) = x;+ VERIFY_IS_APPROX(x, m1(rows - 1 - r, cols - 1 - c));++ /*+ m1.colwise().reverse()(r, c) = x;+ VERIFY_IS_APPROX(x, m1(rows - 1 - r, c));++ m1.rowwise().reverse()(r, c) = x;+ VERIFY_IS_APPROX(x, m1(r, cols - 1 - c));+ */+}++void test_array_reverse()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( reverse(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( reverse(Matrix2f()) );+ CALL_SUBTEST_3( reverse(Matrix4f()) );+ CALL_SUBTEST_4( reverse(Matrix4d()) );+ CALL_SUBTEST_5( reverse(MatrixXcf(3, 3)) );+ CALL_SUBTEST_6( reverse(MatrixXi(6, 3)) );+ CALL_SUBTEST_7( reverse(MatrixXcd(20, 20)) );+ CALL_SUBTEST_8( reverse(Matrix<float, 100, 100>()) );+ CALL_SUBTEST_9( reverse(Matrix<float,Dynamic,Dynamic,RowMajor>(6,3)) );+ }+#ifdef EIGEN_TEST_PART_3+ Vector4f x; x << 1, 2, 3, 4;+ Vector4f y; y << 4, 3, 2, 1;+ VERIFY(x.reverse()[1] == 3);+ VERIFY(x.reverse() == y);+#endif+}
+ eigen3/test/bandmatrix.cpp view
@@ -0,0 +1,74 @@+// This file is triangularView of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void bandmatrix(const MatrixType& _m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrixType;++ Index rows = _m.rows();+ Index cols = _m.cols();+ Index supers = _m.supers();+ Index subs = _m.subs();++ MatrixType m(rows,cols,supers,subs);++ DenseMatrixType dm1(rows,cols);+ dm1.setZero();++ m.diagonal().setConstant(123);+ dm1.diagonal().setConstant(123);+ for (int i=1; i<=m.supers();++i)+ {+ m.diagonal(i).setConstant(static_cast<RealScalar>(i));+ dm1.diagonal(i).setConstant(static_cast<RealScalar>(i));+ }+ for (int i=1; i<=m.subs();++i)+ {+ m.diagonal(-i).setConstant(-static_cast<RealScalar>(i));+ dm1.diagonal(-i).setConstant(-static_cast<RealScalar>(i));+ }+ //std::cerr << m.m_data << "\n\n" << m.toDense() << "\n\n" << dm1 << "\n\n\n\n";+ VERIFY_IS_APPROX(dm1,m.toDenseMatrix());++ for (int i=0; i<cols; ++i)+ {+ m.col(i).setConstant(static_cast<RealScalar>(i+1));+ dm1.col(i).setConstant(static_cast<RealScalar>(i+1));+ }+ Index d = (std::min)(rows,cols);+ Index a = std::max<Index>(0,cols-d-supers);+ Index b = std::max<Index>(0,rows-d-subs);+ if(a>0) dm1.block(0,d+supers,rows,a).setZero();+ dm1.block(0,supers+1,cols-supers-1-a,cols-supers-1-a).template triangularView<Upper>().setZero();+ dm1.block(subs+1,0,rows-subs-1-b,rows-subs-1-b).template triangularView<Lower>().setZero();+ if(b>0) dm1.block(d+subs,0,b,cols).setZero();+ //std::cerr << m.m_data << "\n\n" << m.toDense() << "\n\n" << dm1 << "\n\n";+ VERIFY_IS_APPROX(dm1,m.toDenseMatrix());++}++using Eigen::internal::BandMatrix;++void test_bandmatrix()+{+ typedef BandMatrix<float>::Index Index;++ for(int i = 0; i < 10*g_repeat ; i++) {+ Index rows = internal::random<Index>(1,10);+ Index cols = internal::random<Index>(1,10);+ Index sups = internal::random<Index>(0,cols-1);+ Index subs = internal::random<Index>(0,rows-1);+ CALL_SUBTEST(bandmatrix(BandMatrix<float>(rows,cols,sups,subs)) );+ }+}
+ eigen3/test/basicstuff.cpp view
@@ -0,0 +1,214 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN_NO_STATIC_ASSERT++#include "main.h"++template<typename MatrixType> void basicStuff(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;++ Index rows = m.rows();+ Index cols = m.cols();++ // this test relies a lot on Random.h, and there's not much more that we can do+ // to test it, hence I consider that we will have tested Random.h+ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols),+ mzero = MatrixType::Zero(rows, cols),+ square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>::Random(rows, rows);+ VectorType v1 = VectorType::Random(rows),+ vzero = VectorType::Zero(rows);+ SquareMatrixType sm1 = SquareMatrixType::Random(rows,rows), sm2(rows,rows);++ Scalar x = 0;+ while(x == Scalar(0)) x = internal::random<Scalar>();++ Index r = internal::random<Index>(0, rows-1),+ c = internal::random<Index>(0, cols-1);++ m1.coeffRef(r,c) = x;+ VERIFY_IS_APPROX(x, m1.coeff(r,c));+ m1(r,c) = x;+ VERIFY_IS_APPROX(x, m1(r,c));+ v1.coeffRef(r) = x;+ VERIFY_IS_APPROX(x, v1.coeff(r));+ v1(r) = x;+ VERIFY_IS_APPROX(x, v1(r));+ v1[r] = x;+ VERIFY_IS_APPROX(x, v1[r]);++ VERIFY_IS_APPROX( v1, v1);+ VERIFY_IS_NOT_APPROX( v1, 2*v1);+ VERIFY_IS_MUCH_SMALLER_THAN( vzero, v1);+ VERIFY_IS_MUCH_SMALLER_THAN( vzero, v1.squaredNorm());+ VERIFY_IS_NOT_MUCH_SMALLER_THAN(v1, v1);+ VERIFY_IS_APPROX( vzero, v1-v1);+ VERIFY_IS_APPROX( m1, m1);+ VERIFY_IS_NOT_APPROX( m1, 2*m1);+ VERIFY_IS_MUCH_SMALLER_THAN( mzero, m1);+ VERIFY_IS_NOT_MUCH_SMALLER_THAN(m1, m1);+ VERIFY_IS_APPROX( mzero, m1-m1);++ // always test operator() on each read-only expression class,+ // in order to check const-qualifiers.+ // indeed, if an expression class (here Zero) is meant to be read-only,+ // hence has no _write() method, the corresponding MatrixBase method (here zero())+ // should return a const-qualified object so that it is the const-qualified+ // operator() that gets called, which in turn calls _read().+ VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::Zero(rows,cols)(r,c), static_cast<Scalar>(1));++ // now test copying a row-vector into a (column-)vector and conversely.+ square.col(r) = square.row(r).eval();+ Matrix<Scalar, 1, MatrixType::RowsAtCompileTime> rv(rows);+ Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> cv(rows);+ rv = square.row(r);+ cv = square.col(r);+ + VERIFY_IS_APPROX(rv, cv.transpose());++ if(cols!=1 && rows!=1 && MatrixType::SizeAtCompileTime!=Dynamic)+ {+ VERIFY_RAISES_ASSERT(m1 = (m2.block(0,0, rows-1, cols-1)));+ }++ if(cols!=1 && rows!=1)+ {+ VERIFY_RAISES_ASSERT(m1[0]);+ VERIFY_RAISES_ASSERT((m1+m1)[0]);+ }++ VERIFY_IS_APPROX(m3 = m1,m1);+ MatrixType m4;+ VERIFY_IS_APPROX(m4 = m1,m1);++ m3.real() = m1.real();+ VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), static_cast<const MatrixType&>(m1).real());+ VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), m1.real());++ // check == / != operators+ VERIFY(m1==m1);+ VERIFY(m1!=m2);+ VERIFY(!(m1==m2));+ VERIFY(!(m1!=m1));+ m1 = m2;+ VERIFY(m1==m2);+ VERIFY(!(m1!=m2));+ + // check automatic transposition+ sm2.setZero();+ for(typename MatrixType::Index i=0;i<rows;++i)+ sm2.col(i) = sm1.row(i);+ VERIFY_IS_APPROX(sm2,sm1.transpose());+ + sm2.setZero();+ for(typename MatrixType::Index i=0;i<rows;++i)+ sm2.col(i).noalias() = sm1.row(i);+ VERIFY_IS_APPROX(sm2,sm1.transpose());+ + sm2.setZero();+ for(typename MatrixType::Index i=0;i<rows;++i)+ sm2.col(i).noalias() += sm1.row(i);+ VERIFY_IS_APPROX(sm2,sm1.transpose());+ + sm2.setZero();+ for(typename MatrixType::Index i=0;i<rows;++i)+ sm2.col(i).noalias() -= sm1.row(i);+ VERIFY_IS_APPROX(sm2,-sm1.transpose());+}++template<typename MatrixType> void basicStuffComplex(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime> RealMatrixType;++ Index rows = m.rows();+ Index cols = m.cols();++ Scalar s1 = internal::random<Scalar>(),+ s2 = internal::random<Scalar>();++ VERIFY(numext::real(s1)==numext::real_ref(s1));+ VERIFY(numext::imag(s1)==numext::imag_ref(s1));+ numext::real_ref(s1) = numext::real(s2);+ numext::imag_ref(s1) = numext::imag(s2);+ VERIFY(internal::isApprox(s1, s2, NumTraits<RealScalar>::epsilon()));+ // extended precision in Intel FPUs means that s1 == s2 in the line above is not guaranteed.++ RealMatrixType rm1 = RealMatrixType::Random(rows,cols),+ rm2 = RealMatrixType::Random(rows,cols);+ MatrixType cm(rows,cols);+ cm.real() = rm1;+ cm.imag() = rm2;+ VERIFY_IS_APPROX(static_cast<const MatrixType&>(cm).real(), rm1);+ VERIFY_IS_APPROX(static_cast<const MatrixType&>(cm).imag(), rm2);+ rm1.setZero();+ rm2.setZero();+ rm1 = cm.real();+ rm2 = cm.imag();+ VERIFY_IS_APPROX(static_cast<const MatrixType&>(cm).real(), rm1);+ VERIFY_IS_APPROX(static_cast<const MatrixType&>(cm).imag(), rm2);+ cm.real().setZero();+ VERIFY(static_cast<const MatrixType&>(cm).real().isZero());+ VERIFY(!static_cast<const MatrixType&>(cm).imag().isZero());+}++#ifdef EIGEN_TEST_PART_2+void casting()+{+ Matrix4f m = Matrix4f::Random(), m2;+ Matrix4d n = m.cast<double>();+ VERIFY(m.isApprox(n.cast<float>()));+ m2 = m.cast<float>(); // check the specialization when NewType == Type+ VERIFY(m.isApprox(m2));+}+#endif++template <typename Scalar>+void fixedSizeMatrixConstruction()+{+ const Scalar raw[3] = {1,2,3};+ Matrix<Scalar,3,1> m(raw);+ Array<Scalar,3,1> a(raw);+ VERIFY(m(0) == 1);+ VERIFY(m(1) == 2);+ VERIFY(m(2) == 3);+ VERIFY(a(0) == 1);+ VERIFY(a(1) == 2);+ VERIFY(a(2) == 3); +}++void test_basicstuff()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( basicStuff(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( basicStuff(Matrix4d()) );+ CALL_SUBTEST_3( basicStuff(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_4( basicStuff(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_5( basicStuff(MatrixXcd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_6( basicStuff(Matrix<float, 100, 100>()) );+ CALL_SUBTEST_7( basicStuff(Matrix<long double,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );++ CALL_SUBTEST_3( basicStuffComplex(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_5( basicStuffComplex(MatrixXcd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ }++ CALL_SUBTEST_1(fixedSizeMatrixConstruction<unsigned char>());+ CALL_SUBTEST_1(fixedSizeMatrixConstruction<double>());+ CALL_SUBTEST_1(fixedSizeMatrixConstruction<double>());++ CALL_SUBTEST_2(casting());+}
+ eigen3/test/bicgstab.cpp view
@@ -0,0 +1,30 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "sparse_solver.h"+#include <Eigen/IterativeLinearSolvers>++template<typename T> void test_bicgstab_T()+{+ BiCGSTAB<SparseMatrix<T>, DiagonalPreconditioner<T> > bicgstab_colmajor_diag;+ BiCGSTAB<SparseMatrix<T>, IdentityPreconditioner > bicgstab_colmajor_I;+ BiCGSTAB<SparseMatrix<T>, IncompleteLUT<T> > bicgstab_colmajor_ilut;+ //BiCGSTAB<SparseMatrix<T>, SSORPreconditioner<T> > bicgstab_colmajor_ssor;++ CALL_SUBTEST( check_sparse_square_solving(bicgstab_colmajor_diag) );+// CALL_SUBTEST( check_sparse_square_solving(bicgstab_colmajor_I) );+ CALL_SUBTEST( check_sparse_square_solving(bicgstab_colmajor_ilut) );+ //CALL_SUBTEST( check_sparse_square_solving(bicgstab_colmajor_ssor) );+}++void test_bicgstab()+{+ CALL_SUBTEST_1(test_bicgstab_T<double>());+ CALL_SUBTEST_2(test_bicgstab_T<std::complex<double> >());+}
+ eigen3/test/block.cpp view
@@ -0,0 +1,251 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN_NO_STATIC_ASSERT // otherwise we fail at compile time on unused paths+#include "main.h"++template<typename MatrixType, typename Index, typename Scalar>+typename Eigen::internal::enable_if<!NumTraits<typename MatrixType::Scalar>::IsComplex,typename MatrixType::Scalar>::type+block_real_only(const MatrixType &m1, Index r1, Index r2, Index c1, Index c2, const Scalar& s1) {+ // check cwise-Functions:+ VERIFY_IS_APPROX(m1.row(r1).cwiseMax(s1), m1.cwiseMax(s1).row(r1));+ VERIFY_IS_APPROX(m1.col(c1).cwiseMin(s1), m1.cwiseMin(s1).col(c1));++ VERIFY_IS_APPROX(m1.block(r1,c1,r2-r1+1,c2-c1+1).cwiseMin(s1), m1.cwiseMin(s1).block(r1,c1,r2-r1+1,c2-c1+1));+ VERIFY_IS_APPROX(m1.block(r1,c1,r2-r1+1,c2-c1+1).cwiseMax(s1), m1.cwiseMax(s1).block(r1,c1,r2-r1+1,c2-c1+1));+ + return Scalar(0);+}++template<typename MatrixType, typename Index, typename Scalar>+typename Eigen::internal::enable_if<NumTraits<typename MatrixType::Scalar>::IsComplex,typename MatrixType::Scalar>::type+block_real_only(const MatrixType &, Index, Index, Index, Index, const Scalar&) {+ return Scalar(0);+}+++template<typename MatrixType> void block(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::RealScalar RealScalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;+ typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;+ typedef Matrix<Scalar, Dynamic, Dynamic> DynamicMatrixType;+ typedef Matrix<Scalar, Dynamic, 1> DynamicVectorType;+ + Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m1_copy = m1,+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols),+ ones = MatrixType::Ones(rows, cols);+ VectorType v1 = VectorType::Random(rows);++ Scalar s1 = internal::random<Scalar>();++ Index r1 = internal::random<Index>(0,rows-1);+ Index r2 = internal::random<Index>(r1,rows-1);+ Index c1 = internal::random<Index>(0,cols-1);+ Index c2 = internal::random<Index>(c1,cols-1);++ block_real_only(m1, r1, r2, c1, c1, s1);++ //check row() and col()+ VERIFY_IS_EQUAL(m1.col(c1).transpose(), m1.transpose().row(c1));+ //check operator(), both constant and non-constant, on row() and col()+ m1 = m1_copy;+ m1.row(r1) += s1 * m1_copy.row(r2);+ VERIFY_IS_APPROX(m1.row(r1), m1_copy.row(r1) + s1 * m1_copy.row(r2));+ // check nested block xpr on lhs+ m1.row(r1).row(0) += s1 * m1_copy.row(r2);+ VERIFY_IS_APPROX(m1.row(r1), m1_copy.row(r1) + Scalar(2) * s1 * m1_copy.row(r2));+ m1 = m1_copy;+ m1.col(c1) += s1 * m1_copy.col(c2);+ VERIFY_IS_APPROX(m1.col(c1), m1_copy.col(c1) + s1 * m1_copy.col(c2));+ m1.col(c1).col(0) += s1 * m1_copy.col(c2);+ VERIFY_IS_APPROX(m1.col(c1), m1_copy.col(c1) + Scalar(2) * s1 * m1_copy.col(c2));+ + + //check block()+ Matrix<Scalar,Dynamic,Dynamic> b1(1,1); b1(0,0) = m1(r1,c1);++ RowVectorType br1(m1.block(r1,0,1,cols));+ VectorType bc1(m1.block(0,c1,rows,1));+ VERIFY_IS_EQUAL(b1, m1.block(r1,c1,1,1));+ VERIFY_IS_EQUAL(m1.row(r1), br1);+ VERIFY_IS_EQUAL(m1.col(c1), bc1);+ //check operator(), both constant and non-constant, on block()+ m1.block(r1,c1,r2-r1+1,c2-c1+1) = s1 * m2.block(0, 0, r2-r1+1,c2-c1+1);+ m1.block(r1,c1,r2-r1+1,c2-c1+1)(r2-r1,c2-c1) = m2.block(0, 0, r2-r1+1,c2-c1+1)(0,0);++ enum {+ BlockRows = 2,+ BlockCols = 5+ };+ if (rows>=5 && cols>=8)+ {+ // test fixed block() as lvalue+ m1.template block<BlockRows,BlockCols>(1,1) *= s1;+ // test operator() on fixed block() both as constant and non-constant+ m1.template block<BlockRows,BlockCols>(1,1)(0, 3) = m1.template block<2,5>(1,1)(1,2);+ // check that fixed block() and block() agree+ Matrix<Scalar,Dynamic,Dynamic> b = m1.template block<BlockRows,BlockCols>(3,3);+ VERIFY_IS_EQUAL(b, m1.block(3,3,BlockRows,BlockCols));++ // same tests with mixed fixed/dynamic size+ m1.template block<BlockRows,Dynamic>(1,1,BlockRows,BlockCols) *= s1;+ m1.template block<BlockRows,Dynamic>(1,1,BlockRows,BlockCols)(0,3) = m1.template block<2,5>(1,1)(1,2);+ Matrix<Scalar,Dynamic,Dynamic> b2 = m1.template block<Dynamic,BlockCols>(3,3,2,5);+ VERIFY_IS_EQUAL(b2, m1.block(3,3,BlockRows,BlockCols));+ }++ if (rows>2)+ {+ // test sub vectors+ VERIFY_IS_EQUAL(v1.template head<2>(), v1.block(0,0,2,1));+ VERIFY_IS_EQUAL(v1.template head<2>(), v1.head(2));+ VERIFY_IS_EQUAL(v1.template head<2>(), v1.segment(0,2));+ VERIFY_IS_EQUAL(v1.template head<2>(), v1.template segment<2>(0));+ Index i = rows-2;+ VERIFY_IS_EQUAL(v1.template tail<2>(), v1.block(i,0,2,1));+ VERIFY_IS_EQUAL(v1.template tail<2>(), v1.tail(2));+ VERIFY_IS_EQUAL(v1.template tail<2>(), v1.segment(i,2));+ VERIFY_IS_EQUAL(v1.template tail<2>(), v1.template segment<2>(i));+ i = internal::random<Index>(0,rows-2);+ VERIFY_IS_EQUAL(v1.segment(i,2), v1.template segment<2>(i));+ }++ // stress some basic stuffs with block matrices+ VERIFY(numext::real(ones.col(c1).sum()) == RealScalar(rows));+ VERIFY(numext::real(ones.row(r1).sum()) == RealScalar(cols));++ VERIFY(numext::real(ones.col(c1).dot(ones.col(c2))) == RealScalar(rows));+ VERIFY(numext::real(ones.row(r1).dot(ones.row(r2))) == RealScalar(cols));++ // now test some block-inside-of-block.+ + // expressions with direct access+ VERIFY_IS_EQUAL( (m1.block(r1,c1,rows-r1,cols-c1).block(r2-r1,c2-c1,rows-r2,cols-c2)) , (m1.block(r2,c2,rows-r2,cols-c2)) );+ VERIFY_IS_EQUAL( (m1.block(r1,c1,r2-r1+1,c2-c1+1).row(0)) , (m1.row(r1).segment(c1,c2-c1+1)) );+ VERIFY_IS_EQUAL( (m1.block(r1,c1,r2-r1+1,c2-c1+1).col(0)) , (m1.col(c1).segment(r1,r2-r1+1)) );+ VERIFY_IS_EQUAL( (m1.block(r1,c1,r2-r1+1,c2-c1+1).transpose().col(0)) , (m1.row(r1).segment(c1,c2-c1+1)).transpose() );+ VERIFY_IS_EQUAL( (m1.transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0)) , (m1.row(r1).segment(c1,c2-c1+1)).transpose() );++ // expressions without direct access+ VERIFY_IS_EQUAL( ((m1+m2).block(r1,c1,rows-r1,cols-c1).block(r2-r1,c2-c1,rows-r2,cols-c2)) , ((m1+m2).block(r2,c2,rows-r2,cols-c2)) );+ VERIFY_IS_EQUAL( ((m1+m2).block(r1,c1,r2-r1+1,c2-c1+1).row(0)) , ((m1+m2).row(r1).segment(c1,c2-c1+1)) );+ VERIFY_IS_EQUAL( ((m1+m2).block(r1,c1,r2-r1+1,c2-c1+1).col(0)) , ((m1+m2).col(c1).segment(r1,r2-r1+1)) );+ VERIFY_IS_EQUAL( ((m1+m2).block(r1,c1,r2-r1+1,c2-c1+1).transpose().col(0)) , ((m1+m2).row(r1).segment(c1,c2-c1+1)).transpose() );+ VERIFY_IS_EQUAL( ((m1+m2).transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0)) , ((m1+m2).row(r1).segment(c1,c2-c1+1)).transpose() );++ // evaluation into plain matrices from expressions with direct access (stress MapBase)+ DynamicMatrixType dm;+ DynamicVectorType dv;+ dm.setZero();+ dm = m1.block(r1,c1,rows-r1,cols-c1).block(r2-r1,c2-c1,rows-r2,cols-c2);+ VERIFY_IS_EQUAL(dm, (m1.block(r2,c2,rows-r2,cols-c2)));+ dm.setZero();+ dv.setZero();+ dm = m1.block(r1,c1,r2-r1+1,c2-c1+1).row(0).transpose();+ dv = m1.row(r1).segment(c1,c2-c1+1);+ VERIFY_IS_EQUAL(dv, dm);+ dm.setZero();+ dv.setZero();+ dm = m1.col(c1).segment(r1,r2-r1+1);+ dv = m1.block(r1,c1,r2-r1+1,c2-c1+1).col(0);+ VERIFY_IS_EQUAL(dv, dm);+ dm.setZero();+ dv.setZero();+ dm = m1.block(r1,c1,r2-r1+1,c2-c1+1).transpose().col(0);+ dv = m1.row(r1).segment(c1,c2-c1+1);+ VERIFY_IS_EQUAL(dv, dm);+ dm.setZero();+ dv.setZero();+ dm = m1.row(r1).segment(c1,c2-c1+1).transpose();+ dv = m1.transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0);+ VERIFY_IS_EQUAL(dv, dm);+}+++template<typename MatrixType>+void compare_using_data_and_stride(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ Index rows = m.rows();+ Index cols = m.cols();+ Index size = m.size();+ Index innerStride = m.innerStride();+ Index outerStride = m.outerStride();+ Index rowStride = m.rowStride();+ Index colStride = m.colStride();+ const typename MatrixType::Scalar* data = m.data();++ for(int j=0;j<cols;++j)+ for(int i=0;i<rows;++i)+ VERIFY(m.coeff(i,j) == data[i*rowStride + j*colStride]);++ if(!MatrixType::IsVectorAtCompileTime)+ {+ for(int j=0;j<cols;++j)+ for(int i=0;i<rows;++i)+ VERIFY(m.coeff(i,j) == data[(MatrixType::Flags&RowMajorBit)+ ? i*outerStride + j*innerStride+ : j*outerStride + i*innerStride]);+ }++ if(MatrixType::IsVectorAtCompileTime)+ {+ VERIFY(innerStride == int((&m.coeff(1))-(&m.coeff(0))));+ for (int i=0;i<size;++i)+ VERIFY(m.coeff(i) == data[i*innerStride]);+ }+}++template<typename MatrixType>+void data_and_stride(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ Index rows = m.rows();+ Index cols = m.cols();++ Index r1 = internal::random<Index>(0,rows-1);+ Index r2 = internal::random<Index>(r1,rows-1);+ Index c1 = internal::random<Index>(0,cols-1);+ Index c2 = internal::random<Index>(c1,cols-1);++ MatrixType m1 = MatrixType::Random(rows, cols);+ compare_using_data_and_stride(m1.block(r1, c1, r2-r1+1, c2-c1+1));+ compare_using_data_and_stride(m1.transpose().block(c1, r1, c2-c1+1, r2-r1+1));+ compare_using_data_and_stride(m1.row(r1));+ compare_using_data_and_stride(m1.col(c1));+ compare_using_data_and_stride(m1.row(r1).transpose());+ compare_using_data_and_stride(m1.col(c1).transpose());+}++void test_block()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( block(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( block(Matrix4d()) );+ CALL_SUBTEST_3( block(MatrixXcf(3, 3)) );+ CALL_SUBTEST_4( block(MatrixXi(8, 12)) );+ CALL_SUBTEST_5( block(MatrixXcd(20, 20)) );+ CALL_SUBTEST_6( block(MatrixXf(20, 20)) );++ CALL_SUBTEST_8( block(Matrix<float,Dynamic,4>(3, 4)) );++#ifndef EIGEN_DEFAULT_TO_ROW_MAJOR+ CALL_SUBTEST_6( data_and_stride(MatrixXf(internal::random(5,50), internal::random(5,50))) );+ CALL_SUBTEST_7( data_and_stride(Matrix<int,Dynamic,Dynamic,RowMajor>(internal::random(5,50), internal::random(5,50))) );+#endif+ }+}
+ eigen3/test/cholesky.cpp view
@@ -0,0 +1,404 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_NO_ASSERTION_CHECKING+#define EIGEN_NO_ASSERTION_CHECKING+#endif++static int nb_temporaries;++#define EIGEN_DENSE_STORAGE_CTOR_PLUGIN { if(size!=0) nb_temporaries++; }++#include "main.h"+#include <Eigen/Cholesky>+#include <Eigen/QR>++#define VERIFY_EVALUATION_COUNT(XPR,N) {\+ nb_temporaries = 0; \+ XPR; \+ if(nb_temporaries!=N) std::cerr << "nb_temporaries == " << nb_temporaries << "\n"; \+ VERIFY( (#XPR) && nb_temporaries==N ); \+ }++template<typename MatrixType,template <typename,int> class CholType> void test_chol_update(const MatrixType& symm)+{+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::RealScalar RealScalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ MatrixType symmLo = symm.template triangularView<Lower>();+ MatrixType symmUp = symm.template triangularView<Upper>();+ MatrixType symmCpy = symm;++ CholType<MatrixType,Lower> chollo(symmLo);+ CholType<MatrixType,Upper> cholup(symmUp);++ for (int k=0; k<10; ++k)+ {+ VectorType vec = VectorType::Random(symm.rows());+ RealScalar sigma = internal::random<RealScalar>();+ symmCpy += sigma * vec * vec.adjoint();++ // we are doing some downdates, so it might be the case that the matrix is not SPD anymore+ CholType<MatrixType,Lower> chol(symmCpy);+ if(chol.info()!=Success)+ break;++ chollo.rankUpdate(vec, sigma);+ VERIFY_IS_APPROX(symmCpy, chollo.reconstructedMatrix());++ cholup.rankUpdate(vec, sigma);+ VERIFY_IS_APPROX(symmCpy, cholup.reconstructedMatrix());+ }+}++template<typename MatrixType> void cholesky(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ /* this test covers the following files:+ LLT.h LDLT.h+ */+ Index rows = m.rows();+ Index cols = m.cols();++ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ MatrixType a0 = MatrixType::Random(rows,cols);+ VectorType vecB = VectorType::Random(rows), vecX(rows);+ MatrixType matB = MatrixType::Random(rows,cols), matX(rows,cols);+ SquareMatrixType symm = a0 * a0.adjoint();+ // let's make sure the matrix is not singular or near singular+ for (int k=0; k<3; ++k)+ {+ MatrixType a1 = MatrixType::Random(rows,cols);+ symm += a1 * a1.adjoint();+ }++ // to test if really Cholesky only uses the upper triangular part, uncomment the following+ // FIXME: currently that fails !!+ //symm.template part<StrictlyLower>().setZero();++ {+ SquareMatrixType symmUp = symm.template triangularView<Upper>();+ SquareMatrixType symmLo = symm.template triangularView<Lower>();+ + LLT<SquareMatrixType,Lower> chollo(symmLo);+ VERIFY_IS_APPROX(symm, chollo.reconstructedMatrix());+ vecX = chollo.solve(vecB);+ VERIFY_IS_APPROX(symm * vecX, vecB);+ matX = chollo.solve(matB);+ VERIFY_IS_APPROX(symm * matX, matB);++ // test the upper mode+ LLT<SquareMatrixType,Upper> cholup(symmUp);+ VERIFY_IS_APPROX(symm, cholup.reconstructedMatrix());+ vecX = cholup.solve(vecB);+ VERIFY_IS_APPROX(symm * vecX, vecB);+ matX = cholup.solve(matB);+ VERIFY_IS_APPROX(symm * matX, matB);++ MatrixType neg = -symmLo;+ chollo.compute(neg);+ VERIFY(chollo.info()==NumericalIssue);++ VERIFY_IS_APPROX(MatrixType(chollo.matrixL().transpose().conjugate()), MatrixType(chollo.matrixU()));+ VERIFY_IS_APPROX(MatrixType(chollo.matrixU().transpose().conjugate()), MatrixType(chollo.matrixL()));+ VERIFY_IS_APPROX(MatrixType(cholup.matrixL().transpose().conjugate()), MatrixType(cholup.matrixU()));+ VERIFY_IS_APPROX(MatrixType(cholup.matrixU().transpose().conjugate()), MatrixType(cholup.matrixL()));+ + // test some special use cases of SelfCwiseBinaryOp:+ MatrixType m1 = MatrixType::Random(rows,cols), m2(rows,cols);+ m2 = m1;+ m2 += symmLo.template selfadjointView<Lower>().llt().solve(matB);+ VERIFY_IS_APPROX(m2, m1 + symmLo.template selfadjointView<Lower>().llt().solve(matB));+ m2 = m1;+ m2 -= symmLo.template selfadjointView<Lower>().llt().solve(matB);+ VERIFY_IS_APPROX(m2, m1 - symmLo.template selfadjointView<Lower>().llt().solve(matB));+ m2 = m1;+ m2.noalias() += symmLo.template selfadjointView<Lower>().llt().solve(matB);+ VERIFY_IS_APPROX(m2, m1 + symmLo.template selfadjointView<Lower>().llt().solve(matB));+ m2 = m1;+ m2.noalias() -= symmLo.template selfadjointView<Lower>().llt().solve(matB);+ VERIFY_IS_APPROX(m2, m1 - symmLo.template selfadjointView<Lower>().llt().solve(matB));+ }++ // LDLT+ {+ int sign = internal::random<int>()%2 ? 1 : -1;++ if(sign == -1)+ {+ symm = -symm; // test a negative matrix+ }++ SquareMatrixType symmUp = symm.template triangularView<Upper>();+ SquareMatrixType symmLo = symm.template triangularView<Lower>();++ LDLT<SquareMatrixType,Lower> ldltlo(symmLo);+ VERIFY_IS_APPROX(symm, ldltlo.reconstructedMatrix());+ vecX = ldltlo.solve(vecB);+ VERIFY_IS_APPROX(symm * vecX, vecB);+ matX = ldltlo.solve(matB);+ VERIFY_IS_APPROX(symm * matX, matB);++ LDLT<SquareMatrixType,Upper> ldltup(symmUp);+ VERIFY_IS_APPROX(symm, ldltup.reconstructedMatrix());+ vecX = ldltup.solve(vecB);+ VERIFY_IS_APPROX(symm * vecX, vecB);+ matX = ldltup.solve(matB);+ VERIFY_IS_APPROX(symm * matX, matB);++ VERIFY_IS_APPROX(MatrixType(ldltlo.matrixL().transpose().conjugate()), MatrixType(ldltlo.matrixU()));+ VERIFY_IS_APPROX(MatrixType(ldltlo.matrixU().transpose().conjugate()), MatrixType(ldltlo.matrixL()));+ VERIFY_IS_APPROX(MatrixType(ldltup.matrixL().transpose().conjugate()), MatrixType(ldltup.matrixU()));+ VERIFY_IS_APPROX(MatrixType(ldltup.matrixU().transpose().conjugate()), MatrixType(ldltup.matrixL()));++ if(MatrixType::RowsAtCompileTime==Dynamic)+ {+ // note : each inplace permutation requires a small temporary vector (mask)++ // check inplace solve+ matX = matB;+ VERIFY_EVALUATION_COUNT(matX = ldltlo.solve(matX), 0);+ VERIFY_IS_APPROX(matX, ldltlo.solve(matB).eval());+++ matX = matB;+ VERIFY_EVALUATION_COUNT(matX = ldltup.solve(matX), 0);+ VERIFY_IS_APPROX(matX, ldltup.solve(matB).eval());+ }++ // restore+ if(sign == -1)+ symm = -symm;++ // check matrices coming from linear constraints with Lagrange multipliers+ if(rows>=3)+ {+ SquareMatrixType A = symm;+ int c = internal::random<int>(0,rows-2);+ A.bottomRightCorner(c,c).setZero();+ // Make sure a solution exists:+ vecX.setRandom();+ vecB = A * vecX;+ vecX.setZero();+ ldltlo.compute(A);+ VERIFY_IS_APPROX(A, ldltlo.reconstructedMatrix());+ vecX = ldltlo.solve(vecB);+ VERIFY_IS_APPROX(A * vecX, vecB);+ }+ + // check non-full rank matrices+ if(rows>=3)+ {+ int r = internal::random<int>(1,rows-1);+ Matrix<Scalar,Dynamic,Dynamic> a = Matrix<Scalar,Dynamic,Dynamic>::Random(rows,r);+ SquareMatrixType A = a * a.adjoint();+ // Make sure a solution exists:+ vecX.setRandom();+ vecB = A * vecX;+ vecX.setZero();+ ldltlo.compute(A);+ VERIFY_IS_APPROX(A, ldltlo.reconstructedMatrix());+ vecX = ldltlo.solve(vecB);+ VERIFY_IS_APPROX(A * vecX, vecB);+ }+ + // check matrices with a wide spectrum+ if(rows>=3)+ {+ RealScalar s = (std::min)(16,std::numeric_limits<RealScalar>::max_exponent10/8);+ Matrix<Scalar,Dynamic,Dynamic> a = Matrix<Scalar,Dynamic,Dynamic>::Random(rows,rows);+ Matrix<RealScalar,Dynamic,1> d = Matrix<RealScalar,Dynamic,1>::Random(rows);+ for(int k=0; k<rows; ++k)+ d(k) = d(k)*std::pow(RealScalar(10),internal::random<RealScalar>(-s,s));+ SquareMatrixType A = a * d.asDiagonal() * a.adjoint();+ // Make sure a solution exists:+ vecX.setRandom();+ vecB = A * vecX;+ vecX.setZero();+ ldltlo.compute(A);+ VERIFY_IS_APPROX(A, ldltlo.reconstructedMatrix());+ vecX = ldltlo.solve(vecB);+ VERIFY_IS_APPROX(A * vecX, vecB);+ }+ }++ // update/downdate+ CALL_SUBTEST(( test_chol_update<SquareMatrixType,LLT>(symm) ));+ CALL_SUBTEST(( test_chol_update<SquareMatrixType,LDLT>(symm) ));+}++template<typename MatrixType> void cholesky_cplx(const MatrixType& m)+{+ // classic test+ cholesky(m);++ // test mixing real/scalar types++ typedef typename MatrixType::Index Index;++ Index rows = m.rows();+ Index cols = m.cols();++ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> RealMatrixType;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ RealMatrixType a0 = RealMatrixType::Random(rows,cols);+ VectorType vecB = VectorType::Random(rows), vecX(rows);+ MatrixType matB = MatrixType::Random(rows,cols), matX(rows,cols);+ RealMatrixType symm = a0 * a0.adjoint();+ // let's make sure the matrix is not singular or near singular+ for (int k=0; k<3; ++k)+ {+ RealMatrixType a1 = RealMatrixType::Random(rows,cols);+ symm += a1 * a1.adjoint();+ }++ {+ RealMatrixType symmLo = symm.template triangularView<Lower>();++ LLT<RealMatrixType,Lower> chollo(symmLo);+ VERIFY_IS_APPROX(symm, chollo.reconstructedMatrix());+ vecX = chollo.solve(vecB);+ VERIFY_IS_APPROX(symm * vecX, vecB);+// matX = chollo.solve(matB);+// VERIFY_IS_APPROX(symm * matX, matB);+ }++ // LDLT+ {+ int sign = internal::random<int>()%2 ? 1 : -1;++ if(sign == -1)+ {+ symm = -symm; // test a negative matrix+ }++ RealMatrixType symmLo = symm.template triangularView<Lower>();++ LDLT<RealMatrixType,Lower> ldltlo(symmLo);+ VERIFY_IS_APPROX(symm, ldltlo.reconstructedMatrix());+ vecX = ldltlo.solve(vecB);+ VERIFY_IS_APPROX(symm * vecX, vecB);+// matX = ldltlo.solve(matB);+// VERIFY_IS_APPROX(symm * matX, matB);+ }+}++// regression test for bug 241+template<typename MatrixType> void cholesky_bug241(const MatrixType& m)+{+ eigen_assert(m.rows() == 2 && m.cols() == 2);++ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ MatrixType matA;+ matA << 1, 1, 1, 1;+ VectorType vecB;+ vecB << 1, 1;+ VectorType vecX = matA.ldlt().solve(vecB);+ VERIFY_IS_APPROX(matA * vecX, vecB);+}++// LDLT is not guaranteed to work for indefinite matrices, but happens to work fine if matrix is diagonal.+// This test checks that LDLT reports correctly that matrix is indefinite. +// See http://forum.kde.org/viewtopic.php?f=74&t=106942 and bug 736+template<typename MatrixType> void cholesky_definiteness(const MatrixType& m)+{+ eigen_assert(m.rows() == 2 && m.cols() == 2);+ MatrixType mat;+ LDLT<MatrixType> ldlt(2);+ + {+ mat << 1, 0, 0, -1;+ ldlt.compute(mat);+ VERIFY(!ldlt.isNegative());+ VERIFY(!ldlt.isPositive());+ }+ {+ mat << 1, 2, 2, 1;+ ldlt.compute(mat);+ VERIFY(!ldlt.isNegative());+ VERIFY(!ldlt.isPositive());+ }+ {+ mat << 0, 0, 0, 0;+ ldlt.compute(mat);+ VERIFY(ldlt.isNegative());+ VERIFY(ldlt.isPositive());+ }+ {+ mat << 0, 0, 0, 1;+ ldlt.compute(mat);+ VERIFY(!ldlt.isNegative());+ VERIFY(ldlt.isPositive());+ }+ {+ mat << -1, 0, 0, 0;+ ldlt.compute(mat);+ VERIFY(ldlt.isNegative());+ VERIFY(!ldlt.isPositive());+ }+}++template<typename MatrixType> void cholesky_verify_assert()+{+ MatrixType tmp;++ LLT<MatrixType> llt;+ VERIFY_RAISES_ASSERT(llt.matrixL())+ VERIFY_RAISES_ASSERT(llt.matrixU())+ VERIFY_RAISES_ASSERT(llt.solve(tmp))+ VERIFY_RAISES_ASSERT(llt.solveInPlace(&tmp))++ LDLT<MatrixType> ldlt;+ VERIFY_RAISES_ASSERT(ldlt.matrixL())+ VERIFY_RAISES_ASSERT(ldlt.permutationP())+ VERIFY_RAISES_ASSERT(ldlt.vectorD())+ VERIFY_RAISES_ASSERT(ldlt.isPositive())+ VERIFY_RAISES_ASSERT(ldlt.isNegative())+ VERIFY_RAISES_ASSERT(ldlt.solve(tmp))+ VERIFY_RAISES_ASSERT(ldlt.solveInPlace(&tmp))+}++void test_cholesky()+{+ int s = 0;+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( cholesky(Matrix<double,1,1>()) );+ CALL_SUBTEST_3( cholesky(Matrix2d()) );+ CALL_SUBTEST_3( cholesky_bug241(Matrix2d()) );+ CALL_SUBTEST_3( cholesky_definiteness(Matrix2d()) );+ CALL_SUBTEST_4( cholesky(Matrix3f()) );+ CALL_SUBTEST_5( cholesky(Matrix4d()) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);+ CALL_SUBTEST_2( cholesky(MatrixXd(s,s)) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2);+ CALL_SUBTEST_6( cholesky_cplx(MatrixXcd(s,s)) );+ }++ CALL_SUBTEST_4( cholesky_verify_assert<Matrix3f>() );+ CALL_SUBTEST_7( cholesky_verify_assert<Matrix3d>() );+ CALL_SUBTEST_8( cholesky_verify_assert<MatrixXf>() );+ CALL_SUBTEST_2( cholesky_verify_assert<MatrixXd>() );++ // Test problem size constructors+ CALL_SUBTEST_9( LLT<MatrixXf>(10) );+ CALL_SUBTEST_9( LDLT<MatrixXf>(10) );+ + TEST_SET_BUT_UNUSED_VARIABLE(s)+ TEST_SET_BUT_UNUSED_VARIABLE(nb_temporaries)+}
+ eigen3/test/cholmod_support.cpp view
@@ -0,0 +1,56 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "sparse_solver.h"++#include <Eigen/CholmodSupport>++template<typename T> void test_cholmod_T()+{+ CholmodDecomposition<SparseMatrix<T>, Lower> g_chol_colmajor_lower; g_chol_colmajor_lower.setMode(CholmodSupernodalLLt);+ CholmodDecomposition<SparseMatrix<T>, Upper> g_chol_colmajor_upper; g_chol_colmajor_upper.setMode(CholmodSupernodalLLt);+ CholmodDecomposition<SparseMatrix<T>, Lower> g_llt_colmajor_lower; g_llt_colmajor_lower.setMode(CholmodSimplicialLLt);+ CholmodDecomposition<SparseMatrix<T>, Upper> g_llt_colmajor_upper; g_llt_colmajor_upper.setMode(CholmodSimplicialLLt);+ CholmodDecomposition<SparseMatrix<T>, Lower> g_ldlt_colmajor_lower; g_ldlt_colmajor_lower.setMode(CholmodLDLt);+ CholmodDecomposition<SparseMatrix<T>, Upper> g_ldlt_colmajor_upper; g_ldlt_colmajor_upper.setMode(CholmodLDLt);+ + CholmodSupernodalLLT<SparseMatrix<T>, Lower> chol_colmajor_lower;+ CholmodSupernodalLLT<SparseMatrix<T>, Upper> chol_colmajor_upper;+ CholmodSimplicialLLT<SparseMatrix<T>, Lower> llt_colmajor_lower;+ CholmodSimplicialLLT<SparseMatrix<T>, Upper> llt_colmajor_upper;+ CholmodSimplicialLDLT<SparseMatrix<T>, Lower> ldlt_colmajor_lower;+ CholmodSimplicialLDLT<SparseMatrix<T>, Upper> ldlt_colmajor_upper;++ check_sparse_spd_solving(g_chol_colmajor_lower);+ check_sparse_spd_solving(g_chol_colmajor_upper);+ check_sparse_spd_solving(g_llt_colmajor_lower);+ check_sparse_spd_solving(g_llt_colmajor_upper);+ check_sparse_spd_solving(g_ldlt_colmajor_lower);+ check_sparse_spd_solving(g_ldlt_colmajor_upper);+ + check_sparse_spd_solving(chol_colmajor_lower);+ check_sparse_spd_solving(chol_colmajor_upper);+ check_sparse_spd_solving(llt_colmajor_lower);+ check_sparse_spd_solving(llt_colmajor_upper);+ check_sparse_spd_solving(ldlt_colmajor_lower);+ check_sparse_spd_solving(ldlt_colmajor_upper);+ +// check_sparse_spd_determinant(chol_colmajor_lower);+// check_sparse_spd_determinant(chol_colmajor_upper);+// check_sparse_spd_determinant(llt_colmajor_lower);+// check_sparse_spd_determinant(llt_colmajor_upper);+// check_sparse_spd_determinant(ldlt_colmajor_lower);+// check_sparse_spd_determinant(ldlt_colmajor_upper);+}++void test_cholmod_support()+{+ CALL_SUBTEST_1(test_cholmod_T<double>());+ CALL_SUBTEST_2(test_cholmod_T<std::complex<double> >());+}
+ eigen3/test/commainitializer.cpp view
@@ -0,0 +1,46 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++void test_commainitializer()+{+ Matrix3d m3;+ Matrix4d m4;++ VERIFY_RAISES_ASSERT( (m3 << 1, 2, 3, 4, 5, 6, 7, 8) );+ + #ifndef _MSC_VER+ VERIFY_RAISES_ASSERT( (m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) );+ #endif++ double data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};+ Matrix3d ref = Map<Matrix<double,3,3,RowMajor> >(data);++ m3 = Matrix3d::Random();+ m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9;+ VERIFY_IS_APPROX(m3, ref );++ Vector3d vec[3];+ vec[0] << 1, 4, 7;+ vec[1] << 2, 5, 8;+ vec[2] << 3, 6, 9;+ m3 = Matrix3d::Random();+ m3 << vec[0], vec[1], vec[2];+ VERIFY_IS_APPROX(m3, ref);++ vec[0] << 1, 2, 3;+ vec[1] << 4, 5, 6;+ vec[2] << 7, 8, 9;+ m3 = Matrix3d::Random();+ m3 << vec[0].transpose(),+ 4, 5, 6,+ vec[2].transpose();+ VERIFY_IS_APPROX(m3, ref);+}
+ eigen3/test/conjugate_gradient.cpp view
@@ -0,0 +1,32 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "sparse_solver.h"+#include <Eigen/IterativeLinearSolvers>++template<typename T> void test_conjugate_gradient_T()+{+ ConjugateGradient<SparseMatrix<T>, Lower > cg_colmajor_lower_diag;+ ConjugateGradient<SparseMatrix<T>, Upper > cg_colmajor_upper_diag;+ ConjugateGradient<SparseMatrix<T>, Lower|Upper> cg_colmajor_loup_diag;+ ConjugateGradient<SparseMatrix<T>, Lower, IdentityPreconditioner> cg_colmajor_lower_I;+ ConjugateGradient<SparseMatrix<T>, Upper, IdentityPreconditioner> cg_colmajor_upper_I;++ CALL_SUBTEST( check_sparse_spd_solving(cg_colmajor_lower_diag) );+ CALL_SUBTEST( check_sparse_spd_solving(cg_colmajor_upper_diag) );+ CALL_SUBTEST( check_sparse_spd_solving(cg_colmajor_loup_diag) );+ CALL_SUBTEST( check_sparse_spd_solving(cg_colmajor_lower_I) );+ CALL_SUBTEST( check_sparse_spd_solving(cg_colmajor_upper_I) );+}++void test_conjugate_gradient()+{+ CALL_SUBTEST_1(test_conjugate_gradient_T<double>());+ CALL_SUBTEST_2(test_conjugate_gradient_T<std::complex<double> >());+}
+ eigen3/test/conservative_resize.cpp view
@@ -0,0 +1,134 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Hauke Heibel <hauke.heibel@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++#include <Eigen/Core>++using namespace Eigen;++template <typename Scalar, int Storage>+void run_matrix_tests()+{+ typedef Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Storage> MatrixType;+ typedef typename MatrixType::Index Index;++ MatrixType m, n;++ // boundary cases ...+ m = n = MatrixType::Random(50,50);+ m.conservativeResize(1,50);+ VERIFY_IS_APPROX(m, n.block(0,0,1,50));++ m = n = MatrixType::Random(50,50);+ m.conservativeResize(50,1);+ VERIFY_IS_APPROX(m, n.block(0,0,50,1));++ m = n = MatrixType::Random(50,50);+ m.conservativeResize(50,50);+ VERIFY_IS_APPROX(m, n.block(0,0,50,50));++ // random shrinking ...+ for (int i=0; i<25; ++i)+ {+ const Index rows = internal::random<Index>(1,50);+ const Index cols = internal::random<Index>(1,50);+ m = n = MatrixType::Random(50,50);+ m.conservativeResize(rows,cols);+ VERIFY_IS_APPROX(m, n.block(0,0,rows,cols));+ }++ // random growing with zeroing ...+ for (int i=0; i<25; ++i)+ {+ const Index rows = internal::random<Index>(50,75);+ const Index cols = internal::random<Index>(50,75);+ m = n = MatrixType::Random(50,50);+ m.conservativeResizeLike(MatrixType::Zero(rows,cols));+ VERIFY_IS_APPROX(m.block(0,0,n.rows(),n.cols()), n);+ VERIFY( rows<=50 || m.block(50,0,rows-50,cols).sum() == Scalar(0) );+ VERIFY( cols<=50 || m.block(0,50,rows,cols-50).sum() == Scalar(0) );+ }+}++template <typename Scalar>+void run_vector_tests()+{+ typedef Matrix<Scalar, 1, Eigen::Dynamic> VectorType;++ VectorType m, n;++ // boundary cases ...+ m = n = VectorType::Random(50);+ m.conservativeResize(1);+ VERIFY_IS_APPROX(m, n.segment(0,1));++ m = n = VectorType::Random(50);+ m.conservativeResize(50);+ VERIFY_IS_APPROX(m, n.segment(0,50));+ + m = n = VectorType::Random(50);+ m.conservativeResize(m.rows(),1);+ VERIFY_IS_APPROX(m, n.segment(0,1));++ m = n = VectorType::Random(50);+ m.conservativeResize(m.rows(),50);+ VERIFY_IS_APPROX(m, n.segment(0,50));++ // random shrinking ...+ for (int i=0; i<50; ++i)+ {+ const int size = internal::random<int>(1,50);+ m = n = VectorType::Random(50);+ m.conservativeResize(size);+ VERIFY_IS_APPROX(m, n.segment(0,size));+ + m = n = VectorType::Random(50);+ m.conservativeResize(m.rows(), size);+ VERIFY_IS_APPROX(m, n.segment(0,size));+ }++ // random growing with zeroing ...+ for (int i=0; i<50; ++i)+ {+ const int size = internal::random<int>(50,100);+ m = n = VectorType::Random(50);+ m.conservativeResizeLike(VectorType::Zero(size));+ VERIFY_IS_APPROX(m.segment(0,50), n);+ VERIFY( size<=50 || m.segment(50,size-50).sum() == Scalar(0) );+ + m = n = VectorType::Random(50);+ m.conservativeResizeLike(Matrix<Scalar,Dynamic,Dynamic>::Zero(1,size));+ VERIFY_IS_APPROX(m.segment(0,50), n);+ VERIFY( size<=50 || m.segment(50,size-50).sum() == Scalar(0) );+ }+}++void test_conservative_resize()+{+ for(int i=0; i<g_repeat; ++i)+ {+ CALL_SUBTEST_1((run_matrix_tests<int, Eigen::RowMajor>()));+ CALL_SUBTEST_1((run_matrix_tests<int, Eigen::ColMajor>()));+ CALL_SUBTEST_2((run_matrix_tests<float, Eigen::RowMajor>()));+ CALL_SUBTEST_2((run_matrix_tests<float, Eigen::ColMajor>()));+ CALL_SUBTEST_3((run_matrix_tests<double, Eigen::RowMajor>()));+ CALL_SUBTEST_3((run_matrix_tests<double, Eigen::ColMajor>()));+ CALL_SUBTEST_4((run_matrix_tests<std::complex<float>, Eigen::RowMajor>()));+ CALL_SUBTEST_4((run_matrix_tests<std::complex<float>, Eigen::ColMajor>()));+ CALL_SUBTEST_5((run_matrix_tests<std::complex<double>, Eigen::RowMajor>()));+ CALL_SUBTEST_6((run_matrix_tests<std::complex<double>, Eigen::ColMajor>()));++ CALL_SUBTEST_1((run_vector_tests<int>()));+ CALL_SUBTEST_2((run_vector_tests<float>()));+ CALL_SUBTEST_3((run_vector_tests<double>()));+ CALL_SUBTEST_4((run_vector_tests<std::complex<float> >()));+ CALL_SUBTEST_5((run_vector_tests<std::complex<double> >()));+ }+}
+ eigen3/test/corners.cpp view
@@ -0,0 +1,118 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++#define COMPARE_CORNER(A,B) \+ VERIFY_IS_EQUAL(matrix.A, matrix.B); \+ VERIFY_IS_EQUAL(const_matrix.A, const_matrix.B);++template<typename MatrixType> void corners(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ Index rows = m.rows();+ Index cols = m.cols();++ Index r = internal::random<Index>(1,rows);+ Index c = internal::random<Index>(1,cols);++ MatrixType matrix = MatrixType::Random(rows,cols);+ const MatrixType const_matrix = MatrixType::Random(rows,cols);++ COMPARE_CORNER(topLeftCorner(r,c), block(0,0,r,c));+ COMPARE_CORNER(topRightCorner(r,c), block(0,cols-c,r,c));+ COMPARE_CORNER(bottomLeftCorner(r,c), block(rows-r,0,r,c));+ COMPARE_CORNER(bottomRightCorner(r,c), block(rows-r,cols-c,r,c));++ Index sr = internal::random<Index>(1,rows) - 1;+ Index nr = internal::random<Index>(1,rows-sr);+ Index sc = internal::random<Index>(1,cols) - 1;+ Index nc = internal::random<Index>(1,cols-sc);++ COMPARE_CORNER(topRows(r), block(0,0,r,cols));+ COMPARE_CORNER(middleRows(sr,nr), block(sr,0,nr,cols));+ COMPARE_CORNER(bottomRows(r), block(rows-r,0,r,cols));+ COMPARE_CORNER(leftCols(c), block(0,0,rows,c));+ COMPARE_CORNER(middleCols(sc,nc), block(0,sc,rows,nc));+ COMPARE_CORNER(rightCols(c), block(0,cols-c,rows,c));+}++template<typename MatrixType, int CRows, int CCols, int SRows, int SCols> void corners_fixedsize()+{+ MatrixType matrix = MatrixType::Random();+ const MatrixType const_matrix = MatrixType::Random();++ enum {+ rows = MatrixType::RowsAtCompileTime,+ cols = MatrixType::ColsAtCompileTime,+ r = CRows,+ c = CCols,+ sr = SRows,+ sc = SCols+ };++ VERIFY_IS_EQUAL((matrix.template topLeftCorner<r,c>()), (matrix.template block<r,c>(0,0)));+ VERIFY_IS_EQUAL((matrix.template topRightCorner<r,c>()), (matrix.template block<r,c>(0,cols-c)));+ VERIFY_IS_EQUAL((matrix.template bottomLeftCorner<r,c>()), (matrix.template block<r,c>(rows-r,0)));+ VERIFY_IS_EQUAL((matrix.template bottomRightCorner<r,c>()), (matrix.template block<r,c>(rows-r,cols-c)));++ VERIFY_IS_EQUAL((matrix.template topLeftCorner<r,c>()), (matrix.template topLeftCorner<r,Dynamic>(r,c)));+ VERIFY_IS_EQUAL((matrix.template topRightCorner<r,c>()), (matrix.template topRightCorner<r,Dynamic>(r,c)));+ VERIFY_IS_EQUAL((matrix.template bottomLeftCorner<r,c>()), (matrix.template bottomLeftCorner<r,Dynamic>(r,c)));+ VERIFY_IS_EQUAL((matrix.template bottomRightCorner<r,c>()), (matrix.template bottomRightCorner<r,Dynamic>(r,c)));++ VERIFY_IS_EQUAL((matrix.template topLeftCorner<r,c>()), (matrix.template topLeftCorner<Dynamic,c>(r,c)));+ VERIFY_IS_EQUAL((matrix.template topRightCorner<r,c>()), (matrix.template topRightCorner<Dynamic,c>(r,c)));+ VERIFY_IS_EQUAL((matrix.template bottomLeftCorner<r,c>()), (matrix.template bottomLeftCorner<Dynamic,c>(r,c)));+ VERIFY_IS_EQUAL((matrix.template bottomRightCorner<r,c>()), (matrix.template bottomRightCorner<Dynamic,c>(r,c)));++ VERIFY_IS_EQUAL((matrix.template topRows<r>()), (matrix.template block<r,cols>(0,0)));+ VERIFY_IS_EQUAL((matrix.template middleRows<r>(sr)), (matrix.template block<r,cols>(sr,0)));+ VERIFY_IS_EQUAL((matrix.template bottomRows<r>()), (matrix.template block<r,cols>(rows-r,0)));+ VERIFY_IS_EQUAL((matrix.template leftCols<c>()), (matrix.template block<rows,c>(0,0)));+ VERIFY_IS_EQUAL((matrix.template middleCols<c>(sc)), (matrix.template block<rows,c>(0,sc)));+ VERIFY_IS_EQUAL((matrix.template rightCols<c>()), (matrix.template block<rows,c>(0,cols-c)));++ VERIFY_IS_EQUAL((const_matrix.template topLeftCorner<r,c>()), (const_matrix.template block<r,c>(0,0)));+ VERIFY_IS_EQUAL((const_matrix.template topRightCorner<r,c>()), (const_matrix.template block<r,c>(0,cols-c)));+ VERIFY_IS_EQUAL((const_matrix.template bottomLeftCorner<r,c>()), (const_matrix.template block<r,c>(rows-r,0)));+ VERIFY_IS_EQUAL((const_matrix.template bottomRightCorner<r,c>()), (const_matrix.template block<r,c>(rows-r,cols-c)));++ VERIFY_IS_EQUAL((const_matrix.template topLeftCorner<r,c>()), (const_matrix.template topLeftCorner<r,Dynamic>(r,c)));+ VERIFY_IS_EQUAL((const_matrix.template topRightCorner<r,c>()), (const_matrix.template topRightCorner<r,Dynamic>(r,c)));+ VERIFY_IS_EQUAL((const_matrix.template bottomLeftCorner<r,c>()), (const_matrix.template bottomLeftCorner<r,Dynamic>(r,c)));+ VERIFY_IS_EQUAL((const_matrix.template bottomRightCorner<r,c>()), (const_matrix.template bottomRightCorner<r,Dynamic>(r,c)));++ VERIFY_IS_EQUAL((const_matrix.template topLeftCorner<r,c>()), (const_matrix.template topLeftCorner<Dynamic,c>(r,c)));+ VERIFY_IS_EQUAL((const_matrix.template topRightCorner<r,c>()), (const_matrix.template topRightCorner<Dynamic,c>(r,c)));+ VERIFY_IS_EQUAL((const_matrix.template bottomLeftCorner<r,c>()), (const_matrix.template bottomLeftCorner<Dynamic,c>(r,c)));+ VERIFY_IS_EQUAL((const_matrix.template bottomRightCorner<r,c>()), (const_matrix.template bottomRightCorner<Dynamic,c>(r,c)));++ VERIFY_IS_EQUAL((const_matrix.template topRows<r>()), (const_matrix.template block<r,cols>(0,0)));+ VERIFY_IS_EQUAL((const_matrix.template middleRows<r>(sr)), (const_matrix.template block<r,cols>(sr,0)));+ VERIFY_IS_EQUAL((const_matrix.template bottomRows<r>()), (const_matrix.template block<r,cols>(rows-r,0)));+ VERIFY_IS_EQUAL((const_matrix.template leftCols<c>()), (const_matrix.template block<rows,c>(0,0)));+ VERIFY_IS_EQUAL((const_matrix.template middleCols<c>(sc)), (const_matrix.template block<rows,c>(0,sc)));+ VERIFY_IS_EQUAL((const_matrix.template rightCols<c>()), (const_matrix.template block<rows,c>(0,cols-c)));+}++void test_corners()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( corners(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( corners(Matrix4d()) );+ CALL_SUBTEST_3( corners(Matrix<int,10,12>()) );+ CALL_SUBTEST_4( corners(MatrixXcf(5, 7)) );+ CALL_SUBTEST_5( corners(MatrixXf(21, 20)) );++ CALL_SUBTEST_1(( corners_fixedsize<Matrix<float, 1, 1>, 1, 1, 0, 0>() ));+ CALL_SUBTEST_2(( corners_fixedsize<Matrix4d,2,2,1,1>() ));+ CALL_SUBTEST_3(( corners_fixedsize<Matrix<int,10,12>,4,7,5,2>() ));+ }+}
+ eigen3/test/cwiseop.cpp view
@@ -0,0 +1,184 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN2_SUPPORT+#define EIGEN_NO_EIGEN2_DEPRECATED_WARNING++#define EIGEN_NO_STATIC_ASSERT+#include "main.h"+#include <functional>++#ifdef min+#undef min+#endif++#ifdef max+#undef max+#endif++using namespace std;++template<typename Scalar> struct AddIfNull {+ const Scalar operator() (const Scalar a, const Scalar b) const {return a<=1e-3 ? b : a;}+ enum { Cost = NumTraits<Scalar>::AddCost };+};++template<typename MatrixType>+typename Eigen::internal::enable_if<!NumTraits<typename MatrixType::Scalar>::IsInteger,typename MatrixType::Scalar>::type+cwiseops_real_only(MatrixType& m1, MatrixType& m2, MatrixType& m3, MatrixType& mones)+{+ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ + VERIFY_IS_APPROX(m1.cwise() / m2, m1.cwise() * (m2.cwise().inverse()));+ m3 = m1.cwise().abs().cwise().sqrt();+ VERIFY_IS_APPROX(m3.cwise().square(), m1.cwise().abs());+ VERIFY_IS_APPROX(m1.cwise().square().cwise().sqrt(), m1.cwise().abs());+ VERIFY_IS_APPROX(m1.cwise().abs().cwise().log().cwise().exp() , m1.cwise().abs());++ VERIFY_IS_APPROX(m1.cwise().pow(2), m1.cwise().square());+ m3 = (m1.cwise().abs().cwise()<=RealScalar(0.01)).select(mones,m1);+ VERIFY_IS_APPROX(m3.cwise().pow(-1), m3.cwise().inverse());+ m3 = m1.cwise().abs();+ VERIFY_IS_APPROX(m3.cwise().pow(RealScalar(0.5)), m3.cwise().sqrt());++// VERIFY_IS_APPROX(m1.cwise().tan(), m1.cwise().sin().cwise() / m1.cwise().cos());+ VERIFY_IS_APPROX(mones, m1.cwise().sin().cwise().square() + m1.cwise().cos().cwise().square());+ m3 = m1;+ m3.cwise() /= m2;+ VERIFY_IS_APPROX(m3, m1.cwise() / m2);+ + return Scalar(0);+}++template<typename MatrixType>+typename Eigen::internal::enable_if<NumTraits<typename MatrixType::Scalar>::IsInteger,typename MatrixType::Scalar>::type+cwiseops_real_only(MatrixType& , MatrixType& , MatrixType& , MatrixType& )+{+ return 0;+}++template<typename MatrixType> void cwiseops(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m1bis = m1,+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols),+ m4(rows, cols),+ mzero = MatrixType::Zero(rows, cols),+ mones = MatrixType::Ones(rows, cols),+ identity = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>+ ::Identity(rows, rows);+ VectorType vzero = VectorType::Zero(rows),+ vones = VectorType::Ones(rows),+ v3(rows);++ Index r = internal::random<Index>(0, rows-1),+ c = internal::random<Index>(0, cols-1);++ Scalar s1 = internal::random<Scalar>();++ // test Zero, Ones, Constant, and the set* variants+ m3 = MatrixType::Constant(rows, cols, s1);+ for (int j=0; j<cols; ++j)+ for (int i=0; i<rows; ++i)+ {+ VERIFY_IS_APPROX(mzero(i,j), Scalar(0));+ VERIFY_IS_APPROX(mones(i,j), Scalar(1));+ VERIFY_IS_APPROX(m3(i,j), s1);+ }+ VERIFY(mzero.isZero());+ VERIFY(mones.isOnes());+ VERIFY(m3.isConstant(s1));+ VERIFY(identity.isIdentity());+ VERIFY_IS_APPROX(m4.setConstant(s1), m3);+ VERIFY_IS_APPROX(m4.setConstant(rows,cols,s1), m3);+ VERIFY_IS_APPROX(m4.setZero(), mzero);+ VERIFY_IS_APPROX(m4.setZero(rows,cols), mzero);+ VERIFY_IS_APPROX(m4.setOnes(), mones);+ VERIFY_IS_APPROX(m4.setOnes(rows,cols), mones);+ m4.fill(s1);+ VERIFY_IS_APPROX(m4, m3);++ VERIFY_IS_APPROX(v3.setConstant(rows, s1), VectorType::Constant(rows,s1));+ VERIFY_IS_APPROX(v3.setZero(rows), vzero);+ VERIFY_IS_APPROX(v3.setOnes(rows), vones);++ m2 = m2.template binaryExpr<AddIfNull<Scalar> >(mones);++ VERIFY_IS_APPROX(m1.cwise().pow(2), m1.cwise().abs2());+ VERIFY_IS_APPROX(m1.cwise().pow(2), m1.cwise().square());+ VERIFY_IS_APPROX(m1.cwise().pow(3), m1.cwise().cube());++ VERIFY_IS_APPROX(m1 + mones, m1.cwise()+Scalar(1));+ VERIFY_IS_APPROX(m1 - mones, m1.cwise()-Scalar(1));+ m3 = m1; m3.cwise() += 1;+ VERIFY_IS_APPROX(m1 + mones, m3);+ m3 = m1; m3.cwise() -= 1;+ VERIFY_IS_APPROX(m1 - mones, m3);++ VERIFY_IS_APPROX(m2, m2.cwise() * mones);+ VERIFY_IS_APPROX(m1.cwise() * m2, m2.cwise() * m1);+ m3 = m1;+ m3.cwise() *= m2;+ VERIFY_IS_APPROX(m3, m1.cwise() * m2);++ VERIFY_IS_APPROX(mones, m2.cwise()/m2);++ // check min+ VERIFY_IS_APPROX( m1.cwise().min(m2), m2.cwise().min(m1) );+ VERIFY_IS_APPROX( m1.cwise().min(m1+mones), m1 );+ VERIFY_IS_APPROX( m1.cwise().min(m1-mones), m1-mones );++ // check max+ VERIFY_IS_APPROX( m1.cwise().max(m2), m2.cwise().max(m1) );+ VERIFY_IS_APPROX( m1.cwise().max(m1-mones), m1 );+ VERIFY_IS_APPROX( m1.cwise().max(m1+mones), m1+mones );++ VERIFY( (m1.cwise() == m1).all() );+ VERIFY( (m1.cwise() != m2).any() );+ VERIFY(!(m1.cwise() == (m1+mones)).any() );+ if (rows*cols>1)+ {+ m3 = m1;+ m3(r,c) += 1;+ VERIFY( (m1.cwise() == m3).any() );+ VERIFY( !(m1.cwise() == m3).all() );+ }+ VERIFY( (m1.cwise().min(m2).cwise() <= m2).all() );+ VERIFY( (m1.cwise().max(m2).cwise() >= m2).all() );+ VERIFY( (m1.cwise().min(m2).cwise() < (m1+mones)).all() );+ VERIFY( (m1.cwise().max(m2).cwise() > (m1-mones)).all() );++ VERIFY( (m1.cwise()<m1.unaryExpr(bind2nd(plus<Scalar>(), Scalar(1)))).all() );+ VERIFY( !(m1.cwise()<m1bis.unaryExpr(bind2nd(minus<Scalar>(), Scalar(1)))).all() );+ VERIFY( !(m1.cwise()>m1bis.unaryExpr(bind2nd(plus<Scalar>(), Scalar(1)))).any() );+ + cwiseops_real_only(m1, m2, m3, mones);+}++void test_cwiseop()+{+ for(int i = 0; i < g_repeat ; i++) {+ CALL_SUBTEST_1( cwiseops(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( cwiseops(Matrix4d()) );+ CALL_SUBTEST_3( cwiseops(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_4( cwiseops(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_5( cwiseops(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_6( cwiseops(MatrixXd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ }+}
+ eigen3/test/denseLM.cpp view
@@ -0,0 +1,190 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Desire Nuentsa <desire.nuentsa_wakam@inria.fr>+// Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include <iostream>+#include <fstream>+#include <iomanip>++#include "main.h"+#include <Eigen/LevenbergMarquardt>+using namespace std;+using namespace Eigen;++template<typename Scalar>+struct DenseLM : DenseFunctor<Scalar>+{+ typedef DenseFunctor<Scalar> Base;+ typedef typename Base::JacobianType JacobianType;+ typedef Matrix<Scalar,Dynamic,1> VectorType;+ + DenseLM(int n, int m) : DenseFunctor<Scalar>(n,m) + { }+ + VectorType model(const VectorType& uv, VectorType& x)+ {+ VectorType y; // Should change to use expression template+ int m = Base::values(); + int n = Base::inputs();+ eigen_assert(uv.size()%2 == 0);+ eigen_assert(uv.size() == n);+ eigen_assert(x.size() == m);+ y.setZero(m);+ int half = n/2;+ VectorBlock<const VectorType> u(uv, 0, half);+ VectorBlock<const VectorType> v(uv, half, half);+ for (int j = 0; j < m; j++)+ {+ for (int i = 0; i < half; i++)+ y(j) += u(i)*std::exp(-(x(j)-i)*(x(j)-i)/(v(i)*v(i)));+ }+ return y;+ + }+ void initPoints(VectorType& uv_ref, VectorType& x)+ {+ m_x = x;+ m_y = this->model(uv_ref, x);+ }+ + int operator()(const VectorType& uv, VectorType& fvec)+ {+ + int m = Base::values(); + int n = Base::inputs();+ eigen_assert(uv.size()%2 == 0);+ eigen_assert(uv.size() == n);+ eigen_assert(fvec.size() == m);+ int half = n/2;+ VectorBlock<const VectorType> u(uv, 0, half);+ VectorBlock<const VectorType> v(uv, half, half);+ for (int j = 0; j < m; j++)+ {+ fvec(j) = m_y(j);+ for (int i = 0; i < half; i++)+ {+ fvec(j) -= u(i) *std::exp(-(m_x(j)-i)*(m_x(j)-i)/(v(i)*v(i)));+ }+ }+ + return 0;+ }+ int df(const VectorType& uv, JacobianType& fjac)+ {+ int m = Base::values(); + int n = Base::inputs();+ eigen_assert(n == uv.size());+ eigen_assert(fjac.rows() == m);+ eigen_assert(fjac.cols() == n);+ int half = n/2;+ VectorBlock<const VectorType> u(uv, 0, half);+ VectorBlock<const VectorType> v(uv, half, half);+ for (int j = 0; j < m; j++)+ {+ for (int i = 0; i < half; i++)+ {+ fjac.coeffRef(j,i) = -std::exp(-(m_x(j)-i)*(m_x(j)-i)/(v(i)*v(i)));+ fjac.coeffRef(j,i+half) = -2.*u(i)*(m_x(j)-i)*(m_x(j)-i)/(std::pow(v(i),3)) * std::exp(-(m_x(j)-i)*(m_x(j)-i)/(v(i)*v(i)));+ }+ }+ return 0;+ }+ VectorType m_x, m_y; //Data Points+};++template<typename FunctorType, typename VectorType>+int test_minimizeLM(FunctorType& functor, VectorType& uv)+{+ LevenbergMarquardt<FunctorType> lm(functor);+ LevenbergMarquardtSpace::Status info; + + info = lm.minimize(uv);+ + VERIFY_IS_EQUAL(info, 1);+ //FIXME Check other parameters+ return info;+}++template<typename FunctorType, typename VectorType>+int test_lmder(FunctorType& functor, VectorType& uv)+{+ typedef typename VectorType::Scalar Scalar;+ LevenbergMarquardtSpace::Status info; + LevenbergMarquardt<FunctorType> lm(functor);+ info = lm.lmder1(uv);+ + VERIFY_IS_EQUAL(info, 1);+ //FIXME Check other parameters+ return info;+}++template<typename FunctorType, typename VectorType>+int test_minimizeSteps(FunctorType& functor, VectorType& uv)+{+ LevenbergMarquardtSpace::Status info; + LevenbergMarquardt<FunctorType> lm(functor);+ info = lm.minimizeInit(uv);+ if (info==LevenbergMarquardtSpace::ImproperInputParameters)+ return info;+ do + {+ info = lm.minimizeOneStep(uv);+ } while (info==LevenbergMarquardtSpace::Running);+ + VERIFY_IS_EQUAL(info, 1);+ //FIXME Check other parameters+ return info;+}++template<typename T>+void test_denseLM_T()+{+ typedef Matrix<T,Dynamic,1> VectorType;+ + int inputs = 10; + int values = 1000; + DenseLM<T> dense_gaussian(inputs, values);+ VectorType uv(inputs),uv_ref(inputs);+ VectorType x(values);+ + // Generate the reference solution + uv_ref << -2, 1, 4 ,8, 6, 1.8, 1.2, 1.1, 1.9 , 3;+ + //Generate the reference data points+ x.setRandom();+ x = 10*x;+ x.array() += 10;+ dense_gaussian.initPoints(uv_ref, x);+ + // Generate the initial parameters + VectorBlock<VectorType> u(uv, 0, inputs/2); + VectorBlock<VectorType> v(uv, inputs/2, inputs/2);+ + // Solve the optimization problem+ + //Solve in one go+ u.setOnes(); v.setOnes();+ test_minimizeLM(dense_gaussian, uv);+ + //Solve until the machine precision+ u.setOnes(); v.setOnes();+ test_lmder(dense_gaussian, uv); + + // Solve step by step+ v.setOnes(); u.setOnes();+ test_minimizeSteps(dense_gaussian, uv);+ +}++void test_denseLM()+{+ CALL_SUBTEST_2(test_denseLM_T<double>());+ + // CALL_SUBTEST_2(test_sparseLM_T<std::complex<double>());+}
+ eigen3/test/determinant.cpp view
@@ -0,0 +1,67 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/LU>++template<typename MatrixType> void determinant(const MatrixType& m)+{+ /* this test covers the following files:+ Determinant.h+ */+ typedef typename MatrixType::Index Index;+ Index size = m.rows();++ MatrixType m1(size, size), m2(size, size);+ m1.setRandom();+ m2.setRandom();+ typedef typename MatrixType::Scalar Scalar;+ Scalar x = internal::random<Scalar>();+ VERIFY_IS_APPROX(MatrixType::Identity(size, size).determinant(), Scalar(1));+ VERIFY_IS_APPROX((m1*m2).eval().determinant(), m1.determinant() * m2.determinant());+ if(size==1) return;+ Index i = internal::random<Index>(0, size-1);+ Index j;+ do {+ j = internal::random<Index>(0, size-1);+ } while(j==i);+ m2 = m1;+ m2.row(i).swap(m2.row(j));+ VERIFY_IS_APPROX(m2.determinant(), -m1.determinant());+ m2 = m1;+ m2.col(i).swap(m2.col(j));+ VERIFY_IS_APPROX(m2.determinant(), -m1.determinant());+ VERIFY_IS_APPROX(m2.determinant(), m2.transpose().determinant());+ VERIFY_IS_APPROX(numext::conj(m2.determinant()), m2.adjoint().determinant());+ m2 = m1;+ m2.row(i) += x*m2.row(j);+ VERIFY_IS_APPROX(m2.determinant(), m1.determinant());+ m2 = m1;+ m2.row(i) *= x;+ VERIFY_IS_APPROX(m2.determinant(), m1.determinant() * x);+ + // check empty matrix+ VERIFY_IS_APPROX(m2.block(0,0,0,0).determinant(), Scalar(1));+}++void test_determinant()+{+ for(int i = 0; i < g_repeat; i++) {+ int s = 0;+ CALL_SUBTEST_1( determinant(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( determinant(Matrix<double, 2, 2>()) );+ CALL_SUBTEST_3( determinant(Matrix<double, 3, 3>()) );+ CALL_SUBTEST_4( determinant(Matrix<double, 4, 4>()) );+ CALL_SUBTEST_5( determinant(Matrix<std::complex<double>, 10, 10>()) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);+ CALL_SUBTEST_6( determinant(MatrixXd(s, s)) );+ TEST_SET_BUT_UNUSED_VARIABLE(s)+ }+}
+ eigen3/test/diagonal.cpp view
@@ -0,0 +1,77 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void diagonal(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;++ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols);++ //check diagonal()+ VERIFY_IS_APPROX(m1.diagonal(), m1.transpose().diagonal());+ m2.diagonal() = 2 * m1.diagonal();+ m2.diagonal()[0] *= 3;++ if (rows>2)+ {+ enum {+ N1 = MatrixType::RowsAtCompileTime>2 ? 2 : 0,+ N2 = MatrixType::RowsAtCompileTime>1 ? -1 : 0+ };++ // check sub/super diagonal+ if(MatrixType::SizeAtCompileTime!=Dynamic)+ {+ VERIFY(m1.template diagonal<N1>().RowsAtCompileTime == m1.diagonal(N1).size());+ VERIFY(m1.template diagonal<N2>().RowsAtCompileTime == m1.diagonal(N2).size());+ }++ m2.template diagonal<N1>() = 2 * m1.template diagonal<N1>();+ VERIFY_IS_APPROX(m2.template diagonal<N1>(), static_cast<Scalar>(2) * m1.diagonal(N1));+ m2.template diagonal<N1>()[0] *= 3;+ VERIFY_IS_APPROX(m2.template diagonal<N1>()[0], static_cast<Scalar>(6) * m1.template diagonal<N1>()[0]);+++ m2.template diagonal<N2>() = 2 * m1.template diagonal<N2>();+ m2.template diagonal<N2>()[0] *= 3;+ VERIFY_IS_APPROX(m2.template diagonal<N2>()[0], static_cast<Scalar>(6) * m1.template diagonal<N2>()[0]);++ m2.diagonal(N1) = 2 * m1.diagonal(N1);+ VERIFY_IS_APPROX(m2.template diagonal<N1>(), static_cast<Scalar>(2) * m1.diagonal(N1));+ m2.diagonal(N1)[0] *= 3;+ VERIFY_IS_APPROX(m2.diagonal(N1)[0], static_cast<Scalar>(6) * m1.diagonal(N1)[0]);++ m2.diagonal(N2) = 2 * m1.diagonal(N2);+ VERIFY_IS_APPROX(m2.template diagonal<N2>(), static_cast<Scalar>(2) * m1.diagonal(N2));+ m2.diagonal(N2)[0] *= 3;+ VERIFY_IS_APPROX(m2.diagonal(N2)[0], static_cast<Scalar>(6) * m1.diagonal(N2)[0]);+ }+}++void test_diagonal()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( diagonal(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_1( diagonal(Matrix<float, 4, 9>()) );+ CALL_SUBTEST_1( diagonal(Matrix<float, 7, 3>()) );+ CALL_SUBTEST_2( diagonal(Matrix4d()) );+ CALL_SUBTEST_2( diagonal(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_2( diagonal(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_2( diagonal(MatrixXcd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_1( diagonal(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_1( diagonal(Matrix<float,Dynamic,4>(3, 4)) );+ }+}
+ eigen3/test/diagonalmatrices.cpp view
@@ -0,0 +1,102 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+using namespace std;+template<typename MatrixType> void diagonalmatrices(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };+ typedef Matrix<Scalar, Rows, 1> VectorType;+ typedef Matrix<Scalar, 1, Cols> RowVectorType;+ typedef Matrix<Scalar, Rows, Rows> SquareMatrixType;+ typedef DiagonalMatrix<Scalar, Rows> LeftDiagonalMatrix;+ typedef DiagonalMatrix<Scalar, Cols> RightDiagonalMatrix;+ typedef Matrix<Scalar, Rows==Dynamic?Dynamic:2*Rows, Cols==Dynamic?Dynamic:2*Cols> BigMatrix;+ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols);+ VectorType v1 = VectorType::Random(rows),+ v2 = VectorType::Random(rows);+ RowVectorType rv1 = RowVectorType::Random(cols),+ rv2 = RowVectorType::Random(cols);+ LeftDiagonalMatrix ldm1(v1), ldm2(v2);+ RightDiagonalMatrix rdm1(rv1), rdm2(rv2);+ + Scalar s1 = internal::random<Scalar>();++ SquareMatrixType sq_m1 (v1.asDiagonal());+ VERIFY_IS_APPROX(sq_m1, v1.asDiagonal().toDenseMatrix());+ sq_m1 = v1.asDiagonal();+ VERIFY_IS_APPROX(sq_m1, v1.asDiagonal().toDenseMatrix());+ SquareMatrixType sq_m2 = v1.asDiagonal();+ VERIFY_IS_APPROX(sq_m1, sq_m2);+ + ldm1 = v1.asDiagonal();+ LeftDiagonalMatrix ldm3(v1);+ VERIFY_IS_APPROX(ldm1.diagonal(), ldm3.diagonal());+ LeftDiagonalMatrix ldm4 = v1.asDiagonal();+ VERIFY_IS_APPROX(ldm1.diagonal(), ldm4.diagonal());+ + sq_m1.block(0,0,rows,rows) = ldm1;+ VERIFY_IS_APPROX(sq_m1, ldm1.toDenseMatrix());+ sq_m1.transpose() = ldm1;+ VERIFY_IS_APPROX(sq_m1, ldm1.toDenseMatrix());+ + Index i = internal::random<Index>(0, rows-1);+ Index j = internal::random<Index>(0, cols-1);+ + VERIFY_IS_APPROX( ((ldm1 * m1)(i,j)) , ldm1.diagonal()(i) * m1(i,j) );+ VERIFY_IS_APPROX( ((ldm1 * (m1+m2))(i,j)) , ldm1.diagonal()(i) * (m1+m2)(i,j) );+ VERIFY_IS_APPROX( ((m1 * rdm1)(i,j)) , rdm1.diagonal()(j) * m1(i,j) );+ VERIFY_IS_APPROX( ((v1.asDiagonal() * m1)(i,j)) , v1(i) * m1(i,j) );+ VERIFY_IS_APPROX( ((m1 * rv1.asDiagonal())(i,j)) , rv1(j) * m1(i,j) );+ VERIFY_IS_APPROX( (((v1+v2).asDiagonal() * m1)(i,j)) , (v1+v2)(i) * m1(i,j) );+ VERIFY_IS_APPROX( (((v1+v2).asDiagonal() * (m1+m2))(i,j)) , (v1+v2)(i) * (m1+m2)(i,j) );+ VERIFY_IS_APPROX( ((m1 * (rv1+rv2).asDiagonal())(i,j)) , (rv1+rv2)(j) * m1(i,j) );+ VERIFY_IS_APPROX( (((m1+m2) * (rv1+rv2).asDiagonal())(i,j)) , (rv1+rv2)(j) * (m1+m2)(i,j) );++ BigMatrix big;+ big.setZero(2*rows, 2*cols);+ + big.block(i,j,rows,cols) = m1;+ big.block(i,j,rows,cols) = v1.asDiagonal() * big.block(i,j,rows,cols);+ + VERIFY_IS_APPROX((big.block(i,j,rows,cols)) , v1.asDiagonal() * m1 );+ + big.block(i,j,rows,cols) = m1;+ big.block(i,j,rows,cols) = big.block(i,j,rows,cols) * rv1.asDiagonal();+ VERIFY_IS_APPROX((big.block(i,j,rows,cols)) , m1 * rv1.asDiagonal() );+ + + // scalar multiple+ VERIFY_IS_APPROX(LeftDiagonalMatrix(ldm1*s1).diagonal(), ldm1.diagonal() * s1);+ VERIFY_IS_APPROX(LeftDiagonalMatrix(s1*ldm1).diagonal(), s1 * ldm1.diagonal());+ + VERIFY_IS_APPROX(m1 * (rdm1 * s1), (m1 * rdm1) * s1);+ VERIFY_IS_APPROX(m1 * (s1 * rdm1), (m1 * rdm1) * s1);+}++void test_diagonalmatrices()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( diagonalmatrices(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( diagonalmatrices(Matrix3f()) );+ CALL_SUBTEST_3( diagonalmatrices(Matrix<double,3,3,RowMajor>()) );+ CALL_SUBTEST_4( diagonalmatrices(Matrix4d()) );+ CALL_SUBTEST_5( diagonalmatrices(Matrix<float,4,4,RowMajor>()) );+ CALL_SUBTEST_6( diagonalmatrices(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_7( diagonalmatrices(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_8( diagonalmatrices(Matrix<double,Dynamic,Dynamic,RowMajor>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_9( diagonalmatrices(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ }+}
+ eigen3/test/dontalign.cpp view
@@ -0,0 +1,63 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#if defined EIGEN_TEST_PART_1 || defined EIGEN_TEST_PART_2 || defined EIGEN_TEST_PART_3 || defined EIGEN_TEST_PART_4+#define EIGEN_DONT_ALIGN+#elif defined EIGEN_TEST_PART_5 || defined EIGEN_TEST_PART_6 || defined EIGEN_TEST_PART_7 || defined EIGEN_TEST_PART_8+#define EIGEN_DONT_ALIGN_STATICALLY+#endif++#include "main.h"+#include <Eigen/Dense>++template<typename MatrixType>+void dontalign(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;++ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType a = MatrixType::Random(rows,cols);+ SquareMatrixType square = SquareMatrixType::Random(rows,rows);+ VectorType v = VectorType::Random(rows);++ VERIFY_IS_APPROX(v, square * square.colPivHouseholderQr().solve(v));+ square = square.inverse().eval();+ a = square * a;+ square = square*square;+ v = square * v;+ v = a.adjoint() * v;+ VERIFY(square.determinant() != Scalar(0));++ // bug 219: MapAligned() was giving an assert with EIGEN_DONT_ALIGN, because Map Flags were miscomputed+ Scalar* array = internal::aligned_new<Scalar>(rows);+ v = VectorType::MapAligned(array, rows);+ internal::aligned_delete(array, rows);+}++void test_dontalign()+{+#if defined EIGEN_TEST_PART_1 || defined EIGEN_TEST_PART_5+ dontalign(Matrix3d());+ dontalign(Matrix4f());+#elif defined EIGEN_TEST_PART_2 || defined EIGEN_TEST_PART_6+ dontalign(Matrix3cd());+ dontalign(Matrix4cf());+#elif defined EIGEN_TEST_PART_3 || defined EIGEN_TEST_PART_7+ dontalign(Matrix<float, 32, 32>());+ dontalign(Matrix<std::complex<float>, 32, 32>());+#elif defined EIGEN_TEST_PART_4 || defined EIGEN_TEST_PART_8+ dontalign(MatrixXd(32, 32));+ dontalign(MatrixXcf(32, 32));+#endif+}
+ eigen3/test/dynalloc.cpp view
@@ -0,0 +1,134 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++#if EIGEN_ALIGN+#define ALIGNMENT 16+#else+#define ALIGNMENT 1+#endif++void check_handmade_aligned_malloc()+{+ for(int i = 1; i < 1000; i++)+ {+ char *p = (char*)internal::handmade_aligned_malloc(i);+ VERIFY(size_t(p)%ALIGNMENT==0);+ // if the buffer is wrongly allocated this will give a bad write --> check with valgrind+ for(int j = 0; j < i; j++) p[j]=0;+ internal::handmade_aligned_free(p);+ }+}++void check_aligned_malloc()+{+ for(int i = 1; i < 1000; i++)+ {+ char *p = (char*)internal::aligned_malloc(i);+ VERIFY(size_t(p)%ALIGNMENT==0);+ // if the buffer is wrongly allocated this will give a bad write --> check with valgrind+ for(int j = 0; j < i; j++) p[j]=0;+ internal::aligned_free(p);+ }+}++void check_aligned_new()+{+ for(int i = 1; i < 1000; i++)+ {+ float *p = internal::aligned_new<float>(i);+ VERIFY(size_t(p)%ALIGNMENT==0);+ // if the buffer is wrongly allocated this will give a bad write --> check with valgrind+ for(int j = 0; j < i; j++) p[j]=0;+ internal::aligned_delete(p,i);+ }+}++void check_aligned_stack_alloc()+{+ for(int i = 1; i < 400; i++)+ {+ ei_declare_aligned_stack_constructed_variable(float,p,i,0);+ VERIFY(size_t(p)%ALIGNMENT==0);+ // if the buffer is wrongly allocated this will give a bad write --> check with valgrind+ for(int j = 0; j < i; j++) p[j]=0;+ }+}+++// test compilation with both a struct and a class...+struct MyStruct+{+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW+ char dummychar;+ Vector4f avec;+};++class MyClassA+{+ public:+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW+ char dummychar;+ Vector4f avec;+};++template<typename T> void check_dynaligned()+{+ T* obj = new T;+ VERIFY(T::NeedsToAlign==1);+ VERIFY(size_t(obj)%ALIGNMENT==0);+ delete obj;+}++void test_dynalloc()+{+ // low level dynamic memory allocation+ CALL_SUBTEST(check_handmade_aligned_malloc());+ CALL_SUBTEST(check_aligned_malloc());+ CALL_SUBTEST(check_aligned_new());+ CALL_SUBTEST(check_aligned_stack_alloc());++ for (int i=0; i<g_repeat*100; ++i)+ {+ CALL_SUBTEST(check_dynaligned<Vector4f>() );+ CALL_SUBTEST(check_dynaligned<Vector2d>() );+ CALL_SUBTEST(check_dynaligned<Matrix4f>() );+ CALL_SUBTEST(check_dynaligned<Vector4d>() );+ CALL_SUBTEST(check_dynaligned<Vector4i>() );+ }+ + // check static allocation, who knows ?+ #if EIGEN_ALIGN_STATICALLY+ {+ MyStruct foo0; VERIFY(size_t(foo0.avec.data())%ALIGNMENT==0);+ MyClassA fooA; VERIFY(size_t(fooA.avec.data())%ALIGNMENT==0);+ }+ + // dynamic allocation, single object+ for (int i=0; i<g_repeat*100; ++i)+ {+ MyStruct *foo0 = new MyStruct(); VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0);+ MyClassA *fooA = new MyClassA(); VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0);+ delete foo0;+ delete fooA;+ }++ // dynamic allocation, array+ const int N = 10;+ for (int i=0; i<g_repeat*100; ++i)+ {+ MyStruct *foo0 = new MyStruct[N]; VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0);+ MyClassA *fooA = new MyClassA[N]; VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0);+ delete[] foo0;+ delete[] fooA;+ }+ #endif+ +}
+ eigen3/test/eigen2/CMakeLists.txt view
@@ -0,0 +1,61 @@+add_custom_target(eigen2_buildtests)+add_custom_target(eigen2_check COMMAND "ctest -R eigen2")+add_dependencies(eigen2_check eigen2_buildtests)+add_dependencies(buildtests eigen2_buildtests)++add_definitions("-DEIGEN2_SUPPORT_STAGE10_FULL_EIGEN2_API")+add_definitions("-DEIGEN_NO_EIGEN2_DEPRECATED_WARNING")++ei_add_test(eigen2_meta)+ei_add_test(eigen2_sizeof)+ei_add_test(eigen2_dynalloc)+ei_add_test(eigen2_nomalloc)+#ei_add_test(eigen2_first_aligned)+ei_add_test(eigen2_mixingtypes)+#ei_add_test(eigen2_packetmath)+ei_add_test(eigen2_unalignedassert)+#ei_add_test(eigen2_vectorization_logic)+ei_add_test(eigen2_basicstuff)+ei_add_test(eigen2_linearstructure)+ei_add_test(eigen2_cwiseop)+ei_add_test(eigen2_sum)+ei_add_test(eigen2_product_small)+ei_add_test(eigen2_product_large ${EI_OFLAG})+ei_add_test(eigen2_adjoint)+ei_add_test(eigen2_submatrices)+ei_add_test(eigen2_miscmatrices)+ei_add_test(eigen2_commainitializer)+ei_add_test(eigen2_smallvectors)+ei_add_test(eigen2_map)+ei_add_test(eigen2_array)+ei_add_test(eigen2_triangular)+ei_add_test(eigen2_cholesky " " "${GSL_LIBRARIES}")+ei_add_test(eigen2_lu ${EI_OFLAG})+ei_add_test(eigen2_determinant ${EI_OFLAG})+ei_add_test(eigen2_inverse)+ei_add_test(eigen2_qr)+ei_add_test(eigen2_eigensolver " " "${GSL_LIBRARIES}")+ei_add_test(eigen2_svd)+ei_add_test(eigen2_geometry)+ei_add_test(eigen2_geometry_with_eigen2_prefix)+ei_add_test(eigen2_hyperplane)+ei_add_test(eigen2_parametrizedline)+ei_add_test(eigen2_alignedbox)+ei_add_test(eigen2_regression)+ei_add_test(eigen2_stdvector)+ei_add_test(eigen2_newstdvector)+if(QT4_FOUND)+ ei_add_test(eigen2_qtvector " " "${QT_QTCORE_LIBRARY}")+endif(QT4_FOUND)+# no support for eigen2 sparse module+# if(NOT EIGEN_DEFAULT_TO_ROW_MAJOR)+# ei_add_test(eigen2_sparse_vector)+# ei_add_test(eigen2_sparse_basic)+# ei_add_test(eigen2_sparse_solvers " " "${SPARSE_LIBS}")+# ei_add_test(eigen2_sparse_product)+# endif()+ei_add_test(eigen2_swap)+ei_add_test(eigen2_visitor)+ei_add_test(eigen2_bug_132)++ei_add_test(eigen2_prec_inverse_4x4 ${EI_OFLAG})
+ eigen3/test/eigen2/eigen2_adjoint.cpp view
@@ -0,0 +1,99 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void adjoint(const MatrixType& m)+{+ /* this test covers the following files:+ Transpose.h Conjugate.h Dot.h+ */++ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;+ int rows = m.rows();+ int cols = m.cols();++ RealScalar largerEps = test_precision<RealScalar>();+ if (ei_is_same_type<RealScalar,float>::ret)+ largerEps = RealScalar(1e-3f);++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols),+ square = SquareMatrixType::Random(rows, rows);+ VectorType v1 = VectorType::Random(rows),+ v2 = VectorType::Random(rows),+ v3 = VectorType::Random(rows),+ vzero = VectorType::Zero(rows);++ Scalar s1 = ei_random<Scalar>(),+ s2 = ei_random<Scalar>();++ // check basic compatibility of adjoint, transpose, conjugate+ VERIFY_IS_APPROX(m1.transpose().conjugate().adjoint(), m1);+ VERIFY_IS_APPROX(m1.adjoint().conjugate().transpose(), m1);++ // check multiplicative behavior+ VERIFY_IS_APPROX((m1.adjoint() * m2).adjoint(), m2.adjoint() * m1);+ VERIFY_IS_APPROX((s1 * m1).adjoint(), ei_conj(s1) * m1.adjoint());++ // check basic properties of dot, norm, norm2+ typedef typename NumTraits<Scalar>::Real RealScalar;+ VERIFY(ei_isApprox((s1 * v1 + s2 * v2).eigen2_dot(v3), s1 * v1.eigen2_dot(v3) + s2 * v2.eigen2_dot(v3), largerEps));+ VERIFY(ei_isApprox(v3.eigen2_dot(s1 * v1 + s2 * v2), ei_conj(s1)*v3.eigen2_dot(v1)+ei_conj(s2)*v3.eigen2_dot(v2), largerEps));+ VERIFY_IS_APPROX(ei_conj(v1.eigen2_dot(v2)), v2.eigen2_dot(v1));+ VERIFY_IS_APPROX(ei_real(v1.eigen2_dot(v1)), v1.squaredNorm());+ if(NumTraits<Scalar>::HasFloatingPoint)+ VERIFY_IS_APPROX(v1.squaredNorm(), v1.norm() * v1.norm());+ VERIFY_IS_MUCH_SMALLER_THAN(ei_abs(vzero.eigen2_dot(v1)), static_cast<RealScalar>(1));+ if(NumTraits<Scalar>::HasFloatingPoint)+ VERIFY_IS_MUCH_SMALLER_THAN(vzero.norm(), static_cast<RealScalar>(1));++ // check compatibility of dot and adjoint+ VERIFY(ei_isApprox(v1.eigen2_dot(square * v2), (square.adjoint() * v1).eigen2_dot(v2), largerEps));++ // like in testBasicStuff, test operator() to check const-qualification+ int r = ei_random<int>(0, rows-1),+ c = ei_random<int>(0, cols-1);+ VERIFY_IS_APPROX(m1.conjugate()(r,c), ei_conj(m1(r,c)));+ VERIFY_IS_APPROX(m1.adjoint()(c,r), ei_conj(m1(r,c)));++ if(NumTraits<Scalar>::HasFloatingPoint)+ {+ // check that Random().normalized() works: tricky as the random xpr must be evaluated by+ // normalized() in order to produce a consistent result.+ VERIFY_IS_APPROX(VectorType::Random(rows).normalized().norm(), RealScalar(1));+ }++ // check inplace transpose+ m3 = m1;+ m3.transposeInPlace();+ VERIFY_IS_APPROX(m3,m1.transpose());+ m3.transposeInPlace();+ VERIFY_IS_APPROX(m3,m1);+ +}++void test_eigen2_adjoint()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( adjoint(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( adjoint(Matrix3d()) );+ CALL_SUBTEST_3( adjoint(Matrix4f()) );+ CALL_SUBTEST_4( adjoint(MatrixXcf(4, 4)) );+ CALL_SUBTEST_5( adjoint(MatrixXi(8, 12)) );+ CALL_SUBTEST_6( adjoint(MatrixXf(21, 21)) );+ }+ // test a large matrix only once+ CALL_SUBTEST_7( adjoint(Matrix<float, 100, 100>()) );+}+
+ eigen3/test/eigen2/eigen2_alignedbox.cpp view
@@ -0,0 +1,60 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/Geometry>+#include <Eigen/LU>+#include <Eigen/QR>++template<typename BoxType> void alignedbox(const BoxType& _box)+{+ /* this test covers the following files:+ AlignedBox.h+ */++ const int dim = _box.dim();+ typedef typename BoxType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, BoxType::AmbientDimAtCompileTime, 1> VectorType;++ VectorType p0 = VectorType::Random(dim);+ VectorType p1 = VectorType::Random(dim);+ RealScalar s1 = ei_random<RealScalar>(0,1);++ BoxType b0(dim);+ BoxType b1(VectorType::Random(dim),VectorType::Random(dim));+ BoxType b2;++ b0.extend(p0);+ b0.extend(p1);+ VERIFY(b0.contains(p0*s1+(Scalar(1)-s1)*p1));+ VERIFY(!b0.contains(p0 + (1+s1)*(p1-p0)));++ (b2 = b0).extend(b1);+ VERIFY(b2.contains(b0));+ VERIFY(b2.contains(b1));+ VERIFY_IS_APPROX(b2.clamp(b0), b0);++ // casting+ const int Dim = BoxType::AmbientDimAtCompileTime;+ typedef typename GetDifferentType<Scalar>::type OtherScalar;+ AlignedBox<OtherScalar,Dim> hp1f = b0.template cast<OtherScalar>();+ VERIFY_IS_APPROX(hp1f.template cast<Scalar>(),b0);+ AlignedBox<Scalar,Dim> hp1d = b0.template cast<Scalar>();+ VERIFY_IS_APPROX(hp1d.template cast<Scalar>(),b0);+}++void test_eigen2_alignedbox()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( alignedbox(AlignedBox<float,2>()) );+ CALL_SUBTEST_2( alignedbox(AlignedBox<float,3>()) );+ CALL_SUBTEST_3( alignedbox(AlignedBox<double,4>()) );+ }+}
+ eigen3/test/eigen2/eigen2_array.cpp view
@@ -0,0 +1,142 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/Array>++template<typename MatrixType> void array(const MatrixType& m)+{+ /* this test covers the following files:+ Array.cpp+ */++ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ int rows = m.rows();+ int cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols);++ Scalar s1 = ei_random<Scalar>(),+ s2 = ei_random<Scalar>();++ // scalar addition+ VERIFY_IS_APPROX(m1.cwise() + s1, s1 + m1.cwise());+ VERIFY_IS_APPROX(m1.cwise() + s1, MatrixType::Constant(rows,cols,s1) + m1);+ VERIFY_IS_APPROX((m1*Scalar(2)).cwise() - s2, (m1+m1) - MatrixType::Constant(rows,cols,s2) );+ m3 = m1;+ m3.cwise() += s2;+ VERIFY_IS_APPROX(m3, m1.cwise() + s2);+ m3 = m1;+ m3.cwise() -= s1;+ VERIFY_IS_APPROX(m3, m1.cwise() - s1);++ // reductions+ VERIFY_IS_APPROX(m1.colwise().sum().sum(), m1.sum());+ VERIFY_IS_APPROX(m1.rowwise().sum().sum(), m1.sum());+ if (!ei_isApprox(m1.sum(), (m1+m2).sum()))+ VERIFY_IS_NOT_APPROX(((m1+m2).rowwise().sum()).sum(), m1.sum());+ VERIFY_IS_APPROX(m1.colwise().sum(), m1.colwise().redux(internal::scalar_sum_op<Scalar>()));+}++template<typename MatrixType> void comparisons(const MatrixType& m)+{+ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ int rows = m.rows();+ int cols = m.cols();++ int r = ei_random<int>(0, rows-1),+ c = ei_random<int>(0, cols-1);++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols);++ VERIFY(((m1.cwise() + Scalar(1)).cwise() > m1).all());+ VERIFY(((m1.cwise() - Scalar(1)).cwise() < m1).all());+ if (rows*cols>1)+ {+ m3 = m1;+ m3(r,c) += 1;+ VERIFY(! (m1.cwise() < m3).all() );+ VERIFY(! (m1.cwise() > m3).all() );+ }+ + // comparisons to scalar+ VERIFY( (m1.cwise() != (m1(r,c)+1) ).any() );+ VERIFY( (m1.cwise() > (m1(r,c)-1) ).any() );+ VERIFY( (m1.cwise() < (m1(r,c)+1) ).any() );+ VERIFY( (m1.cwise() == m1(r,c) ).any() );+ + // test Select+ VERIFY_IS_APPROX( (m1.cwise()<m2).select(m1,m2), m1.cwise().min(m2) );+ VERIFY_IS_APPROX( (m1.cwise()>m2).select(m1,m2), m1.cwise().max(m2) );+ Scalar mid = (m1.cwise().abs().minCoeff() + m1.cwise().abs().maxCoeff())/Scalar(2);+ for (int j=0; j<cols; ++j)+ for (int i=0; i<rows; ++i)+ m3(i,j) = ei_abs(m1(i,j))<mid ? 0 : m1(i,j);+ VERIFY_IS_APPROX( (m1.cwise().abs().cwise()<MatrixType::Constant(rows,cols,mid))+ .select(MatrixType::Zero(rows,cols),m1), m3);+ // shorter versions:+ VERIFY_IS_APPROX( (m1.cwise().abs().cwise()<MatrixType::Constant(rows,cols,mid))+ .select(0,m1), m3);+ VERIFY_IS_APPROX( (m1.cwise().abs().cwise()>=MatrixType::Constant(rows,cols,mid))+ .select(m1,0), m3);+ // even shorter version:+ VERIFY_IS_APPROX( (m1.cwise().abs().cwise()<mid).select(0,m1), m3);+ + // count+ VERIFY(((m1.cwise().abs().cwise()+1).cwise()>RealScalar(0.1)).count() == rows*cols);+ VERIFY_IS_APPROX(((m1.cwise().abs().cwise()+1).cwise()>RealScalar(0.1)).colwise().count().template cast<int>(), RowVectorXi::Constant(cols,rows));+ VERIFY_IS_APPROX(((m1.cwise().abs().cwise()+1).cwise()>RealScalar(0.1)).rowwise().count().template cast<int>(), VectorXi::Constant(rows, cols));+}++template<typename VectorType> void lpNorm(const VectorType& v)+{+ VectorType u = VectorType::Random(v.size());++ VERIFY_IS_APPROX(u.template lpNorm<Infinity>(), u.cwise().abs().maxCoeff());+ VERIFY_IS_APPROX(u.template lpNorm<1>(), u.cwise().abs().sum());+ VERIFY_IS_APPROX(u.template lpNorm<2>(), ei_sqrt(u.cwise().abs().cwise().square().sum()));+ VERIFY_IS_APPROX(ei_pow(u.template lpNorm<5>(), typename VectorType::RealScalar(5)), u.cwise().abs().cwise().pow(5).sum());+}++void test_eigen2_array()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( array(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( array(Matrix2f()) );+ CALL_SUBTEST_3( array(Matrix4d()) );+ CALL_SUBTEST_4( array(MatrixXcf(3, 3)) );+ CALL_SUBTEST_5( array(MatrixXf(8, 12)) );+ CALL_SUBTEST_6( array(MatrixXi(8, 12)) );+ }+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( comparisons(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( comparisons(Matrix2f()) );+ CALL_SUBTEST_3( comparisons(Matrix4d()) );+ CALL_SUBTEST_5( comparisons(MatrixXf(8, 12)) );+ CALL_SUBTEST_6( comparisons(MatrixXi(8, 12)) );+ }+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( lpNorm(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( lpNorm(Vector2f()) );+ CALL_SUBTEST_3( lpNorm(Vector3d()) );+ CALL_SUBTEST_4( lpNorm(Vector4f()) );+ CALL_SUBTEST_5( lpNorm(VectorXf(16)) );+ CALL_SUBTEST_7( lpNorm(VectorXcd(10)) );+ }+}
+ eigen3/test/eigen2/eigen2_basicstuff.cpp view
@@ -0,0 +1,105 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void basicStuff(const MatrixType& m)+{+ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ int rows = m.rows();+ int cols = m.cols();++ // this test relies a lot on Random.h, and there's not much more that we can do+ // to test it, hence I consider that we will have tested Random.h+ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols),+ mzero = MatrixType::Zero(rows, cols),+ square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>::Random(rows, rows);+ VectorType v1 = VectorType::Random(rows),+ vzero = VectorType::Zero(rows);++ Scalar x = ei_random<Scalar>();++ int r = ei_random<int>(0, rows-1),+ c = ei_random<int>(0, cols-1);++ m1.coeffRef(r,c) = x;+ VERIFY_IS_APPROX(x, m1.coeff(r,c));+ m1(r,c) = x;+ VERIFY_IS_APPROX(x, m1(r,c));+ v1.coeffRef(r) = x;+ VERIFY_IS_APPROX(x, v1.coeff(r));+ v1(r) = x;+ VERIFY_IS_APPROX(x, v1(r));+ v1[r] = x;+ VERIFY_IS_APPROX(x, v1[r]);++ VERIFY_IS_APPROX( v1, v1);+ VERIFY_IS_NOT_APPROX( v1, 2*v1);+ VERIFY_IS_MUCH_SMALLER_THAN( vzero, v1);+ if(NumTraits<Scalar>::HasFloatingPoint)+ VERIFY_IS_MUCH_SMALLER_THAN( vzero, v1.norm());+ VERIFY_IS_NOT_MUCH_SMALLER_THAN(v1, v1);+ VERIFY_IS_APPROX( vzero, v1-v1);+ VERIFY_IS_APPROX( m1, m1);+ VERIFY_IS_NOT_APPROX( m1, 2*m1);+ VERIFY_IS_MUCH_SMALLER_THAN( mzero, m1);+ VERIFY_IS_NOT_MUCH_SMALLER_THAN(m1, m1);+ VERIFY_IS_APPROX( mzero, m1-m1);++ // always test operator() on each read-only expression class,+ // in order to check const-qualifiers.+ // indeed, if an expression class (here Zero) is meant to be read-only,+ // hence has no _write() method, the corresponding MatrixBase method (here zero())+ // should return a const-qualified object so that it is the const-qualified+ // operator() that gets called, which in turn calls _read().+ VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::Zero(rows,cols)(r,c), static_cast<Scalar>(1));++ // now test copying a row-vector into a (column-)vector and conversely.+ square.col(r) = square.row(r).eval();+ Matrix<Scalar, 1, MatrixType::RowsAtCompileTime> rv(rows);+ Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> cv(rows);+ rv = square.row(r);+ cv = square.col(r);+ VERIFY_IS_APPROX(rv, cv.transpose());++ if(cols!=1 && rows!=1 && MatrixType::SizeAtCompileTime!=Dynamic)+ {+ VERIFY_RAISES_ASSERT(m1 = (m2.block(0,0, rows-1, cols-1)));+ }++ VERIFY_IS_APPROX(m3 = m1,m1);+ MatrixType m4;+ VERIFY_IS_APPROX(m4 = m1,m1);++ // test swap+ m3 = m1;+ m1.swap(m2);+ VERIFY_IS_APPROX(m3, m2);+ if(rows*cols>=3)+ {+ VERIFY_IS_NOT_APPROX(m3, m1);+ }+}++void test_eigen2_basicstuff()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( basicStuff(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( basicStuff(Matrix4d()) );+ CALL_SUBTEST_3( basicStuff(MatrixXcf(3, 3)) );+ CALL_SUBTEST_4( basicStuff(MatrixXi(8, 12)) );+ CALL_SUBTEST_5( basicStuff(MatrixXcd(20, 20)) );+ CALL_SUBTEST_6( basicStuff(Matrix<float, 100, 100>()) );+ CALL_SUBTEST_7( basicStuff(Matrix<long double,Dynamic,Dynamic>(10,10)) );+ }+}
+ eigen3/test/eigen2/eigen2_bug_132.cpp view
@@ -0,0 +1,26 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++void test_eigen2_bug_132() {+ int size = 100;+ MatrixXd A(size, size);+ VectorXd b(size), c(size);+ {+ VectorXd y = A.transpose() * (b-c); // bug 132: infinite recursion in coeffRef+ VectorXd z = (b-c).transpose() * A; // bug 132: infinite recursion in coeffRef+ }++ // the following ones weren't failing, but let's include them for completeness:+ {+ VectorXd y = A * (b-c);+ VectorXd z = (b-c).transpose() * A.transpose();+ }+}
+ eigen3/test/eigen2/eigen2_cholesky.cpp view
@@ -0,0 +1,113 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN_NO_ASSERTION_CHECKING+#include "main.h"+#include <Eigen/Cholesky>+#include <Eigen/LU>++#ifdef HAS_GSL+#include "gsl_helper.h"+#endif++template<typename MatrixType> void cholesky(const MatrixType& m)+{+ /* this test covers the following files:+ LLT.h LDLT.h+ */+ int rows = m.rows();+ int cols = m.cols();++ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ MatrixType a0 = MatrixType::Random(rows,cols);+ VectorType vecB = VectorType::Random(rows), vecX(rows);+ MatrixType matB = MatrixType::Random(rows,cols), matX(rows,cols);+ SquareMatrixType symm = a0 * a0.adjoint();+ // let's make sure the matrix is not singular or near singular+ MatrixType a1 = MatrixType::Random(rows,cols);+ symm += a1 * a1.adjoint();++ #ifdef HAS_GSL+ if (ei_is_same_type<RealScalar,double>::ret)+ {+ typedef GslTraits<Scalar> Gsl;+ typename Gsl::Matrix gMatA=0, gSymm=0;+ typename Gsl::Vector gVecB=0, gVecX=0;+ convert<MatrixType>(symm, gSymm);+ convert<MatrixType>(symm, gMatA);+ convert<VectorType>(vecB, gVecB);+ convert<VectorType>(vecB, gVecX);+ Gsl::cholesky(gMatA);+ Gsl::cholesky_solve(gMatA, gVecB, gVecX);+ VectorType vecX(rows), _vecX, _vecB;+ convert(gVecX, _vecX);+ symm.llt().solve(vecB, &vecX);+ Gsl::prod(gSymm, gVecX, gVecB);+ convert(gVecB, _vecB);+ // test gsl itself !+ VERIFY_IS_APPROX(vecB, _vecB);+ VERIFY_IS_APPROX(vecX, _vecX);++ Gsl::free(gMatA);+ Gsl::free(gSymm);+ Gsl::free(gVecB);+ Gsl::free(gVecX);+ }+ #endif++ {+ LDLT<SquareMatrixType> ldlt(symm);+ VERIFY(ldlt.isPositiveDefinite());+ // in eigen3, LDLT is pivoting+ //VERIFY_IS_APPROX(symm, ldlt.matrixL() * ldlt.vectorD().asDiagonal() * ldlt.matrixL().adjoint());+ ldlt.solve(vecB, &vecX);+ VERIFY_IS_APPROX(symm * vecX, vecB);+ ldlt.solve(matB, &matX);+ VERIFY_IS_APPROX(symm * matX, matB);+ }++ {+ LLT<SquareMatrixType> chol(symm);+ VERIFY(chol.isPositiveDefinite());+ VERIFY_IS_APPROX(symm, chol.matrixL() * chol.matrixL().adjoint());+ chol.solve(vecB, &vecX);+ VERIFY_IS_APPROX(symm * vecX, vecB);+ chol.solve(matB, &matX);+ VERIFY_IS_APPROX(symm * matX, matB);+ }++#if 0 // cholesky is not rank-revealing anyway+ // test isPositiveDefinite on non definite matrix+ if (rows>4)+ {+ SquareMatrixType symm = a0.block(0,0,rows,cols-4) * a0.block(0,0,rows,cols-4).adjoint();+ LLT<SquareMatrixType> chol(symm);+ VERIFY(!chol.isPositiveDefinite());+ LDLT<SquareMatrixType> cholnosqrt(symm);+ VERIFY(!cholnosqrt.isPositiveDefinite());+ }+#endif+}++void test_eigen2_cholesky()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( cholesky(Matrix<double,1,1>()) );+ CALL_SUBTEST_2( cholesky(Matrix2d()) );+ CALL_SUBTEST_3( cholesky(Matrix3f()) );+ CALL_SUBTEST_4( cholesky(Matrix4d()) );+ CALL_SUBTEST_5( cholesky(MatrixXcd(7,7)) );+ CALL_SUBTEST_6( cholesky(MatrixXf(17,17)) );+ CALL_SUBTEST_7( cholesky(MatrixXd(33,33)) );+ }+}
+ eigen3/test/eigen2/eigen2_commainitializer.cpp view
@@ -0,0 +1,46 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++void test_eigen2_commainitializer()+{+ Matrix3d m3;+ Matrix4d m4;++ VERIFY_RAISES_ASSERT( (m3 << 1, 2, 3, 4, 5, 6, 7, 8) );+ + #ifndef _MSC_VER+ VERIFY_RAISES_ASSERT( (m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9, 10) );+ #endif++ double data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};+ Matrix3d ref = Map<Matrix<double,3,3,RowMajor> >(data);++ m3 = Matrix3d::Random();+ m3 << 1, 2, 3, 4, 5, 6, 7, 8, 9;+ VERIFY_IS_APPROX(m3, ref );++ Vector3d vec[3];+ vec[0] << 1, 4, 7;+ vec[1] << 2, 5, 8;+ vec[2] << 3, 6, 9;+ m3 = Matrix3d::Random();+ m3 << vec[0], vec[1], vec[2];+ VERIFY_IS_APPROX(m3, ref);++ vec[0] << 1, 2, 3;+ vec[1] << 4, 5, 6;+ vec[2] << 7, 8, 9;+ m3 = Matrix3d::Random();+ m3 << vec[0].transpose(),+ 4, 5, 6,+ vec[2].transpose();+ VERIFY_IS_APPROX(m3, ref);+}
+ eigen3/test/eigen2/eigen2_cwiseop.cpp view
@@ -0,0 +1,155 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <functional>+#include <Eigen/Array>++using namespace std;++template<typename Scalar> struct AddIfNull {+ const Scalar operator() (const Scalar a, const Scalar b) const {return a<=1e-3 ? b : a;}+ enum { Cost = NumTraits<Scalar>::AddCost };+};++template<typename MatrixType> void cwiseops(const MatrixType& m)+{+ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ int rows = m.rows();+ int cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols),+ m4(rows, cols),+ mzero = MatrixType::Zero(rows, cols),+ mones = MatrixType::Ones(rows, cols),+ identity = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>+ ::Identity(rows, rows);+ VectorType vzero = VectorType::Zero(rows),+ vones = VectorType::Ones(rows),+ v3(rows);++ int r = ei_random<int>(0, rows-1),+ c = ei_random<int>(0, cols-1);+ + Scalar s1 = ei_random<Scalar>();+ + // test Zero, Ones, Constant, and the set* variants+ m3 = MatrixType::Constant(rows, cols, s1);+ for (int j=0; j<cols; ++j)+ for (int i=0; i<rows; ++i)+ {+ VERIFY_IS_APPROX(mzero(i,j), Scalar(0));+ VERIFY_IS_APPROX(mones(i,j), Scalar(1));+ VERIFY_IS_APPROX(m3(i,j), s1);+ }+ VERIFY(mzero.isZero());+ VERIFY(mones.isOnes());+ VERIFY(m3.isConstant(s1));+ VERIFY(identity.isIdentity());+ VERIFY_IS_APPROX(m4.setConstant(s1), m3);+ VERIFY_IS_APPROX(m4.setConstant(rows,cols,s1), m3);+ VERIFY_IS_APPROX(m4.setZero(), mzero);+ VERIFY_IS_APPROX(m4.setZero(rows,cols), mzero);+ VERIFY_IS_APPROX(m4.setOnes(), mones);+ VERIFY_IS_APPROX(m4.setOnes(rows,cols), mones);+ m4.fill(s1);+ VERIFY_IS_APPROX(m4, m3);+ + VERIFY_IS_APPROX(v3.setConstant(rows, s1), VectorType::Constant(rows,s1));+ VERIFY_IS_APPROX(v3.setZero(rows), vzero);+ VERIFY_IS_APPROX(v3.setOnes(rows), vones);++ m2 = m2.template binaryExpr<AddIfNull<Scalar> >(mones);++ VERIFY_IS_APPROX(m1.cwise().pow(2), m1.cwise().abs2());+ VERIFY_IS_APPROX(m1.cwise().pow(2), m1.cwise().square());+ VERIFY_IS_APPROX(m1.cwise().pow(3), m1.cwise().cube());++ VERIFY_IS_APPROX(m1 + mones, m1.cwise()+Scalar(1));+ VERIFY_IS_APPROX(m1 - mones, m1.cwise()-Scalar(1));+ m3 = m1; m3.cwise() += 1;+ VERIFY_IS_APPROX(m1 + mones, m3);+ m3 = m1; m3.cwise() -= 1;+ VERIFY_IS_APPROX(m1 - mones, m3);++ VERIFY_IS_APPROX(m2, m2.cwise() * mones);+ VERIFY_IS_APPROX(m1.cwise() * m2, m2.cwise() * m1);+ m3 = m1;+ m3.cwise() *= m2;+ VERIFY_IS_APPROX(m3, m1.cwise() * m2);+ + VERIFY_IS_APPROX(mones, m2.cwise()/m2);+ if(NumTraits<Scalar>::HasFloatingPoint)+ {+ VERIFY_IS_APPROX(m1.cwise() / m2, m1.cwise() * (m2.cwise().inverse()));+ m3 = m1.cwise().abs().cwise().sqrt();+ VERIFY_IS_APPROX(m3.cwise().square(), m1.cwise().abs());+ VERIFY_IS_APPROX(m1.cwise().square().cwise().sqrt(), m1.cwise().abs());+ VERIFY_IS_APPROX(m1.cwise().abs().cwise().log().cwise().exp() , m1.cwise().abs());++ VERIFY_IS_APPROX(m1.cwise().pow(2), m1.cwise().square());+ m3 = (m1.cwise().abs().cwise()<=RealScalar(0.01)).select(mones,m1);+ VERIFY_IS_APPROX(m3.cwise().pow(-1), m3.cwise().inverse());+ m3 = m1.cwise().abs();+ VERIFY_IS_APPROX(m3.cwise().pow(RealScalar(0.5)), m3.cwise().sqrt());+ +// VERIFY_IS_APPROX(m1.cwise().tan(), m1.cwise().sin().cwise() / m1.cwise().cos());+ VERIFY_IS_APPROX(mones, m1.cwise().sin().cwise().square() + m1.cwise().cos().cwise().square());+ m3 = m1;+ m3.cwise() /= m2;+ VERIFY_IS_APPROX(m3, m1.cwise() / m2);+ }++ // check min+ VERIFY_IS_APPROX( m1.cwise().min(m2), m2.cwise().min(m1) );+ VERIFY_IS_APPROX( m1.cwise().min(m1+mones), m1 );+ VERIFY_IS_APPROX( m1.cwise().min(m1-mones), m1-mones );++ // check max+ VERIFY_IS_APPROX( m1.cwise().max(m2), m2.cwise().max(m1) );+ VERIFY_IS_APPROX( m1.cwise().max(m1-mones), m1 );+ VERIFY_IS_APPROX( m1.cwise().max(m1+mones), m1+mones );+ + VERIFY( (m1.cwise() == m1).all() );+ VERIFY( (m1.cwise() != m2).any() );+ VERIFY(!(m1.cwise() == (m1+mones)).any() );+ if (rows*cols>1)+ {+ m3 = m1;+ m3(r,c) += 1;+ VERIFY( (m1.cwise() == m3).any() );+ VERIFY( !(m1.cwise() == m3).all() );+ }+ VERIFY( (m1.cwise().min(m2).cwise() <= m2).all() );+ VERIFY( (m1.cwise().max(m2).cwise() >= m2).all() );+ VERIFY( (m1.cwise().min(m2).cwise() < (m1+mones)).all() );+ VERIFY( (m1.cwise().max(m2).cwise() > (m1-mones)).all() );++ VERIFY( (m1.cwise()<m1.unaryExpr(bind2nd(plus<Scalar>(), Scalar(1)))).all() );+ VERIFY( !(m1.cwise()<m1.unaryExpr(bind2nd(minus<Scalar>(), Scalar(1)))).all() );+ VERIFY( !(m1.cwise()>m1.unaryExpr(bind2nd(plus<Scalar>(), Scalar(1)))).any() );+}++void test_eigen2_cwiseop()+{+ for(int i = 0; i < g_repeat ; i++) {+ CALL_SUBTEST_1( cwiseops(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( cwiseops(Matrix4d()) );+ CALL_SUBTEST_3( cwiseops(MatrixXf(3, 3)) );+ CALL_SUBTEST_3( cwiseops(MatrixXf(22, 22)) );+ CALL_SUBTEST_4( cwiseops(MatrixXi(8, 12)) );+ CALL_SUBTEST_5( cwiseops(MatrixXd(20, 20)) );+ }+}
+ eigen3/test/eigen2/eigen2_determinant.cpp view
@@ -0,0 +1,61 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/LU>++template<typename MatrixType> void determinant(const MatrixType& m)+{+ /* this test covers the following files:+ Determinant.h+ */+ int size = m.rows();++ MatrixType m1(size, size), m2(size, size);+ m1.setRandom();+ m2.setRandom();+ typedef typename MatrixType::Scalar Scalar;+ Scalar x = ei_random<Scalar>();+ VERIFY_IS_APPROX(MatrixType::Identity(size, size).determinant(), Scalar(1));+ VERIFY_IS_APPROX((m1*m2).determinant(), m1.determinant() * m2.determinant());+ if(size==1) return;+ int i = ei_random<int>(0, size-1);+ int j;+ do {+ j = ei_random<int>(0, size-1);+ } while(j==i);+ m2 = m1;+ m2.row(i).swap(m2.row(j));+ VERIFY_IS_APPROX(m2.determinant(), -m1.determinant());+ m2 = m1;+ m2.col(i).swap(m2.col(j));+ VERIFY_IS_APPROX(m2.determinant(), -m1.determinant());+ VERIFY_IS_APPROX(m2.determinant(), m2.transpose().determinant());+ VERIFY_IS_APPROX(ei_conj(m2.determinant()), m2.adjoint().determinant());+ m2 = m1;+ m2.row(i) += x*m2.row(j);+ VERIFY_IS_APPROX(m2.determinant(), m1.determinant());+ m2 = m1;+ m2.row(i) *= x;+ VERIFY_IS_APPROX(m2.determinant(), m1.determinant() * x);+}++void test_eigen2_determinant()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( determinant(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( determinant(Matrix<double, 2, 2>()) );+ CALL_SUBTEST_3( determinant(Matrix<double, 3, 3>()) );+ CALL_SUBTEST_4( determinant(Matrix<double, 4, 4>()) );+ CALL_SUBTEST_5( determinant(Matrix<std::complex<double>, 10, 10>()) );+ CALL_SUBTEST_6( determinant(MatrixXd(20, 20)) );+ }+ CALL_SUBTEST_6( determinant(MatrixXd(200, 200)) );+}
+ eigen3/test/eigen2/eigen2_dynalloc.cpp view
@@ -0,0 +1,131 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++#if EIGEN_ARCH_WANTS_ALIGNMENT+#define ALIGNMENT 16+#else+#define ALIGNMENT 1+#endif++void check_handmade_aligned_malloc()+{+ for(int i = 1; i < 1000; i++)+ {+ char *p = (char*)ei_handmade_aligned_malloc(i);+ VERIFY(std::size_t(p)%ALIGNMENT==0);+ // if the buffer is wrongly allocated this will give a bad write --> check with valgrind+ for(int j = 0; j < i; j++) p[j]=0;+ ei_handmade_aligned_free(p);+ }+}++void check_aligned_malloc()+{+ for(int i = 1; i < 1000; i++)+ {+ char *p = (char*)ei_aligned_malloc(i);+ VERIFY(std::size_t(p)%ALIGNMENT==0);+ // if the buffer is wrongly allocated this will give a bad write --> check with valgrind+ for(int j = 0; j < i; j++) p[j]=0;+ ei_aligned_free(p);+ }+}++void check_aligned_new()+{+ for(int i = 1; i < 1000; i++)+ {+ float *p = ei_aligned_new<float>(i);+ VERIFY(std::size_t(p)%ALIGNMENT==0);+ // if the buffer is wrongly allocated this will give a bad write --> check with valgrind+ for(int j = 0; j < i; j++) p[j]=0;+ ei_aligned_delete(p,i);+ }+}++void check_aligned_stack_alloc()+{+ for(int i = 1; i < 1000; i++)+ {+ ei_declare_aligned_stack_constructed_variable(float, p, i, 0);+ VERIFY(std::size_t(p)%ALIGNMENT==0);+ // if the buffer is wrongly allocated this will give a bad write --> check with valgrind+ for(int j = 0; j < i; j++) p[j]=0;+ }+}+++// test compilation with both a struct and a class...+struct MyStruct+{+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW+ char dummychar;+ Vector4f avec;+};++class MyClassA+{+ public:+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW+ char dummychar;+ Vector4f avec;+};++template<typename T> void check_dynaligned()+{+ T* obj = new T;+ VERIFY(std::size_t(obj)%ALIGNMENT==0);+ delete obj;+}++void test_eigen2_dynalloc()+{+ // low level dynamic memory allocation+ CALL_SUBTEST(check_handmade_aligned_malloc());+ CALL_SUBTEST(check_aligned_malloc());+ CALL_SUBTEST(check_aligned_new());+ CALL_SUBTEST(check_aligned_stack_alloc());++ for (int i=0; i<g_repeat*100; ++i)+ {+ CALL_SUBTEST( check_dynaligned<Vector4f>() );+ CALL_SUBTEST( check_dynaligned<Vector2d>() );+ CALL_SUBTEST( check_dynaligned<Matrix4f>() );+ CALL_SUBTEST( check_dynaligned<Vector4d>() );+ CALL_SUBTEST( check_dynaligned<Vector4i>() );+ }+ + // check static allocation, who knows ?+ {+ MyStruct foo0; VERIFY(std::size_t(foo0.avec.data())%ALIGNMENT==0);+ MyClassA fooA; VERIFY(std::size_t(fooA.avec.data())%ALIGNMENT==0);+ }++ // dynamic allocation, single object+ for (int i=0; i<g_repeat*100; ++i)+ {+ MyStruct *foo0 = new MyStruct(); VERIFY(std::size_t(foo0->avec.data())%ALIGNMENT==0);+ MyClassA *fooA = new MyClassA(); VERIFY(std::size_t(fooA->avec.data())%ALIGNMENT==0);+ delete foo0;+ delete fooA;+ }++ // dynamic allocation, array+ const int N = 10;+ for (int i=0; i<g_repeat*100; ++i)+ {+ MyStruct *foo0 = new MyStruct[N]; VERIFY(std::size_t(foo0->avec.data())%ALIGNMENT==0);+ MyClassA *fooA = new MyClassA[N]; VERIFY(std::size_t(fooA->avec.data())%ALIGNMENT==0);+ delete[] foo0;+ delete[] fooA;+ }+ +}
+ eigen3/test/eigen2/eigen2_eigensolver.cpp view
@@ -0,0 +1,146 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/QR>++#ifdef HAS_GSL+#include "gsl_helper.h"+#endif++template<typename MatrixType> void selfadjointeigensolver(const MatrixType& m)+{+ /* this test covers the following files:+ EigenSolver.h, SelfAdjointEigenSolver.h (and indirectly: Tridiagonalization.h)+ */+ int rows = m.rows();+ int cols = m.cols();++ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;+ typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, 1> RealVectorType;+ typedef typename std::complex<typename NumTraits<typename MatrixType::Scalar>::Real> Complex;++ RealScalar largerEps = 10*test_precision<RealScalar>();++ MatrixType a = MatrixType::Random(rows,cols);+ MatrixType a1 = MatrixType::Random(rows,cols);+ MatrixType symmA = a.adjoint() * a + a1.adjoint() * a1;++ MatrixType b = MatrixType::Random(rows,cols);+ MatrixType b1 = MatrixType::Random(rows,cols);+ MatrixType symmB = b.adjoint() * b + b1.adjoint() * b1;++ SelfAdjointEigenSolver<MatrixType> eiSymm(symmA);+ // generalized eigen pb+ SelfAdjointEigenSolver<MatrixType> eiSymmGen(symmA, symmB);++ #ifdef HAS_GSL+ if (ei_is_same_type<RealScalar,double>::ret)+ {+ typedef GslTraits<Scalar> Gsl;+ typename Gsl::Matrix gEvec=0, gSymmA=0, gSymmB=0;+ typename GslTraits<RealScalar>::Vector gEval=0;+ RealVectorType _eval;+ MatrixType _evec;+ convert<MatrixType>(symmA, gSymmA);+ convert<MatrixType>(symmB, gSymmB);+ convert<MatrixType>(symmA, gEvec);+ gEval = GslTraits<RealScalar>::createVector(rows);++ Gsl::eigen_symm(gSymmA, gEval, gEvec);+ convert(gEval, _eval);+ convert(gEvec, _evec);++ // test gsl itself !+ VERIFY((symmA * _evec).isApprox(_evec * _eval.asDiagonal(), largerEps));++ // compare with eigen+ VERIFY_IS_APPROX(_eval, eiSymm.eigenvalues());+ VERIFY_IS_APPROX(_evec.cwise().abs(), eiSymm.eigenvectors().cwise().abs());++ // generalized pb+ Gsl::eigen_symm_gen(gSymmA, gSymmB, gEval, gEvec);+ convert(gEval, _eval);+ convert(gEvec, _evec);+ // test GSL itself:+ VERIFY((symmA * _evec).isApprox(symmB * (_evec * _eval.asDiagonal()), largerEps));++ // compare with eigen+ MatrixType normalized_eivec = eiSymmGen.eigenvectors()*eiSymmGen.eigenvectors().colwise().norm().asDiagonal().inverse();+ VERIFY_IS_APPROX(_eval, eiSymmGen.eigenvalues());+ VERIFY_IS_APPROX(_evec.cwiseAbs(), normalized_eivec.cwiseAbs());++ Gsl::free(gSymmA);+ Gsl::free(gSymmB);+ GslTraits<RealScalar>::free(gEval);+ Gsl::free(gEvec);+ }+ #endif++ VERIFY((symmA * eiSymm.eigenvectors()).isApprox(+ eiSymm.eigenvectors() * eiSymm.eigenvalues().asDiagonal(), largerEps));++ // generalized eigen problem Ax = lBx+ VERIFY((symmA * eiSymmGen.eigenvectors()).isApprox(+ symmB * (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));++ MatrixType sqrtSymmA = eiSymm.operatorSqrt();+ VERIFY_IS_APPROX(symmA, sqrtSymmA*sqrtSymmA);+ VERIFY_IS_APPROX(sqrtSymmA, symmA*eiSymm.operatorInverseSqrt());+}++template<typename MatrixType> void eigensolver(const MatrixType& m)+{+ /* this test covers the following files:+ EigenSolver.h+ */+ int rows = m.rows();+ int cols = m.cols();++ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;+ typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, 1> RealVectorType;+ typedef typename std::complex<typename NumTraits<typename MatrixType::Scalar>::Real> Complex;++ // RealScalar largerEps = 10*test_precision<RealScalar>();++ MatrixType a = MatrixType::Random(rows,cols);+ MatrixType a1 = MatrixType::Random(rows,cols);+ MatrixType symmA = a.adjoint() * a + a1.adjoint() * a1;++ EigenSolver<MatrixType> ei0(symmA);+ VERIFY_IS_APPROX(symmA * ei0.pseudoEigenvectors(), ei0.pseudoEigenvectors() * ei0.pseudoEigenvalueMatrix());+ VERIFY_IS_APPROX((symmA.template cast<Complex>()) * (ei0.pseudoEigenvectors().template cast<Complex>()),+ (ei0.pseudoEigenvectors().template cast<Complex>()) * (ei0.eigenvalues().asDiagonal()));++ EigenSolver<MatrixType> ei1(a);+ VERIFY_IS_APPROX(a * ei1.pseudoEigenvectors(), ei1.pseudoEigenvectors() * ei1.pseudoEigenvalueMatrix());+ VERIFY_IS_APPROX(a.template cast<Complex>() * ei1.eigenvectors(),+ ei1.eigenvectors() * ei1.eigenvalues().asDiagonal());++}++void test_eigen2_eigensolver()+{+ for(int i = 0; i < g_repeat; i++) {+ // very important to test a 3x3 matrix since we provide a special path for it+ CALL_SUBTEST_1( selfadjointeigensolver(Matrix3f()) );+ CALL_SUBTEST_2( selfadjointeigensolver(Matrix4d()) );+ CALL_SUBTEST_3( selfadjointeigensolver(MatrixXf(7,7)) );+ CALL_SUBTEST_4( selfadjointeigensolver(MatrixXcd(5,5)) );+ CALL_SUBTEST_5( selfadjointeigensolver(MatrixXd(19,19)) );++ CALL_SUBTEST_6( eigensolver(Matrix4f()) );+ CALL_SUBTEST_5( eigensolver(MatrixXd(17,17)) );+ }+}+
+ eigen3/test/eigen2/eigen2_first_aligned.cpp view
@@ -0,0 +1,49 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename Scalar>+void test_eigen2_first_aligned_helper(Scalar *array, int size)+{+ const int packet_size = sizeof(Scalar) * ei_packet_traits<Scalar>::size;+ VERIFY(((std::size_t(array) + sizeof(Scalar) * ei_alignmentOffset(array, size)) % packet_size) == 0);+}++template<typename Scalar>+void test_eigen2_none_aligned_helper(Scalar *array, int size)+{+ VERIFY(ei_packet_traits<Scalar>::size == 1 || ei_alignmentOffset(array, size) == size);+}++struct some_non_vectorizable_type { float x; };++void test_eigen2_first_aligned()+{+ EIGEN_ALIGN_128 float array_float[100];+ test_first_aligned_helper(array_float, 50);+ test_first_aligned_helper(array_float+1, 50);+ test_first_aligned_helper(array_float+2, 50);+ test_first_aligned_helper(array_float+3, 50);+ test_first_aligned_helper(array_float+4, 50);+ test_first_aligned_helper(array_float+5, 50);+ + EIGEN_ALIGN_128 double array_double[100];+ test_first_aligned_helper(array_double, 50);+ test_first_aligned_helper(array_double+1, 50);+ test_first_aligned_helper(array_double+2, 50);+ + double *array_double_plus_4_bytes = (double*)(std::size_t(array_double)+4);+ test_none_aligned_helper(array_double_plus_4_bytes, 50);+ test_none_aligned_helper(array_double_plus_4_bytes+1, 50);+ + some_non_vectorizable_type array_nonvec[100];+ test_first_aligned_helper(array_nonvec, 100);+ test_none_aligned_helper(array_nonvec, 100);+}
+ eigen3/test/eigen2/eigen2_geometry.cpp view
@@ -0,0 +1,432 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/Geometry>+#include <Eigen/LU>+#include <Eigen/SVD>++template<typename Scalar> void geometry(void)+{+ /* this test covers the following files:+ Cross.h Quaternion.h, Transform.cpp+ */++ typedef Matrix<Scalar,2,2> Matrix2;+ typedef Matrix<Scalar,3,3> Matrix3;+ typedef Matrix<Scalar,4,4> Matrix4;+ typedef Matrix<Scalar,2,1> Vector2;+ typedef Matrix<Scalar,3,1> Vector3;+ typedef Matrix<Scalar,4,1> Vector4;+ typedef Quaternion<Scalar> Quaternionx;+ typedef AngleAxis<Scalar> AngleAxisx;+ typedef Transform<Scalar,2> Transform2;+ typedef Transform<Scalar,3> Transform3;+ typedef Scaling<Scalar,2> Scaling2;+ typedef Scaling<Scalar,3> Scaling3;+ typedef Translation<Scalar,2> Translation2;+ typedef Translation<Scalar,3> Translation3;++ Scalar largeEps = test_precision<Scalar>();+ if (ei_is_same_type<Scalar,float>::ret)+ largeEps = 1e-2f;++ Vector3 v0 = Vector3::Random(),+ v1 = Vector3::Random(),+ v2 = Vector3::Random();+ Vector2 u0 = Vector2::Random();+ Matrix3 matrot1;++ Scalar a = ei_random<Scalar>(-Scalar(M_PI), Scalar(M_PI));++ // cross product+ VERIFY_IS_MUCH_SMALLER_THAN(v1.cross(v2).eigen2_dot(v1), Scalar(1));+ Matrix3 m;+ m << v0.normalized(),+ (v0.cross(v1)).normalized(),+ (v0.cross(v1).cross(v0)).normalized();+ VERIFY(m.isUnitary());++ // Quaternion: Identity(), setIdentity();+ Quaternionx q1, q2;+ q2.setIdentity();+ VERIFY_IS_APPROX(Quaternionx(Quaternionx::Identity()).coeffs(), q2.coeffs());+ q1.coeffs().setRandom();+ VERIFY_IS_APPROX(q1.coeffs(), (q1*q2).coeffs());++ // unitOrthogonal+ VERIFY_IS_MUCH_SMALLER_THAN(u0.unitOrthogonal().eigen2_dot(u0), Scalar(1));+ VERIFY_IS_MUCH_SMALLER_THAN(v0.unitOrthogonal().eigen2_dot(v0), Scalar(1));+ VERIFY_IS_APPROX(u0.unitOrthogonal().norm(), Scalar(1));+ VERIFY_IS_APPROX(v0.unitOrthogonal().norm(), Scalar(1));+++ VERIFY_IS_APPROX(v0, AngleAxisx(a, v0.normalized()) * v0);+ VERIFY_IS_APPROX(-v0, AngleAxisx(Scalar(M_PI), v0.unitOrthogonal()) * v0);+ VERIFY_IS_APPROX(ei_cos(a)*v0.squaredNorm(), v0.eigen2_dot(AngleAxisx(a, v0.unitOrthogonal()) * v0));+ m = AngleAxisx(a, v0.normalized()).toRotationMatrix().adjoint();+ VERIFY_IS_APPROX(Matrix3::Identity(), m * AngleAxisx(a, v0.normalized()));+ VERIFY_IS_APPROX(Matrix3::Identity(), AngleAxisx(a, v0.normalized()) * m);++ q1 = AngleAxisx(a, v0.normalized());+ q2 = AngleAxisx(a, v1.normalized());++ // angular distance+ Scalar refangle = ei_abs(AngleAxisx(q1.inverse()*q2).angle());+ if (refangle>Scalar(M_PI))+ refangle = Scalar(2)*Scalar(M_PI) - refangle;+ + if((q1.coeffs()-q2.coeffs()).norm() > 10*largeEps)+ {+ VERIFY(ei_isApprox(q1.angularDistance(q2), refangle, largeEps));+ }++ // rotation matrix conversion+ VERIFY_IS_APPROX(q1 * v2, q1.toRotationMatrix() * v2);+ VERIFY_IS_APPROX(q1 * q2 * v2,+ q1.toRotationMatrix() * q2.toRotationMatrix() * v2);++ VERIFY( (q2*q1).isApprox(q1*q2, largeEps) || !(q2 * q1 * v2).isApprox(+ q1.toRotationMatrix() * q2.toRotationMatrix() * v2));++ q2 = q1.toRotationMatrix();+ VERIFY_IS_APPROX(q1*v1,q2*v1);++ matrot1 = AngleAxisx(Scalar(0.1), Vector3::UnitX())+ * AngleAxisx(Scalar(0.2), Vector3::UnitY())+ * AngleAxisx(Scalar(0.3), Vector3::UnitZ());+ VERIFY_IS_APPROX(matrot1 * v1,+ AngleAxisx(Scalar(0.1), Vector3(1,0,0)).toRotationMatrix()+ * (AngleAxisx(Scalar(0.2), Vector3(0,1,0)).toRotationMatrix()+ * (AngleAxisx(Scalar(0.3), Vector3(0,0,1)).toRotationMatrix() * v1)));++ // angle-axis conversion+ AngleAxisx aa = q1;+ VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);+ VERIFY_IS_NOT_APPROX(q1 * v1, Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1);++ // from two vector creation+ VERIFY_IS_APPROX(v2.normalized(),(q2.setFromTwoVectors(v1,v2)*v1).normalized());+ VERIFY_IS_APPROX(v2.normalized(),(q2.setFromTwoVectors(v1,v2)*v1).normalized());++ // inverse and conjugate+ VERIFY_IS_APPROX(q1 * (q1.inverse() * v1), v1);+ VERIFY_IS_APPROX(q1 * (q1.conjugate() * v1), v1);++ // AngleAxis+ VERIFY_IS_APPROX(AngleAxisx(a,v1.normalized()).toRotationMatrix(),+ Quaternionx(AngleAxisx(a,v1.normalized())).toRotationMatrix());++ AngleAxisx aa1;+ m = q1.toRotationMatrix();+ aa1 = m;+ VERIFY_IS_APPROX(AngleAxisx(m).toRotationMatrix(),+ Quaternionx(m).toRotationMatrix());++ // Transform+ // TODO complete the tests !+ a = 0;+ while (ei_abs(a)<Scalar(0.1))+ a = ei_random<Scalar>(-Scalar(0.4)*Scalar(M_PI), Scalar(0.4)*Scalar(M_PI));+ q1 = AngleAxisx(a, v0.normalized());+ Transform3 t0, t1, t2;+ // first test setIdentity() and Identity()+ t0.setIdentity();+ VERIFY_IS_APPROX(t0.matrix(), Transform3::MatrixType::Identity());+ t0.matrix().setZero();+ t0 = Transform3::Identity();+ VERIFY_IS_APPROX(t0.matrix(), Transform3::MatrixType::Identity());++ t0.linear() = q1.toRotationMatrix();+ t1.setIdentity();+ t1.linear() = q1.toRotationMatrix();++ v0 << 50, 2, 1;//= ei_random_matrix<Vector3>().cwiseProduct(Vector3(10,2,0.5));+ t0.scale(v0);+ t1.prescale(v0);++ VERIFY_IS_APPROX( (t0 * Vector3(1,0,0)).norm(), v0.x());+ //VERIFY(!ei_isApprox((t1 * Vector3(1,0,0)).norm(), v0.x()));++ t0.setIdentity();+ t1.setIdentity();+ v1 << 1, 2, 3;+ t0.linear() = q1.toRotationMatrix();+ t0.pretranslate(v0);+ t0.scale(v1);+ t1.linear() = q1.conjugate().toRotationMatrix();+ t1.prescale(v1.cwise().inverse());+ t1.translate(-v0);++ VERIFY((t0.matrix() * t1.matrix()).isIdentity(test_precision<Scalar>()));++ t1.fromPositionOrientationScale(v0, q1, v1);+ VERIFY_IS_APPROX(t1.matrix(), t0.matrix());+ VERIFY_IS_APPROX(t1*v1, t0*v1);++ t0.setIdentity(); t0.scale(v0).rotate(q1.toRotationMatrix());+ t1.setIdentity(); t1.scale(v0).rotate(q1);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ t0.setIdentity(); t0.scale(v0).rotate(AngleAxisx(q1));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ VERIFY_IS_APPROX(t0.scale(a).matrix(), t1.scale(Vector3::Constant(a)).matrix());+ VERIFY_IS_APPROX(t0.prescale(a).matrix(), t1.prescale(Vector3::Constant(a)).matrix());++ // More transform constructors, operator=, operator*=++ Matrix3 mat3 = Matrix3::Random();+ Matrix4 mat4;+ mat4 << mat3 , Vector3::Zero() , Vector4::Zero().transpose();+ Transform3 tmat3(mat3), tmat4(mat4);+ tmat4.matrix()(3,3) = Scalar(1);+ VERIFY_IS_APPROX(tmat3.matrix(), tmat4.matrix());++ Scalar a3 = ei_random<Scalar>(-Scalar(M_PI), Scalar(M_PI));+ Vector3 v3 = Vector3::Random().normalized();+ AngleAxisx aa3(a3, v3);+ Transform3 t3(aa3);+ Transform3 t4;+ t4 = aa3;+ VERIFY_IS_APPROX(t3.matrix(), t4.matrix());+ t4.rotate(AngleAxisx(-a3,v3));+ VERIFY_IS_APPROX(t4.matrix(), Matrix4::Identity());+ t4 *= aa3;+ VERIFY_IS_APPROX(t3.matrix(), t4.matrix());++ v3 = Vector3::Random();+ Translation3 tv3(v3);+ Transform3 t5(tv3);+ t4 = tv3;+ VERIFY_IS_APPROX(t5.matrix(), t4.matrix());+ t4.translate(-v3);+ VERIFY_IS_APPROX(t4.matrix(), Matrix4::Identity());+ t4 *= tv3;+ VERIFY_IS_APPROX(t5.matrix(), t4.matrix());++ Scaling3 sv3(v3);+ Transform3 t6(sv3);+ t4 = sv3;+ VERIFY_IS_APPROX(t6.matrix(), t4.matrix());+ t4.scale(v3.cwise().inverse());+ VERIFY_IS_APPROX(t4.matrix(), Matrix4::Identity());+ t4 *= sv3;+ VERIFY_IS_APPROX(t6.matrix(), t4.matrix());++ // matrix * transform+ VERIFY_IS_APPROX(Transform3(t3.matrix()*t4).matrix(), Transform3(t3*t4).matrix());++ // chained Transform product+ VERIFY_IS_APPROX(((t3*t4)*t5).matrix(), (t3*(t4*t5)).matrix());++ // check that Transform product doesn't have aliasing problems+ t5 = t4;+ t5 = t5*t5;+ VERIFY_IS_APPROX(t5, t4*t4);++ // 2D transformation+ Transform2 t20, t21;+ Vector2 v20 = Vector2::Random();+ Vector2 v21 = Vector2::Random();+ for (int k=0; k<2; ++k)+ if (ei_abs(v21[k])<Scalar(1e-3)) v21[k] = Scalar(1e-3);+ t21.setIdentity();+ t21.linear() = Rotation2D<Scalar>(a).toRotationMatrix();+ VERIFY_IS_APPROX(t20.fromPositionOrientationScale(v20,a,v21).matrix(),+ t21.pretranslate(v20).scale(v21).matrix());++ t21.setIdentity();+ t21.linear() = Rotation2D<Scalar>(-a).toRotationMatrix();+ VERIFY( (t20.fromPositionOrientationScale(v20,a,v21)+ * (t21.prescale(v21.cwise().inverse()).translate(-v20))).matrix().isIdentity(test_precision<Scalar>()) );++ // Transform - new API+ // 3D+ t0.setIdentity();+ t0.rotate(q1).scale(v0).translate(v0);+ // mat * scaling and mat * translation+ t1 = (Matrix3(q1) * Scaling3(v0)) * Translation3(v0);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ // mat * transformation and scaling * translation+ t1 = Matrix3(q1) * (Scaling3(v0) * Translation3(v0));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ t0.setIdentity();+ t0.prerotate(q1).prescale(v0).pretranslate(v0);+ // translation * scaling and transformation * mat+ t1 = (Translation3(v0) * Scaling3(v0)) * Matrix3(q1);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ // scaling * mat and translation * mat+ t1 = Translation3(v0) * (Scaling3(v0) * Matrix3(q1));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ t0.setIdentity();+ t0.scale(v0).translate(v0).rotate(q1);+ // translation * mat and scaling * transformation+ t1 = Scaling3(v0) * (Translation3(v0) * Matrix3(q1));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ // transformation * scaling+ t0.scale(v0);+ t1 = t1 * Scaling3(v0);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ // transformation * translation+ t0.translate(v0);+ t1 = t1 * Translation3(v0);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ // translation * transformation+ t0.pretranslate(v0);+ t1 = Translation3(v0) * t1;+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // transform * quaternion+ t0.rotate(q1);+ t1 = t1 * q1;+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // translation * quaternion+ t0.translate(v1).rotate(q1);+ t1 = t1 * (Translation3(v1) * q1);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // scaling * quaternion+ t0.scale(v1).rotate(q1);+ t1 = t1 * (Scaling3(v1) * q1);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // quaternion * transform+ t0.prerotate(q1);+ t1 = q1 * t1;+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // quaternion * translation+ t0.rotate(q1).translate(v1);+ t1 = t1 * (q1 * Translation3(v1));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // quaternion * scaling+ t0.rotate(q1).scale(v1);+ t1 = t1 * (q1 * Scaling3(v1));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // translation * vector+ t0.setIdentity();+ t0.translate(v0);+ VERIFY_IS_APPROX(t0 * v1, Translation3(v0) * v1);++ // scaling * vector+ t0.setIdentity();+ t0.scale(v0);+ VERIFY_IS_APPROX(t0 * v1, Scaling3(v0) * v1);++ // test transform inversion+ t0.setIdentity();+ t0.translate(v0);+ t0.linear().setRandom();+ VERIFY_IS_APPROX(t0.inverse(Affine), t0.matrix().inverse());+ t0.setIdentity();+ t0.translate(v0).rotate(q1);+ VERIFY_IS_APPROX(t0.inverse(Isometry), t0.matrix().inverse());++ // test extract rotation and scaling+ t0.setIdentity();+ t0.translate(v0).rotate(q1).scale(v1);+ VERIFY_IS_APPROX(t0.rotation() * v1, Matrix3(q1) * v1);++ Matrix3 mat_rotation, mat_scaling;+ t0.setIdentity();+ t0.translate(v0).rotate(q1).scale(v1);+ t0.computeRotationScaling(&mat_rotation, &mat_scaling);+ VERIFY_IS_APPROX(t0.linear(), mat_rotation * mat_scaling);+ VERIFY_IS_APPROX(mat_rotation*mat_rotation.adjoint(), Matrix3::Identity());+ VERIFY_IS_APPROX(mat_rotation.determinant(), Scalar(1));+ t0.computeScalingRotation(&mat_scaling, &mat_rotation);+ VERIFY_IS_APPROX(t0.linear(), mat_scaling * mat_rotation);+ VERIFY_IS_APPROX(mat_rotation*mat_rotation.adjoint(), Matrix3::Identity());+ VERIFY_IS_APPROX(mat_rotation.determinant(), Scalar(1));++ // test casting+ Transform<float,3> t1f = t1.template cast<float>();+ VERIFY_IS_APPROX(t1f.template cast<Scalar>(),t1);+ Transform<double,3> t1d = t1.template cast<double>();+ VERIFY_IS_APPROX(t1d.template cast<Scalar>(),t1);++ Translation3 tr1(v0);+ Translation<float,3> tr1f = tr1.template cast<float>();+ VERIFY_IS_APPROX(tr1f.template cast<Scalar>(),tr1);+ Translation<double,3> tr1d = tr1.template cast<double>();+ VERIFY_IS_APPROX(tr1d.template cast<Scalar>(),tr1);++ Scaling3 sc1(v0);+ Scaling<float,3> sc1f = sc1.template cast<float>();+ VERIFY_IS_APPROX(sc1f.template cast<Scalar>(),sc1);+ Scaling<double,3> sc1d = sc1.template cast<double>();+ VERIFY_IS_APPROX(sc1d.template cast<Scalar>(),sc1);++ Quaternion<float> q1f = q1.template cast<float>();+ VERIFY_IS_APPROX(q1f.template cast<Scalar>(),q1);+ Quaternion<double> q1d = q1.template cast<double>();+ VERIFY_IS_APPROX(q1d.template cast<Scalar>(),q1);++ AngleAxis<float> aa1f = aa1.template cast<float>();+ VERIFY_IS_APPROX(aa1f.template cast<Scalar>(),aa1);+ AngleAxis<double> aa1d = aa1.template cast<double>();+ VERIFY_IS_APPROX(aa1d.template cast<Scalar>(),aa1);++ Rotation2D<Scalar> r2d1(ei_random<Scalar>());+ Rotation2D<float> r2d1f = r2d1.template cast<float>();+ VERIFY_IS_APPROX(r2d1f.template cast<Scalar>(),r2d1);+ Rotation2D<double> r2d1d = r2d1.template cast<double>();+ VERIFY_IS_APPROX(r2d1d.template cast<Scalar>(),r2d1);++ m = q1;+// m.col(1) = Vector3(0,ei_random<Scalar>(),ei_random<Scalar>()).normalized();+// m.col(0) = Vector3(-1,0,0).normalized();+// m.col(2) = m.col(0).cross(m.col(1));+ #define VERIFY_EULER(I,J,K, X,Y,Z) { \+ Vector3 ea = m.eulerAngles(I,J,K); \+ Matrix3 m1 = Matrix3(AngleAxisx(ea[0], Vector3::Unit##X()) * AngleAxisx(ea[1], Vector3::Unit##Y()) * AngleAxisx(ea[2], Vector3::Unit##Z())); \+ VERIFY_IS_APPROX(m, m1); \+ VERIFY_IS_APPROX(m, Matrix3(AngleAxisx(ea[0], Vector3::Unit##X()) * AngleAxisx(ea[1], Vector3::Unit##Y()) * AngleAxisx(ea[2], Vector3::Unit##Z()))); \+ }+ VERIFY_EULER(0,1,2, X,Y,Z);+ VERIFY_EULER(0,1,0, X,Y,X);+ VERIFY_EULER(0,2,1, X,Z,Y);+ VERIFY_EULER(0,2,0, X,Z,X);++ VERIFY_EULER(1,2,0, Y,Z,X);+ VERIFY_EULER(1,2,1, Y,Z,Y);+ VERIFY_EULER(1,0,2, Y,X,Z);+ VERIFY_EULER(1,0,1, Y,X,Y);++ VERIFY_EULER(2,0,1, Z,X,Y);+ VERIFY_EULER(2,0,2, Z,X,Z);+ VERIFY_EULER(2,1,0, Z,Y,X);+ VERIFY_EULER(2,1,2, Z,Y,Z);++ // colwise/rowwise cross product+ mat3.setRandom();+ Vector3 vec3 = Vector3::Random();+ Matrix3 mcross;+ int i = ei_random<int>(0,2);+ mcross = mat3.colwise().cross(vec3);+ VERIFY_IS_APPROX(mcross.col(i), mat3.col(i).cross(vec3));+ mcross = mat3.rowwise().cross(vec3);+ VERIFY_IS_APPROX(mcross.row(i), mat3.row(i).cross(vec3));+++}++void test_eigen2_geometry()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( geometry<float>() );+ CALL_SUBTEST_2( geometry<double>() );+ }+}
+ eigen3/test/eigen2/eigen2_geometry_with_eigen2_prefix.cpp view
@@ -0,0 +1,435 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN2_SUPPORT_STAGE15_RESOLVE_API_CONFLICTS_WARN++#include "main.h"+#include <Eigen/Geometry>+#include <Eigen/LU>+#include <Eigen/SVD>++template<typename Scalar> void geometry(void)+{+ /* this test covers the following files:+ Cross.h Quaternion.h, Transform.cpp+ */++ typedef Matrix<Scalar,2,2> Matrix2;+ typedef Matrix<Scalar,3,3> Matrix3;+ typedef Matrix<Scalar,4,4> Matrix4;+ typedef Matrix<Scalar,2,1> Vector2;+ typedef Matrix<Scalar,3,1> Vector3;+ typedef Matrix<Scalar,4,1> Vector4;+ typedef eigen2_Quaternion<Scalar> Quaternionx;+ typedef eigen2_AngleAxis<Scalar> AngleAxisx;+ typedef eigen2_Transform<Scalar,2> Transform2;+ typedef eigen2_Transform<Scalar,3> Transform3;+ typedef eigen2_Scaling<Scalar,2> Scaling2;+ typedef eigen2_Scaling<Scalar,3> Scaling3;+ typedef eigen2_Translation<Scalar,2> Translation2;+ typedef eigen2_Translation<Scalar,3> Translation3;++ Scalar largeEps = test_precision<Scalar>();+ if (ei_is_same_type<Scalar,float>::ret)+ largeEps = 1e-2f;++ Vector3 v0 = Vector3::Random(),+ v1 = Vector3::Random(),+ v2 = Vector3::Random();+ Vector2 u0 = Vector2::Random();+ Matrix3 matrot1;++ Scalar a = ei_random<Scalar>(-Scalar(M_PI), Scalar(M_PI));++ // cross product+ VERIFY_IS_MUCH_SMALLER_THAN(v1.cross(v2).eigen2_dot(v1), Scalar(1));+ Matrix3 m;+ m << v0.normalized(),+ (v0.cross(v1)).normalized(),+ (v0.cross(v1).cross(v0)).normalized();+ VERIFY(m.isUnitary());++ // Quaternion: Identity(), setIdentity();+ Quaternionx q1, q2;+ q2.setIdentity();+ VERIFY_IS_APPROX(Quaternionx(Quaternionx::Identity()).coeffs(), q2.coeffs());+ q1.coeffs().setRandom();+ VERIFY_IS_APPROX(q1.coeffs(), (q1*q2).coeffs());++ // unitOrthogonal+ VERIFY_IS_MUCH_SMALLER_THAN(u0.unitOrthogonal().eigen2_dot(u0), Scalar(1));+ VERIFY_IS_MUCH_SMALLER_THAN(v0.unitOrthogonal().eigen2_dot(v0), Scalar(1));+ VERIFY_IS_APPROX(u0.unitOrthogonal().norm(), Scalar(1));+ VERIFY_IS_APPROX(v0.unitOrthogonal().norm(), Scalar(1));+++ VERIFY_IS_APPROX(v0, AngleAxisx(a, v0.normalized()) * v0);+ VERIFY_IS_APPROX(-v0, AngleAxisx(Scalar(M_PI), v0.unitOrthogonal()) * v0);+ VERIFY_IS_APPROX(ei_cos(a)*v0.squaredNorm(), v0.eigen2_dot(AngleAxisx(a, v0.unitOrthogonal()) * v0));+ m = AngleAxisx(a, v0.normalized()).toRotationMatrix().adjoint();+ VERIFY_IS_APPROX(Matrix3::Identity(), m * AngleAxisx(a, v0.normalized()));+ VERIFY_IS_APPROX(Matrix3::Identity(), AngleAxisx(a, v0.normalized()) * m);++ q1 = AngleAxisx(a, v0.normalized());+ q2 = AngleAxisx(a, v1.normalized());++ // angular distance+ Scalar refangle = ei_abs(AngleAxisx(q1.inverse()*q2).angle());+ if (refangle>Scalar(M_PI))+ refangle = Scalar(2)*Scalar(M_PI) - refangle;+ + if((q1.coeffs()-q2.coeffs()).norm() > 10*largeEps)+ {+ VERIFY(ei_isApprox(q1.angularDistance(q2), refangle, largeEps));+ }++ // rotation matrix conversion+ VERIFY_IS_APPROX(q1 * v2, q1.toRotationMatrix() * v2);+ VERIFY_IS_APPROX(q1 * q2 * v2,+ q1.toRotationMatrix() * q2.toRotationMatrix() * v2);++ VERIFY( (q2*q1).isApprox(q1*q2, largeEps) || !(q2 * q1 * v2).isApprox(+ q1.toRotationMatrix() * q2.toRotationMatrix() * v2));++ q2 = q1.toRotationMatrix();+ VERIFY_IS_APPROX(q1*v1,q2*v1);++ matrot1 = AngleAxisx(Scalar(0.1), Vector3::UnitX())+ * AngleAxisx(Scalar(0.2), Vector3::UnitY())+ * AngleAxisx(Scalar(0.3), Vector3::UnitZ());+ VERIFY_IS_APPROX(matrot1 * v1,+ AngleAxisx(Scalar(0.1), Vector3(1,0,0)).toRotationMatrix()+ * (AngleAxisx(Scalar(0.2), Vector3(0,1,0)).toRotationMatrix()+ * (AngleAxisx(Scalar(0.3), Vector3(0,0,1)).toRotationMatrix() * v1)));++ // angle-axis conversion+ AngleAxisx aa = q1;+ VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);+ VERIFY_IS_NOT_APPROX(q1 * v1, Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1);++ // from two vector creation+ VERIFY_IS_APPROX(v2.normalized(),(q2.setFromTwoVectors(v1,v2)*v1).normalized());+ VERIFY_IS_APPROX(v2.normalized(),(q2.setFromTwoVectors(v1,v2)*v1).normalized());++ // inverse and conjugate+ VERIFY_IS_APPROX(q1 * (q1.inverse() * v1), v1);+ VERIFY_IS_APPROX(q1 * (q1.conjugate() * v1), v1);++ // AngleAxis+ VERIFY_IS_APPROX(AngleAxisx(a,v1.normalized()).toRotationMatrix(),+ Quaternionx(AngleAxisx(a,v1.normalized())).toRotationMatrix());++ AngleAxisx aa1;+ m = q1.toRotationMatrix();+ aa1 = m;+ VERIFY_IS_APPROX(AngleAxisx(m).toRotationMatrix(),+ Quaternionx(m).toRotationMatrix());++ // Transform+ // TODO complete the tests !+ a = 0;+ while (ei_abs(a)<Scalar(0.1))+ a = ei_random<Scalar>(-Scalar(0.4)*Scalar(M_PI), Scalar(0.4)*Scalar(M_PI));+ q1 = AngleAxisx(a, v0.normalized());+ Transform3 t0, t1, t2;+ // first test setIdentity() and Identity()+ t0.setIdentity();+ VERIFY_IS_APPROX(t0.matrix(), Transform3::MatrixType::Identity());+ t0.matrix().setZero();+ t0 = Transform3::Identity();+ VERIFY_IS_APPROX(t0.matrix(), Transform3::MatrixType::Identity());++ t0.linear() = q1.toRotationMatrix();+ t1.setIdentity();+ t1.linear() = q1.toRotationMatrix();++ v0 << 50, 2, 1;//= ei_random_matrix<Vector3>().cwiseProduct(Vector3(10,2,0.5));+ t0.scale(v0);+ t1.prescale(v0);++ VERIFY_IS_APPROX( (t0 * Vector3(1,0,0)).norm(), v0.x());+ //VERIFY(!ei_isApprox((t1 * Vector3(1,0,0)).norm(), v0.x()));++ t0.setIdentity();+ t1.setIdentity();+ v1 << 1, 2, 3;+ t0.linear() = q1.toRotationMatrix();+ t0.pretranslate(v0);+ t0.scale(v1);+ t1.linear() = q1.conjugate().toRotationMatrix();+ t1.prescale(v1.cwise().inverse());+ t1.translate(-v0);++ VERIFY((t0.matrix() * t1.matrix()).isIdentity(test_precision<Scalar>()));++ t1.fromPositionOrientationScale(v0, q1, v1);+ VERIFY_IS_APPROX(t1.matrix(), t0.matrix());+ VERIFY_IS_APPROX(t1*v1, t0*v1);++ t0.setIdentity(); t0.scale(v0).rotate(q1.toRotationMatrix());+ t1.setIdentity(); t1.scale(v0).rotate(q1);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ t0.setIdentity(); t0.scale(v0).rotate(AngleAxisx(q1));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ VERIFY_IS_APPROX(t0.scale(a).matrix(), t1.scale(Vector3::Constant(a)).matrix());+ VERIFY_IS_APPROX(t0.prescale(a).matrix(), t1.prescale(Vector3::Constant(a)).matrix());++ // More transform constructors, operator=, operator*=++ Matrix3 mat3 = Matrix3::Random();+ Matrix4 mat4;+ mat4 << mat3 , Vector3::Zero() , Vector4::Zero().transpose();+ Transform3 tmat3(mat3), tmat4(mat4);+ tmat4.matrix()(3,3) = Scalar(1);+ VERIFY_IS_APPROX(tmat3.matrix(), tmat4.matrix());++ Scalar a3 = ei_random<Scalar>(-Scalar(M_PI), Scalar(M_PI));+ Vector3 v3 = Vector3::Random().normalized();+ AngleAxisx aa3(a3, v3);+ Transform3 t3(aa3);+ Transform3 t4;+ t4 = aa3;+ VERIFY_IS_APPROX(t3.matrix(), t4.matrix());+ t4.rotate(AngleAxisx(-a3,v3));+ VERIFY_IS_APPROX(t4.matrix(), Matrix4::Identity());+ t4 *= aa3;+ VERIFY_IS_APPROX(t3.matrix(), t4.matrix());++ v3 = Vector3::Random();+ Translation3 tv3(v3);+ Transform3 t5(tv3);+ t4 = tv3;+ VERIFY_IS_APPROX(t5.matrix(), t4.matrix());+ t4.translate(-v3);+ VERIFY_IS_APPROX(t4.matrix(), Matrix4::Identity());+ t4 *= tv3;+ VERIFY_IS_APPROX(t5.matrix(), t4.matrix());++ Scaling3 sv3(v3);+ Transform3 t6(sv3);+ t4 = sv3;+ VERIFY_IS_APPROX(t6.matrix(), t4.matrix());+ t4.scale(v3.cwise().inverse());+ VERIFY_IS_APPROX(t4.matrix(), Matrix4::Identity());+ t4 *= sv3;+ VERIFY_IS_APPROX(t6.matrix(), t4.matrix());++ // matrix * transform+ VERIFY_IS_APPROX(Transform3(t3.matrix()*t4).matrix(), Transform3(t3*t4).matrix());++ // chained Transform product+ VERIFY_IS_APPROX(((t3*t4)*t5).matrix(), (t3*(t4*t5)).matrix());++ // check that Transform product doesn't have aliasing problems+ t5 = t4;+ t5 = t5*t5;+ VERIFY_IS_APPROX(t5, t4*t4);++ // 2D transformation+ Transform2 t20, t21;+ Vector2 v20 = Vector2::Random();+ Vector2 v21 = Vector2::Random();+ for (int k=0; k<2; ++k)+ if (ei_abs(v21[k])<Scalar(1e-3)) v21[k] = Scalar(1e-3);+ t21.setIdentity();+ t21.linear() = Rotation2D<Scalar>(a).toRotationMatrix();+ VERIFY_IS_APPROX(t20.fromPositionOrientationScale(v20,a,v21).matrix(),+ t21.pretranslate(v20).scale(v21).matrix());++ t21.setIdentity();+ t21.linear() = Rotation2D<Scalar>(-a).toRotationMatrix();+ VERIFY( (t20.fromPositionOrientationScale(v20,a,v21)+ * (t21.prescale(v21.cwise().inverse()).translate(-v20))).matrix().isIdentity(test_precision<Scalar>()) );++ // Transform - new API+ // 3D+ t0.setIdentity();+ t0.rotate(q1).scale(v0).translate(v0);+ // mat * scaling and mat * translation+ t1 = (Matrix3(q1) * Scaling3(v0)) * Translation3(v0);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ // mat * transformation and scaling * translation+ t1 = Matrix3(q1) * (Scaling3(v0) * Translation3(v0));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ t0.setIdentity();+ t0.prerotate(q1).prescale(v0).pretranslate(v0);+ // translation * scaling and transformation * mat+ t1 = (Translation3(v0) * Scaling3(v0)) * Matrix3(q1);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ // scaling * mat and translation * mat+ t1 = Translation3(v0) * (Scaling3(v0) * Matrix3(q1));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ t0.setIdentity();+ t0.scale(v0).translate(v0).rotate(q1);+ // translation * mat and scaling * transformation+ t1 = Scaling3(v0) * (Translation3(v0) * Matrix3(q1));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ // transformation * scaling+ t0.scale(v0);+ t1 = t1 * Scaling3(v0);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ // transformation * translation+ t0.translate(v0);+ t1 = t1 * Translation3(v0);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ // translation * transformation+ t0.pretranslate(v0);+ t1 = Translation3(v0) * t1;+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // transform * quaternion+ t0.rotate(q1);+ t1 = t1 * q1;+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // translation * quaternion+ t0.translate(v1).rotate(q1);+ t1 = t1 * (Translation3(v1) * q1);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // scaling * quaternion+ t0.scale(v1).rotate(q1);+ t1 = t1 * (Scaling3(v1) * q1);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // quaternion * transform+ t0.prerotate(q1);+ t1 = q1 * t1;+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // quaternion * translation+ t0.rotate(q1).translate(v1);+ t1 = t1 * (q1 * Translation3(v1));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // quaternion * scaling+ t0.rotate(q1).scale(v1);+ t1 = t1 * (q1 * Scaling3(v1));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // translation * vector+ t0.setIdentity();+ t0.translate(v0);+ VERIFY_IS_APPROX(t0 * v1, Translation3(v0) * v1);++ // scaling * vector+ t0.setIdentity();+ t0.scale(v0);+ VERIFY_IS_APPROX(t0 * v1, Scaling3(v0) * v1);++ // test transform inversion+ t0.setIdentity();+ t0.translate(v0);+ t0.linear().setRandom();+ VERIFY_IS_APPROX(t0.inverse(Affine), t0.matrix().inverse());+ t0.setIdentity();+ t0.translate(v0).rotate(q1);+ VERIFY_IS_APPROX(t0.inverse(Isometry), t0.matrix().inverse());++ // test extract rotation and scaling+ t0.setIdentity();+ t0.translate(v0).rotate(q1).scale(v1);+ VERIFY_IS_APPROX(t0.rotation() * v1, Matrix3(q1) * v1);++ Matrix3 mat_rotation, mat_scaling;+ t0.setIdentity();+ t0.translate(v0).rotate(q1).scale(v1);+ t0.computeRotationScaling(&mat_rotation, &mat_scaling);+ VERIFY_IS_APPROX(t0.linear(), mat_rotation * mat_scaling);+ VERIFY_IS_APPROX(mat_rotation*mat_rotation.adjoint(), Matrix3::Identity());+ VERIFY_IS_APPROX(mat_rotation.determinant(), Scalar(1));+ t0.computeScalingRotation(&mat_scaling, &mat_rotation);+ VERIFY_IS_APPROX(t0.linear(), mat_scaling * mat_rotation);+ VERIFY_IS_APPROX(mat_rotation*mat_rotation.adjoint(), Matrix3::Identity());+ VERIFY_IS_APPROX(mat_rotation.determinant(), Scalar(1));++ // test casting+ eigen2_Transform<float,3> t1f = t1.template cast<float>();+ VERIFY_IS_APPROX(t1f.template cast<Scalar>(),t1);+ eigen2_Transform<double,3> t1d = t1.template cast<double>();+ VERIFY_IS_APPROX(t1d.template cast<Scalar>(),t1);++ Translation3 tr1(v0);+ eigen2_Translation<float,3> tr1f = tr1.template cast<float>();+ VERIFY_IS_APPROX(tr1f.template cast<Scalar>(),tr1);+ eigen2_Translation<double,3> tr1d = tr1.template cast<double>();+ VERIFY_IS_APPROX(tr1d.template cast<Scalar>(),tr1);++ Scaling3 sc1(v0);+ eigen2_Scaling<float,3> sc1f = sc1.template cast<float>();+ VERIFY_IS_APPROX(sc1f.template cast<Scalar>(),sc1);+ eigen2_Scaling<double,3> sc1d = sc1.template cast<double>();+ VERIFY_IS_APPROX(sc1d.template cast<Scalar>(),sc1);++ eigen2_Quaternion<float> q1f = q1.template cast<float>();+ VERIFY_IS_APPROX(q1f.template cast<Scalar>(),q1);+ eigen2_Quaternion<double> q1d = q1.template cast<double>();+ VERIFY_IS_APPROX(q1d.template cast<Scalar>(),q1);++ eigen2_AngleAxis<float> aa1f = aa1.template cast<float>();+ VERIFY_IS_APPROX(aa1f.template cast<Scalar>(),aa1);+ eigen2_AngleAxis<double> aa1d = aa1.template cast<double>();+ VERIFY_IS_APPROX(aa1d.template cast<Scalar>(),aa1);++ eigen2_Rotation2D<Scalar> r2d1(ei_random<Scalar>());+ eigen2_Rotation2D<float> r2d1f = r2d1.template cast<float>();+ VERIFY_IS_APPROX(r2d1f.template cast<Scalar>(),r2d1);+ eigen2_Rotation2D<double> r2d1d = r2d1.template cast<double>();+ VERIFY_IS_APPROX(r2d1d.template cast<Scalar>(),r2d1);++ m = q1;+// m.col(1) = Vector3(0,ei_random<Scalar>(),ei_random<Scalar>()).normalized();+// m.col(0) = Vector3(-1,0,0).normalized();+// m.col(2) = m.col(0).cross(m.col(1));+ #define VERIFY_EULER(I,J,K, X,Y,Z) { \+ Vector3 ea = m.eulerAngles(I,J,K); \+ Matrix3 m1 = Matrix3(AngleAxisx(ea[0], Vector3::Unit##X()) * AngleAxisx(ea[1], Vector3::Unit##Y()) * AngleAxisx(ea[2], Vector3::Unit##Z())); \+ VERIFY_IS_APPROX(m, m1); \+ VERIFY_IS_APPROX(m, Matrix3(AngleAxisx(ea[0], Vector3::Unit##X()) * AngleAxisx(ea[1], Vector3::Unit##Y()) * AngleAxisx(ea[2], Vector3::Unit##Z()))); \+ }+ VERIFY_EULER(0,1,2, X,Y,Z);+ VERIFY_EULER(0,1,0, X,Y,X);+ VERIFY_EULER(0,2,1, X,Z,Y);+ VERIFY_EULER(0,2,0, X,Z,X);++ VERIFY_EULER(1,2,0, Y,Z,X);+ VERIFY_EULER(1,2,1, Y,Z,Y);+ VERIFY_EULER(1,0,2, Y,X,Z);+ VERIFY_EULER(1,0,1, Y,X,Y);++ VERIFY_EULER(2,0,1, Z,X,Y);+ VERIFY_EULER(2,0,2, Z,X,Z);+ VERIFY_EULER(2,1,0, Z,Y,X);+ VERIFY_EULER(2,1,2, Z,Y,Z);++ // colwise/rowwise cross product+ mat3.setRandom();+ Vector3 vec3 = Vector3::Random();+ Matrix3 mcross;+ int i = ei_random<int>(0,2);+ mcross = mat3.colwise().cross(vec3);+ VERIFY_IS_APPROX(mcross.col(i), mat3.col(i).cross(vec3));+ mcross = mat3.rowwise().cross(vec3);+ VERIFY_IS_APPROX(mcross.row(i), mat3.row(i).cross(vec3));+++}++void test_eigen2_geometry_with_eigen2_prefix()+{+ std::cout << "eigen2 support: " << EIGEN2_SUPPORT_STAGE << std::endl;+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( geometry<float>() );+ CALL_SUBTEST_2( geometry<double>() );+ }+}
+ eigen3/test/eigen2/eigen2_hyperplane.cpp view
@@ -0,0 +1,126 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/Geometry>+#include <Eigen/LU>+#include <Eigen/QR>++template<typename HyperplaneType> void hyperplane(const HyperplaneType& _plane)+{+ /* this test covers the following files:+ Hyperplane.h+ */++ const int dim = _plane.dim();+ typedef typename HyperplaneType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, HyperplaneType::AmbientDimAtCompileTime, 1> VectorType;+ typedef Matrix<Scalar, HyperplaneType::AmbientDimAtCompileTime,+ HyperplaneType::AmbientDimAtCompileTime> MatrixType;++ VectorType p0 = VectorType::Random(dim);+ VectorType p1 = VectorType::Random(dim);++ VectorType n0 = VectorType::Random(dim).normalized();+ VectorType n1 = VectorType::Random(dim).normalized();++ HyperplaneType pl0(n0, p0);+ HyperplaneType pl1(n1, p1);+ HyperplaneType pl2 = pl1;++ Scalar s0 = ei_random<Scalar>();+ Scalar s1 = ei_random<Scalar>();++ VERIFY_IS_APPROX( n1.eigen2_dot(n1), Scalar(1) );++ VERIFY_IS_MUCH_SMALLER_THAN( pl0.absDistance(p0), Scalar(1) );+ VERIFY_IS_APPROX( pl1.signedDistance(p1 + n1 * s0), s0 );+ VERIFY_IS_MUCH_SMALLER_THAN( pl1.signedDistance(pl1.projection(p0)), Scalar(1) );+ VERIFY_IS_MUCH_SMALLER_THAN( pl1.absDistance(p1 + pl1.normal().unitOrthogonal() * s1), Scalar(1) );++ // transform+ if (!NumTraits<Scalar>::IsComplex)+ {+ MatrixType rot = MatrixType::Random(dim,dim).qr().matrixQ();+ Scaling<Scalar,HyperplaneType::AmbientDimAtCompileTime> scaling(VectorType::Random());+ Translation<Scalar,HyperplaneType::AmbientDimAtCompileTime> translation(VectorType::Random());++ pl2 = pl1;+ VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot).absDistance(rot * p1), Scalar(1) );+ pl2 = pl1;+ VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot,Isometry).absDistance(rot * p1), Scalar(1) );+ pl2 = pl1;+ VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot*scaling).absDistance((rot*scaling) * p1), Scalar(1) );+ pl2 = pl1;+ VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot*scaling*translation)+ .absDistance((rot*scaling*translation) * p1), Scalar(1) );+ pl2 = pl1;+ VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot*translation,Isometry)+ .absDistance((rot*translation) * p1), Scalar(1) );+ }++ // casting+ const int Dim = HyperplaneType::AmbientDimAtCompileTime;+ typedef typename GetDifferentType<Scalar>::type OtherScalar;+ Hyperplane<OtherScalar,Dim> hp1f = pl1.template cast<OtherScalar>();+ VERIFY_IS_APPROX(hp1f.template cast<Scalar>(),pl1);+ Hyperplane<Scalar,Dim> hp1d = pl1.template cast<Scalar>();+ VERIFY_IS_APPROX(hp1d.template cast<Scalar>(),pl1);+}++template<typename Scalar> void lines()+{+ typedef Hyperplane<Scalar, 2> HLine;+ typedef ParametrizedLine<Scalar, 2> PLine;+ typedef Matrix<Scalar,2,1> Vector;+ typedef Matrix<Scalar,3,1> CoeffsType;++ for(int i = 0; i < 10; i++)+ {+ Vector center = Vector::Random();+ Vector u = Vector::Random();+ Vector v = Vector::Random();+ Scalar a = ei_random<Scalar>();+ while (ei_abs(a-1) < 1e-4) a = ei_random<Scalar>();+ while (u.norm() < 1e-4) u = Vector::Random();+ while (v.norm() < 1e-4) v = Vector::Random();++ HLine line_u = HLine::Through(center + u, center + a*u);+ HLine line_v = HLine::Through(center + v, center + a*v);++ // the line equations should be normalized so that a^2+b^2=1+ VERIFY_IS_APPROX(line_u.normal().norm(), Scalar(1));+ VERIFY_IS_APPROX(line_v.normal().norm(), Scalar(1));++ Vector result = line_u.intersection(line_v);++ // the lines should intersect at the point we called "center"+ VERIFY_IS_APPROX(result, center);++ // check conversions between two types of lines+ PLine pl(line_u); // gcc 3.3 will commit suicide if we don't name this variable+ CoeffsType converted_coeffs(HLine(pl).coeffs());+ converted_coeffs *= line_u.coeffs()(0)/converted_coeffs(0);+ VERIFY(line_u.coeffs().isApprox(converted_coeffs));+ }+}++void test_eigen2_hyperplane()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( hyperplane(Hyperplane<float,2>()) );+ CALL_SUBTEST_2( hyperplane(Hyperplane<float,3>()) );+ CALL_SUBTEST_3( hyperplane(Hyperplane<double,4>()) );+ CALL_SUBTEST_4( hyperplane(Hyperplane<std::complex<double>,5>()) );+ CALL_SUBTEST_5( lines<float>() );+ CALL_SUBTEST_6( lines<double>() );+ }+}
+ eigen3/test/eigen2/eigen2_inverse.cpp view
@@ -0,0 +1,62 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/LU>++template<typename MatrixType> void inverse(const MatrixType& m)+{+ /* this test covers the following files:+ Inverse.h+ */+ int rows = m.rows();+ int cols = m.cols();++ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2(rows, cols),+ identity = MatrixType::Identity(rows, rows);++ while(ei_abs(m1.determinant()) < RealScalar(0.1) && rows <= 8)+ {+ m1 = MatrixType::Random(rows, cols);+ }++ m2 = m1.inverse();+ VERIFY_IS_APPROX(m1, m2.inverse() );++ m1.computeInverse(&m2);+ VERIFY_IS_APPROX(m1, m2.inverse() );++ VERIFY_IS_APPROX((Scalar(2)*m2).inverse(), m2.inverse()*Scalar(0.5));++ VERIFY_IS_APPROX(identity, m1.inverse() * m1 );+ VERIFY_IS_APPROX(identity, m1 * m1.inverse() );++ VERIFY_IS_APPROX(m1, m1.inverse().inverse() );++ // since for the general case we implement separately row-major and col-major, test that+ VERIFY_IS_APPROX(m1.transpose().inverse(), m1.inverse().transpose());+}++void test_eigen2_inverse()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( inverse(Matrix<double,1,1>()) );+ CALL_SUBTEST_2( inverse(Matrix2d()) );+ CALL_SUBTEST_3( inverse(Matrix3f()) );+ CALL_SUBTEST_4( inverse(Matrix4f()) );+ CALL_SUBTEST_5( inverse(MatrixXf(8,8)) );+ CALL_SUBTEST_6( inverse(MatrixXcd(7,7)) );+ }+}
+ eigen3/test/eigen2/eigen2_linearstructure.cpp view
@@ -0,0 +1,83 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void linearStructure(const MatrixType& m)+{+ /* this test covers the following files:+ Sum.h Difference.h Opposite.h ScalarMultiple.h+ */++ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ int rows = m.rows();+ int cols = m.cols();++ // this test relies a lot on Random.h, and there's not much more that we can do+ // to test it, hence I consider that we will have tested Random.h+ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols);++ Scalar s1 = ei_random<Scalar>();+ while (ei_abs(s1)<1e-3) s1 = ei_random<Scalar>();++ int r = ei_random<int>(0, rows-1),+ c = ei_random<int>(0, cols-1);++ VERIFY_IS_APPROX(-(-m1), m1);+ VERIFY_IS_APPROX(m1+m1, 2*m1);+ VERIFY_IS_APPROX(m1+m2-m1, m2);+ VERIFY_IS_APPROX(-m2+m1+m2, m1);+ VERIFY_IS_APPROX(m1*s1, s1*m1);+ VERIFY_IS_APPROX((m1+m2)*s1, s1*m1+s1*m2);+ VERIFY_IS_APPROX((-m1+m2)*s1, -s1*m1+s1*m2);+ m3 = m2; m3 += m1;+ VERIFY_IS_APPROX(m3, m1+m2);+ m3 = m2; m3 -= m1;+ VERIFY_IS_APPROX(m3, m2-m1);+ m3 = m2; m3 *= s1;+ VERIFY_IS_APPROX(m3, s1*m2);+ if(NumTraits<Scalar>::HasFloatingPoint)+ {+ m3 = m2; m3 /= s1;+ VERIFY_IS_APPROX(m3, m2/s1);+ }++ // again, test operator() to check const-qualification+ VERIFY_IS_APPROX((-m1)(r,c), -(m1(r,c)));+ VERIFY_IS_APPROX((m1-m2)(r,c), (m1(r,c))-(m2(r,c)));+ VERIFY_IS_APPROX((m1+m2)(r,c), (m1(r,c))+(m2(r,c)));+ VERIFY_IS_APPROX((s1*m1)(r,c), s1*(m1(r,c)));+ VERIFY_IS_APPROX((m1*s1)(r,c), (m1(r,c))*s1);+ if(NumTraits<Scalar>::HasFloatingPoint)+ VERIFY_IS_APPROX((m1/s1)(r,c), (m1(r,c))/s1);++ // use .block to disable vectorization and compare to the vectorized version+ VERIFY_IS_APPROX(m1+m1.block(0,0,rows,cols), m1+m1);+ VERIFY_IS_APPROX(m1.cwise() * m1.block(0,0,rows,cols), m1.cwise() * m1);+ VERIFY_IS_APPROX(m1 - m1.block(0,0,rows,cols), m1 - m1);+ VERIFY_IS_APPROX(m1.block(0,0,rows,cols) * s1, m1 * s1);+}++void test_eigen2_linearstructure()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( linearStructure(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( linearStructure(Matrix2f()) );+ CALL_SUBTEST_3( linearStructure(Vector3d()) );+ CALL_SUBTEST_4( linearStructure(Matrix4d()) );+ CALL_SUBTEST_5( linearStructure(MatrixXcf(3, 3)) );+ CALL_SUBTEST_6( linearStructure(MatrixXf(8, 12)) );+ CALL_SUBTEST_7( linearStructure(MatrixXi(8, 12)) );+ CALL_SUBTEST_8( linearStructure(MatrixXcd(20, 20)) );+ }+}
+ eigen3/test/eigen2/eigen2_lu.cpp view
@@ -0,0 +1,122 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/LU>++template<typename Derived>+void doSomeRankPreservingOperations(Eigen::MatrixBase<Derived>& m)+{+ typedef typename Derived::RealScalar RealScalar;+ for(int a = 0; a < 3*(m.rows()+m.cols()); a++)+ {+ RealScalar d = Eigen::ei_random<RealScalar>(-1,1);+ int i = Eigen::ei_random<int>(0,m.rows()-1); // i is a random row number+ int j;+ do {+ j = Eigen::ei_random<int>(0,m.rows()-1);+ } while (i==j); // j is another one (must be different)+ m.row(i) += d * m.row(j);++ i = Eigen::ei_random<int>(0,m.cols()-1); // i is a random column number+ do {+ j = Eigen::ei_random<int>(0,m.cols()-1);+ } while (i==j); // j is another one (must be different)+ m.col(i) += d * m.col(j);+ }+}++template<typename MatrixType> void lu_non_invertible()+{+ /* this test covers the following files:+ LU.h+ */+ // NOTE there seems to be a problem with too small sizes -- could easily lie in the doSomeRankPreservingOperations function+ int rows = ei_random<int>(20,200), cols = ei_random<int>(20,200), cols2 = ei_random<int>(20,200);+ int rank = ei_random<int>(1, std::min(rows, cols)-1);++ MatrixType m1(rows, cols), m2(cols, cols2), m3(rows, cols2), k(1,1);+ m1 = MatrixType::Random(rows,cols);+ if(rows <= cols)+ for(int i = rank; i < rows; i++) m1.row(i).setZero();+ else+ for(int i = rank; i < cols; i++) m1.col(i).setZero();+ doSomeRankPreservingOperations(m1);++ LU<MatrixType> lu(m1);+ typename LU<MatrixType>::KernelResultType m1kernel = lu.kernel();+ typename LU<MatrixType>::ImageResultType m1image = lu.image();++ VERIFY(rank == lu.rank());+ VERIFY(cols - lu.rank() == lu.dimensionOfKernel());+ VERIFY(!lu.isInjective());+ VERIFY(!lu.isInvertible());+ VERIFY(lu.isSurjective() == (lu.rank() == rows));+ VERIFY((m1 * m1kernel).isMuchSmallerThan(m1));+ VERIFY(m1image.lu().rank() == rank);+ MatrixType sidebyside(m1.rows(), m1.cols() + m1image.cols());+ sidebyside << m1, m1image;+ VERIFY(sidebyside.lu().rank() == rank);+ m2 = MatrixType::Random(cols,cols2);+ m3 = m1*m2;+ m2 = MatrixType::Random(cols,cols2);+ lu.solve(m3, &m2);+ VERIFY_IS_APPROX(m3, m1*m2);+ /* solve now always returns true+ m3 = MatrixType::Random(rows,cols2);+ VERIFY(!lu.solve(m3, &m2));+ */+}++template<typename MatrixType> void lu_invertible()+{+ /* this test covers the following files:+ LU.h+ */+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;+ int size = ei_random<int>(10,200);++ MatrixType m1(size, size), m2(size, size), m3(size, size);+ m1 = MatrixType::Random(size,size);++ if (ei_is_same_type<RealScalar,float>::ret)+ {+ // let's build a matrix more stable to inverse+ MatrixType a = MatrixType::Random(size,size*2);+ m1 += a * a.adjoint();+ }++ LU<MatrixType> lu(m1);+ VERIFY(0 == lu.dimensionOfKernel());+ VERIFY(size == lu.rank());+ VERIFY(lu.isInjective());+ VERIFY(lu.isSurjective());+ VERIFY(lu.isInvertible());+ VERIFY(lu.image().lu().isInvertible());+ m3 = MatrixType::Random(size,size);+ lu.solve(m3, &m2);+ VERIFY_IS_APPROX(m3, m1*m2);+ VERIFY_IS_APPROX(m2, lu.inverse()*m3);+ m3 = MatrixType::Random(size,size);+ VERIFY(lu.solve(m3, &m2));+}++void test_eigen2_lu()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( lu_non_invertible<MatrixXf>() );+ CALL_SUBTEST_2( lu_non_invertible<MatrixXd>() );+ CALL_SUBTEST_3( lu_non_invertible<MatrixXcf>() );+ CALL_SUBTEST_4( lu_non_invertible<MatrixXcd>() );+ CALL_SUBTEST_1( lu_invertible<MatrixXf>() );+ CALL_SUBTEST_2( lu_invertible<MatrixXd>() );+ CALL_SUBTEST_3( lu_invertible<MatrixXcf>() );+ CALL_SUBTEST_4( lu_invertible<MatrixXcd>() );+ }+}
+ eigen3/test/eigen2/eigen2_map.cpp view
@@ -0,0 +1,114 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename VectorType> void map_class_vector(const VectorType& m)+{+ typedef typename VectorType::Scalar Scalar;++ int size = m.size();++ // test Map.h+ Scalar* array1 = ei_aligned_new<Scalar>(size);+ Scalar* array2 = ei_aligned_new<Scalar>(size);+ Scalar* array3 = new Scalar[size+1];+ Scalar* array3unaligned = std::size_t(array3)%16 == 0 ? array3+1 : array3;+ + Map<VectorType, Aligned>(array1, size) = VectorType::Random(size);+ Map<VectorType>(array2, size) = Map<VectorType>(array1, size);+ Map<VectorType>(array3unaligned, size) = Map<VectorType>((const Scalar*)array1, size); // test non-const-correctness support in eigen2+ VectorType ma1 = Map<VectorType>(array1, size);+ VectorType ma2 = Map<VectorType, Aligned>(array2, size);+ VectorType ma3 = Map<VectorType>(array3unaligned, size);+ VERIFY_IS_APPROX(ma1, ma2);+ VERIFY_IS_APPROX(ma1, ma3);+ + ei_aligned_delete(array1, size);+ ei_aligned_delete(array2, size);+ delete[] array3;+}++template<typename MatrixType> void map_class_matrix(const MatrixType& m)+{+ typedef typename MatrixType::Scalar Scalar;++ int rows = m.rows(), cols = m.cols(), size = rows*cols;++ // test Map.h+ Scalar* array1 = ei_aligned_new<Scalar>(size);+ for(int i = 0; i < size; i++) array1[i] = Scalar(1);+ Scalar* array2 = ei_aligned_new<Scalar>(size);+ for(int i = 0; i < size; i++) array2[i] = Scalar(1);+ Scalar* array3 = new Scalar[size+1];+ for(int i = 0; i < size+1; i++) array3[i] = Scalar(1);+ Scalar* array3unaligned = std::size_t(array3)%16 == 0 ? array3+1 : array3;+ Map<MatrixType, Aligned>(array1, rows, cols) = MatrixType::Ones(rows,cols);+ Map<MatrixType>(array2, rows, cols) = Map<MatrixType>((const Scalar*)array1, rows, cols); // test non-const-correctness support in eigen2+ Map<MatrixType>(array3unaligned, rows, cols) = Map<MatrixType>(array1, rows, cols);+ MatrixType ma1 = Map<MatrixType>(array1, rows, cols);+ MatrixType ma2 = Map<MatrixType, Aligned>(array2, rows, cols);+ VERIFY_IS_APPROX(ma1, ma2);+ MatrixType ma3 = Map<MatrixType>(array3unaligned, rows, cols);+ VERIFY_IS_APPROX(ma1, ma3);+ + ei_aligned_delete(array1, size);+ ei_aligned_delete(array2, size);+ delete[] array3;+}++template<typename VectorType> void map_static_methods(const VectorType& m)+{+ typedef typename VectorType::Scalar Scalar;++ int size = m.size();++ // test Map.h+ Scalar* array1 = ei_aligned_new<Scalar>(size);+ Scalar* array2 = ei_aligned_new<Scalar>(size);+ Scalar* array3 = new Scalar[size+1];+ Scalar* array3unaligned = std::size_t(array3)%16 == 0 ? array3+1 : array3;+ + VectorType::MapAligned(array1, size) = VectorType::Random(size);+ VectorType::Map(array2, size) = VectorType::Map(array1, size);+ VectorType::Map(array3unaligned, size) = VectorType::Map(array1, size);+ VectorType ma1 = VectorType::Map(array1, size);+ VectorType ma2 = VectorType::MapAligned(array2, size);+ VectorType ma3 = VectorType::Map(array3unaligned, size);+ VERIFY_IS_APPROX(ma1, ma2);+ VERIFY_IS_APPROX(ma1, ma3);+ + ei_aligned_delete(array1, size);+ ei_aligned_delete(array2, size);+ delete[] array3;+}+++void test_eigen2_map()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( map_class_vector(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( map_class_vector(Vector4d()) );+ CALL_SUBTEST_3( map_class_vector(RowVector4f()) );+ CALL_SUBTEST_4( map_class_vector(VectorXcf(8)) );+ CALL_SUBTEST_5( map_class_vector(VectorXi(12)) );++ CALL_SUBTEST_1( map_class_matrix(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( map_class_matrix(Matrix4d()) );+ CALL_SUBTEST_6( map_class_matrix(Matrix<float,3,5>()) );+ CALL_SUBTEST_4( map_class_matrix(MatrixXcf(ei_random<int>(1,10),ei_random<int>(1,10))) );+ CALL_SUBTEST_5( map_class_matrix(MatrixXi(ei_random<int>(1,10),ei_random<int>(1,10))) );++ CALL_SUBTEST_1( map_static_methods(Matrix<double, 1, 1>()) );+ CALL_SUBTEST_2( map_static_methods(Vector3f()) );+ CALL_SUBTEST_7( map_static_methods(RowVector3d()) );+ CALL_SUBTEST_4( map_static_methods(VectorXcd(8)) );+ CALL_SUBTEST_5( map_static_methods(VectorXf(12)) );+ }+}
+ eigen3/test/eigen2/eigen2_meta.cpp view
@@ -0,0 +1,60 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++void test_eigen2_meta()+{+ typedef float & FloatRef;+ typedef const float & ConstFloatRef;+ + VERIFY((ei_meta_if<(3<4),ei_meta_true, ei_meta_false>::ret::ret));+ VERIFY(( ei_is_same_type<float,float>::ret));+ VERIFY((!ei_is_same_type<float,double>::ret));+ VERIFY((!ei_is_same_type<float,float&>::ret));+ VERIFY((!ei_is_same_type<float,const float&>::ret));+ + VERIFY(( ei_is_same_type<float,ei_cleantype<const float&>::type >::ret));+ VERIFY(( ei_is_same_type<float,ei_cleantype<const float*>::type >::ret));+ VERIFY(( ei_is_same_type<float,ei_cleantype<const float*&>::type >::ret));+ VERIFY(( ei_is_same_type<float,ei_cleantype<float**>::type >::ret));+ VERIFY(( ei_is_same_type<float,ei_cleantype<float**&>::type >::ret));+ VERIFY(( ei_is_same_type<float,ei_cleantype<float* const *&>::type >::ret));+ VERIFY(( ei_is_same_type<float,ei_cleantype<float* const>::type >::ret));++ VERIFY(( ei_is_same_type<float*,ei_unconst<const float*>::type >::ret));+ VERIFY(( ei_is_same_type<float&,ei_unconst<const float&>::type >::ret));+ VERIFY(( ei_is_same_type<float&,ei_unconst<ConstFloatRef>::type >::ret));+ + VERIFY(( ei_is_same_type<float&,ei_unconst<float&>::type >::ret));+ VERIFY(( ei_is_same_type<float,ei_unref<float&>::type >::ret));+ VERIFY(( ei_is_same_type<const float,ei_unref<const float&>::type >::ret));+ VERIFY(( ei_is_same_type<float,ei_unpointer<float*>::type >::ret));+ VERIFY(( ei_is_same_type<const float,ei_unpointer<const float*>::type >::ret));+ VERIFY(( ei_is_same_type<float,ei_unpointer<float* const >::type >::ret));+ + VERIFY(ei_meta_sqrt<1>::ret == 1);+ #define VERIFY_META_SQRT(X) VERIFY(ei_meta_sqrt<X>::ret == int(ei_sqrt(double(X))))+ VERIFY_META_SQRT(2);+ VERIFY_META_SQRT(3);+ VERIFY_META_SQRT(4);+ VERIFY_META_SQRT(5);+ VERIFY_META_SQRT(6);+ VERIFY_META_SQRT(8);+ VERIFY_META_SQRT(9);+ VERIFY_META_SQRT(15);+ VERIFY_META_SQRT(16);+ VERIFY_META_SQRT(17);+ VERIFY_META_SQRT(255);+ VERIFY_META_SQRT(256);+ VERIFY_META_SQRT(257);+ VERIFY_META_SQRT(1023);+ VERIFY_META_SQRT(1024);+ VERIFY_META_SQRT(1025);+}
+ eigen3/test/eigen2/eigen2_miscmatrices.cpp view
@@ -0,0 +1,48 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void miscMatrices(const MatrixType& m)+{+ /* this test covers the following files:+ DiagonalMatrix.h Ones.h+ */++ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;+ typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;+ int rows = m.rows();+ int cols = m.cols();++ int r = ei_random<int>(0, rows-1), r2 = ei_random<int>(0, rows-1), c = ei_random<int>(0, cols-1);+ VERIFY_IS_APPROX(MatrixType::Ones(rows,cols)(r,c), static_cast<Scalar>(1));+ MatrixType m1 = MatrixType::Ones(rows,cols);+ VERIFY_IS_APPROX(m1(r,c), static_cast<Scalar>(1));+ VectorType v1 = VectorType::Random(rows);+ v1[0];+ Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>+ square = v1.asDiagonal();+ if(r==r2) VERIFY_IS_APPROX(square(r,r2), v1[r]);+ else VERIFY_IS_MUCH_SMALLER_THAN(square(r,r2), static_cast<Scalar>(1));+ square = MatrixType::Zero(rows, rows);+ square.diagonal() = VectorType::Ones(rows);+ VERIFY_IS_APPROX(square, MatrixType::Identity(rows, rows));+}++void test_eigen2_miscmatrices()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( miscMatrices(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( miscMatrices(Matrix4d()) );+ CALL_SUBTEST_3( miscMatrices(MatrixXcf(3, 3)) );+ CALL_SUBTEST_4( miscMatrices(MatrixXi(8, 12)) );+ CALL_SUBTEST_5( miscMatrices(MatrixXcd(20, 20)) );+ }+}
+ eigen3/test/eigen2/eigen2_mixingtypes.cpp view
@@ -0,0 +1,77 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_NO_STATIC_ASSERT+#define EIGEN_NO_STATIC_ASSERT // turn static asserts into runtime asserts in order to check them+#endif++#ifndef EIGEN_DONT_VECTORIZE+#define EIGEN_DONT_VECTORIZE // SSE intrinsics aren't designed to allow mixing types+#endif++#include "main.h"+++template<int SizeAtCompileType> void mixingtypes(int size = SizeAtCompileType)+{+ typedef Matrix<float, SizeAtCompileType, SizeAtCompileType> Mat_f;+ typedef Matrix<double, SizeAtCompileType, SizeAtCompileType> Mat_d;+ typedef Matrix<std::complex<float>, SizeAtCompileType, SizeAtCompileType> Mat_cf;+ typedef Matrix<std::complex<double>, SizeAtCompileType, SizeAtCompileType> Mat_cd;+ typedef Matrix<float, SizeAtCompileType, 1> Vec_f;+ typedef Matrix<double, SizeAtCompileType, 1> Vec_d;+ typedef Matrix<std::complex<float>, SizeAtCompileType, 1> Vec_cf;+ typedef Matrix<std::complex<double>, SizeAtCompileType, 1> Vec_cd;++ Mat_f mf(size,size);+ Mat_d md(size,size);+ Mat_cf mcf(size,size);+ Mat_cd mcd(size,size);+ Vec_f vf(size,1);+ Vec_d vd(size,1);+ Vec_cf vcf(size,1);+ Vec_cd vcd(size,1);++ mf+mf;+ VERIFY_RAISES_ASSERT(mf+md);+ VERIFY_RAISES_ASSERT(mf+mcf);+ VERIFY_RAISES_ASSERT(vf=vd);+ VERIFY_RAISES_ASSERT(vf+=vd);+ VERIFY_RAISES_ASSERT(mcd=md);++ mf*mf;+ md*mcd;+ mcd*md;+ mf*vcf;+ mcf*vf;+ mcf *= mf;+ vcd = md*vcd;+ vcf = mcf*vf;+#if 0+ // these are know generating hard build errors in eigen3+ VERIFY_RAISES_ASSERT(mf*md);+ VERIFY_RAISES_ASSERT(mcf*mcd);+ VERIFY_RAISES_ASSERT(mcf*vcd);+ VERIFY_RAISES_ASSERT(vcf = mf*vf);++ vf.eigen2_dot(vf);+ VERIFY_RAISES_ASSERT(vd.eigen2_dot(vf));+ VERIFY_RAISES_ASSERT(vcf.eigen2_dot(vf)); // yeah eventually we should allow this but i'm too lazy to make that change now in Dot.h+ // especially as that might be rewritten as cwise product .sum() which would make that automatic.+#endif+}++void test_eigen2_mixingtypes()+{+ // check that our operator new is indeed called:+ CALL_SUBTEST_1(mixingtypes<3>());+ CALL_SUBTEST_2(mixingtypes<4>());+ CALL_SUBTEST_3(mixingtypes<Dynamic>(20));+}
+ eigen3/test/eigen2/eigen2_newstdvector.cpp view
@@ -0,0 +1,149 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN_USE_NEW_STDVECTOR+#include "main.h"+#include <Eigen/StdVector>+#include <Eigen/Geometry>++template<typename MatrixType>+void check_stdvector_matrix(const MatrixType& m)+{+ int rows = m.rows();+ int cols = m.cols();+ MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols);+ std::vector<MatrixType,Eigen::aligned_allocator<MatrixType> > v(10, MatrixType(rows,cols)), w(20, y);+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((std::size_t)&(v[22]) == (std::size_t)&(v[21]) + sizeof(MatrixType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ MatrixType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(unsigned int i=23; i<v.size(); ++i)+ {+ VERIFY(v[i]==w[(i-23)%w.size()]);+ }+}++template<typename TransformType>+void check_stdvector_transform(const TransformType&)+{+ typedef typename TransformType::MatrixType MatrixType;+ TransformType x(MatrixType::Random()), y(MatrixType::Random());+ std::vector<TransformType,Eigen::aligned_allocator<TransformType> > v(10), w(20, y);+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((std::size_t)&(v[22]) == (std::size_t)&(v[21]) + sizeof(TransformType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ TransformType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(unsigned int i=23; i<v.size(); ++i)+ {+ VERIFY(v[i].matrix()==w[(i-23)%w.size()].matrix());+ }+}++template<typename QuaternionType>+void check_stdvector_quaternion(const QuaternionType&)+{+ typedef typename QuaternionType::Coefficients Coefficients;+ QuaternionType x(Coefficients::Random()), y(Coefficients::Random());+ std::vector<QuaternionType,Eigen::aligned_allocator<QuaternionType> > v(10), w(20, y);+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((std::size_t)&(v[22]) == (std::size_t)&(v[21]) + sizeof(QuaternionType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ QuaternionType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(unsigned int i=23; i<v.size(); ++i)+ {+ VERIFY(v[i].coeffs()==w[(i-23)%w.size()].coeffs());+ }+}++void test_eigen2_newstdvector()+{+ // some non vectorizable fixed sizes+ CALL_SUBTEST_1(check_stdvector_matrix(Vector2f()));+ CALL_SUBTEST_1(check_stdvector_matrix(Matrix3f()));+ CALL_SUBTEST_1(check_stdvector_matrix(Matrix3d()));++ // some vectorizable fixed sizes+ CALL_SUBTEST_2(check_stdvector_matrix(Matrix2f()));+ CALL_SUBTEST_2(check_stdvector_matrix(Vector4f()));+ CALL_SUBTEST_2(check_stdvector_matrix(Matrix4f()));+ CALL_SUBTEST_2(check_stdvector_matrix(Matrix4d()));++ // some dynamic sizes+ CALL_SUBTEST_3(check_stdvector_matrix(MatrixXd(1,1)));+ CALL_SUBTEST_3(check_stdvector_matrix(VectorXd(20)));+ CALL_SUBTEST_3(check_stdvector_matrix(RowVectorXf(20)));+ CALL_SUBTEST_3(check_stdvector_matrix(MatrixXcf(10,10)));++ // some Transform+ CALL_SUBTEST_4(check_stdvector_transform(Transform2f()));+ CALL_SUBTEST_4(check_stdvector_transform(Transform3f()));+ CALL_SUBTEST_4(check_stdvector_transform(Transform3d()));+ //CALL_SUBTEST(check_stdvector_transform(Transform4d()));++ // some Quaternion+ CALL_SUBTEST_5(check_stdvector_quaternion(Quaternionf()));+ CALL_SUBTEST_5(check_stdvector_quaternion(Quaterniond()));+}
+ eigen3/test/eigen2/eigen2_nomalloc.cpp view
@@ -0,0 +1,53 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++// this hack is needed to make this file compiles with -pedantic (gcc)+#ifdef __GNUC__+#define throw(X)+#endif+// discard stack allocation as that too bypasses malloc+#define EIGEN_STACK_ALLOCATION_LIMIT 0+// any heap allocation will raise an assert+#define EIGEN_NO_MALLOC++#include "main.h"++template<typename MatrixType> void nomalloc(const MatrixType& m)+{+ /* this test check no dynamic memory allocation are issued with fixed-size matrices+ */++ typedef typename MatrixType::Scalar Scalar;++ int rows = m.rows();+ int cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols);++ Scalar s1 = ei_random<Scalar>();++ int r = ei_random<int>(0, rows-1),+ c = ei_random<int>(0, cols-1);++ VERIFY_IS_APPROX((m1+m2)*s1, s1*m1+s1*m2);+ VERIFY_IS_APPROX((m1+m2)(r,c), (m1(r,c))+(m2(r,c)));+ VERIFY_IS_APPROX(m1.cwise() * m1.block(0,0,rows,cols), m1.cwise() * m1);+ VERIFY_IS_APPROX((m1*m1.transpose())*m2, m1*(m1.transpose()*m2));+}++void test_eigen2_nomalloc()+{+ // check that our operator new is indeed called:+ VERIFY_RAISES_ASSERT(MatrixXd dummy = MatrixXd::Random(3,3));+ CALL_SUBTEST_1( nomalloc(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( nomalloc(Matrix4d()) );+ CALL_SUBTEST_3( nomalloc(Matrix<float,32,32>()) );+}
+ eigen3/test/eigen2/eigen2_packetmath.cpp view
@@ -0,0 +1,132 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++// using namespace Eigen;++template<typename Scalar> bool areApprox(const Scalar* a, const Scalar* b, int size)+{+ for (int i=0; i<size; ++i)+ if (!ei_isApprox(a[i],b[i])) return false;+ return true;+}++#define CHECK_CWISE(REFOP, POP) { \+ for (int i=0; i<PacketSize; ++i) \+ ref[i] = REFOP(data1[i], data1[i+PacketSize]); \+ ei_pstore(data2, POP(ei_pload(data1), ei_pload(data1+PacketSize))); \+ VERIFY(areApprox(ref, data2, PacketSize) && #POP); \+}++#define REF_ADD(a,b) ((a)+(b))+#define REF_SUB(a,b) ((a)-(b))+#define REF_MUL(a,b) ((a)*(b))+#define REF_DIV(a,b) ((a)/(b))++namespace std {++template<> const complex<float>& min(const complex<float>& a, const complex<float>& b)+{ return a.real() < b.real() ? a : b; }++template<> const complex<float>& max(const complex<float>& a, const complex<float>& b)+{ return a.real() < b.real() ? b : a; }++}++template<typename Scalar> void packetmath()+{+ typedef typename ei_packet_traits<Scalar>::type Packet;+ const int PacketSize = ei_packet_traits<Scalar>::size;++ const int size = PacketSize*4;+ EIGEN_ALIGN_128 Scalar data1[ei_packet_traits<Scalar>::size*4];+ EIGEN_ALIGN_128 Scalar data2[ei_packet_traits<Scalar>::size*4];+ EIGEN_ALIGN_128 Packet packets[PacketSize*2];+ EIGEN_ALIGN_128 Scalar ref[ei_packet_traits<Scalar>::size*4];+ for (int i=0; i<size; ++i)+ {+ data1[i] = ei_random<Scalar>();+ data2[i] = ei_random<Scalar>();+ }++ ei_pstore(data2, ei_pload(data1));+ VERIFY(areApprox(data1, data2, PacketSize) && "aligned load/store");++ for (int offset=0; offset<PacketSize; ++offset)+ {+ ei_pstore(data2, ei_ploadu(data1+offset));+ VERIFY(areApprox(data1+offset, data2, PacketSize) && "ei_ploadu");+ }++ for (int offset=0; offset<PacketSize; ++offset)+ {+ ei_pstoreu(data2+offset, ei_pload(data1));+ VERIFY(areApprox(data1, data2+offset, PacketSize) && "ei_pstoreu");+ }++ for (int offset=0; offset<PacketSize; ++offset)+ {+ packets[0] = ei_pload(data1);+ packets[1] = ei_pload(data1+PacketSize);+ if (offset==0) ei_palign<0>(packets[0], packets[1]);+ else if (offset==1) ei_palign<1>(packets[0], packets[1]);+ else if (offset==2) ei_palign<2>(packets[0], packets[1]);+ else if (offset==3) ei_palign<3>(packets[0], packets[1]);+ ei_pstore(data2, packets[0]);++ for (int i=0; i<PacketSize; ++i)+ ref[i] = data1[i+offset];++ typedef Matrix<Scalar, PacketSize, 1> Vector;+ VERIFY(areApprox(ref, data2, PacketSize) && "ei_palign");+ }++ CHECK_CWISE(REF_ADD, ei_padd);+ CHECK_CWISE(REF_SUB, ei_psub);+ CHECK_CWISE(REF_MUL, ei_pmul);+ #ifndef EIGEN_VECTORIZE_ALTIVEC+ if (!ei_is_same_type<Scalar,int>::ret)+ CHECK_CWISE(REF_DIV, ei_pdiv);+ #endif+ CHECK_CWISE(std::min, ei_pmin);+ CHECK_CWISE(std::max, ei_pmax);++ for (int i=0; i<PacketSize; ++i)+ ref[i] = data1[0];+ ei_pstore(data2, ei_pset1(data1[0]));+ VERIFY(areApprox(ref, data2, PacketSize) && "ei_pset1");++ VERIFY(ei_isApprox(data1[0], ei_pfirst(ei_pload(data1))) && "ei_pfirst");++ ref[0] = 0;+ for (int i=0; i<PacketSize; ++i)+ ref[0] += data1[i];+ VERIFY(ei_isApprox(ref[0], ei_predux(ei_pload(data1))) && "ei_predux");++ for (int j=0; j<PacketSize; ++j)+ {+ ref[j] = 0;+ for (int i=0; i<PacketSize; ++i)+ ref[j] += data1[i+j*PacketSize];+ packets[j] = ei_pload(data1+j*PacketSize);+ }+ ei_pstore(data2, ei_preduxp(packets));+ VERIFY(areApprox(ref, data2, PacketSize) && "ei_preduxp");+}++void test_eigen2_packetmath()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( packetmath<float>() );+ CALL_SUBTEST_2( packetmath<double>() );+ CALL_SUBTEST_3( packetmath<int>() );+ CALL_SUBTEST_4( packetmath<std::complex<float> >() );+ }+}
+ eigen3/test/eigen2/eigen2_parametrizedline.cpp view
@@ -0,0 +1,62 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/Geometry>+#include <Eigen/LU>+#include <Eigen/QR>++template<typename LineType> void parametrizedline(const LineType& _line)+{+ /* this test covers the following files:+ ParametrizedLine.h+ */++ const int dim = _line.dim();+ typedef typename LineType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, LineType::AmbientDimAtCompileTime, 1> VectorType;+ typedef Matrix<Scalar, LineType::AmbientDimAtCompileTime,+ LineType::AmbientDimAtCompileTime> MatrixType;++ VectorType p0 = VectorType::Random(dim);+ VectorType p1 = VectorType::Random(dim);++ VectorType d0 = VectorType::Random(dim).normalized();++ LineType l0(p0, d0);++ Scalar s0 = ei_random<Scalar>();+ Scalar s1 = ei_abs(ei_random<Scalar>());++ VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(p0), RealScalar(1) );+ VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(p0+s0*d0), RealScalar(1) );+ VERIFY_IS_APPROX( (l0.projection(p1)-p1).norm(), l0.distance(p1) );+ VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(l0.projection(p1)), RealScalar(1) );+ VERIFY_IS_APPROX( Scalar(l0.distance((p0+s0*d0) + d0.unitOrthogonal() * s1)), s1 );++ // casting+ const int Dim = LineType::AmbientDimAtCompileTime;+ typedef typename GetDifferentType<Scalar>::type OtherScalar;+ ParametrizedLine<OtherScalar,Dim> hp1f = l0.template cast<OtherScalar>();+ VERIFY_IS_APPROX(hp1f.template cast<Scalar>(),l0);+ ParametrizedLine<Scalar,Dim> hp1d = l0.template cast<Scalar>();+ VERIFY_IS_APPROX(hp1d.template cast<Scalar>(),l0);+}++void test_eigen2_parametrizedline()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( parametrizedline(ParametrizedLine<float,2>()) );+ CALL_SUBTEST_2( parametrizedline(ParametrizedLine<float,3>()) );+ CALL_SUBTEST_3( parametrizedline(ParametrizedLine<double,4>()) );+ CALL_SUBTEST_4( parametrizedline(ParametrizedLine<std::complex<double>,5>()) );+ }+}
+ eigen3/test/eigen2/eigen2_prec_inverse_4x4.cpp view
@@ -0,0 +1,84 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/LU>+#include <algorithm>++template<typename T> std::string type_name() { return "other"; }+template<> std::string type_name<float>() { return "float"; }+template<> std::string type_name<double>() { return "double"; }+template<> std::string type_name<int>() { return "int"; }+template<> std::string type_name<std::complex<float> >() { return "complex<float>"; }+template<> std::string type_name<std::complex<double> >() { return "complex<double>"; }+template<> std::string type_name<std::complex<int> >() { return "complex<int>"; }++#define EIGEN_DEBUG_VAR(x) std::cerr << #x << " = " << x << std::endl;++template<typename T> inline typename NumTraits<T>::Real epsilon()+{+ return std::numeric_limits<typename NumTraits<T>::Real>::epsilon();+}++template<typename MatrixType> void inverse_permutation_4x4()+{+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::RealScalar RealScalar;+ Vector4i indices(0,1,2,3);+ for(int i = 0; i < 24; ++i)+ {+ MatrixType m = MatrixType::Zero();+ m(indices(0),0) = 1;+ m(indices(1),1) = 1;+ m(indices(2),2) = 1;+ m(indices(3),3) = 1;+ MatrixType inv = m.inverse();+ double error = double( (m*inv-MatrixType::Identity()).norm() / epsilon<Scalar>() );+ VERIFY(error == 0.0);+ std::next_permutation(indices.data(),indices.data()+4);+ }+}++template<typename MatrixType> void inverse_general_4x4(int repeat)+{+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::RealScalar RealScalar;+ double error_sum = 0., error_max = 0.;+ for(int i = 0; i < repeat; ++i)+ {+ MatrixType m;+ RealScalar absdet;+ do {+ m = MatrixType::Random();+ absdet = ei_abs(m.determinant());+ } while(absdet < 10 * epsilon<Scalar>());+ MatrixType inv = m.inverse();+ double error = double( (m*inv-MatrixType::Identity()).norm() * absdet / epsilon<Scalar>() );+ error_sum += error;+ error_max = std::max(error_max, error);+ }+ std::cerr << "inverse_general_4x4, Scalar = " << type_name<Scalar>() << std::endl;+ double error_avg = error_sum / repeat;+ EIGEN_DEBUG_VAR(error_avg);+ EIGEN_DEBUG_VAR(error_max);+ VERIFY(error_avg < (NumTraits<Scalar>::IsComplex ? 8.0 : 1.25));+ VERIFY(error_max < (NumTraits<Scalar>::IsComplex ? 64.0 : 20.0));+}++void test_eigen2_prec_inverse_4x4()+{+ CALL_SUBTEST_1((inverse_permutation_4x4<Matrix4f>()));+ CALL_SUBTEST_1(( inverse_general_4x4<Matrix4f>(200000 * g_repeat) ));++ CALL_SUBTEST_2((inverse_permutation_4x4<Matrix<double,4,4,RowMajor> >()));+ CALL_SUBTEST_2(( inverse_general_4x4<Matrix<double,4,4,RowMajor> >(200000 * g_repeat) ));++ CALL_SUBTEST_3((inverse_permutation_4x4<Matrix4cf>()));+ CALL_SUBTEST_3((inverse_general_4x4<Matrix4cf>(50000 * g_repeat)));+}
+ eigen3/test/eigen2/eigen2_product_large.cpp view
@@ -0,0 +1,45 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "product.h"++void test_eigen2_product_large()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( product(MatrixXf(ei_random<int>(1,320), ei_random<int>(1,320))) );+ CALL_SUBTEST_2( product(MatrixXd(ei_random<int>(1,320), ei_random<int>(1,320))) );+ CALL_SUBTEST_3( product(MatrixXi(ei_random<int>(1,320), ei_random<int>(1,320))) );+ CALL_SUBTEST_4( product(MatrixXcf(ei_random<int>(1,50), ei_random<int>(1,50))) );+ CALL_SUBTEST_5( product(Matrix<float,Dynamic,Dynamic,RowMajor>(ei_random<int>(1,320), ei_random<int>(1,320))) );+ }++#ifdef EIGEN_TEST_PART_6+ {+ // test a specific issue in DiagonalProduct+ int N = 1000000;+ VectorXf v = VectorXf::Ones(N);+ MatrixXf m = MatrixXf::Ones(N,3);+ m = (v+v).asDiagonal() * m;+ VERIFY_IS_APPROX(m, MatrixXf::Constant(N,3,2));+ }++ {+ // test deferred resizing in Matrix::operator=+ MatrixXf a = MatrixXf::Random(10,4), b = MatrixXf::Random(4,10), c = a;+ VERIFY_IS_APPROX((a = a * b), (c * b).eval());+ }++ {+ MatrixXf mat1(10,10); mat1.setRandom();+ MatrixXf mat2(32,10); mat2.setRandom();+ MatrixXf result = mat1.row(2)*mat2.transpose();+ VERIFY_IS_APPROX(result, (mat1.row(2)*mat2.transpose()).eval());+ }+#endif+}
+ eigen3/test/eigen2/eigen2_product_small.cpp view
@@ -0,0 +1,22 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN_NO_STATIC_ASSERT+#include "product.h"++void test_eigen2_product_small()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( product(Matrix<float, 3, 2>()) );+ CALL_SUBTEST_2( product(Matrix<int, 3, 5>()) );+ CALL_SUBTEST_3( product(Matrix3d()) );+ CALL_SUBTEST_4( product(Matrix4d()) );+ CALL_SUBTEST_5( product(Matrix4f()) );+ }+}
+ eigen3/test/eigen2/eigen2_qr.cpp view
@@ -0,0 +1,69 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/QR>++template<typename MatrixType> void qr(const MatrixType& m)+{+ /* this test covers the following files:+ QR.h+ */+ int rows = m.rows();+ int cols = m.cols();++ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime> SquareMatrixType;+ typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;++ MatrixType a = MatrixType::Random(rows,cols);+ QR<MatrixType> qrOfA(a);+ VERIFY_IS_APPROX(a, qrOfA.matrixQ() * qrOfA.matrixR());+ VERIFY_IS_NOT_APPROX(a+MatrixType::Identity(rows, cols), qrOfA.matrixQ() * qrOfA.matrixR());++ #if 0 // eigenvalues module not yet ready+ SquareMatrixType b = a.adjoint() * a;++ // check tridiagonalization+ Tridiagonalization<SquareMatrixType> tridiag(b);+ VERIFY_IS_APPROX(b, tridiag.matrixQ() * tridiag.matrixT() * tridiag.matrixQ().adjoint());++ // check hessenberg decomposition+ HessenbergDecomposition<SquareMatrixType> hess(b);+ VERIFY_IS_APPROX(b, hess.matrixQ() * hess.matrixH() * hess.matrixQ().adjoint());+ VERIFY_IS_APPROX(tridiag.matrixT(), hess.matrixH());+ b = SquareMatrixType::Random(cols,cols);+ hess.compute(b);+ VERIFY_IS_APPROX(b, hess.matrixQ() * hess.matrixH() * hess.matrixQ().adjoint());+ #endif+}++void test_eigen2_qr()+{+ for(int i = 0; i < 1; i++) {+ CALL_SUBTEST_1( qr(Matrix2f()) );+ CALL_SUBTEST_2( qr(Matrix4d()) );+ CALL_SUBTEST_3( qr(MatrixXf(12,8)) );+ CALL_SUBTEST_4( qr(MatrixXcd(5,5)) );+ CALL_SUBTEST_4( qr(MatrixXcd(7,3)) );+ }++#ifdef EIGEN_TEST_PART_5+ // small isFullRank test+ {+ Matrix3d mat;+ mat << 1, 45, 1, 2, 2, 2, 1, 2, 3;+ VERIFY(mat.qr().isFullRank());+ mat << 1, 1, 1, 2, 2, 2, 1, 2, 3;+ //always returns true in eigen2support+ //VERIFY(!mat.qr().isFullRank());+ }++#endif+}
+ eigen3/test/eigen2/eigen2_qtvector.cpp view
@@ -0,0 +1,158 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN_WORK_AROUND_QT_BUG_CALLING_WRONG_OPERATOR_NEW_FIXED_IN_QT_4_5++#include "main.h"++#include <Eigen/Geometry>+#include <Eigen/QtAlignedMalloc>++#include <QtCore/QVector>++template<typename MatrixType>+void check_qtvector_matrix(const MatrixType& m)+{+ int rows = m.rows();+ int cols = m.cols();+ MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols);+ QVector<MatrixType> v(10, MatrixType(rows,cols)), w(20, y);+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], y);+ }+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.fill(y,22);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(MatrixType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ MatrixType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(int i=23; i<v.size(); ++i)+ {+ VERIFY(v[i]==w[(i-23)%w.size()]);+ }+}++template<typename TransformType>+void check_qtvector_transform(const TransformType&)+{+ typedef typename TransformType::MatrixType MatrixType;+ TransformType x(MatrixType::Random()), y(MatrixType::Random());+ QVector<TransformType> v(10), w(20, y);+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.fill(y,22);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(TransformType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ TransformType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(unsigned int i=23; int(i)<v.size(); ++i)+ {+ VERIFY(v[i].matrix()==w[(i-23)%w.size()].matrix());+ }+}++template<typename QuaternionType>+void check_qtvector_quaternion(const QuaternionType&)+{+ typedef typename QuaternionType::Coefficients Coefficients;+ QuaternionType x(Coefficients::Random()), y(Coefficients::Random());+ QVector<QuaternionType> v(10), w(20, y);+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.fill(y,22);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(QuaternionType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ QuaternionType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(unsigned int i=23; int(i)<v.size(); ++i)+ {+ VERIFY(v[i].coeffs()==w[(i-23)%w.size()].coeffs());+ }+}++void test_eigen2_qtvector()+{+ // some non vectorizable fixed sizes+ CALL_SUBTEST_1(check_qtvector_matrix(Vector2f()));+ CALL_SUBTEST_1(check_qtvector_matrix(Matrix3f()));+ CALL_SUBTEST_1(check_qtvector_matrix(Matrix3d()));++ // some vectorizable fixed sizes+ CALL_SUBTEST_2(check_qtvector_matrix(Matrix2f()));+ CALL_SUBTEST_2(check_qtvector_matrix(Vector4f()));+ CALL_SUBTEST_2(check_qtvector_matrix(Matrix4f()));+ CALL_SUBTEST_2(check_qtvector_matrix(Matrix4d()));++ // some dynamic sizes+ CALL_SUBTEST_3(check_qtvector_matrix(MatrixXd(1,1)));+ CALL_SUBTEST_3(check_qtvector_matrix(VectorXd(20)));+ CALL_SUBTEST_3(check_qtvector_matrix(RowVectorXf(20)));+ CALL_SUBTEST_3(check_qtvector_matrix(MatrixXcf(10,10)));++ // some Transform+ CALL_SUBTEST_4(check_qtvector_transform(Transform2f()));+ CALL_SUBTEST_4(check_qtvector_transform(Transform3f()));+ CALL_SUBTEST_4(check_qtvector_transform(Transform3d()));+ //CALL_SUBTEST_4(check_qtvector_transform(Transform4d()));++ // some Quaternion+ CALL_SUBTEST_5(check_qtvector_quaternion(Quaternionf()));+ CALL_SUBTEST_5(check_qtvector_quaternion(Quaternionf()));+}
+ eigen3/test/eigen2/eigen2_regression.cpp view
@@ -0,0 +1,136 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/LeastSquares>++template<typename VectorType,+ typename HyperplaneType>+void makeNoisyCohyperplanarPoints(int numPoints,+ VectorType **points,+ HyperplaneType *hyperplane,+ typename VectorType::Scalar noiseAmplitude)+{+ typedef typename VectorType::Scalar Scalar;+ const int size = points[0]->size();+ // pick a random hyperplane, store the coefficients of its equation+ hyperplane->coeffs().resize(size + 1);+ for(int j = 0; j < size + 1; j++)+ {+ do {+ hyperplane->coeffs().coeffRef(j) = ei_random<Scalar>();+ } while(ei_abs(hyperplane->coeffs().coeff(j)) < 0.5);+ }++ // now pick numPoints random points on this hyperplane+ for(int i = 0; i < numPoints; i++)+ {+ VectorType& cur_point = *(points[i]);+ do+ {+ cur_point = VectorType::Random(size)/*.normalized()*/;+ // project cur_point onto the hyperplane+ Scalar x = - (hyperplane->coeffs().start(size).cwise()*cur_point).sum();+ cur_point *= hyperplane->coeffs().coeff(size) / x;+ } while( cur_point.norm() < 0.5+ || cur_point.norm() > 2.0 );+ }++ // add some noise to these points+ for(int i = 0; i < numPoints; i++ )+ *(points[i]) += noiseAmplitude * VectorType::Random(size);+}++template<typename VectorType>+void check_linearRegression(int numPoints,+ VectorType **points,+ const VectorType& original,+ typename VectorType::Scalar tolerance)+{+ int size = points[0]->size();+ assert(size==2);+ VectorType result(size);+ linearRegression(numPoints, points, &result, 1);+ typename VectorType::Scalar error = (result - original).norm() / original.norm();+ VERIFY(ei_abs(error) < ei_abs(tolerance));+}++template<typename VectorType,+ typename HyperplaneType>+void check_fitHyperplane(int numPoints,+ VectorType **points,+ const HyperplaneType& original,+ typename VectorType::Scalar tolerance)+{+ int size = points[0]->size();+ HyperplaneType result(size);+ fitHyperplane(numPoints, points, &result);+ result.coeffs() *= original.coeffs().coeff(size)/result.coeffs().coeff(size);+ typename VectorType::Scalar error = (result.coeffs() - original.coeffs()).norm() / original.coeffs().norm();+ std::cout << ei_abs(error) << " xxx " << ei_abs(tolerance) << std::endl;+ VERIFY(ei_abs(error) < ei_abs(tolerance));+}++void test_eigen2_regression()+{+ for(int i = 0; i < g_repeat; i++)+ {+#ifdef EIGEN_TEST_PART_1+ {+ Vector2f points2f [1000];+ Vector2f *points2f_ptrs [1000];+ for(int i = 0; i < 1000; i++) points2f_ptrs[i] = &(points2f[i]);+ Vector2f coeffs2f;+ Hyperplane<float,2> coeffs3f;+ makeNoisyCohyperplanarPoints(1000, points2f_ptrs, &coeffs3f, 0.01f);+ coeffs2f[0] = -coeffs3f.coeffs()[0]/coeffs3f.coeffs()[1];+ coeffs2f[1] = -coeffs3f.coeffs()[2]/coeffs3f.coeffs()[1];+ CALL_SUBTEST(check_linearRegression(10, points2f_ptrs, coeffs2f, 0.05f));+ CALL_SUBTEST(check_linearRegression(100, points2f_ptrs, coeffs2f, 0.01f));+ CALL_SUBTEST(check_linearRegression(1000, points2f_ptrs, coeffs2f, 0.002f));+ }+#endif+#ifdef EIGEN_TEST_PART_2+ {+ Vector2f points2f [1000];+ Vector2f *points2f_ptrs [1000];+ for(int i = 0; i < 1000; i++) points2f_ptrs[i] = &(points2f[i]);+ Hyperplane<float,2> coeffs3f;+ makeNoisyCohyperplanarPoints(1000, points2f_ptrs, &coeffs3f, 0.01f);+ CALL_SUBTEST(check_fitHyperplane(10, points2f_ptrs, coeffs3f, 0.05f));+ CALL_SUBTEST(check_fitHyperplane(100, points2f_ptrs, coeffs3f, 0.01f));+ CALL_SUBTEST(check_fitHyperplane(1000, points2f_ptrs, coeffs3f, 0.002f));+ }+#endif+#ifdef EIGEN_TEST_PART_3+ {+ Vector4d points4d [1000];+ Vector4d *points4d_ptrs [1000];+ for(int i = 0; i < 1000; i++) points4d_ptrs[i] = &(points4d[i]);+ Hyperplane<double,4> coeffs5d;+ makeNoisyCohyperplanarPoints(1000, points4d_ptrs, &coeffs5d, 0.01);+ CALL_SUBTEST(check_fitHyperplane(10, points4d_ptrs, coeffs5d, 0.05));+ CALL_SUBTEST(check_fitHyperplane(100, points4d_ptrs, coeffs5d, 0.01));+ CALL_SUBTEST(check_fitHyperplane(1000, points4d_ptrs, coeffs5d, 0.002));+ }+#endif+#ifdef EIGEN_TEST_PART_4+ {+ VectorXcd *points11cd_ptrs[1000];+ for(int i = 0; i < 1000; i++) points11cd_ptrs[i] = new VectorXcd(11);+ Hyperplane<std::complex<double>,Dynamic> *coeffs12cd = new Hyperplane<std::complex<double>,Dynamic>(11);+ makeNoisyCohyperplanarPoints(1000, points11cd_ptrs, coeffs12cd, 0.01);+ CALL_SUBTEST(check_fitHyperplane(100, points11cd_ptrs, *coeffs12cd, 0.025));+ CALL_SUBTEST(check_fitHyperplane(1000, points11cd_ptrs, *coeffs12cd, 0.006));+ delete coeffs12cd;+ for(int i = 0; i < 1000; i++) delete points11cd_ptrs[i];+ }+#endif+ }+}
+ eigen3/test/eigen2/eigen2_sizeof.cpp view
@@ -0,0 +1,31 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void verifySizeOf(const MatrixType&)+{+ typedef typename MatrixType::Scalar Scalar;+ if (MatrixType::RowsAtCompileTime!=Dynamic && MatrixType::ColsAtCompileTime!=Dynamic)+ VERIFY(sizeof(MatrixType)==sizeof(Scalar)*MatrixType::SizeAtCompileTime);+ else+ VERIFY(sizeof(MatrixType)==sizeof(Scalar*) + 2 * sizeof(typename MatrixType::Index));+}++void test_eigen2_sizeof()+{+ CALL_SUBTEST( verifySizeOf(Matrix<float, 1, 1>()) );+ CALL_SUBTEST( verifySizeOf(Matrix4d()) );+ CALL_SUBTEST( verifySizeOf(Matrix<double, 4, 2>()) );+ CALL_SUBTEST( verifySizeOf(Matrix<bool, 7, 5>()) );+ CALL_SUBTEST( verifySizeOf(MatrixXcf(3, 3)) );+ CALL_SUBTEST( verifySizeOf(MatrixXi(8, 12)) );+ CALL_SUBTEST( verifySizeOf(MatrixXcd(20, 20)) );+ CALL_SUBTEST( verifySizeOf(Matrix<float, 100, 100>()) );+}
+ eigen3/test/eigen2/eigen2_smallvectors.cpp view
@@ -0,0 +1,42 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename Scalar> void smallVectors()+{+ typedef Matrix<Scalar, 1, 2> V2;+ typedef Matrix<Scalar, 3, 1> V3;+ typedef Matrix<Scalar, 1, 4> V4;+ Scalar x1 = ei_random<Scalar>(),+ x2 = ei_random<Scalar>(),+ x3 = ei_random<Scalar>(),+ x4 = ei_random<Scalar>();+ V2 v2(x1, x2);+ V3 v3(x1, x2, x3);+ V4 v4(x1, x2, x3, x4);+ VERIFY_IS_APPROX(x1, v2.x());+ VERIFY_IS_APPROX(x1, v3.x());+ VERIFY_IS_APPROX(x1, v4.x());+ VERIFY_IS_APPROX(x2, v2.y());+ VERIFY_IS_APPROX(x2, v3.y());+ VERIFY_IS_APPROX(x2, v4.y());+ VERIFY_IS_APPROX(x3, v3.z());+ VERIFY_IS_APPROX(x3, v4.z());+ VERIFY_IS_APPROX(x4, v4.w());+}++void test_eigen2_smallvectors()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST( smallVectors<int>() );+ CALL_SUBTEST( smallVectors<float>() );+ CALL_SUBTEST( smallVectors<double>() );+ }+}
+ eigen3/test/eigen2/eigen2_sparse_basic.cpp view
@@ -0,0 +1,317 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Daniel Gomez Ferro <dgomezferro@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "sparse.h"++template<typename SetterType,typename DenseType, typename Scalar, int Options>+bool test_random_setter(SparseMatrix<Scalar,Options>& sm, const DenseType& ref, const std::vector<Vector2i>& nonzeroCoords)+{+ typedef SparseMatrix<Scalar,Options> SparseType;+ {+ sm.setZero();+ SetterType w(sm);+ std::vector<Vector2i> remaining = nonzeroCoords;+ while(!remaining.empty())+ {+ int i = ei_random<int>(0,remaining.size()-1);+ w(remaining[i].x(),remaining[i].y()) = ref.coeff(remaining[i].x(),remaining[i].y());+ remaining[i] = remaining.back();+ remaining.pop_back();+ }+ }+ return sm.isApprox(ref);+}++template<typename SetterType,typename DenseType, typename T>+bool test_random_setter(DynamicSparseMatrix<T>& sm, const DenseType& ref, const std::vector<Vector2i>& nonzeroCoords)+{+ sm.setZero();+ std::vector<Vector2i> remaining = nonzeroCoords;+ while(!remaining.empty())+ {+ int i = ei_random<int>(0,remaining.size()-1);+ sm.coeffRef(remaining[i].x(),remaining[i].y()) = ref.coeff(remaining[i].x(),remaining[i].y());+ remaining[i] = remaining.back();+ remaining.pop_back();+ }+ return sm.isApprox(ref);+}++template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& ref)+{+ const int rows = ref.rows();+ const int cols = ref.cols();+ typedef typename SparseMatrixType::Scalar Scalar;+ enum { Flags = SparseMatrixType::Flags };+ + double density = std::max(8./(rows*cols), 0.01);+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;+ typedef Matrix<Scalar,Dynamic,1> DenseVector;+ Scalar eps = 1e-6;++ SparseMatrixType m(rows, cols);+ DenseMatrix refMat = DenseMatrix::Zero(rows, cols);+ DenseVector vec1 = DenseVector::Random(rows);+ Scalar s1 = ei_random<Scalar>();++ std::vector<Vector2i> zeroCoords;+ std::vector<Vector2i> nonzeroCoords;+ initSparse<Scalar>(density, refMat, m, 0, &zeroCoords, &nonzeroCoords);+ + if (zeroCoords.size()==0 || nonzeroCoords.size()==0)+ return;++ // test coeff and coeffRef+ for (int i=0; i<(int)zeroCoords.size(); ++i)+ {+ VERIFY_IS_MUCH_SMALLER_THAN( m.coeff(zeroCoords[i].x(),zeroCoords[i].y()), eps );+ if(ei_is_same_type<SparseMatrixType,SparseMatrix<Scalar,Flags> >::ret)+ VERIFY_RAISES_ASSERT( m.coeffRef(zeroCoords[0].x(),zeroCoords[0].y()) = 5 );+ }+ VERIFY_IS_APPROX(m, refMat);++ m.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);+ refMat.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);++ VERIFY_IS_APPROX(m, refMat);+ /*+ // test InnerIterators and Block expressions+ for (int t=0; t<10; ++t)+ {+ int j = ei_random<int>(0,cols-1);+ int i = ei_random<int>(0,rows-1);+ int w = ei_random<int>(1,cols-j-1);+ int h = ei_random<int>(1,rows-i-1);++// VERIFY_IS_APPROX(m.block(i,j,h,w), refMat.block(i,j,h,w));+ for(int c=0; c<w; c++)+ {+ VERIFY_IS_APPROX(m.block(i,j,h,w).col(c), refMat.block(i,j,h,w).col(c));+ for(int r=0; r<h; r++)+ {+// VERIFY_IS_APPROX(m.block(i,j,h,w).col(c).coeff(r), refMat.block(i,j,h,w).col(c).coeff(r));+ }+ }+// for(int r=0; r<h; r++)+// {+// VERIFY_IS_APPROX(m.block(i,j,h,w).row(r), refMat.block(i,j,h,w).row(r));+// for(int c=0; c<w; c++)+// {+// VERIFY_IS_APPROX(m.block(i,j,h,w).row(r).coeff(c), refMat.block(i,j,h,w).row(r).coeff(c));+// }+// }+ }++ for(int c=0; c<cols; c++)+ {+ VERIFY_IS_APPROX(m.col(c) + m.col(c), (m + m).col(c));+ VERIFY_IS_APPROX(m.col(c) + m.col(c), refMat.col(c) + refMat.col(c));+ }++ for(int r=0; r<rows; r++)+ {+ VERIFY_IS_APPROX(m.row(r) + m.row(r), (m + m).row(r));+ VERIFY_IS_APPROX(m.row(r) + m.row(r), refMat.row(r) + refMat.row(r));+ }+ */++ // test SparseSetters+ // coherent setter+ // TODO extend the MatrixSetter+// {+// m.setZero();+// VERIFY_IS_NOT_APPROX(m, refMat);+// SparseSetter<SparseMatrixType, FullyCoherentAccessPattern> w(m);+// for (int i=0; i<nonzeroCoords.size(); ++i)+// {+// w->coeffRef(nonzeroCoords[i].x(),nonzeroCoords[i].y()) = refMat.coeff(nonzeroCoords[i].x(),nonzeroCoords[i].y());+// }+// }+// VERIFY_IS_APPROX(m, refMat);++ // random setter+// {+// m.setZero();+// VERIFY_IS_NOT_APPROX(m, refMat);+// SparseSetter<SparseMatrixType, RandomAccessPattern> w(m);+// std::vector<Vector2i> remaining = nonzeroCoords;+// while(!remaining.empty())+// {+// int i = ei_random<int>(0,remaining.size()-1);+// w->coeffRef(remaining[i].x(),remaining[i].y()) = refMat.coeff(remaining[i].x(),remaining[i].y());+// remaining[i] = remaining.back();+// remaining.pop_back();+// }+// }+// VERIFY_IS_APPROX(m, refMat);++ VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, StdMapTraits> >(m,refMat,nonzeroCoords) ));+ #ifdef EIGEN_UNORDERED_MAP_SUPPORT+ VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, StdUnorderedMapTraits> >(m,refMat,nonzeroCoords) ));+ #endif+ #ifdef _DENSE_HASH_MAP_H_+ VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, GoogleDenseHashMapTraits> >(m,refMat,nonzeroCoords) ));+ #endif+ #ifdef _SPARSE_HASH_MAP_H_+ VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, GoogleSparseHashMapTraits> >(m,refMat,nonzeroCoords) ));+ #endif++ // test fillrand+ {+ DenseMatrix m1(rows,cols);+ m1.setZero();+ SparseMatrixType m2(rows,cols);+ m2.startFill();+ for (int j=0; j<cols; ++j)+ {+ for (int k=0; k<rows/2; ++k)+ {+ int i = ei_random<int>(0,rows-1);+ if (m1.coeff(i,j)==Scalar(0))+ m2.fillrand(i,j) = m1(i,j) = ei_random<Scalar>();+ }+ }+ m2.endFill();+ VERIFY_IS_APPROX(m2,m1);+ }+ + // test RandomSetter+ /*{+ SparseMatrixType m1(rows,cols), m2(rows,cols);+ DenseMatrix refM1 = DenseMatrix::Zero(rows, rows);+ initSparse<Scalar>(density, refM1, m1);+ {+ Eigen::RandomSetter<SparseMatrixType > setter(m2);+ for (int j=0; j<m1.outerSize(); ++j)+ for (typename SparseMatrixType::InnerIterator i(m1,j); i; ++i)+ setter(i.index(), j) = i.value();+ }+ VERIFY_IS_APPROX(m1, m2);+ }*/+// std::cerr << m.transpose() << "\n\n" << refMat.transpose() << "\n\n";+// VERIFY_IS_APPROX(m, refMat);++ // test basic computations+ {+ DenseMatrix refM1 = DenseMatrix::Zero(rows, rows);+ DenseMatrix refM2 = DenseMatrix::Zero(rows, rows);+ DenseMatrix refM3 = DenseMatrix::Zero(rows, rows);+ DenseMatrix refM4 = DenseMatrix::Zero(rows, rows);+ SparseMatrixType m1(rows, rows);+ SparseMatrixType m2(rows, rows);+ SparseMatrixType m3(rows, rows);+ SparseMatrixType m4(rows, rows);+ initSparse<Scalar>(density, refM1, m1);+ initSparse<Scalar>(density, refM2, m2);+ initSparse<Scalar>(density, refM3, m3);+ initSparse<Scalar>(density, refM4, m4);++ VERIFY_IS_APPROX(m1+m2, refM1+refM2);+ VERIFY_IS_APPROX(m1+m2+m3, refM1+refM2+refM3);+ VERIFY_IS_APPROX(m3.cwise()*(m1+m2), refM3.cwise()*(refM1+refM2));+ VERIFY_IS_APPROX(m1*s1-m2, refM1*s1-refM2);++ VERIFY_IS_APPROX(m1*=s1, refM1*=s1);+ VERIFY_IS_APPROX(m1/=s1, refM1/=s1);+ + VERIFY_IS_APPROX(m1+=m2, refM1+=refM2);+ VERIFY_IS_APPROX(m1-=m2, refM1-=refM2);+ + VERIFY_IS_APPROX(m1.col(0).eigen2_dot(refM2.row(0)), refM1.col(0).eigen2_dot(refM2.row(0)));+ + refM4.setRandom();+ // sparse cwise* dense+ VERIFY_IS_APPROX(m3.cwise()*refM4, refM3.cwise()*refM4);+// VERIFY_IS_APPROX(m3.cwise()/refM4, refM3.cwise()/refM4);+ }++ // test innerVector()+ {+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);+ SparseMatrixType m2(rows, rows);+ initSparse<Scalar>(density, refMat2, m2);+ int j0 = ei_random(0,rows-1);+ int j1 = ei_random(0,rows-1);+ VERIFY_IS_APPROX(m2.innerVector(j0), refMat2.col(j0));+ VERIFY_IS_APPROX(m2.innerVector(j0)+m2.innerVector(j1), refMat2.col(j0)+refMat2.col(j1));+ //m2.innerVector(j0) = 2*m2.innerVector(j1);+ //refMat2.col(j0) = 2*refMat2.col(j1);+ //VERIFY_IS_APPROX(m2, refMat2);+ }+ + // test innerVectors()+ {+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);+ SparseMatrixType m2(rows, rows);+ initSparse<Scalar>(density, refMat2, m2);+ int j0 = ei_random(0,rows-2);+ int j1 = ei_random(0,rows-2);+ int n0 = ei_random<int>(1,rows-std::max(j0,j1));+ VERIFY_IS_APPROX(m2.innerVectors(j0,n0), refMat2.block(0,j0,rows,n0));+ VERIFY_IS_APPROX(m2.innerVectors(j0,n0)+m2.innerVectors(j1,n0),+ refMat2.block(0,j0,rows,n0)+refMat2.block(0,j1,rows,n0));+ //m2.innerVectors(j0,n0) = m2.innerVectors(j0,n0) + m2.innerVectors(j1,n0);+ //refMat2.block(0,j0,rows,n0) = refMat2.block(0,j0,rows,n0) + refMat2.block(0,j1,rows,n0);+ }++ // test transpose+ {+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);+ SparseMatrixType m2(rows, rows);+ initSparse<Scalar>(density, refMat2, m2);+ VERIFY_IS_APPROX(m2.transpose().eval(), refMat2.transpose().eval());+ VERIFY_IS_APPROX(m2.transpose(), refMat2.transpose());+ }+ + // test prune+ {+ SparseMatrixType m2(rows, rows);+ DenseMatrix refM2(rows, rows);+ refM2.setZero();+ int countFalseNonZero = 0;+ int countTrueNonZero = 0;+ m2.startFill();+ for (int j=0; j<m2.outerSize(); ++j)+ for (int i=0; i<m2.innerSize(); ++i)+ {+ float x = ei_random<float>(0,1);+ if (x<0.1)+ {+ // do nothing+ }+ else if (x<0.5)+ {+ countFalseNonZero++;+ m2.fill(i,j) = Scalar(0);+ }+ else+ {+ countTrueNonZero++;+ m2.fill(i,j) = refM2(i,j) = Scalar(1);+ }+ }+ m2.endFill();+ VERIFY(countFalseNonZero+countTrueNonZero == m2.nonZeros());+ VERIFY_IS_APPROX(m2, refM2);+ m2.prune(1);+ VERIFY(countTrueNonZero==m2.nonZeros());+ VERIFY_IS_APPROX(m2, refM2);+ }+}++void test_eigen2_sparse_basic()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( sparse_basic(SparseMatrix<double>(8, 8)) );+ CALL_SUBTEST_2( sparse_basic(SparseMatrix<std::complex<double> >(16, 16)) );+ CALL_SUBTEST_1( sparse_basic(SparseMatrix<double>(33, 33)) );+ + CALL_SUBTEST_3( sparse_basic(DynamicSparseMatrix<double>(8, 8)) );+ }+}
+ eigen3/test/eigen2/eigen2_sparse_product.cpp view
@@ -0,0 +1,115 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Daniel Gomez Ferro <dgomezferro@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "sparse.h"++template<typename SparseMatrixType> void sparse_product(const SparseMatrixType& ref)+{+ const int rows = ref.rows();+ const int cols = ref.cols();+ typedef typename SparseMatrixType::Scalar Scalar;+ enum { Flags = SparseMatrixType::Flags };++ double density = std::max(8./(rows*cols), 0.01);+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;+ typedef Matrix<Scalar,Dynamic,1> DenseVector;++ // test matrix-matrix product+ {+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);+ DenseMatrix refMat3 = DenseMatrix::Zero(rows, rows);+ DenseMatrix refMat4 = DenseMatrix::Zero(rows, rows);+ DenseMatrix dm4 = DenseMatrix::Zero(rows, rows);+ SparseMatrixType m2(rows, rows);+ SparseMatrixType m3(rows, rows);+ SparseMatrixType m4(rows, rows);+ initSparse<Scalar>(density, refMat2, m2);+ initSparse<Scalar>(density, refMat3, m3);+ initSparse<Scalar>(density, refMat4, m4);+ VERIFY_IS_APPROX(m4=m2*m3, refMat4=refMat2*refMat3);+ VERIFY_IS_APPROX(m4=m2.transpose()*m3, refMat4=refMat2.transpose()*refMat3);+ VERIFY_IS_APPROX(m4=m2.transpose()*m3.transpose(), refMat4=refMat2.transpose()*refMat3.transpose());+ VERIFY_IS_APPROX(m4=m2*m3.transpose(), refMat4=refMat2*refMat3.transpose());++ // sparse * dense+ VERIFY_IS_APPROX(dm4=m2*refMat3, refMat4=refMat2*refMat3);+ VERIFY_IS_APPROX(dm4=m2*refMat3.transpose(), refMat4=refMat2*refMat3.transpose());+ VERIFY_IS_APPROX(dm4=m2.transpose()*refMat3, refMat4=refMat2.transpose()*refMat3);+ VERIFY_IS_APPROX(dm4=m2.transpose()*refMat3.transpose(), refMat4=refMat2.transpose()*refMat3.transpose());++ // dense * sparse+ VERIFY_IS_APPROX(dm4=refMat2*m3, refMat4=refMat2*refMat3);+ VERIFY_IS_APPROX(dm4=refMat2*m3.transpose(), refMat4=refMat2*refMat3.transpose());+ VERIFY_IS_APPROX(dm4=refMat2.transpose()*m3, refMat4=refMat2.transpose()*refMat3);+ VERIFY_IS_APPROX(dm4=refMat2.transpose()*m3.transpose(), refMat4=refMat2.transpose()*refMat3.transpose());++ VERIFY_IS_APPROX(m3=m3*m3, refMat3=refMat3*refMat3);+ }++ // test matrix - diagonal product+ if(false) // it compiles, but the precision is terrible. probably doesn't matter in this branch....+ {+ DenseMatrix refM2 = DenseMatrix::Zero(rows, rows);+ DenseMatrix refM3 = DenseMatrix::Zero(rows, rows);+ DiagonalMatrix<DenseVector> d1(DenseVector::Random(rows));+ SparseMatrixType m2(rows, rows);+ SparseMatrixType m3(rows, rows);+ initSparse<Scalar>(density, refM2, m2);+ initSparse<Scalar>(density, refM3, m3);+ VERIFY_IS_APPROX(m3=m2*d1, refM3=refM2*d1);+ VERIFY_IS_APPROX(m3=m2.transpose()*d1, refM3=refM2.transpose()*d1);+ VERIFY_IS_APPROX(m3=d1*m2, refM3=d1*refM2);+ VERIFY_IS_APPROX(m3=d1*m2.transpose(), refM3=d1 * refM2.transpose());+ }++ // test self adjoint products+ {+ DenseMatrix b = DenseMatrix::Random(rows, rows);+ DenseMatrix x = DenseMatrix::Random(rows, rows);+ DenseMatrix refX = DenseMatrix::Random(rows, rows);+ DenseMatrix refUp = DenseMatrix::Zero(rows, rows);+ DenseMatrix refLo = DenseMatrix::Zero(rows, rows);+ DenseMatrix refS = DenseMatrix::Zero(rows, rows);+ SparseMatrixType mUp(rows, rows);+ SparseMatrixType mLo(rows, rows);+ SparseMatrixType mS(rows, rows);+ do {+ initSparse<Scalar>(density, refUp, mUp, ForceRealDiag|/*ForceNonZeroDiag|*/MakeUpperTriangular);+ } while (refUp.isZero());+ refLo = refUp.transpose().conjugate();+ mLo = mUp.transpose().conjugate();+ refS = refUp + refLo;+ refS.diagonal() *= 0.5;+ mS = mUp + mLo;+ for (int k=0; k<mS.outerSize(); ++k)+ for (typename SparseMatrixType::InnerIterator it(mS,k); it; ++it)+ if (it.index() == k)+ it.valueRef() *= 0.5;++ VERIFY_IS_APPROX(refS.adjoint(), refS);+ VERIFY_IS_APPROX(mS.transpose().conjugate(), mS);+ VERIFY_IS_APPROX(mS, refS);+ VERIFY_IS_APPROX(x=mS*b, refX=refS*b);+ VERIFY_IS_APPROX(x=mUp.template marked<UpperTriangular|SelfAdjoint>()*b, refX=refS*b);+ VERIFY_IS_APPROX(x=mLo.template marked<LowerTriangular|SelfAdjoint>()*b, refX=refS*b);+ VERIFY_IS_APPROX(x=mS.template marked<SelfAdjoint>()*b, refX=refS*b);+ }++}++void test_eigen2_sparse_product()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( sparse_product(SparseMatrix<double>(8, 8)) );+ CALL_SUBTEST_2( sparse_product(SparseMatrix<std::complex<double> >(16, 16)) );+ CALL_SUBTEST_1( sparse_product(SparseMatrix<double>(33, 33)) );++ CALL_SUBTEST_3( sparse_product(DynamicSparseMatrix<double>(8, 8)) );+ }+}
+ eigen3/test/eigen2/eigen2_sparse_solvers.cpp view
@@ -0,0 +1,200 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Daniel Gomez Ferro <dgomezferro@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "sparse.h"++template<typename Scalar> void+initSPD(double density,+ Matrix<Scalar,Dynamic,Dynamic>& refMat,+ SparseMatrix<Scalar>& sparseMat)+{+ Matrix<Scalar,Dynamic,Dynamic> aux(refMat.rows(),refMat.cols());+ initSparse(density,refMat,sparseMat);+ refMat = refMat * refMat.adjoint();+ for (int k=0; k<2; ++k)+ {+ initSparse(density,aux,sparseMat,ForceNonZeroDiag);+ refMat += aux * aux.adjoint();+ }+ sparseMat.startFill();+ for (int j=0 ; j<sparseMat.cols(); ++j)+ for (int i=j ; i<sparseMat.rows(); ++i)+ if (refMat(i,j)!=Scalar(0))+ sparseMat.fill(i,j) = refMat(i,j);+ sparseMat.endFill();+}++template<typename Scalar> void sparse_solvers(int rows, int cols)+{+ double density = std::max(8./(rows*cols), 0.01);+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;+ typedef Matrix<Scalar,Dynamic,1> DenseVector;+ // Scalar eps = 1e-6;++ DenseVector vec1 = DenseVector::Random(rows);++ std::vector<Vector2i> zeroCoords;+ std::vector<Vector2i> nonzeroCoords;++ // test triangular solver+ {+ DenseVector vec2 = vec1, vec3 = vec1;+ SparseMatrix<Scalar> m2(rows, cols);+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, cols);++ // lower+ initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeLowerTriangular, &zeroCoords, &nonzeroCoords);+ VERIFY_IS_APPROX(refMat2.template marked<LowerTriangular>().solveTriangular(vec2),+ m2.template marked<LowerTriangular>().solveTriangular(vec3));++ // lower - transpose+ initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeLowerTriangular, &zeroCoords, &nonzeroCoords);+ VERIFY_IS_APPROX(refMat2.template marked<LowerTriangular>().transpose().solveTriangular(vec2),+ m2.template marked<LowerTriangular>().transpose().solveTriangular(vec3));++ // upper+ initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeUpperTriangular, &zeroCoords, &nonzeroCoords);+ VERIFY_IS_APPROX(refMat2.template marked<UpperTriangular>().solveTriangular(vec2),+ m2.template marked<UpperTriangular>().solveTriangular(vec3));++ // upper - transpose+ initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeUpperTriangular, &zeroCoords, &nonzeroCoords);+ VERIFY_IS_APPROX(refMat2.template marked<UpperTriangular>().transpose().solveTriangular(vec2),+ m2.template marked<UpperTriangular>().transpose().solveTriangular(vec3));+ }++ // test LLT+ {+ // TODO fix the issue with complex (see SparseLLT::solveInPlace)+ SparseMatrix<Scalar> m2(rows, cols);+ DenseMatrix refMat2(rows, cols);++ DenseVector b = DenseVector::Random(cols);+ DenseVector refX(cols), x(cols);++ initSPD(density, refMat2, m2);++ refMat2.llt().solve(b, &refX);+ typedef SparseMatrix<Scalar,LowerTriangular|SelfAdjoint> SparseSelfAdjointMatrix;+ if (!NumTraits<Scalar>::IsComplex)+ {+ x = b;+ SparseLLT<SparseSelfAdjointMatrix> (m2).solveInPlace(x);+ VERIFY(refX.isApprox(x,test_precision<Scalar>()) && "LLT: default");+ }+ #ifdef EIGEN_CHOLMOD_SUPPORT+ x = b;+ SparseLLT<SparseSelfAdjointMatrix,Cholmod>(m2).solveInPlace(x);+ VERIFY(refX.isApprox(x,test_precision<Scalar>()) && "LLT: cholmod");+ #endif+ if (!NumTraits<Scalar>::IsComplex)+ {+ #ifdef EIGEN_TAUCS_SUPPORT+ x = b;+ SparseLLT<SparseSelfAdjointMatrix,Taucs>(m2,IncompleteFactorization).solveInPlace(x);+ VERIFY(refX.isApprox(x,test_precision<Scalar>()) && "LLT: taucs (IncompleteFactorization)");+ x = b;+ SparseLLT<SparseSelfAdjointMatrix,Taucs>(m2,SupernodalMultifrontal).solveInPlace(x);+ VERIFY(refX.isApprox(x,test_precision<Scalar>()) && "LLT: taucs (SupernodalMultifrontal)");+ x = b;+ SparseLLT<SparseSelfAdjointMatrix,Taucs>(m2,SupernodalLeftLooking).solveInPlace(x);+ VERIFY(refX.isApprox(x,test_precision<Scalar>()) && "LLT: taucs (SupernodalLeftLooking)");+ #endif+ }+ }++ // test LDLT+ if (!NumTraits<Scalar>::IsComplex)+ {+ // TODO fix the issue with complex (see SparseLDLT::solveInPlace)+ SparseMatrix<Scalar> m2(rows, cols);+ DenseMatrix refMat2(rows, cols);++ DenseVector b = DenseVector::Random(cols);+ DenseVector refX(cols), x(cols);++ //initSPD(density, refMat2, m2);+ initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeUpperTriangular, 0, 0);+ refMat2 += refMat2.adjoint();+ refMat2.diagonal() *= 0.5;++ refMat2.ldlt().solve(b, &refX);+ typedef SparseMatrix<Scalar,UpperTriangular|SelfAdjoint> SparseSelfAdjointMatrix;+ x = b;+ SparseLDLT<SparseSelfAdjointMatrix> ldlt(m2);+ if (ldlt.succeeded())+ ldlt.solveInPlace(x);+ VERIFY(refX.isApprox(x,test_precision<Scalar>()) && "LDLT: default");+ }++ // test LU+ {+ static int count = 0;+ SparseMatrix<Scalar> m2(rows, cols);+ DenseMatrix refMat2(rows, cols);++ DenseVector b = DenseVector::Random(cols);+ DenseVector refX(cols), x(cols);++ initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag, &zeroCoords, &nonzeroCoords);++ LU<DenseMatrix> refLu(refMat2);+ refLu.solve(b, &refX);+ #if defined(EIGEN_SUPERLU_SUPPORT) || defined(EIGEN_UMFPACK_SUPPORT)+ Scalar refDet = refLu.determinant();+ #endif+ x.setZero();+ // // SparseLU<SparseMatrix<Scalar> > (m2).solve(b,&x);+ // // VERIFY(refX.isApprox(x,test_precision<Scalar>()) && "LU: default");+ #ifdef EIGEN_SUPERLU_SUPPORT+ {+ x.setZero();+ SparseLU<SparseMatrix<Scalar>,SuperLU> slu(m2);+ if (slu.succeeded())+ {+ if (slu.solve(b,&x)) {+ VERIFY(refX.isApprox(x,test_precision<Scalar>()) && "LU: SuperLU");+ }+ // std::cerr << refDet << " == " << slu.determinant() << "\n";+ if (count==0) {+ VERIFY_IS_APPROX(refDet,slu.determinant()); // FIXME det is not very stable for complex+ }+ }+ }+ #endif+ #ifdef EIGEN_UMFPACK_SUPPORT+ {+ // check solve+ x.setZero();+ SparseLU<SparseMatrix<Scalar>,UmfPack> slu(m2);+ if (slu.succeeded()) {+ if (slu.solve(b,&x)) {+ if (count==0) {+ VERIFY(refX.isApprox(x,test_precision<Scalar>()) && "LU: umfpack"); // FIXME solve is not very stable for complex+ }+ }+ VERIFY_IS_APPROX(refDet,slu.determinant());+ // TODO check the extracted data+ //std::cerr << slu.matrixL() << "\n";+ }+ }+ #endif+ count++;+ }++}++void test_eigen2_sparse_solvers()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( sparse_solvers<double>(8, 8) );+ CALL_SUBTEST_2( sparse_solvers<std::complex<double> >(16, 16) );+ CALL_SUBTEST_1( sparse_solvers<double>(101, 101) );+ }+}
+ eigen3/test/eigen2/eigen2_sparse_vector.cpp view
@@ -0,0 +1,84 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Daniel Gomez Ferro <dgomezferro@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "sparse.h"++template<typename Scalar> void sparse_vector(int rows, int cols)+{+ double densityMat = std::max(8./(rows*cols), 0.01);+ double densityVec = std::max(8./float(rows), 0.1);+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;+ typedef Matrix<Scalar,Dynamic,1> DenseVector;+ typedef SparseVector<Scalar> SparseVectorType;+ typedef SparseMatrix<Scalar> SparseMatrixType;+ Scalar eps = 1e-6;++ SparseMatrixType m1(rows,cols);+ SparseVectorType v1(rows), v2(rows), v3(rows);+ DenseMatrix refM1 = DenseMatrix::Zero(rows, cols);+ DenseVector refV1 = DenseVector::Random(rows),+ refV2 = DenseVector::Random(rows),+ refV3 = DenseVector::Random(rows);++ std::vector<int> zerocoords, nonzerocoords;+ initSparse<Scalar>(densityVec, refV1, v1, &zerocoords, &nonzerocoords);+ initSparse<Scalar>(densityMat, refM1, m1);++ initSparse<Scalar>(densityVec, refV2, v2);+ initSparse<Scalar>(densityVec, refV3, v3);++ Scalar s1 = ei_random<Scalar>();++ // test coeff and coeffRef+ for (unsigned int i=0; i<zerocoords.size(); ++i)+ {+ VERIFY_IS_MUCH_SMALLER_THAN( v1.coeff(zerocoords[i]), eps );+ //VERIFY_RAISES_ASSERT( v1.coeffRef(zerocoords[i]) = 5 );+ }+ {+ VERIFY(int(nonzerocoords.size()) == v1.nonZeros());+ int j=0;+ for (typename SparseVectorType::InnerIterator it(v1); it; ++it,++j)+ {+ VERIFY(nonzerocoords[j]==it.index());+ VERIFY(it.value()==v1.coeff(it.index()));+ VERIFY(it.value()==refV1.coeff(it.index()));+ }+ }+ VERIFY_IS_APPROX(v1, refV1);++ v1.coeffRef(nonzerocoords[0]) = Scalar(5);+ refV1.coeffRef(nonzerocoords[0]) = Scalar(5);+ VERIFY_IS_APPROX(v1, refV1);++ VERIFY_IS_APPROX(v1+v2, refV1+refV2);+ VERIFY_IS_APPROX(v1+v2+v3, refV1+refV2+refV3);++ VERIFY_IS_APPROX(v1*s1-v2, refV1*s1-refV2);++ VERIFY_IS_APPROX(v1*=s1, refV1*=s1);+ VERIFY_IS_APPROX(v1/=s1, refV1/=s1);+ + VERIFY_IS_APPROX(v1+=v2, refV1+=refV2);+ VERIFY_IS_APPROX(v1-=v2, refV1-=refV2);++ VERIFY_IS_APPROX(v1.eigen2_dot(v2), refV1.eigen2_dot(refV2));+ VERIFY_IS_APPROX(v1.eigen2_dot(refV2), refV1.eigen2_dot(refV2));++}++void test_eigen2_sparse_vector()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( sparse_vector<double>(8, 8) );+ CALL_SUBTEST_2( sparse_vector<std::complex<double> >(16, 16) );+ CALL_SUBTEST_1( sparse_vector<double>(299, 535) );+ }+}+
+ eigen3/test/eigen2/eigen2_stdvector.cpp view
@@ -0,0 +1,148 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include <Eigen/StdVector>+#include "main.h"+#include <Eigen/Geometry>++template<typename MatrixType>+void check_stdvector_matrix(const MatrixType& m)+{+ int rows = m.rows();+ int cols = m.cols();+ MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols);+ std::vector<MatrixType, aligned_allocator<MatrixType> > v(10, MatrixType(rows,cols)), w(20, y);+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((std::size_t)&(v[22]) == (std::size_t)&(v[21]) + sizeof(MatrixType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ MatrixType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(unsigned int i=23; i<v.size(); ++i)+ {+ VERIFY(v[i]==w[(i-23)%w.size()]);+ }+}++template<typename TransformType>+void check_stdvector_transform(const TransformType&)+{+ typedef typename TransformType::MatrixType MatrixType;+ TransformType x(MatrixType::Random()), y(MatrixType::Random());+ std::vector<TransformType, aligned_allocator<TransformType> > v(10), w(20, y);+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((std::size_t)&(v[22]) == (std::size_t)&(v[21]) + sizeof(TransformType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ TransformType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(unsigned int i=23; i<v.size(); ++i)+ {+ VERIFY(v[i].matrix()==w[(i-23)%w.size()].matrix());+ }+}++template<typename QuaternionType>+void check_stdvector_quaternion(const QuaternionType&)+{+ typedef typename QuaternionType::Coefficients Coefficients;+ QuaternionType x(Coefficients::Random()), y(Coefficients::Random());+ std::vector<QuaternionType, aligned_allocator<QuaternionType> > v(10), w(20, y);+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((std::size_t)&(v[22]) == (std::size_t)&(v[21]) + sizeof(QuaternionType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ QuaternionType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(unsigned int i=23; i<v.size(); ++i)+ {+ VERIFY(v[i].coeffs()==w[(i-23)%w.size()].coeffs());+ }+}++void test_eigen2_stdvector()+{+ // some non vectorizable fixed sizes+ CALL_SUBTEST_1(check_stdvector_matrix(Vector2f()));+ CALL_SUBTEST_1(check_stdvector_matrix(Matrix3f()));+ CALL_SUBTEST_1(check_stdvector_matrix(Matrix3d()));++ // some vectorizable fixed sizes+ CALL_SUBTEST_2(check_stdvector_matrix(Matrix2f()));+ CALL_SUBTEST_2(check_stdvector_matrix(Vector4f()));+ CALL_SUBTEST_2(check_stdvector_matrix(Matrix4f()));+ CALL_SUBTEST_2(check_stdvector_matrix(Matrix4d()));++ // some dynamic sizes+ CALL_SUBTEST_3(check_stdvector_matrix(MatrixXd(1,1)));+ CALL_SUBTEST_3(check_stdvector_matrix(VectorXd(20)));+ CALL_SUBTEST_3(check_stdvector_matrix(RowVectorXf(20)));+ CALL_SUBTEST_3(check_stdvector_matrix(MatrixXcf(10,10)));++ // some Transform+ CALL_SUBTEST_4(check_stdvector_transform(Transform2f()));+ CALL_SUBTEST_4(check_stdvector_transform(Transform3f()));+ CALL_SUBTEST_4(check_stdvector_transform(Transform3d()));+ //CALL_SUBTEST_4(check_stdvector_transform(Transform4d()));++ // some Quaternion+ CALL_SUBTEST_5(check_stdvector_quaternion(Quaternionf()));+ CALL_SUBTEST_5(check_stdvector_quaternion(Quaternionf()));+}
+ eigen3/test/eigen2/eigen2_submatrices.cpp view
@@ -0,0 +1,142 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++// check minor separately in order to avoid the possible creation of a zero-sized+// array. Comes from a compilation error with gcc-3.4 or gcc-4 with -ansi -pedantic.+// Another solution would be to declare the array like this: T m_data[Size==0?1:Size]; in ei_matrix_storage+// but this is probably not bad to raise such an error at compile time...+template<typename Scalar, int _Rows, int _Cols> struct CheckMinor+{+ typedef Matrix<Scalar, _Rows, _Cols> MatrixType;+ CheckMinor(MatrixType& m1, int r1, int c1)+ {+ int rows = m1.rows();+ int cols = m1.cols();++ Matrix<Scalar, Dynamic, Dynamic> mi = m1.minor(0,0).eval();+ VERIFY_IS_APPROX(mi, m1.block(1,1,rows-1,cols-1));+ mi = m1.minor(r1,c1);+ VERIFY_IS_APPROX(mi.transpose(), m1.transpose().minor(c1,r1));+ //check operator(), both constant and non-constant, on minor()+ m1.minor(r1,c1)(0,0) = m1.minor(0,0)(0,0);+ }+};++template<typename Scalar> struct CheckMinor<Scalar,1,1>+{+ typedef Matrix<Scalar, 1, 1> MatrixType;+ CheckMinor(MatrixType&, int, int) {}+};++template<typename MatrixType> void submatrices(const MatrixType& m)+{+ /* this test covers the following files:+ Row.h Column.h Block.h Minor.h DiagonalCoeffs.h+ */+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::RealScalar RealScalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;+ typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;+ int rows = m.rows();+ int cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols),+ ones = MatrixType::Ones(rows, cols),+ square = Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>+ ::Random(rows, rows);+ VectorType v1 = VectorType::Random(rows);++ Scalar s1 = ei_random<Scalar>();++ int r1 = ei_random<int>(0,rows-1);+ int r2 = ei_random<int>(r1,rows-1);+ int c1 = ei_random<int>(0,cols-1);+ int c2 = ei_random<int>(c1,cols-1);++ //check row() and col()+ VERIFY_IS_APPROX(m1.col(c1).transpose(), m1.transpose().row(c1));+ VERIFY_IS_APPROX(square.row(r1).eigen2_dot(m1.col(c1)), (square.lazy() * m1.conjugate())(r1,c1));+ //check operator(), both constant and non-constant, on row() and col()+ m1.row(r1) += s1 * m1.row(r2);+ m1.col(c1) += s1 * m1.col(c2);++ //check block()+ Matrix<Scalar,Dynamic,Dynamic> b1(1,1); b1(0,0) = m1(r1,c1);+ RowVectorType br1(m1.block(r1,0,1,cols));+ VectorType bc1(m1.block(0,c1,rows,1));+ VERIFY_IS_APPROX(b1, m1.block(r1,c1,1,1));+ VERIFY_IS_APPROX(m1.row(r1), br1);+ VERIFY_IS_APPROX(m1.col(c1), bc1);+ //check operator(), both constant and non-constant, on block()+ m1.block(r1,c1,r2-r1+1,c2-c1+1) = s1 * m2.block(0, 0, r2-r1+1,c2-c1+1);+ m1.block(r1,c1,r2-r1+1,c2-c1+1)(r2-r1,c2-c1) = m2.block(0, 0, r2-r1+1,c2-c1+1)(0,0);++ //check minor()+ CheckMinor<Scalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime> checkminor(m1,r1,c1);++ //check diagonal()+ VERIFY_IS_APPROX(m1.diagonal(), m1.transpose().diagonal());+ m2.diagonal() = 2 * m1.diagonal();+ m2.diagonal()[0] *= 3;+ VERIFY_IS_APPROX(m2.diagonal()[0], static_cast<Scalar>(6) * m1.diagonal()[0]);++ enum {+ BlockRows = EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::RowsAtCompileTime,2),+ BlockCols = EIGEN_SIZE_MIN_PREFER_FIXED(MatrixType::ColsAtCompileTime,5)+ };+ if (rows>=5 && cols>=8)+ {+ // test fixed block() as lvalue+ m1.template block<BlockRows,BlockCols>(1,1) *= s1;+ // test operator() on fixed block() both as constant and non-constant+ m1.template block<BlockRows,BlockCols>(1,1)(0, 3) = m1.template block<2,5>(1,1)(1,2);+ // check that fixed block() and block() agree+ Matrix<Scalar,Dynamic,Dynamic> b = m1.template block<BlockRows,BlockCols>(3,3);+ VERIFY_IS_APPROX(b, m1.block(3,3,BlockRows,BlockCols));+ }++ if (rows>2)+ {+ // test sub vectors+ VERIFY_IS_APPROX(v1.template start<2>(), v1.block(0,0,2,1));+ VERIFY_IS_APPROX(v1.template start<2>(), v1.start(2));+ VERIFY_IS_APPROX(v1.template start<2>(), v1.segment(0,2));+ VERIFY_IS_APPROX(v1.template start<2>(), v1.template segment<2>(0));+ int i = rows-2;+ VERIFY_IS_APPROX(v1.template end<2>(), v1.block(i,0,2,1));+ VERIFY_IS_APPROX(v1.template end<2>(), v1.end(2));+ VERIFY_IS_APPROX(v1.template end<2>(), v1.segment(i,2));+ VERIFY_IS_APPROX(v1.template end<2>(), v1.template segment<2>(i));+ i = ei_random(0,rows-2);+ VERIFY_IS_APPROX(v1.segment(i,2), v1.template segment<2>(i));+ }++ // stress some basic stuffs with block matrices+ VERIFY(ei_real(ones.col(c1).sum()) == RealScalar(rows));+ VERIFY(ei_real(ones.row(r1).sum()) == RealScalar(cols));++ VERIFY(ei_real(ones.col(c1).eigen2_dot(ones.col(c2))) == RealScalar(rows));+ VERIFY(ei_real(ones.row(r1).eigen2_dot(ones.row(r2))) == RealScalar(cols));+}++void test_eigen2_submatrices()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( submatrices(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( submatrices(Matrix4d()) );+ CALL_SUBTEST_3( submatrices(MatrixXcf(3, 3)) );+ CALL_SUBTEST_4( submatrices(MatrixXi(8, 12)) );+ CALL_SUBTEST_5( submatrices(MatrixXcd(20, 20)) );+ CALL_SUBTEST_6( submatrices(MatrixXf(20, 20)) );+ }+}
+ eigen3/test/eigen2/eigen2_sum.cpp view
@@ -0,0 +1,71 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void matrixSum(const MatrixType& m)+{+ typedef typename MatrixType::Scalar Scalar;++ int rows = m.rows();+ int cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols);++ VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::Zero(rows, cols).sum(), Scalar(1));+ VERIFY_IS_APPROX(MatrixType::Ones(rows, cols).sum(), Scalar(float(rows*cols))); // the float() here to shut up excessive MSVC warning about int->complex conversion being lossy+ Scalar x = Scalar(0);+ for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) x += m1(i,j);+ VERIFY_IS_APPROX(m1.sum(), x);+}++template<typename VectorType> void vectorSum(const VectorType& w)+{+ typedef typename VectorType::Scalar Scalar;+ int size = w.size();++ VectorType v = VectorType::Random(size);+ for(int i = 1; i < size; i++)+ {+ Scalar s = Scalar(0);+ for(int j = 0; j < i; j++) s += v[j];+ VERIFY_IS_APPROX(s, v.start(i).sum());+ }++ for(int i = 0; i < size-1; i++)+ {+ Scalar s = Scalar(0);+ for(int j = i; j < size; j++) s += v[j];+ VERIFY_IS_APPROX(s, v.end(size-i).sum());+ }++ for(int i = 0; i < size/2; i++)+ {+ Scalar s = Scalar(0);+ for(int j = i; j < size-i; j++) s += v[j];+ VERIFY_IS_APPROX(s, v.segment(i, size-2*i).sum());+ }+}++void test_eigen2_sum()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( matrixSum(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( matrixSum(Matrix2f()) );+ CALL_SUBTEST_3( matrixSum(Matrix4d()) );+ CALL_SUBTEST_4( matrixSum(MatrixXcf(3, 3)) );+ CALL_SUBTEST_5( matrixSum(MatrixXf(8, 12)) );+ CALL_SUBTEST_6( matrixSum(MatrixXi(8, 12)) );+ }+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_5( vectorSum(VectorXf(5)) );+ CALL_SUBTEST_7( vectorSum(VectorXd(10)) );+ CALL_SUBTEST_5( vectorSum(VectorXf(33)) );+ }+}
+ eigen3/test/eigen2/eigen2_svd.cpp view
@@ -0,0 +1,87 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/SVD>++template<typename MatrixType> void svd(const MatrixType& m)+{+ /* this test covers the following files:+ SVD.h+ */+ int rows = m.rows();+ int cols = m.cols();++ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ MatrixType a = MatrixType::Random(rows,cols);+ Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> b =+ Matrix<Scalar, MatrixType::RowsAtCompileTime, 1>::Random(rows,1);+ Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> x(cols,1), x2(cols,1);++ RealScalar largerEps = test_precision<RealScalar>();+ if (ei_is_same_type<RealScalar,float>::ret)+ largerEps = 1e-3f;++ {+ SVD<MatrixType> svd(a);+ MatrixType sigma = MatrixType::Zero(rows,cols);+ MatrixType matU = MatrixType::Zero(rows,rows);+ sigma.block(0,0,cols,cols) = svd.singularValues().asDiagonal();+ matU.block(0,0,rows,cols) = svd.matrixU();+ VERIFY_IS_APPROX(a, matU * sigma * svd.matrixV().transpose());+ }+++ if (rows==cols)+ {+ if (ei_is_same_type<RealScalar,float>::ret)+ {+ MatrixType a1 = MatrixType::Random(rows,cols);+ a += a * a.adjoint() + a1 * a1.adjoint();+ }+ SVD<MatrixType> svd(a);+ svd.solve(b, &x);+ VERIFY_IS_APPROX(a * x,b);+ }+++ if(rows==cols)+ {+ SVD<MatrixType> svd(a);+ MatrixType unitary, positive;+ svd.computeUnitaryPositive(&unitary, &positive);+ VERIFY_IS_APPROX(unitary * unitary.adjoint(), MatrixType::Identity(unitary.rows(),unitary.rows()));+ VERIFY_IS_APPROX(positive, positive.adjoint());+ for(int i = 0; i < rows; i++) VERIFY(positive.diagonal()[i] >= 0); // cheap necessary (not sufficient) condition for positivity+ VERIFY_IS_APPROX(unitary*positive, a);++ svd.computePositiveUnitary(&positive, &unitary);+ VERIFY_IS_APPROX(unitary * unitary.adjoint(), MatrixType::Identity(unitary.rows(),unitary.rows()));+ VERIFY_IS_APPROX(positive, positive.adjoint());+ for(int i = 0; i < rows; i++) VERIFY(positive.diagonal()[i] >= 0); // cheap necessary (not sufficient) condition for positivity+ VERIFY_IS_APPROX(positive*unitary, a);+ }+}++void test_eigen2_svd()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( svd(Matrix3f()) );+ CALL_SUBTEST_2( svd(Matrix4d()) );+ CALL_SUBTEST_3( svd(MatrixXf(7,7)) );+ CALL_SUBTEST_4( svd(MatrixXd(14,7)) );+ // complex are not implemented yet+// CALL_SUBTEST( svd(MatrixXcd(6,6)) );+// CALL_SUBTEST( svd(MatrixXcf(3,3)) );+ SVD<MatrixXf> s;+ MatrixXf m = MatrixXf::Random(10,1);+ s.compute(m);+ }+}
+ eigen3/test/eigen2/eigen2_swap.cpp view
@@ -0,0 +1,83 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN_NO_STATIC_ASSERT+#include "main.h"++template<typename T>+struct other_matrix_type+{+ typedef int type;+};++template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>+struct other_matrix_type<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >+{+ typedef Matrix<_Scalar, _Rows, _Cols, _Options^RowMajor, _MaxRows, _MaxCols> type;+};++template<typename MatrixType> void swap(const MatrixType& m)+{+ typedef typename other_matrix_type<MatrixType>::type OtherMatrixType;+ typedef typename MatrixType::Scalar Scalar;++ ei_assert((!ei_is_same_type<MatrixType,OtherMatrixType>::ret));+ int rows = m.rows();+ int cols = m.cols();+ + // construct 3 matrix guaranteed to be distinct+ MatrixType m1 = MatrixType::Random(rows,cols);+ MatrixType m2 = MatrixType::Random(rows,cols) + Scalar(100) * MatrixType::Identity(rows,cols);+ OtherMatrixType m3 = OtherMatrixType::Random(rows,cols) + Scalar(200) * OtherMatrixType::Identity(rows,cols);+ + MatrixType m1_copy = m1;+ MatrixType m2_copy = m2;+ OtherMatrixType m3_copy = m3;+ + // test swapping 2 matrices of same type+ m1.swap(m2);+ VERIFY_IS_APPROX(m1,m2_copy);+ VERIFY_IS_APPROX(m2,m1_copy);+ m1 = m1_copy;+ m2 = m2_copy;+ + // test swapping 2 matrices of different types+ m1.swap(m3);+ VERIFY_IS_APPROX(m1,m3_copy);+ VERIFY_IS_APPROX(m3,m1_copy);+ m1 = m1_copy;+ m3 = m3_copy;+ + // test swapping matrix with expression+ m1.swap(m2.block(0,0,rows,cols));+ VERIFY_IS_APPROX(m1,m2_copy);+ VERIFY_IS_APPROX(m2,m1_copy);+ m1 = m1_copy;+ m2 = m2_copy;++ // test swapping two expressions of different types+ m1.transpose().swap(m3.transpose());+ VERIFY_IS_APPROX(m1,m3_copy);+ VERIFY_IS_APPROX(m3,m1_copy);+ m1 = m1_copy;+ m3 = m3_copy;+ + // test assertion on mismatching size -- matrix case+ VERIFY_RAISES_ASSERT(m1.swap(m1.row(0)));+ // test assertion on mismatching size -- xpr case+ VERIFY_RAISES_ASSERT(m1.row(0).swap(m1));+}++void test_eigen2_swap()+{+ CALL_SUBTEST_1( swap(Matrix3f()) ); // fixed size, no vectorization + CALL_SUBTEST_1( swap(Matrix4d()) ); // fixed size, possible vectorization + CALL_SUBTEST_1( swap(MatrixXd(3,3)) ); // dyn size, no vectorization + CALL_SUBTEST_1( swap(MatrixXf(30,30)) ); // dyn size, possible vectorization +}
+ eigen3/test/eigen2/eigen2_triangular.cpp view
@@ -0,0 +1,148 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void triangular(const MatrixType& m)+{+ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;++ RealScalar largerEps = 10*test_precision<RealScalar>();++ int rows = m.rows();+ int cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols),+ m4(rows, cols),+ r1(rows, cols),+ r2(rows, cols);++ MatrixType m1up = m1.template part<Eigen::UpperTriangular>();+ MatrixType m2up = m2.template part<Eigen::UpperTriangular>();++ if (rows*cols>1)+ {+ VERIFY(m1up.isUpperTriangular());+ VERIFY(m2up.transpose().isLowerTriangular());+ VERIFY(!m2.isLowerTriangular());+ }++// VERIFY_IS_APPROX(m1up.transpose() * m2, m1.upper().transpose().lower() * m2);++ // test overloaded operator+=+ r1.setZero();+ r2.setZero();+ r1.template part<Eigen::UpperTriangular>() += m1;+ r2 += m1up;+ VERIFY_IS_APPROX(r1,r2);++ // test overloaded operator=+ m1.setZero();+ m1.template part<Eigen::UpperTriangular>() = (m2.transpose() * m2).lazy();+ m3 = m2.transpose() * m2;+ VERIFY_IS_APPROX(m3.template part<Eigen::LowerTriangular>().transpose(), m1);++ // test overloaded operator=+ m1.setZero();+ m1.template part<Eigen::LowerTriangular>() = (m2.transpose() * m2).lazy();+ VERIFY_IS_APPROX(m3.template part<Eigen::LowerTriangular>(), m1);++ VERIFY_IS_APPROX(m3.template part<Diagonal>(), m3.diagonal().asDiagonal());++ m1 = MatrixType::Random(rows, cols);+ for (int i=0; i<rows; ++i)+ while (ei_abs2(m1(i,i))<1e-3) m1(i,i) = ei_random<Scalar>();++ Transpose<MatrixType> trm4(m4);+ // test back and forward subsitution+ m3 = m1.template part<Eigen::LowerTriangular>();+ VERIFY(m3.template marked<Eigen::LowerTriangular>().solveTriangular(m3).cwise().abs().isIdentity(test_precision<RealScalar>()));+ VERIFY(m3.transpose().template marked<Eigen::UpperTriangular>()+ .solveTriangular(m3.transpose()).cwise().abs().isIdentity(test_precision<RealScalar>()));+ // check M * inv(L) using in place API+ m4 = m3;+ m3.transpose().template marked<Eigen::UpperTriangular>().solveTriangularInPlace(trm4);+ VERIFY(m4.cwise().abs().isIdentity(test_precision<RealScalar>()));++ m3 = m1.template part<Eigen::UpperTriangular>();+ VERIFY(m3.template marked<Eigen::UpperTriangular>().solveTriangular(m3).cwise().abs().isIdentity(test_precision<RealScalar>()));+ VERIFY(m3.transpose().template marked<Eigen::LowerTriangular>()+ .solveTriangular(m3.transpose()).cwise().abs().isIdentity(test_precision<RealScalar>()));+ // check M * inv(U) using in place API+ m4 = m3;+ m3.transpose().template marked<Eigen::LowerTriangular>().solveTriangularInPlace(trm4);+ VERIFY(m4.cwise().abs().isIdentity(test_precision<RealScalar>()));++ m3 = m1.template part<Eigen::UpperTriangular>();+ VERIFY(m2.isApprox(m3 * (m3.template marked<Eigen::UpperTriangular>().solveTriangular(m2)), largerEps));+ m3 = m1.template part<Eigen::LowerTriangular>();+ VERIFY(m2.isApprox(m3 * (m3.template marked<Eigen::LowerTriangular>().solveTriangular(m2)), largerEps));++ VERIFY((m1.template part<Eigen::UpperTriangular>() * m2.template part<Eigen::UpperTriangular>()).isUpperTriangular());++ // test swap+ m1.setOnes();+ m2.setZero();+ m2.template part<Eigen::UpperTriangular>().swap(m1);+ m3.setZero();+ m3.template part<Eigen::UpperTriangular>().setOnes();+ VERIFY_IS_APPROX(m2,m3);++}++void selfadjoint()+{+ Matrix2i m;+ m << 1, 2,+ 3, 4;++ Matrix2i m1 = Matrix2i::Zero();+ m1.part<SelfAdjoint>() = m;+ Matrix2i ref1;+ ref1 << 1, 2,+ 2, 4;+ VERIFY(m1 == ref1);+ + Matrix2i m2 = Matrix2i::Zero();+ m2.part<SelfAdjoint>() = m.part<UpperTriangular>();+ Matrix2i ref2;+ ref2 << 1, 2,+ 2, 4;+ VERIFY(m2 == ref2);+ + Matrix2i m3 = Matrix2i::Zero();+ m3.part<SelfAdjoint>() = m.part<LowerTriangular>();+ Matrix2i ref3;+ ref3 << 1, 0,+ 0, 4;+ VERIFY(m3 == ref3);+ + // example inspired from bug 159+ int array[] = {1, 2, 3, 4};+ Matrix2i::Map(array).part<SelfAdjoint>() = Matrix2i::Random().part<LowerTriangular>();+ + std::cout << "hello\n" << array << std::endl;+}++void test_eigen2_triangular()+{+ CALL_SUBTEST_8( selfadjoint() );+ for(int i = 0; i < g_repeat ; i++) {+ CALL_SUBTEST_1( triangular(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( triangular(Matrix<float, 2, 2>()) );+ CALL_SUBTEST_3( triangular(Matrix3d()) );+ CALL_SUBTEST_4( triangular(MatrixXcf(4, 4)) );+ CALL_SUBTEST_5( triangular(Matrix<std::complex<float>,8, 8>()) );+ CALL_SUBTEST_6( triangular(MatrixXd(17,17)) );+ CALL_SUBTEST_7( triangular(Matrix<float,Dynamic,Dynamic,RowMajor>(5, 5)) );+ }+}
+ eigen3/test/eigen2/eigen2_unalignedassert.cpp view
@@ -0,0 +1,116 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++struct Good1+{+ MatrixXd m; // good: m will allocate its own array, taking care of alignment.+ Good1() : m(20,20) {}+};++struct Good2+{+ Matrix3d m; // good: m's size isn't a multiple of 16 bytes, so m doesn't have to be aligned+};++struct Good3+{+ Vector2f m; // good: same reason+};++struct Bad4+{+ Vector2d m; // bad: sizeof(m)%16==0 so alignment is required+};++struct Bad5+{+ Matrix<float, 2, 6> m; // bad: same reason+};++struct Bad6+{+ Matrix<double, 3, 4> m; // bad: same reason+};++struct Good7+{+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW+ Vector2d m;+ float f; // make the struct have sizeof%16!=0 to make it a little more tricky when we allow an array of 2 such objects+};++struct Good8+{+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW+ float f; // try the f at first -- the EIGEN_ALIGN_128 attribute of m should make that still work+ Matrix4f m;+};++struct Good9+{+ Matrix<float,2,2,DontAlign> m; // good: no alignment requested+ float f;+};++template<bool Align> struct Depends+{+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(Align)+ Vector2d m;+ float f;+};++template<typename T>+void check_unalignedassert_good()+{+ T *x, *y;+ x = new T;+ delete x;+ y = new T[2];+ delete[] y;+}++#if EIGEN_ARCH_WANTS_ALIGNMENT+template<typename T>+void check_unalignedassert_bad()+{+ float buf[sizeof(T)+16];+ float *unaligned = buf;+ while((reinterpret_cast<std::size_t>(unaligned)&0xf)==0) ++unaligned; // make sure unaligned is really unaligned+ T *x = ::new(static_cast<void*>(unaligned)) T;+ x->~T();+}+#endif++void unalignedassert()+{+ check_unalignedassert_good<Good1>();+ check_unalignedassert_good<Good2>();+ check_unalignedassert_good<Good3>();+#if EIGEN_ARCH_WANTS_ALIGNMENT+ VERIFY_RAISES_ASSERT(check_unalignedassert_bad<Bad4>());+ VERIFY_RAISES_ASSERT(check_unalignedassert_bad<Bad5>());+ VERIFY_RAISES_ASSERT(check_unalignedassert_bad<Bad6>());+#endif++ check_unalignedassert_good<Good7>();+ check_unalignedassert_good<Good8>();+ check_unalignedassert_good<Good9>();+ check_unalignedassert_good<Depends<true> >();++#if EIGEN_ARCH_WANTS_ALIGNMENT+ VERIFY_RAISES_ASSERT(check_unalignedassert_bad<Depends<false> >());+#endif+}++void test_eigen2_unalignedassert()+{+ CALL_SUBTEST(unalignedassert());+}
+ eigen3/test/eigen2/eigen2_visitor.cpp view
@@ -0,0 +1,116 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void matrixVisitor(const MatrixType& p)+{+ typedef typename MatrixType::Scalar Scalar;++ int rows = p.rows();+ int cols = p.cols();++ // construct a random matrix where all coefficients are different+ MatrixType m;+ m = MatrixType::Random(rows, cols);+ for(int i = 0; i < m.size(); i++)+ for(int i2 = 0; i2 < i; i2++)+ while(m(i) == m(i2)) // yes, ==+ m(i) = ei_random<Scalar>();+ + Scalar minc = Scalar(1000), maxc = Scalar(-1000);+ int minrow=0,mincol=0,maxrow=0,maxcol=0;+ for(int j = 0; j < cols; j++)+ for(int i = 0; i < rows; i++)+ {+ if(m(i,j) < minc)+ {+ minc = m(i,j);+ minrow = i;+ mincol = j;+ }+ if(m(i,j) > maxc)+ {+ maxc = m(i,j);+ maxrow = i;+ maxcol = j;+ }+ }+ int eigen_minrow, eigen_mincol, eigen_maxrow, eigen_maxcol;+ Scalar eigen_minc, eigen_maxc;+ eigen_minc = m.minCoeff(&eigen_minrow,&eigen_mincol);+ eigen_maxc = m.maxCoeff(&eigen_maxrow,&eigen_maxcol);+ VERIFY(minrow == eigen_minrow);+ VERIFY(maxrow == eigen_maxrow);+ VERIFY(mincol == eigen_mincol);+ VERIFY(maxcol == eigen_maxcol);+ VERIFY_IS_APPROX(minc, eigen_minc);+ VERIFY_IS_APPROX(maxc, eigen_maxc);+ VERIFY_IS_APPROX(minc, m.minCoeff());+ VERIFY_IS_APPROX(maxc, m.maxCoeff());+}++template<typename VectorType> void vectorVisitor(const VectorType& w)+{+ typedef typename VectorType::Scalar Scalar;++ int size = w.size();++ // construct a random vector where all coefficients are different+ VectorType v;+ v = VectorType::Random(size);+ for(int i = 0; i < size; i++)+ for(int i2 = 0; i2 < i; i2++)+ while(v(i) == v(i2)) // yes, ==+ v(i) = ei_random<Scalar>();+ + Scalar minc = Scalar(1000), maxc = Scalar(-1000);+ int minidx=0,maxidx=0;+ for(int i = 0; i < size; i++)+ {+ if(v(i) < minc)+ {+ minc = v(i);+ minidx = i;+ }+ if(v(i) > maxc)+ {+ maxc = v(i);+ maxidx = i;+ }+ }+ int eigen_minidx, eigen_maxidx;+ Scalar eigen_minc, eigen_maxc;+ eigen_minc = v.minCoeff(&eigen_minidx);+ eigen_maxc = v.maxCoeff(&eigen_maxidx);+ VERIFY(minidx == eigen_minidx);+ VERIFY(maxidx == eigen_maxidx);+ VERIFY_IS_APPROX(minc, eigen_minc);+ VERIFY_IS_APPROX(maxc, eigen_maxc);+ VERIFY_IS_APPROX(minc, v.minCoeff());+ VERIFY_IS_APPROX(maxc, v.maxCoeff());+}++void test_eigen2_visitor()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( matrixVisitor(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( matrixVisitor(Matrix2f()) );+ CALL_SUBTEST_3( matrixVisitor(Matrix4d()) );+ CALL_SUBTEST_4( matrixVisitor(MatrixXd(8, 12)) );+ CALL_SUBTEST_5( matrixVisitor(Matrix<double,Dynamic,Dynamic,RowMajor>(20, 20)) );+ CALL_SUBTEST_6( matrixVisitor(MatrixXi(8, 12)) );+ }+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_7( vectorVisitor(Vector4f()) );+ CALL_SUBTEST_4( vectorVisitor(VectorXd(10)) );+ CALL_SUBTEST_4( vectorVisitor(RowVectorXd(10)) );+ CALL_SUBTEST_8( vectorVisitor(VectorXf(33)) );+ }+}
+ eigen3/test/eigen2/gsl_helper.h view
@@ -0,0 +1,175 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_GSL_HELPER+#define EIGEN_GSL_HELPER++#include <Eigen/Core>++#include <gsl/gsl_blas.h>+#include <gsl/gsl_multifit.h>+#include <gsl/gsl_eigen.h>+#include <gsl/gsl_linalg.h>+#include <gsl/gsl_complex.h>+#include <gsl/gsl_complex_math.h>++namespace Eigen {++template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex> struct GslTraits+{+ typedef gsl_matrix* Matrix;+ typedef gsl_vector* Vector;+ static Matrix createMatrix(int rows, int cols) { return gsl_matrix_alloc(rows,cols); }+ static Vector createVector(int size) { return gsl_vector_alloc(size); }+ static void free(Matrix& m) { gsl_matrix_free(m); m=0; }+ static void free(Vector& m) { gsl_vector_free(m); m=0; }+ static void prod(const Matrix& m, const Vector& v, Vector& x) { gsl_blas_dgemv(CblasNoTrans,1,m,v,0,x); }+ static void cholesky(Matrix& m) { gsl_linalg_cholesky_decomp(m); }+ static void cholesky_solve(const Matrix& m, const Vector& b, Vector& x) { gsl_linalg_cholesky_solve(m,b,x); }+ static void eigen_symm(const Matrix& m, Vector& eval, Matrix& evec)+ {+ gsl_eigen_symmv_workspace * w = gsl_eigen_symmv_alloc(m->size1);+ Matrix a = createMatrix(m->size1, m->size2);+ gsl_matrix_memcpy(a, m);+ gsl_eigen_symmv(a,eval,evec,w);+ gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_VAL_ASC);+ gsl_eigen_symmv_free(w);+ free(a);+ }+ static void eigen_symm_gen(const Matrix& m, const Matrix& _b, Vector& eval, Matrix& evec)+ {+ gsl_eigen_gensymmv_workspace * w = gsl_eigen_gensymmv_alloc(m->size1);+ Matrix a = createMatrix(m->size1, m->size2);+ Matrix b = createMatrix(_b->size1, _b->size2);+ gsl_matrix_memcpy(a, m);+ gsl_matrix_memcpy(b, _b);+ gsl_eigen_gensymmv(a,b,eval,evec,w);+ gsl_eigen_symmv_sort(eval, evec, GSL_EIGEN_SORT_VAL_ASC);+ gsl_eigen_gensymmv_free(w);+ free(a);+ }+};++template<typename Scalar> struct GslTraits<Scalar,true>+{+ typedef gsl_matrix_complex* Matrix;+ typedef gsl_vector_complex* Vector;+ static Matrix createMatrix(int rows, int cols) { return gsl_matrix_complex_alloc(rows,cols); }+ static Vector createVector(int size) { return gsl_vector_complex_alloc(size); }+ static void free(Matrix& m) { gsl_matrix_complex_free(m); m=0; }+ static void free(Vector& m) { gsl_vector_complex_free(m); m=0; }+ static void cholesky(Matrix& m) { gsl_linalg_complex_cholesky_decomp(m); }+ static void cholesky_solve(const Matrix& m, const Vector& b, Vector& x) { gsl_linalg_complex_cholesky_solve(m,b,x); }+ static void prod(const Matrix& m, const Vector& v, Vector& x)+ { gsl_blas_zgemv(CblasNoTrans,gsl_complex_rect(1,0),m,v,gsl_complex_rect(0,0),x); }+ static void eigen_symm(const Matrix& m, gsl_vector* &eval, Matrix& evec)+ {+ gsl_eigen_hermv_workspace * w = gsl_eigen_hermv_alloc(m->size1);+ Matrix a = createMatrix(m->size1, m->size2);+ gsl_matrix_complex_memcpy(a, m);+ gsl_eigen_hermv(a,eval,evec,w);+ gsl_eigen_hermv_sort(eval, evec, GSL_EIGEN_SORT_VAL_ASC);+ gsl_eigen_hermv_free(w);+ free(a);+ }+ static void eigen_symm_gen(const Matrix& m, const Matrix& _b, gsl_vector* &eval, Matrix& evec)+ {+ gsl_eigen_genhermv_workspace * w = gsl_eigen_genhermv_alloc(m->size1);+ Matrix a = createMatrix(m->size1, m->size2);+ Matrix b = createMatrix(_b->size1, _b->size2);+ gsl_matrix_complex_memcpy(a, m);+ gsl_matrix_complex_memcpy(b, _b);+ gsl_eigen_genhermv(a,b,eval,evec,w);+ gsl_eigen_hermv_sort(eval, evec, GSL_EIGEN_SORT_VAL_ASC);+ gsl_eigen_genhermv_free(w);+ free(a);+ }+};++template<typename MatrixType>+void convert(const MatrixType& m, gsl_matrix* &res)+{+// if (res)+// gsl_matrix_free(res);+ res = gsl_matrix_alloc(m.rows(), m.cols());+ for (int i=0 ; i<m.rows() ; ++i)+ for (int j=0 ; j<m.cols(); ++j)+ gsl_matrix_set(res, i, j, m(i,j));+}++template<typename MatrixType>+void convert(const gsl_matrix* m, MatrixType& res)+{+ res.resize(int(m->size1), int(m->size2));+ for (int i=0 ; i<res.rows() ; ++i)+ for (int j=0 ; j<res.cols(); ++j)+ res(i,j) = gsl_matrix_get(m,i,j);+}++template<typename VectorType>+void convert(const VectorType& m, gsl_vector* &res)+{+ if (res) gsl_vector_free(res);+ res = gsl_vector_alloc(m.size());+ for (int i=0 ; i<m.size() ; ++i)+ gsl_vector_set(res, i, m[i]);+}++template<typename VectorType>+void convert(const gsl_vector* m, VectorType& res)+{+ res.resize (m->size);+ for (int i=0 ; i<res.rows() ; ++i)+ res[i] = gsl_vector_get(m, i);+}++template<typename MatrixType>+void convert(const MatrixType& m, gsl_matrix_complex* &res)+{+ res = gsl_matrix_complex_alloc(m.rows(), m.cols());+ for (int i=0 ; i<m.rows() ; ++i)+ for (int j=0 ; j<m.cols(); ++j)+ {+ gsl_matrix_complex_set(res, i, j,+ gsl_complex_rect(m(i,j).real(), m(i,j).imag()));+ }+}++template<typename MatrixType>+void convert(const gsl_matrix_complex* m, MatrixType& res)+{+ res.resize(int(m->size1), int(m->size2));+ for (int i=0 ; i<res.rows() ; ++i)+ for (int j=0 ; j<res.cols(); ++j)+ res(i,j) = typename MatrixType::Scalar(+ GSL_REAL(gsl_matrix_complex_get(m,i,j)),+ GSL_IMAG(gsl_matrix_complex_get(m,i,j)));+}++template<typename VectorType>+void convert(const VectorType& m, gsl_vector_complex* &res)+{+ res = gsl_vector_complex_alloc(m.size());+ for (int i=0 ; i<m.size() ; ++i)+ gsl_vector_complex_set(res, i, gsl_complex_rect(m[i].real(), m[i].imag()));+}++template<typename VectorType>+void convert(const gsl_vector_complex* m, VectorType& res)+{+ res.resize(m->size);+ for (int i=0 ; i<res.rows() ; ++i)+ res[i] = typename VectorType::Scalar(+ GSL_REAL(gsl_vector_complex_get(m, i)),+ GSL_IMAG(gsl_vector_complex_get(m, i)));+}++}++#endif // EIGEN_GSL_HELPER
+ eigen3/test/eigen2/main.h view
@@ -0,0 +1,399 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include <cstdlib>+#include <ctime>+#include <iostream>+#include <string>+#include <vector>++#ifndef EIGEN_TEST_FUNC+#error EIGEN_TEST_FUNC must be defined+#endif++#define DEFAULT_REPEAT 10++namespace Eigen+{+ static std::vector<std::string> g_test_stack;+ static int g_repeat;+}++#define EI_PP_MAKE_STRING2(S) #S+#define EI_PP_MAKE_STRING(S) EI_PP_MAKE_STRING2(S)++#define EI_PP_CAT2(a,b) a ## b+#define EI_PP_CAT(a,b) EI_PP_CAT2(a,b)++#ifndef EIGEN_NO_ASSERTION_CHECKING++ namespace Eigen+ {+ static const bool should_raise_an_assert = false;++ // Used to avoid to raise two exceptions at a time in which+ // case the exception is not properly caught.+ // This may happen when a second exceptions is raise in a destructor.+ static bool no_more_assert = false;++ struct eigen_assert_exception+ {+ eigen_assert_exception(void) {}+ ~eigen_assert_exception() { Eigen::no_more_assert = false; }+ };+ }++ // If EIGEN_DEBUG_ASSERTS is defined and if no assertion is raised while+ // one should have been, then the list of excecuted assertions is printed out.+ //+ // EIGEN_DEBUG_ASSERTS is not enabled by default as it+ // significantly increases the compilation time+ // and might even introduce side effects that would hide+ // some memory errors.+ #ifdef EIGEN_DEBUG_ASSERTS++ namespace Eigen+ {+ static bool ei_push_assert = false;+ static std::vector<std::string> eigen_assert_list;+ }++ #define eigen_assert(a) \+ if( (!(a)) && (!no_more_assert) ) \+ { \+ Eigen::no_more_assert = true; \+ throw Eigen::eigen_assert_exception(); \+ } \+ else if (Eigen::ei_push_assert) \+ { \+ eigen_assert_list.push_back(std::string(EI_PP_MAKE_STRING(__FILE__)" ("EI_PP_MAKE_STRING(__LINE__)") : "#a) ); \+ }++ #define VERIFY_RAISES_ASSERT(a) \+ { \+ Eigen::no_more_assert = false; \+ try { \+ Eigen::eigen_assert_list.clear(); \+ Eigen::ei_push_assert = true; \+ a; \+ Eigen::ei_push_assert = false; \+ std::cerr << "One of the following asserts should have been raised:\n"; \+ for (uint ai=0 ; ai<eigen_assert_list.size() ; ++ai) \+ std::cerr << " " << eigen_assert_list[ai] << "\n"; \+ VERIFY(Eigen::should_raise_an_assert && # a); \+ } catch (Eigen::eigen_assert_exception e) { \+ Eigen::ei_push_assert = false; VERIFY(true); \+ } \+ }++ #else // EIGEN_DEBUG_ASSERTS++ #undef eigen_assert++ // see bug 89. The copy_bool here is working around a bug in gcc <= 4.3+ #define eigen_assert(a) \+ if( (!Eigen::internal::copy_bool(a)) && (!no_more_assert) ) \+ { \+ Eigen::no_more_assert = true; \+ throw Eigen::eigen_assert_exception(); \+ }++ #define VERIFY_RAISES_ASSERT(a) { \+ Eigen::no_more_assert = false; \+ try { a; VERIFY(Eigen::should_raise_an_assert && # a); } \+ catch (Eigen::eigen_assert_exception e) { VERIFY(true); } \+ }++ #endif // EIGEN_DEBUG_ASSERTS++ #define EIGEN_USE_CUSTOM_ASSERT++#else // EIGEN_NO_ASSERTION_CHECKING++ #define VERIFY_RAISES_ASSERT(a) {}++#endif // EIGEN_NO_ASSERTION_CHECKING+++#define EIGEN_INTERNAL_DEBUGGING+#define EIGEN_NICE_RANDOM+#include <Eigen/Array>+++#define VERIFY(a) do { if (!(a)) { \+ std::cerr << "Test " << g_test_stack.back() << " failed in "EI_PP_MAKE_STRING(__FILE__) << " (" << EI_PP_MAKE_STRING(__LINE__) << ")" \+ << std::endl << " " << EI_PP_MAKE_STRING(a) << std::endl << std::endl; \+ abort(); \+ } } while (0)++#define VERIFY_IS_APPROX(a, b) VERIFY(test_ei_isApprox(a, b))+#define VERIFY_IS_NOT_APPROX(a, b) VERIFY(!test_ei_isApprox(a, b))+#define VERIFY_IS_MUCH_SMALLER_THAN(a, b) VERIFY(test_ei_isMuchSmallerThan(a, b))+#define VERIFY_IS_NOT_MUCH_SMALLER_THAN(a, b) VERIFY(!test_ei_isMuchSmallerThan(a, b))+#define VERIFY_IS_APPROX_OR_LESS_THAN(a, b) VERIFY(test_ei_isApproxOrLessThan(a, b))+#define VERIFY_IS_NOT_APPROX_OR_LESS_THAN(a, b) VERIFY(!test_ei_isApproxOrLessThan(a, b))++#define CALL_SUBTEST(FUNC) do { \+ g_test_stack.push_back(EI_PP_MAKE_STRING(FUNC)); \+ FUNC; \+ g_test_stack.pop_back(); \+ } while (0)++namespace Eigen {++template<typename T> inline typename NumTraits<T>::Real test_precision();+template<> inline int test_precision<int>() { return 0; }+template<> inline float test_precision<float>() { return 1e-3f; }+template<> inline double test_precision<double>() { return 1e-6; }+template<> inline float test_precision<std::complex<float> >() { return test_precision<float>(); }+template<> inline double test_precision<std::complex<double> >() { return test_precision<double>(); }+template<> inline long double test_precision<long double>() { return 1e-6; }++inline bool test_ei_isApprox(const int& a, const int& b)+{ return ei_isApprox(a, b, test_precision<int>()); }+inline bool test_ei_isMuchSmallerThan(const int& a, const int& b)+{ return ei_isMuchSmallerThan(a, b, test_precision<int>()); }+inline bool test_ei_isApproxOrLessThan(const int& a, const int& b)+{ return ei_isApproxOrLessThan(a, b, test_precision<int>()); }++inline bool test_ei_isApprox(const float& a, const float& b)+{ return ei_isApprox(a, b, test_precision<float>()); }+inline bool test_ei_isMuchSmallerThan(const float& a, const float& b)+{ return ei_isMuchSmallerThan(a, b, test_precision<float>()); }+inline bool test_ei_isApproxOrLessThan(const float& a, const float& b)+{ return ei_isApproxOrLessThan(a, b, test_precision<float>()); }++inline bool test_ei_isApprox(const double& a, const double& b)+{ return ei_isApprox(a, b, test_precision<double>()); }+inline bool test_ei_isMuchSmallerThan(const double& a, const double& b)+{ return ei_isMuchSmallerThan(a, b, test_precision<double>()); }+inline bool test_ei_isApproxOrLessThan(const double& a, const double& b)+{ return ei_isApproxOrLessThan(a, b, test_precision<double>()); }++inline bool test_ei_isApprox(const std::complex<float>& a, const std::complex<float>& b)+{ return ei_isApprox(a, b, test_precision<std::complex<float> >()); }+inline bool test_ei_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b)+{ return ei_isMuchSmallerThan(a, b, test_precision<std::complex<float> >()); }++inline bool test_ei_isApprox(const std::complex<double>& a, const std::complex<double>& b)+{ return ei_isApprox(a, b, test_precision<std::complex<double> >()); }+inline bool test_ei_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b)+{ return ei_isMuchSmallerThan(a, b, test_precision<std::complex<double> >()); }++inline bool test_ei_isApprox(const long double& a, const long double& b)+{ return ei_isApprox(a, b, test_precision<long double>()); }+inline bool test_ei_isMuchSmallerThan(const long double& a, const long double& b)+{ return ei_isMuchSmallerThan(a, b, test_precision<long double>()); }+inline bool test_ei_isApproxOrLessThan(const long double& a, const long double& b)+{ return ei_isApproxOrLessThan(a, b, test_precision<long double>()); }++template<typename Type1, typename Type2>+inline bool test_ei_isApprox(const Type1& a, const Type2& b)+{+ return a.isApprox(b, test_precision<typename Type1::Scalar>());+}++template<typename Derived1, typename Derived2>+inline bool test_ei_isMuchSmallerThan(const MatrixBase<Derived1>& m1,+ const MatrixBase<Derived2>& m2)+{+ return m1.isMuchSmallerThan(m2, test_precision<typename ei_traits<Derived1>::Scalar>());+}++template<typename Derived>+inline bool test_ei_isMuchSmallerThan(const MatrixBase<Derived>& m,+ const typename NumTraits<typename ei_traits<Derived>::Scalar>::Real& s)+{+ return m.isMuchSmallerThan(s, test_precision<typename ei_traits<Derived>::Scalar>());+}++} // end namespace Eigen++template<typename T> struct GetDifferentType;++template<> struct GetDifferentType<float> { typedef double type; };+template<> struct GetDifferentType<double> { typedef float type; };+template<typename T> struct GetDifferentType<std::complex<T> >+{ typedef std::complex<typename GetDifferentType<T>::type> type; };++// forward declaration of the main test function+void EI_PP_CAT(test_,EIGEN_TEST_FUNC)();++using namespace Eigen;++#ifdef EIGEN_TEST_PART_1+#define CALL_SUBTEST_1(FUNC) CALL_SUBTEST(FUNC)+#else+#define CALL_SUBTEST_1(FUNC)+#endif++#ifdef EIGEN_TEST_PART_2+#define CALL_SUBTEST_2(FUNC) CALL_SUBTEST(FUNC)+#else+#define CALL_SUBTEST_2(FUNC)+#endif++#ifdef EIGEN_TEST_PART_3+#define CALL_SUBTEST_3(FUNC) CALL_SUBTEST(FUNC)+#else+#define CALL_SUBTEST_3(FUNC)+#endif++#ifdef EIGEN_TEST_PART_4+#define CALL_SUBTEST_4(FUNC) CALL_SUBTEST(FUNC)+#else+#define CALL_SUBTEST_4(FUNC)+#endif++#ifdef EIGEN_TEST_PART_5+#define CALL_SUBTEST_5(FUNC) CALL_SUBTEST(FUNC)+#else+#define CALL_SUBTEST_5(FUNC)+#endif++#ifdef EIGEN_TEST_PART_6+#define CALL_SUBTEST_6(FUNC) CALL_SUBTEST(FUNC)+#else+#define CALL_SUBTEST_6(FUNC)+#endif++#ifdef EIGEN_TEST_PART_7+#define CALL_SUBTEST_7(FUNC) CALL_SUBTEST(FUNC)+#else+#define CALL_SUBTEST_7(FUNC)+#endif++#ifdef EIGEN_TEST_PART_8+#define CALL_SUBTEST_8(FUNC) CALL_SUBTEST(FUNC)+#else+#define CALL_SUBTEST_8(FUNC)+#endif++#ifdef EIGEN_TEST_PART_9+#define CALL_SUBTEST_9(FUNC) CALL_SUBTEST(FUNC)+#else+#define CALL_SUBTEST_9(FUNC)+#endif++#ifdef EIGEN_TEST_PART_10+#define CALL_SUBTEST_10(FUNC) CALL_SUBTEST(FUNC)+#else+#define CALL_SUBTEST_10(FUNC)+#endif++#ifdef EIGEN_TEST_PART_11+#define CALL_SUBTEST_11(FUNC) CALL_SUBTEST(FUNC)+#else+#define CALL_SUBTEST_11(FUNC)+#endif++#ifdef EIGEN_TEST_PART_12+#define CALL_SUBTEST_12(FUNC) CALL_SUBTEST(FUNC)+#else+#define CALL_SUBTEST_12(FUNC)+#endif++#ifdef EIGEN_TEST_PART_13+#define CALL_SUBTEST_13(FUNC) CALL_SUBTEST(FUNC)+#else+#define CALL_SUBTEST_13(FUNC)+#endif++#ifdef EIGEN_TEST_PART_14+#define CALL_SUBTEST_14(FUNC) CALL_SUBTEST(FUNC)+#else+#define CALL_SUBTEST_14(FUNC)+#endif++#ifdef EIGEN_TEST_PART_15+#define CALL_SUBTEST_15(FUNC) CALL_SUBTEST(FUNC)+#else+#define CALL_SUBTEST_15(FUNC)+#endif++#ifdef EIGEN_TEST_PART_16+#define CALL_SUBTEST_16(FUNC) CALL_SUBTEST(FUNC)+#else+#define CALL_SUBTEST_16(FUNC)+#endif++++int main(int argc, char *argv[])+{+ bool has_set_repeat = false;+ bool has_set_seed = false;+ bool need_help = false;+ unsigned int seed = 0;+ int repeat = DEFAULT_REPEAT;++ for(int i = 1; i < argc; i++)+ {+ if(argv[i][0] == 'r')+ {+ if(has_set_repeat)+ {+ std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;+ return 1;+ }+ repeat = std::atoi(argv[i]+1);+ has_set_repeat = true;+ if(repeat <= 0)+ {+ std::cout << "Invalid \'repeat\' value " << argv[i]+1 << std::endl;+ return 1;+ }+ }+ else if(argv[i][0] == 's')+ {+ if(has_set_seed)+ {+ std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;+ return 1;+ }+ seed = int(std::strtoul(argv[i]+1, 0, 10));+ has_set_seed = true;+ bool ok = seed!=0;+ if(!ok)+ {+ std::cout << "Invalid \'seed\' value " << argv[i]+1 << std::endl;+ return 1;+ }+ }+ else+ {+ need_help = true;+ }+ }++ if(need_help)+ {+ std::cout << "This test application takes the following optional arguments:" << std::endl;+ std::cout << " rN Repeat each test N times (default: " << DEFAULT_REPEAT << ")" << std::endl;+ std::cout << " sN Use N as seed for random numbers (default: based on current time)" << std::endl;+ return 1;+ }++ if(!has_set_seed) seed = (unsigned int) std::time(NULL);+ if(!has_set_repeat) repeat = DEFAULT_REPEAT;++ std::cout << "Initializing random number generator with seed " << seed << std::endl;+ std::srand(seed);+ std::cout << "Repeating each test " << repeat << " times" << std::endl;++ Eigen::g_repeat = repeat;+ Eigen::g_test_stack.push_back(EI_PP_MAKE_STRING(EIGEN_TEST_FUNC));++ EI_PP_CAT(test_,EIGEN_TEST_FUNC)();+ return 0;+}+++
+ eigen3/test/eigen2/product.h view
@@ -0,0 +1,129 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/Array>+#include <Eigen/QR>++template<typename Derived1, typename Derived2>+bool areNotApprox(const MatrixBase<Derived1>& m1, const MatrixBase<Derived2>& m2, typename Derived1::RealScalar epsilon = precision<typename Derived1::RealScalar>())+{+ return !((m1-m2).cwise().abs2().maxCoeff() < epsilon * epsilon+ * std::max(m1.cwise().abs2().maxCoeff(), m2.cwise().abs2().maxCoeff()));+}++template<typename MatrixType> void product(const MatrixType& m)+{+ /* this test covers the following files:+ Identity.h Product.h+ */++ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::FloatingPoint FloatingPoint;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> RowVectorType;+ typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> ColVectorType;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> RowSquareMatrixType;+ typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime> ColSquareMatrixType;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime,+ MatrixType::Options^RowMajor> OtherMajorMatrixType;++ int rows = m.rows();+ int cols = m.cols();++ // this test relies a lot on Random.h, and there's not much more that we can do+ // to test it, hence I consider that we will have tested Random.h+ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols);+ RowSquareMatrixType+ identity = RowSquareMatrixType::Identity(rows, rows),+ square = RowSquareMatrixType::Random(rows, rows),+ res = RowSquareMatrixType::Random(rows, rows);+ ColSquareMatrixType+ square2 = ColSquareMatrixType::Random(cols, cols),+ res2 = ColSquareMatrixType::Random(cols, cols);+ RowVectorType v1 = RowVectorType::Random(rows);+ ColVectorType vc2 = ColVectorType::Random(cols), vcres(cols);+ OtherMajorMatrixType tm1 = m1;++ Scalar s1 = ei_random<Scalar>();++ int r = ei_random<int>(0, rows-1),+ c = ei_random<int>(0, cols-1);++ // begin testing Product.h: only associativity for now+ // (we use Transpose.h but this doesn't count as a test for it)++ VERIFY_IS_APPROX((m1*m1.transpose())*m2, m1*(m1.transpose()*m2));+ m3 = m1;+ m3 *= m1.transpose() * m2;+ VERIFY_IS_APPROX(m3, m1 * (m1.transpose()*m2));+ VERIFY_IS_APPROX(m3, m1.lazy() * (m1.transpose()*m2));++ // continue testing Product.h: distributivity+ VERIFY_IS_APPROX(square*(m1 + m2), square*m1+square*m2);+ VERIFY_IS_APPROX(square*(m1 - m2), square*m1-square*m2);++ // continue testing Product.h: compatibility with ScalarMultiple.h+ VERIFY_IS_APPROX(s1*(square*m1), (s1*square)*m1);+ VERIFY_IS_APPROX(s1*(square*m1), square*(m1*s1));++ // again, test operator() to check const-qualification+ s1 += (square.lazy() * m1)(r,c);++ // test Product.h together with Identity.h+ VERIFY_IS_APPROX(v1, identity*v1);+ VERIFY_IS_APPROX(v1.transpose(), v1.transpose() * identity);+ // again, test operator() to check const-qualification+ VERIFY_IS_APPROX(MatrixType::Identity(rows, cols)(r,c), static_cast<Scalar>(r==c));++ if (rows!=cols)+ VERIFY_RAISES_ASSERT(m3 = m1*m1);++ // test the previous tests were not screwed up because operator* returns 0+ // (we use the more accurate default epsilon)+ if (NumTraits<Scalar>::HasFloatingPoint && std::min(rows,cols)>1)+ {+ VERIFY(areNotApprox(m1.transpose()*m2,m2.transpose()*m1));+ }++ // test optimized operator+= path+ res = square;+ res += (m1 * m2.transpose()).lazy();+ VERIFY_IS_APPROX(res, square + m1 * m2.transpose());+ if (NumTraits<Scalar>::HasFloatingPoint && std::min(rows,cols)>1)+ {+ VERIFY(areNotApprox(res,square + m2 * m1.transpose()));+ }+ vcres = vc2;+ vcres += (m1.transpose() * v1).lazy();+ VERIFY_IS_APPROX(vcres, vc2 + m1.transpose() * v1);+ tm1 = m1;+ VERIFY_IS_APPROX(tm1.transpose() * v1, m1.transpose() * v1);+ VERIFY_IS_APPROX(v1.transpose() * tm1, v1.transpose() * m1);++ // test submatrix and matrix/vector product+ for (int i=0; i<rows; ++i)+ res.row(i) = m1.row(i) * m2.transpose();+ VERIFY_IS_APPROX(res, m1 * m2.transpose());+ // the other way round:+ for (int i=0; i<rows; ++i)+ res.col(i) = m1 * m2.transpose().col(i);+ VERIFY_IS_APPROX(res, m1 * m2.transpose());++ res2 = square2;+ res2 += (m1.transpose() * m2).lazy();+ VERIFY_IS_APPROX(res2, square2 + m1.transpose() * m2);++ if (NumTraits<Scalar>::HasFloatingPoint && std::min(rows,cols)>1)+ {+ VERIFY(areNotApprox(res2,square2 + m2.transpose() * m1));+ }+}+
+ eigen3/test/eigen2/runtest.sh view
@@ -0,0 +1,28 @@+#!/bin/bash++black='\E[30m'+red='\E[31m'+green='\E[32m'+yellow='\E[33m'+blue='\E[34m'+magenta='\E[35m'+cyan='\E[36m'+white='\E[37m'++if make test_$1 > /dev/null 2> .runtest.log ; then+ if ! ./test_$1 r20 > /dev/null 2> .runtest.log ; then+ echo -e $red Test $1 failed: $black+ echo -e $blue+ cat .runtest.log+ echo -e $black+ exit 1+ else+ echo -e $green Test $1 passed$black+ fi+else+ echo -e $red Build of target $1 failed: $black+ echo -e $blue+ cat .runtest.log+ echo -e $black+ exit 1+fi
+ eigen3/test/eigen2/sparse.h view
@@ -0,0 +1,154 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. Eigen itself is part of the KDE project.+//+// Copyright (C) 2008 Daniel Gomez Ferro <dgomezferro@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_TESTSPARSE_H++#include "main.h"++#if EIGEN_GNUC_AT_LEAST(4,0) && !defined __ICC+#include <tr1/unordered_map>+#define EIGEN_UNORDERED_MAP_SUPPORT+namespace std {+ using std::tr1::unordered_map;+}+#endif++#ifdef EIGEN_GOOGLEHASH_SUPPORT+ #include <google/sparse_hash_map>+#endif++#include <Eigen/Cholesky>+#include <Eigen/LU>+#include <Eigen/Sparse>++enum {+ ForceNonZeroDiag = 1,+ MakeLowerTriangular = 2,+ MakeUpperTriangular = 4,+ ForceRealDiag = 8+};++/* Initializes both a sparse and dense matrix with same random values,+ * and a ratio of \a density non zero entries.+ * \param flags is a union of ForceNonZeroDiag, MakeLowerTriangular and MakeUpperTriangular+ * allowing to control the shape of the matrix.+ * \param zeroCoords and nonzeroCoords allows to get the coordinate lists of the non zero,+ * and zero coefficients respectively.+ */+template<typename Scalar> void+initSparse(double density,+ Matrix<Scalar,Dynamic,Dynamic>& refMat,+ SparseMatrix<Scalar>& sparseMat,+ int flags = 0,+ std::vector<Vector2i>* zeroCoords = 0,+ std::vector<Vector2i>* nonzeroCoords = 0)+{+ sparseMat.startFill(int(refMat.rows()*refMat.cols()*density));+ for(int j=0; j<refMat.cols(); j++)+ {+ for(int i=0; i<refMat.rows(); i++)+ {+ Scalar v = (ei_random<double>(0,1) < density) ? ei_random<Scalar>() : Scalar(0);+ if ((flags&ForceNonZeroDiag) && (i==j))+ {+ v = ei_random<Scalar>()*Scalar(3.);+ v = v*v + Scalar(5.);+ }+ if ((flags & MakeLowerTriangular) && j>i)+ v = Scalar(0);+ else if ((flags & MakeUpperTriangular) && j<i)+ v = Scalar(0);+ + if ((flags&ForceRealDiag) && (i==j))+ v = ei_real(v);+ + if (v!=Scalar(0))+ {+ sparseMat.fill(i,j) = v;+ if (nonzeroCoords)+ nonzeroCoords->push_back(Vector2i(i,j));+ }+ else if (zeroCoords)+ {+ zeroCoords->push_back(Vector2i(i,j));+ }+ refMat(i,j) = v;+ }+ }+ sparseMat.endFill();+}++template<typename Scalar> void+initSparse(double density,+ Matrix<Scalar,Dynamic,Dynamic>& refMat,+ DynamicSparseMatrix<Scalar>& sparseMat,+ int flags = 0,+ std::vector<Vector2i>* zeroCoords = 0,+ std::vector<Vector2i>* nonzeroCoords = 0)+{+ sparseMat.startFill(int(refMat.rows()*refMat.cols()*density));+ for(int j=0; j<refMat.cols(); j++)+ {+ for(int i=0; i<refMat.rows(); i++)+ {+ Scalar v = (ei_random<double>(0,1) < density) ? ei_random<Scalar>() : Scalar(0);+ if ((flags&ForceNonZeroDiag) && (i==j))+ {+ v = ei_random<Scalar>()*Scalar(3.);+ v = v*v + Scalar(5.);+ }+ if ((flags & MakeLowerTriangular) && j>i)+ v = Scalar(0);+ else if ((flags & MakeUpperTriangular) && j<i)+ v = Scalar(0);+ + if ((flags&ForceRealDiag) && (i==j))+ v = ei_real(v);+ + if (v!=Scalar(0))+ {+ sparseMat.fill(i,j) = v;+ if (nonzeroCoords)+ nonzeroCoords->push_back(Vector2i(i,j));+ }+ else if (zeroCoords)+ {+ zeroCoords->push_back(Vector2i(i,j));+ }+ refMat(i,j) = v;+ }+ }+ sparseMat.endFill();+}++template<typename Scalar> void+initSparse(double density,+ Matrix<Scalar,Dynamic,1>& refVec,+ SparseVector<Scalar>& sparseVec,+ std::vector<int>* zeroCoords = 0,+ std::vector<int>* nonzeroCoords = 0)+{+ sparseVec.reserve(int(refVec.size()*density));+ sparseVec.setZero();+ for(int i=0; i<refVec.size(); i++)+ {+ Scalar v = (ei_random<double>(0,1) < density) ? ei_random<Scalar>() : Scalar(0);+ if (v!=Scalar(0))+ {+ sparseVec.fill(i) = v;+ if (nonzeroCoords)+ nonzeroCoords->push_back(i);+ }+ else if (zeroCoords)+ zeroCoords->push_back(i);+ refVec[i] = v;+ }+}++#endif // EIGEN_TESTSPARSE_H
+ eigen3/test/eigen2/testsuite.cmake view
@@ -0,0 +1,197 @@++####################################################################+#+# Usage:+# - create a new folder, let's call it cdash+# - in that folder, do:+# ctest -S path/to/eigen2/test/testsuite.cmake[,option1=value1[,option2=value2]]+#+# Options:+# - EIGEN_CXX: compiler, eg.: g++-4.2+# default: default c++ compiler+# - EIGEN_SITE: eg, INRIA-Bdx_pc-gael, or the name of the contributor, etc.+# default: hostname+# - EIGEN_BUILD_STRING: a string which identify the system/compiler. It should be formed like that:+# <OS_name>-<OS_version>-<arch>-<compiler-version>+# with:+# <OS_name> = opensuse, debian, osx, windows, cygwin, freebsd, solaris, etc.+# <OS_version> = 11.1, XP, vista, leopard, etc.+# <arch> = i386, x86_64, ia64, powerpc, etc.+# <compiler-version> = gcc-4.3.2, icc-11.0, MSVC-2008, etc.+# - EIGEN_EXPLICIT_VECTORIZATION: novec, SSE2, Altivec+# default: SSE2 for x86_64 systems, novec otherwise+# Its value is automatically appended to EIGEN_BUILD_STRING+# - EIGEN_CMAKE_DIR: path to cmake executable+# - EIGEN_MODE: dashboard model, can be Experimental, Nightly, or Continuous+# default: Nightly+# - EIGEN_WORK_DIR: directory used to download the source files and make the builds+# default: folder which contains this script+# - EIGEN_CMAKE_ARGS: additional arguments passed to cmake+# - CTEST_SOURCE_DIRECTORY: path to eigen's src (use a new and empty folder, not the one you are working on)+# default: <EIGEN_WORK_DIR>/src+# - CTEST_BINARY_DIRECTORY: build directory+# default: <EIGEN_WORK_DIR>/nightly-<EIGEN_CXX>+#+# Here is an example running several compilers on a linux system:+# #!/bin/bash+# ARCH=`uname -m`+# SITE=`hostname`+# VERSION=opensuse-11.1+# WORK_DIR=/home/gael/Coding/eigen2/cdash+# # get the last version of the script+# wget http://bitbucket.org/eigen/eigen/raw/tip/test/testsuite.cmake -o $WORK_DIR/testsuite.cmake+# COMMON="ctest -S $WORK_DIR/testsuite.cmake,EIGEN_WORK_DIR=$WORK_DIR,EIGEN_SITE=$SITE,EIGEN_MODE=$1,EIGEN_BUILD_STRING=$OS_VERSION-$ARCH"+# $COMMON-gcc-3.4.6,EIGEN_CXX=g++-3.4+# $COMMON-gcc-4.0.1,EIGEN_CXX=g++-4.0.1+# $COMMON-gcc-4.3.2,EIGEN_CXX=g++-4.3,EIGEN_EXPLICIT_VECTORIZATION=novec+# $COMMON-gcc-4.3.2,EIGEN_CXX=g++-4.3,EIGEN_EXPLICIT_VECTORIZATION=SSE2+# $COMMON-icc-11.0,EIGEN_CXX=icpc+#+####################################################################++# process the arguments++set(ARGLIST ${CTEST_SCRIPT_ARG})+while(${ARGLIST} MATCHES ".+.*")++ # pick first+ string(REGEX MATCH "([^,]*)(,.*)?" DUMMY ${ARGLIST})+ SET(TOP ${CMAKE_MATCH_1})++ # remove first+ string(REGEX MATCHALL "[^,]*,(.*)" DUMMY ${ARGLIST})+ SET(ARGLIST ${CMAKE_MATCH_1})++ # decompose as a pair key=value+ string(REGEX MATCH "([^=]*)(=.*)?" DUMMY ${TOP})+ SET(KEY ${CMAKE_MATCH_1})++ string(REGEX MATCH "[^=]*=(.*)" DUMMY ${TOP})+ SET(VALUE ${CMAKE_MATCH_1})++ # set the variable to the specified value+ if(VALUE)+ SET(${KEY} ${VALUE})+ else(VALUE)+ SET(${KEY} ON)+ endif(VALUE)++endwhile(${ARGLIST} MATCHES ".+.*")++####################################################################+# Automatically set some user variables if they have not been defined manually+####################################################################+cmake_minimum_required(VERSION 2.6 FATAL_ERROR)++if(NOT EIGEN_SITE)+ site_name(EIGEN_SITE)+endif(NOT EIGEN_SITE)++if(NOT EIGEN_CMAKE_DIR)+ SET(EIGEN_CMAKE_DIR "")+endif(NOT EIGEN_CMAKE_DIR)++if(NOT EIGEN_BUILD_STRING)++ # let's try to find all information we need to make the build string ourself++ # OS+ build_name(EIGEN_OS_VERSION)++ # arch+ set(EIGEN_ARCH ${CMAKE_SYSTEM_PROCESSOR})+ if(WIN32)+ set(EIGEN_ARCH $ENV{PROCESSOR_ARCHITECTURE})+ else(WIN32)+ execute_process(COMMAND uname -m OUTPUT_VARIABLE EIGEN_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)+ endif(WIN32)++ set(EIGEN_BUILD_STRING ${EIGEN_OS_VERSION}${EIGEN_ARCH}-${EIGEN_CXX})++endif(NOT EIGEN_BUILD_STRING)++if(DEFINED EIGEN_EXPLICIT_VECTORIZATION)+ set(EIGEN_BUILD_STRING ${EIGEN_BUILD_STRING}-${EIGEN_EXPLICIT_VECTORIZATION})+endif(DEFINED EIGEN_EXPLICIT_VECTORIZATION)++if(NOT EIGEN_WORK_DIR)+ set(EIGEN_WORK_DIR ${CTEST_SCRIPT_DIRECTORY})+endif(NOT EIGEN_WORK_DIR)++if(NOT CTEST_SOURCE_DIRECTORY)+ SET (CTEST_SOURCE_DIRECTORY "${EIGEN_WORK_DIR}/src")+endif(NOT CTEST_SOURCE_DIRECTORY)++if(NOT CTEST_BINARY_DIRECTORY)+ SET (CTEST_BINARY_DIRECTORY "${EIGEN_WORK_DIR}/nightly_${EIGEN_CXX}")+endif(NOT CTEST_BINARY_DIRECTORY)++if(NOT EIGEN_MODE)+ set(EIGEN_MODE Nightly)+endif(NOT EIGEN_MODE)++## mandatory variables (the default should be ok in most cases):++SET (CTEST_CVS_COMMAND "hg")+SET (CTEST_CVS_CHECKOUT "${CTEST_CVS_COMMAND} clone -r 2.0 http://bitbucket.org/eigen/eigen \"${CTEST_SOURCE_DIRECTORY}\"")++# which ctest command to use for running the dashboard+SET (CTEST_COMMAND "${EIGEN_CMAKE_DIR}ctest -D ${EIGEN_MODE}")++# what cmake command to use for configuring this dashboard+SET (CTEST_CMAKE_COMMAND "${EIGEN_CMAKE_DIR}cmake -DEIGEN_BUILD_TESTS=on ")++####################################################################+# The values in this section are optional you can either+# have them or leave them commented out+####################################################################++# this make sure we get consistent outputs+SET($ENV{LC_MESSAGES} "en_EN")++# should ctest wipe the binary tree before running+SET(CTEST_START_WITH_EMPTY_BINARY_DIRECTORY TRUE)+SET(CTEST_BACKUP_AND_RESTORE TRUE)++# this is the initial cache to use for the binary tree, be careful to escape+# any quotes inside of this string if you use it+if(WIN32 AND NOT UNIX)+ #message(SEND_ERROR "win32")+ set(CTEST_CMAKE_COMMAND "${CTEST_CMAKE_COMMAND} -G \"NMake Makefiles\" -DCMAKE_MAKE_PROGRAM=nmake")+ SET (CTEST_INITIAL_CACHE "+ MAKECOMMAND:STRING=nmake -i+ CMAKE_MAKE_PROGRAM:FILEPATH=nmake+ CMAKE_GENERATOR:INTERNAL=NMake Makefiles+ BUILDNAME:STRING=${EIGEN_BUILD_STRING}+ SITE:STRING=${EIGEN_SITE}+ ")+else(WIN32 AND NOT UNIX)+ SET (CTEST_INITIAL_CACHE "+ BUILDNAME:STRING=${EIGEN_BUILD_STRING}+ SITE:STRING=${EIGEN_SITE}+ ")+endif(WIN32 AND NOT UNIX)++# set any extra environment variables to use during the execution of the script here:++if(EIGEN_CXX)+ set(CTEST_ENVIRONMENT "CXX=${EIGEN_CXX}")+endif(EIGEN_CXX)++if(DEFINED EIGEN_EXPLICIT_VECTORIZATION)+ if(EIGEN_EXPLICIT_VECTORIZATION MATCHES SSE2)+ set(CTEST_CMAKE_COMMAND "${CTEST_CMAKE_COMMAND} -DEIGEN_TEST_SSE2=ON")+ elseif(EIGEN_EXPLICIT_VECTORIZATION MATCHES SSE3)+ set(CTEST_CMAKE_COMMAND "${CTEST_CMAKE_COMMAND} -DEIGEN_TEST_SSE2=ON -DEIGEN_TEST_SSE3=ON")+ elseif(EIGEN_EXPLICIT_VECTORIZATION MATCHES Altivec)+ set(CTEST_CMAKE_COMMAND "${CTEST_CMAKE_COMMAND} -DEIGEN_TEST_ALTIVEC=ON")+ elseif(EIGEN_EXPLICIT_VECTORIZATION MATCHES novec)+ set(CTEST_CMAKE_COMMAND "${CTEST_CMAKE_COMMAND} -DEIGEN_TEST_NO_EXPLICIT_VECTORIZATION=ON")+ else(EIGEN_EXPLICIT_VECTORIZATION MATCHES SSE2)+ message(FATAL_ERROR "Invalid value for EIGEN_EXPLICIT_VECTORIZATION (${EIGEN_EXPLICIT_VECTORIZATION}), must be: novec, SSE2, SSE3, Altivec")+ endif(EIGEN_EXPLICIT_VECTORIZATION MATCHES SSE2)+endif(DEFINED EIGEN_EXPLICIT_VECTORIZATION)++if(DEFINED EIGEN_CMAKE_ARGS)+ set(CTEST_CMAKE_COMMAND "${CTEST_CMAKE_COMMAND} ${EIGEN_CMAKE_ARGS}")+endif(DEFINED EIGEN_CMAKE_ARGS)
+ eigen3/test/eigen2support.cpp view
@@ -0,0 +1,67 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN2_SUPPORT+#define EIGEN_NO_EIGEN2_DEPRECATED_WARNING++#include "main.h"++template<typename MatrixType> void eigen2support(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;++ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m3(rows, cols);++ Scalar s1 = internal::random<Scalar>(),+ s2 = internal::random<Scalar>();++ // scalar addition+ VERIFY_IS_APPROX(m1.cwise() + s1, s1 + m1.cwise());+ VERIFY_IS_APPROX(m1.cwise() + s1, MatrixType::Constant(rows,cols,s1) + m1);+ VERIFY_IS_APPROX((m1*Scalar(2)).cwise() - s2, (m1+m1) - MatrixType::Constant(rows,cols,s2) );+ m3 = m1;+ m3.cwise() += s2;+ VERIFY_IS_APPROX(m3, m1.cwise() + s2);+ m3 = m1;+ m3.cwise() -= s1;+ VERIFY_IS_APPROX(m3, m1.cwise() - s1);++ VERIFY_IS_EQUAL((m1.corner(TopLeft,1,1)), (m1.block(0,0,1,1)));+ VERIFY_IS_EQUAL((m1.template corner<1,1>(TopLeft)), (m1.template block<1,1>(0,0)));+ VERIFY_IS_EQUAL((m1.col(0).start(1)), (m1.col(0).segment(0,1)));+ VERIFY_IS_EQUAL((m1.col(0).template start<1>()), (m1.col(0).segment(0,1)));+ VERIFY_IS_EQUAL((m1.col(0).end(1)), (m1.col(0).segment(rows-1,1)));+ VERIFY_IS_EQUAL((m1.col(0).template end<1>()), (m1.col(0).segment(rows-1,1)));+ + using std::cos;+ using numext::real;+ using numext::abs2;+ VERIFY_IS_EQUAL(ei_cos(s1), cos(s1));+ VERIFY_IS_EQUAL(ei_real(s1), real(s1));+ VERIFY_IS_EQUAL(ei_abs2(s1), abs2(s1));++ m1.minor(0,0);+}++void test_eigen2support()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( eigen2support(Matrix<double,1,1>()) );+ CALL_SUBTEST_2( eigen2support(MatrixXd(1,1)) );+ CALL_SUBTEST_4( eigen2support(Matrix3f()) );+ CALL_SUBTEST_5( eigen2support(Matrix4d()) );+ CALL_SUBTEST_2( eigen2support(MatrixXf(200,200)) );+ CALL_SUBTEST_6( eigen2support(MatrixXcd(100,100)) );+ }+}
+ eigen3/test/eigensolver_complex.cpp view
@@ -0,0 +1,122 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <limits>+#include <Eigen/Eigenvalues>+#include <Eigen/LU>++/* Check that two column vectors are approximately equal upto permutations,+ by checking that the k-th power sums are equal for k = 1, ..., vec1.rows() */+template<typename VectorType>+void verify_is_approx_upto_permutation(const VectorType& vec1, const VectorType& vec2)+{+ typedef typename NumTraits<typename VectorType::Scalar>::Real RealScalar;++ VERIFY(vec1.cols() == 1);+ VERIFY(vec2.cols() == 1);+ VERIFY(vec1.rows() == vec2.rows());+ for (int k = 1; k <= vec1.rows(); ++k)+ {+ VERIFY_IS_APPROX(vec1.array().pow(RealScalar(k)).sum(), vec2.array().pow(RealScalar(k)).sum());+ }+}+++template<typename MatrixType> void eigensolver(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ /* this test covers the following files:+ ComplexEigenSolver.h, and indirectly ComplexSchur.h+ */+ Index rows = m.rows();+ Index cols = m.cols();++ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;++ MatrixType a = MatrixType::Random(rows,cols);+ MatrixType symmA = a.adjoint() * a;++ ComplexEigenSolver<MatrixType> ei0(symmA);+ VERIFY_IS_EQUAL(ei0.info(), Success);+ VERIFY_IS_APPROX(symmA * ei0.eigenvectors(), ei0.eigenvectors() * ei0.eigenvalues().asDiagonal());++ ComplexEigenSolver<MatrixType> ei1(a);+ VERIFY_IS_EQUAL(ei1.info(), Success);+ VERIFY_IS_APPROX(a * ei1.eigenvectors(), ei1.eigenvectors() * ei1.eigenvalues().asDiagonal());+ // Note: If MatrixType is real then a.eigenvalues() uses EigenSolver and thus+ // another algorithm so results may differ slightly+ verify_is_approx_upto_permutation(a.eigenvalues(), ei1.eigenvalues());++ ComplexEigenSolver<MatrixType> ei2;+ ei2.setMaxIterations(ComplexSchur<MatrixType>::m_maxIterationsPerRow * rows).compute(a);+ VERIFY_IS_EQUAL(ei2.info(), Success);+ VERIFY_IS_EQUAL(ei2.eigenvectors(), ei1.eigenvectors());+ VERIFY_IS_EQUAL(ei2.eigenvalues(), ei1.eigenvalues());+ if (rows > 2) {+ ei2.setMaxIterations(1).compute(a);+ VERIFY_IS_EQUAL(ei2.info(), NoConvergence);+ VERIFY_IS_EQUAL(ei2.getMaxIterations(), 1);+ }++ ComplexEigenSolver<MatrixType> eiNoEivecs(a, false);+ VERIFY_IS_EQUAL(eiNoEivecs.info(), Success);+ VERIFY_IS_APPROX(ei1.eigenvalues(), eiNoEivecs.eigenvalues());++ // Regression test for issue #66+ MatrixType z = MatrixType::Zero(rows,cols);+ ComplexEigenSolver<MatrixType> eiz(z);+ VERIFY((eiz.eigenvalues().cwiseEqual(0)).all());++ MatrixType id = MatrixType::Identity(rows, cols);+ VERIFY_IS_APPROX(id.operatorNorm(), RealScalar(1));++ if (rows > 1)+ {+ // Test matrix with NaN+ a(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();+ ComplexEigenSolver<MatrixType> eiNaN(a);+ VERIFY_IS_EQUAL(eiNaN.info(), NoConvergence);+ }+}++template<typename MatrixType> void eigensolver_verify_assert(const MatrixType& m)+{+ ComplexEigenSolver<MatrixType> eig;+ VERIFY_RAISES_ASSERT(eig.eigenvectors());+ VERIFY_RAISES_ASSERT(eig.eigenvalues());++ MatrixType a = MatrixType::Random(m.rows(),m.cols());+ eig.compute(a, false);+ VERIFY_RAISES_ASSERT(eig.eigenvectors());+}++void test_eigensolver_complex()+{+ int s = 0;+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( eigensolver(Matrix4cf()) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);+ CALL_SUBTEST_2( eigensolver(MatrixXcd(s,s)) );+ CALL_SUBTEST_3( eigensolver(Matrix<std::complex<float>, 1, 1>()) );+ CALL_SUBTEST_4( eigensolver(Matrix3f()) );+ }+ CALL_SUBTEST_1( eigensolver_verify_assert(Matrix4cf()) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);+ CALL_SUBTEST_2( eigensolver_verify_assert(MatrixXcd(s,s)) );+ CALL_SUBTEST_3( eigensolver_verify_assert(Matrix<std::complex<float>, 1, 1>()) );+ CALL_SUBTEST_4( eigensolver_verify_assert(Matrix3f()) );++ // Test problem size constructors+ CALL_SUBTEST_5(ComplexEigenSolver<MatrixXf> tmp(s));+ + TEST_SET_BUT_UNUSED_VARIABLE(s)+}
+ eigen3/test/eigensolver_generalized_real.cpp view
@@ -0,0 +1,59 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <limits>+#include <Eigen/Eigenvalues>++template<typename MatrixType> void generalized_eigensolver_real(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ /* this test covers the following files:+ GeneralizedEigenSolver.h+ */+ Index rows = m.rows();+ Index cols = m.cols();++ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ MatrixType a = MatrixType::Random(rows,cols);+ MatrixType b = MatrixType::Random(rows,cols);+ MatrixType a1 = MatrixType::Random(rows,cols);+ MatrixType b1 = MatrixType::Random(rows,cols);+ MatrixType spdA = a.adjoint() * a + a1.adjoint() * a1;+ MatrixType spdB = b.adjoint() * b + b1.adjoint() * b1;++ // lets compare to GeneralizedSelfAdjointEigenSolver+ GeneralizedSelfAdjointEigenSolver<MatrixType> symmEig(spdA, spdB);+ GeneralizedEigenSolver<MatrixType> eig(spdA, spdB);++ VERIFY_IS_EQUAL(eig.eigenvalues().imag().cwiseAbs().maxCoeff(), 0);++ VectorType realEigenvalues = eig.eigenvalues().real();+ std::sort(realEigenvalues.data(), realEigenvalues.data()+realEigenvalues.size());+ VERIFY_IS_APPROX(realEigenvalues, symmEig.eigenvalues());+}++void test_eigensolver_generalized_real()+{+ for(int i = 0; i < g_repeat; i++) {+ int s = 0;+ CALL_SUBTEST_1( generalized_eigensolver_real(Matrix4f()) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);+ CALL_SUBTEST_2( generalized_eigensolver_real(MatrixXd(s,s)) );++ // some trivial but implementation-wise tricky cases+ CALL_SUBTEST_2( generalized_eigensolver_real(MatrixXd(1,1)) );+ CALL_SUBTEST_2( generalized_eigensolver_real(MatrixXd(2,2)) );+ CALL_SUBTEST_3( generalized_eigensolver_real(Matrix<double,1,1>()) );+ CALL_SUBTEST_4( generalized_eigensolver_real(Matrix2d()) );+ TEST_SET_BUT_UNUSED_VARIABLE(s)+ }+}
+ eigen3/test/eigensolver_generic.cpp view
@@ -0,0 +1,125 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <limits>+#include <Eigen/Eigenvalues>++template<typename MatrixType> void eigensolver(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ /* this test covers the following files:+ EigenSolver.h+ */+ Index rows = m.rows();+ Index cols = m.cols();++ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, 1> RealVectorType;+ typedef typename std::complex<typename NumTraits<typename MatrixType::Scalar>::Real> Complex;++ MatrixType a = MatrixType::Random(rows,cols);+ MatrixType a1 = MatrixType::Random(rows,cols);+ MatrixType symmA = a.adjoint() * a + a1.adjoint() * a1;++ EigenSolver<MatrixType> ei0(symmA);+ VERIFY_IS_EQUAL(ei0.info(), Success);+ VERIFY_IS_APPROX(symmA * ei0.pseudoEigenvectors(), ei0.pseudoEigenvectors() * ei0.pseudoEigenvalueMatrix());+ VERIFY_IS_APPROX((symmA.template cast<Complex>()) * (ei0.pseudoEigenvectors().template cast<Complex>()),+ (ei0.pseudoEigenvectors().template cast<Complex>()) * (ei0.eigenvalues().asDiagonal()));++ EigenSolver<MatrixType> ei1(a);+ VERIFY_IS_EQUAL(ei1.info(), Success);+ VERIFY_IS_APPROX(a * ei1.pseudoEigenvectors(), ei1.pseudoEigenvectors() * ei1.pseudoEigenvalueMatrix());+ VERIFY_IS_APPROX(a.template cast<Complex>() * ei1.eigenvectors(),+ ei1.eigenvectors() * ei1.eigenvalues().asDiagonal());+ VERIFY_IS_APPROX(ei1.eigenvectors().colwise().norm(), RealVectorType::Ones(rows).transpose());+ VERIFY_IS_APPROX(a.eigenvalues(), ei1.eigenvalues());++ EigenSolver<MatrixType> ei2;+ ei2.setMaxIterations(RealSchur<MatrixType>::m_maxIterationsPerRow * rows).compute(a);+ VERIFY_IS_EQUAL(ei2.info(), Success);+ VERIFY_IS_EQUAL(ei2.eigenvectors(), ei1.eigenvectors());+ VERIFY_IS_EQUAL(ei2.eigenvalues(), ei1.eigenvalues());+ if (rows > 2) {+ ei2.setMaxIterations(1).compute(a);+ VERIFY_IS_EQUAL(ei2.info(), NoConvergence);+ VERIFY_IS_EQUAL(ei2.getMaxIterations(), 1);+ }++ EigenSolver<MatrixType> eiNoEivecs(a, false);+ VERIFY_IS_EQUAL(eiNoEivecs.info(), Success);+ VERIFY_IS_APPROX(ei1.eigenvalues(), eiNoEivecs.eigenvalues());+ VERIFY_IS_APPROX(ei1.pseudoEigenvalueMatrix(), eiNoEivecs.pseudoEigenvalueMatrix());++ MatrixType id = MatrixType::Identity(rows, cols);+ VERIFY_IS_APPROX(id.operatorNorm(), RealScalar(1));++ if (rows > 2)+ {+ // Test matrix with NaN+ a(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();+ EigenSolver<MatrixType> eiNaN(a);+ VERIFY_IS_EQUAL(eiNaN.info(), NoConvergence);+ }+}++template<typename MatrixType> void eigensolver_verify_assert(const MatrixType& m)+{+ EigenSolver<MatrixType> eig;+ VERIFY_RAISES_ASSERT(eig.eigenvectors());+ VERIFY_RAISES_ASSERT(eig.pseudoEigenvectors());+ VERIFY_RAISES_ASSERT(eig.pseudoEigenvalueMatrix());+ VERIFY_RAISES_ASSERT(eig.eigenvalues());++ MatrixType a = MatrixType::Random(m.rows(),m.cols());+ eig.compute(a, false);+ VERIFY_RAISES_ASSERT(eig.eigenvectors());+ VERIFY_RAISES_ASSERT(eig.pseudoEigenvectors());+}++void test_eigensolver_generic()+{+ int s = 0;+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( eigensolver(Matrix4f()) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);+ CALL_SUBTEST_2( eigensolver(MatrixXd(s,s)) );++ // some trivial but implementation-wise tricky cases+ CALL_SUBTEST_2( eigensolver(MatrixXd(1,1)) );+ CALL_SUBTEST_2( eigensolver(MatrixXd(2,2)) );+ CALL_SUBTEST_3( eigensolver(Matrix<double,1,1>()) );+ CALL_SUBTEST_4( eigensolver(Matrix2d()) );+ }++ CALL_SUBTEST_1( eigensolver_verify_assert(Matrix4f()) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);+ CALL_SUBTEST_2( eigensolver_verify_assert(MatrixXd(s,s)) );+ CALL_SUBTEST_3( eigensolver_verify_assert(Matrix<double,1,1>()) );+ CALL_SUBTEST_4( eigensolver_verify_assert(Matrix2d()) );++ // Test problem size constructors+ CALL_SUBTEST_5(EigenSolver<MatrixXf> tmp(s));++ // regression test for bug 410+ CALL_SUBTEST_2(+ {+ MatrixXd A(1,1);+ A(0,0) = std::sqrt(-1.);+ Eigen::EigenSolver<MatrixXd> solver(A);+ MatrixXd V(1, 1);+ V(0,0) = solver.eigenvectors()(0,0).real();+ }+ );+ + TEST_SET_BUT_UNUSED_VARIABLE(s)+}
+ eigen3/test/eigensolver_selfadjoint.cpp view
@@ -0,0 +1,160 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <limits>+#include <Eigen/Eigenvalues>++template<typename MatrixType> void selfadjointeigensolver(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ /* this test covers the following files:+ EigenSolver.h, SelfAdjointEigenSolver.h (and indirectly: Tridiagonalization.h)+ */+ Index rows = m.rows();+ Index cols = m.cols();++ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;++ RealScalar largerEps = 10*test_precision<RealScalar>();++ MatrixType a = MatrixType::Random(rows,cols);+ MatrixType a1 = MatrixType::Random(rows,cols);+ MatrixType symmA = a.adjoint() * a + a1.adjoint() * a1;+ MatrixType symmC = symmA;+ + // randomly nullify some rows/columns+ {+ Index count = 1;//internal::random<Index>(-cols,cols);+ for(Index k=0; k<count; ++k)+ {+ Index i = internal::random<Index>(0,cols-1);+ symmA.row(i).setZero();+ symmA.col(i).setZero();+ }+ }+ + symmA.template triangularView<StrictlyUpper>().setZero();+ symmC.template triangularView<StrictlyUpper>().setZero();++ MatrixType b = MatrixType::Random(rows,cols);+ MatrixType b1 = MatrixType::Random(rows,cols);+ MatrixType symmB = b.adjoint() * b + b1.adjoint() * b1;+ symmB.template triangularView<StrictlyUpper>().setZero();++ SelfAdjointEigenSolver<MatrixType> eiSymm(symmA);+ SelfAdjointEigenSolver<MatrixType> eiDirect;+ eiDirect.computeDirect(symmA);+ // generalized eigen pb+ GeneralizedSelfAdjointEigenSolver<MatrixType> eiSymmGen(symmC, symmB);++ VERIFY_IS_EQUAL(eiSymm.info(), Success);+ VERIFY((symmA.template selfadjointView<Lower>() * eiSymm.eigenvectors()).isApprox(+ eiSymm.eigenvectors() * eiSymm.eigenvalues().asDiagonal(), largerEps));+ VERIFY_IS_APPROX(symmA.template selfadjointView<Lower>().eigenvalues(), eiSymm.eigenvalues());+ + VERIFY_IS_EQUAL(eiDirect.info(), Success);+ VERIFY((symmA.template selfadjointView<Lower>() * eiDirect.eigenvectors()).isApprox(+ eiDirect.eigenvectors() * eiDirect.eigenvalues().asDiagonal(), largerEps));+ VERIFY_IS_APPROX(symmA.template selfadjointView<Lower>().eigenvalues(), eiDirect.eigenvalues());++ SelfAdjointEigenSolver<MatrixType> eiSymmNoEivecs(symmA, false);+ VERIFY_IS_EQUAL(eiSymmNoEivecs.info(), Success);+ VERIFY_IS_APPROX(eiSymm.eigenvalues(), eiSymmNoEivecs.eigenvalues());+ + // generalized eigen problem Ax = lBx+ eiSymmGen.compute(symmC, symmB,Ax_lBx);+ VERIFY_IS_EQUAL(eiSymmGen.info(), Success);+ VERIFY((symmC.template selfadjointView<Lower>() * eiSymmGen.eigenvectors()).isApprox(+ symmB.template selfadjointView<Lower>() * (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));++ // generalized eigen problem BAx = lx+ eiSymmGen.compute(symmC, symmB,BAx_lx);+ VERIFY_IS_EQUAL(eiSymmGen.info(), Success);+ VERIFY((symmB.template selfadjointView<Lower>() * (symmC.template selfadjointView<Lower>() * eiSymmGen.eigenvectors())).isApprox(+ (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));++ // generalized eigen problem ABx = lx+ eiSymmGen.compute(symmC, symmB,ABx_lx);+ VERIFY_IS_EQUAL(eiSymmGen.info(), Success);+ VERIFY((symmC.template selfadjointView<Lower>() * (symmB.template selfadjointView<Lower>() * eiSymmGen.eigenvectors())).isApprox(+ (eiSymmGen.eigenvectors() * eiSymmGen.eigenvalues().asDiagonal()), largerEps));+++ eiSymm.compute(symmC);+ MatrixType sqrtSymmA = eiSymm.operatorSqrt();+ VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()), sqrtSymmA*sqrtSymmA);+ VERIFY_IS_APPROX(sqrtSymmA, symmC.template selfadjointView<Lower>()*eiSymm.operatorInverseSqrt());++ MatrixType id = MatrixType::Identity(rows, cols);+ VERIFY_IS_APPROX(id.template selfadjointView<Lower>().operatorNorm(), RealScalar(1));++ SelfAdjointEigenSolver<MatrixType> eiSymmUninitialized;+ VERIFY_RAISES_ASSERT(eiSymmUninitialized.info());+ VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvalues());+ VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());+ VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());+ VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());++ eiSymmUninitialized.compute(symmA, false);+ VERIFY_RAISES_ASSERT(eiSymmUninitialized.eigenvectors());+ VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorSqrt());+ VERIFY_RAISES_ASSERT(eiSymmUninitialized.operatorInverseSqrt());++ // test Tridiagonalization's methods+ Tridiagonalization<MatrixType> tridiag(symmC);+ // FIXME tridiag.matrixQ().adjoint() does not work+ VERIFY_IS_APPROX(MatrixType(symmC.template selfadjointView<Lower>()), tridiag.matrixQ() * tridiag.matrixT().eval() * MatrixType(tridiag.matrixQ()).adjoint());+ + if (rows > 1)+ {+ // Test matrix with NaN+ symmC(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();+ SelfAdjointEigenSolver<MatrixType> eiSymmNaN(symmC);+ VERIFY_IS_EQUAL(eiSymmNaN.info(), NoConvergence);+ }+}++void test_eigensolver_selfadjoint()+{+ int s = 0;+ for(int i = 0; i < g_repeat; i++) {+ // very important to test 3x3 and 2x2 matrices since we provide special paths for them+ CALL_SUBTEST_1( selfadjointeigensolver(Matrix2f()) );+ CALL_SUBTEST_1( selfadjointeigensolver(Matrix2d()) );+ CALL_SUBTEST_1( selfadjointeigensolver(Matrix3f()) );+ CALL_SUBTEST_1( selfadjointeigensolver(Matrix3d()) );+ CALL_SUBTEST_2( selfadjointeigensolver(Matrix4d()) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);+ CALL_SUBTEST_3( selfadjointeigensolver(MatrixXf(s,s)) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);+ CALL_SUBTEST_4( selfadjointeigensolver(MatrixXd(s,s)) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);+ CALL_SUBTEST_5( selfadjointeigensolver(MatrixXcd(s,s)) );+ + s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);+ CALL_SUBTEST_9( selfadjointeigensolver(Matrix<std::complex<double>,Dynamic,Dynamic,RowMajor>(s,s)) );++ // some trivial but implementation-wise tricky cases+ CALL_SUBTEST_4( selfadjointeigensolver(MatrixXd(1,1)) );+ CALL_SUBTEST_4( selfadjointeigensolver(MatrixXd(2,2)) );+ CALL_SUBTEST_6( selfadjointeigensolver(Matrix<double,1,1>()) );+ CALL_SUBTEST_7( selfadjointeigensolver(Matrix<double,2,2>()) );+ }++ // Test problem size constructors+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);+ CALL_SUBTEST_8(SelfAdjointEigenSolver<MatrixXf> tmp1(s));+ CALL_SUBTEST_8(Tridiagonalization<MatrixXf> tmp2(s));+ + TEST_SET_BUT_UNUSED_VARIABLE(s)+}+
+ eigen3/test/exceptions.cpp view
@@ -0,0 +1,113 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.+++// Various sanity tests with exceptions:+// - no memory leak when a custom scalar type trow an exceptions+// - todo: complete the list of tests!++#define EIGEN_STACK_ALLOCATION_LIMIT 100000000++#include "main.h"++struct my_exception+{+ my_exception() {}+ ~my_exception() {}+};+ +class ScalarWithExceptions+{+ public:+ ScalarWithExceptions() { init(); }+ ScalarWithExceptions(const float& _v) { init(); *v = _v; }+ ScalarWithExceptions(const ScalarWithExceptions& other) { init(); *v = *(other.v); }+ ~ScalarWithExceptions() {+ delete v;+ instances--;+ }++ void init() {+ v = new float;+ instances++;+ }++ ScalarWithExceptions operator+(const ScalarWithExceptions& other) const+ {+ countdown--;+ if(countdown<=0)+ throw my_exception();+ return ScalarWithExceptions(*v+*other.v);+ }+ + ScalarWithExceptions operator-(const ScalarWithExceptions& other) const+ { return ScalarWithExceptions(*v-*other.v); }+ + ScalarWithExceptions operator*(const ScalarWithExceptions& other) const+ { return ScalarWithExceptions((*v)*(*other.v)); }+ + ScalarWithExceptions& operator+=(const ScalarWithExceptions& other)+ { *v+=*other.v; return *this; }+ ScalarWithExceptions& operator-=(const ScalarWithExceptions& other)+ { *v-=*other.v; return *this; }+ ScalarWithExceptions& operator=(const ScalarWithExceptions& other)+ { *v = *(other.v); return *this; }+ + bool operator==(const ScalarWithExceptions& other) const+ { return *v==*other.v; }+ bool operator!=(const ScalarWithExceptions& other) const+ { return *v!=*other.v; }+ + float* v;+ static int instances;+ static int countdown;+};++ScalarWithExceptions real(const ScalarWithExceptions &x) { return x; }+ScalarWithExceptions imag(const ScalarWithExceptions & ) { return 0; }+ScalarWithExceptions conj(const ScalarWithExceptions &x) { return x; }++int ScalarWithExceptions::instances = 0;+int ScalarWithExceptions::countdown = 0;+++#define CHECK_MEMLEAK(OP) { \+ ScalarWithExceptions::countdown = 100; \+ int before = ScalarWithExceptions::instances; \+ bool exception_thrown = false; \+ try { OP; } \+ catch (my_exception) { \+ exception_thrown = true; \+ VERIFY(ScalarWithExceptions::instances==before && "memory leak detected in " && EIGEN_MAKESTRING(OP)); \+ } \+ VERIFY(exception_thrown && " no exception thrown in " && EIGEN_MAKESTRING(OP)); \+ }++void memoryleak()+{+ typedef Eigen::Matrix<ScalarWithExceptions,Dynamic,1> VectorType;+ typedef Eigen::Matrix<ScalarWithExceptions,Dynamic,Dynamic> MatrixType;+ + {+ int n = 50;+ VectorType v0(n), v1(n);+ MatrixType m0(n,n), m1(n,n), m2(n,n);+ v0.setOnes(); v1.setOnes();+ m0.setOnes(); m1.setOnes(); m2.setOnes();+ CHECK_MEMLEAK(v0 = m0 * m1 * v1);+ CHECK_MEMLEAK(m2 = m0 * m1 * m2);+ CHECK_MEMLEAK((v0+v1).dot(v0+v1));+ }+ VERIFY(ScalarWithExceptions::instances==0 && "global memory leak detected in " && EIGEN_MAKESTRING(OP)); \+}++void test_exceptions()+{+ CALL_SUBTEST( memoryleak() );+}
+ eigen3/test/first_aligned.cpp view
@@ -0,0 +1,51 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename Scalar>+void test_first_aligned_helper(Scalar *array, int size)+{+ const int packet_size = sizeof(Scalar) * internal::packet_traits<Scalar>::size;+ VERIFY(((size_t(array) + sizeof(Scalar) * internal::first_aligned(array, size)) % packet_size) == 0);+}++template<typename Scalar>+void test_none_aligned_helper(Scalar *array, int size)+{+ EIGEN_UNUSED_VARIABLE(array);+ EIGEN_UNUSED_VARIABLE(size);+ VERIFY(internal::packet_traits<Scalar>::size == 1 || internal::first_aligned(array, size) == size);+}++struct some_non_vectorizable_type { float x; };++void test_first_aligned()+{+ EIGEN_ALIGN16 float array_float[100];+ test_first_aligned_helper(array_float, 50);+ test_first_aligned_helper(array_float+1, 50);+ test_first_aligned_helper(array_float+2, 50);+ test_first_aligned_helper(array_float+3, 50);+ test_first_aligned_helper(array_float+4, 50);+ test_first_aligned_helper(array_float+5, 50);+ + EIGEN_ALIGN16 double array_double[100];+ test_first_aligned_helper(array_double, 50);+ test_first_aligned_helper(array_double+1, 50);+ test_first_aligned_helper(array_double+2, 50);+ + double *array_double_plus_4_bytes = (double*)(size_t(array_double)+4);+ test_none_aligned_helper(array_double_plus_4_bytes, 50);+ test_none_aligned_helper(array_double_plus_4_bytes+1, 50);+ + some_non_vectorizable_type array_nonvec[100];+ test_first_aligned_helper(array_nonvec, 100);+ test_none_aligned_helper(array_nonvec, 100);+}
+ eigen3/test/geo_alignedbox.cpp view
@@ -0,0 +1,178 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/Geometry>+#include <Eigen/LU>+#include <Eigen/QR>++#include<iostream>+using namespace std;++template<typename T> EIGEN_DONT_INLINE+void kill_extra_precision(T& x) { eigen_assert(&x != 0); }+++template<typename BoxType> void alignedbox(const BoxType& _box)+{+ /* this test covers the following files:+ AlignedBox.h+ */+ typedef typename BoxType::Index Index; + typedef typename BoxType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, BoxType::AmbientDimAtCompileTime, 1> VectorType;++ const Index dim = _box.dim();++ VectorType p0 = VectorType::Random(dim);+ VectorType p1 = VectorType::Random(dim);+ while( p1 == p0 ){+ p1 = VectorType::Random(dim); }+ RealScalar s1 = internal::random<RealScalar>(0,1);++ BoxType b0(dim);+ BoxType b1(VectorType::Random(dim),VectorType::Random(dim));+ BoxType b2;+ + kill_extra_precision(b1);+ kill_extra_precision(p0);+ kill_extra_precision(p1);++ b0.extend(p0);+ b0.extend(p1);+ VERIFY(b0.contains(p0*s1+(Scalar(1)-s1)*p1));++ (b2 = b0).extend(b1);+ VERIFY(b2.contains(b0));+ VERIFY(b2.contains(b1));+ VERIFY_IS_APPROX(b2.clamp(b0), b0);+++ // alignment -- make sure there is no memory alignment assertion+ BoxType *bp0 = new BoxType(dim);+ BoxType *bp1 = new BoxType(dim);+ bp0->extend(*bp1);+ delete bp0;+ delete bp1;++ // sampling+ for( int i=0; i<10; ++i )+ {+ VectorType r = b0.sample();+ VERIFY(b0.contains(r));+ }++}++++template<typename BoxType>+void alignedboxCastTests(const BoxType& _box)+{+ // casting + typedef typename BoxType::Index Index;+ typedef typename BoxType::Scalar Scalar;+ typedef Matrix<Scalar, BoxType::AmbientDimAtCompileTime, 1> VectorType;++ const Index dim = _box.dim();++ VectorType p0 = VectorType::Random(dim);+ VectorType p1 = VectorType::Random(dim);++ BoxType b0(dim);++ b0.extend(p0);+ b0.extend(p1);++ const int Dim = BoxType::AmbientDimAtCompileTime;+ typedef typename GetDifferentType<Scalar>::type OtherScalar;+ AlignedBox<OtherScalar,Dim> hp1f = b0.template cast<OtherScalar>();+ VERIFY_IS_APPROX(hp1f.template cast<Scalar>(),b0);+ AlignedBox<Scalar,Dim> hp1d = b0.template cast<Scalar>();+ VERIFY_IS_APPROX(hp1d.template cast<Scalar>(),b0);+}+++void specificTest1()+{+ Vector2f m; m << -1.0f, -2.0f;+ Vector2f M; M << 1.0f, 5.0f;++ typedef AlignedBox2f BoxType;+ BoxType box( m, M );++ Vector2f sides = M-m;+ VERIFY_IS_APPROX(sides, box.sizes() );+ VERIFY_IS_APPROX(sides[1], box.sizes()[1] );+ VERIFY_IS_APPROX(sides[1], box.sizes().maxCoeff() );+ VERIFY_IS_APPROX(sides[0], box.sizes().minCoeff() );++ VERIFY_IS_APPROX( 14.0f, box.volume() );+ VERIFY_IS_APPROX( 53.0f, box.diagonal().squaredNorm() );+ VERIFY_IS_APPROX( std::sqrt( 53.0f ), box.diagonal().norm() );++ VERIFY_IS_APPROX( m, box.corner( BoxType::BottomLeft ) );+ VERIFY_IS_APPROX( M, box.corner( BoxType::TopRight ) );+ Vector2f bottomRight; bottomRight << M[0], m[1];+ Vector2f topLeft; topLeft << m[0], M[1];+ VERIFY_IS_APPROX( bottomRight, box.corner( BoxType::BottomRight ) );+ VERIFY_IS_APPROX( topLeft, box.corner( BoxType::TopLeft ) );+}+++void specificTest2()+{+ Vector3i m; m << -1, -2, 0;+ Vector3i M; M << 1, 5, 3;++ typedef AlignedBox3i BoxType;+ BoxType box( m, M );++ Vector3i sides = M-m;+ VERIFY_IS_APPROX(sides, box.sizes() );+ VERIFY_IS_APPROX(sides[1], box.sizes()[1] );+ VERIFY_IS_APPROX(sides[1], box.sizes().maxCoeff() );+ VERIFY_IS_APPROX(sides[0], box.sizes().minCoeff() );++ VERIFY_IS_APPROX( 42, box.volume() );+ VERIFY_IS_APPROX( 62, box.diagonal().squaredNorm() );++ VERIFY_IS_APPROX( m, box.corner( BoxType::BottomLeftFloor ) );+ VERIFY_IS_APPROX( M, box.corner( BoxType::TopRightCeil ) );+ Vector3i bottomRightFloor; bottomRightFloor << M[0], m[1], m[2];+ Vector3i topLeftFloor; topLeftFloor << m[0], M[1], m[2];+ VERIFY_IS_APPROX( bottomRightFloor, box.corner( BoxType::BottomRightFloor ) );+ VERIFY_IS_APPROX( topLeftFloor, box.corner( BoxType::TopLeftFloor ) );+}+++void test_geo_alignedbox()+{+ for(int i = 0; i < g_repeat; i++)+ {+ CALL_SUBTEST_1( alignedbox(AlignedBox2f()) );+ CALL_SUBTEST_2( alignedboxCastTests(AlignedBox2f()) );++ CALL_SUBTEST_3( alignedbox(AlignedBox3f()) );+ CALL_SUBTEST_4( alignedboxCastTests(AlignedBox3f()) );++ CALL_SUBTEST_5( alignedbox(AlignedBox4d()) );+ CALL_SUBTEST_6( alignedboxCastTests(AlignedBox4d()) );++ CALL_SUBTEST_7( alignedbox(AlignedBox1d()) );+ CALL_SUBTEST_8( alignedboxCastTests(AlignedBox1d()) );++ CALL_SUBTEST_9( alignedbox(AlignedBox1i()) );+ CALL_SUBTEST_10( alignedbox(AlignedBox2i()) );+ CALL_SUBTEST_11( alignedbox(AlignedBox3i()) );+ }+ CALL_SUBTEST_12( specificTest1() );+ CALL_SUBTEST_13( specificTest2() );+}
+ eigen3/test/geo_eulerangles.cpp view
@@ -0,0 +1,112 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2012 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/Geometry>+#include <Eigen/LU>+#include <Eigen/SVD>+++template<typename Scalar>+void verify_euler(const Matrix<Scalar,3,1>& ea, int i, int j, int k)+{+ typedef Matrix<Scalar,3,3> Matrix3;+ typedef Matrix<Scalar,3,1> Vector3;+ typedef AngleAxis<Scalar> AngleAxisx;+ using std::abs;+ Matrix3 m(AngleAxisx(ea[0], Vector3::Unit(i)) * AngleAxisx(ea[1], Vector3::Unit(j)) * AngleAxisx(ea[2], Vector3::Unit(k)));+ Vector3 eabis = m.eulerAngles(i, j, k);+ Matrix3 mbis(AngleAxisx(eabis[0], Vector3::Unit(i)) * AngleAxisx(eabis[1], Vector3::Unit(j)) * AngleAxisx(eabis[2], Vector3::Unit(k))); + VERIFY_IS_APPROX(m, mbis); + /* If I==K, and ea[1]==0, then there no unique solution. */ + /* The remark apply in the case where I!=K, and |ea[1]| is close to pi/2. */ + if( (i!=k || ea[1]!=0) && (i==k || !internal::isApprox(abs(ea[1]),Scalar(M_PI/2),test_precision<Scalar>())) ) + VERIFY((ea-eabis).norm() <= test_precision<Scalar>());+ + // approx_or_less_than does not work for 0+ VERIFY(0 < eabis[0] || test_isMuchSmallerThan(eabis[0], Scalar(1)));+ VERIFY_IS_APPROX_OR_LESS_THAN(eabis[0], Scalar(M_PI));+ VERIFY_IS_APPROX_OR_LESS_THAN(-Scalar(M_PI), eabis[1]);+ VERIFY_IS_APPROX_OR_LESS_THAN(eabis[1], Scalar(M_PI));+ VERIFY_IS_APPROX_OR_LESS_THAN(-Scalar(M_PI), eabis[2]);+ VERIFY_IS_APPROX_OR_LESS_THAN(eabis[2], Scalar(M_PI));+}++template<typename Scalar> void check_all_var(const Matrix<Scalar,3,1>& ea)+{+ verify_euler(ea, 0,1,2);+ verify_euler(ea, 0,1,0);+ verify_euler(ea, 0,2,1);+ verify_euler(ea, 0,2,0);++ verify_euler(ea, 1,2,0);+ verify_euler(ea, 1,2,1);+ verify_euler(ea, 1,0,2);+ verify_euler(ea, 1,0,1);++ verify_euler(ea, 2,0,1);+ verify_euler(ea, 2,0,2);+ verify_euler(ea, 2,1,0);+ verify_euler(ea, 2,1,2);+}++template<typename Scalar> void eulerangles()+{+ typedef Matrix<Scalar,3,3> Matrix3;+ typedef Matrix<Scalar,3,1> Vector3;+ typedef Array<Scalar,3,1> Array3;+ typedef Quaternion<Scalar> Quaternionx;+ typedef AngleAxis<Scalar> AngleAxisx;++ Scalar a = internal::random<Scalar>(-Scalar(M_PI), Scalar(M_PI));+ Quaternionx q1;+ q1 = AngleAxisx(a, Vector3::Random().normalized());+ Matrix3 m;+ m = q1;+ + Vector3 ea = m.eulerAngles(0,1,2);+ check_all_var(ea);+ ea = m.eulerAngles(0,1,0);+ check_all_var(ea);+ + // Check with purely random Quaternion:+ q1.coeffs() = Quaternionx::Coefficients::Random().normalized();+ m = q1;+ ea = m.eulerAngles(0,1,2);+ check_all_var(ea);+ ea = m.eulerAngles(0,1,0);+ check_all_var(ea);+ + // Check with random angles in range [0:pi]x[-pi:pi]x[-pi:pi].+ ea = (Array3::Random() + Array3(1,0,0))*Scalar(M_PI)*Array3(0.5,1,1);+ check_all_var(ea);+ + ea[2] = ea[0] = internal::random<Scalar>(0,Scalar(M_PI));+ check_all_var(ea);+ + ea[0] = ea[1] = internal::random<Scalar>(0,Scalar(M_PI));+ check_all_var(ea);+ + ea[1] = 0;+ check_all_var(ea);+ + ea.head(2).setZero();+ check_all_var(ea);+ + ea.setZero();+ check_all_var(ea);+}++void test_geo_eulerangles()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( eulerangles<float>() );+ CALL_SUBTEST_2( eulerangles<double>() );+ }+}
+ eigen3/test/geo_homogeneous.cpp view
@@ -0,0 +1,103 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/Geometry>++template<typename Scalar,int Size> void homogeneous(void)+{+ /* this test covers the following files:+ Homogeneous.h+ */++ typedef Matrix<Scalar,Size,Size> MatrixType;+ typedef Matrix<Scalar,Size,1, ColMajor> VectorType;++ typedef Matrix<Scalar,Size+1,Size> HMatrixType;+ typedef Matrix<Scalar,Size+1,1> HVectorType;++ typedef Matrix<Scalar,Size,Size+1> T1MatrixType;+ typedef Matrix<Scalar,Size+1,Size+1> T2MatrixType;+ typedef Matrix<Scalar,Size+1,Size> T3MatrixType;++ VectorType v0 = VectorType::Random(),+ ones = VectorType::Ones();++ HVectorType hv0 = HVectorType::Random();++ MatrixType m0 = MatrixType::Random();++ HMatrixType hm0 = HMatrixType::Random();++ hv0 << v0, 1;+ VERIFY_IS_APPROX(v0.homogeneous(), hv0);+ VERIFY_IS_APPROX(v0, hv0.hnormalized());++ hm0 << m0, ones.transpose();+ VERIFY_IS_APPROX(m0.colwise().homogeneous(), hm0);+ VERIFY_IS_APPROX(m0, hm0.colwise().hnormalized());+ hm0.row(Size-1).setRandom();+ for(int j=0; j<Size; ++j)+ m0.col(j) = hm0.col(j).head(Size) / hm0(Size,j);+ VERIFY_IS_APPROX(m0, hm0.colwise().hnormalized());++ T1MatrixType t1 = T1MatrixType::Random();+ VERIFY_IS_APPROX(t1 * (v0.homogeneous().eval()), t1 * v0.homogeneous());+ VERIFY_IS_APPROX(t1 * (m0.colwise().homogeneous().eval()), t1 * m0.colwise().homogeneous());++ T2MatrixType t2 = T2MatrixType::Random();+ VERIFY_IS_APPROX(t2 * (v0.homogeneous().eval()), t2 * v0.homogeneous());+ VERIFY_IS_APPROX(t2 * (m0.colwise().homogeneous().eval()), t2 * m0.colwise().homogeneous());++ VERIFY_IS_APPROX((v0.transpose().rowwise().homogeneous().eval()) * t2,+ v0.transpose().rowwise().homogeneous() * t2);+ m0.transpose().rowwise().homogeneous().eval();+ VERIFY_IS_APPROX((m0.transpose().rowwise().homogeneous().eval()) * t2,+ m0.transpose().rowwise().homogeneous() * t2);++ T3MatrixType t3 = T3MatrixType::Random();+ VERIFY_IS_APPROX((v0.transpose().rowwise().homogeneous().eval()) * t3,+ v0.transpose().rowwise().homogeneous() * t3);+ VERIFY_IS_APPROX((m0.transpose().rowwise().homogeneous().eval()) * t3,+ m0.transpose().rowwise().homogeneous() * t3);++ // test product with a Transform object+ Transform<Scalar, Size, Affine> aff;+ Transform<Scalar, Size, AffineCompact> caff;+ Transform<Scalar, Size, Projective> proj;+ Matrix<Scalar, Size, Dynamic> pts;+ Matrix<Scalar, Size+1, Dynamic> pts1, pts2;++ aff.affine().setRandom();+ proj = caff = aff;+ pts.setRandom(Size,internal::random<int>(1,20));+ + pts1 = pts.colwise().homogeneous();+ VERIFY_IS_APPROX(aff * pts.colwise().homogeneous(), (aff * pts1).colwise().hnormalized());+ VERIFY_IS_APPROX(caff * pts.colwise().homogeneous(), (caff * pts1).colwise().hnormalized());+ VERIFY_IS_APPROX(proj * pts.colwise().homogeneous(), (proj * pts1));+ + VERIFY_IS_APPROX((aff * pts1).colwise().hnormalized(), aff * pts);+ VERIFY_IS_APPROX((caff * pts1).colwise().hnormalized(), caff * pts);+ + pts2 = pts1;+ pts2.row(Size).setRandom();+ VERIFY_IS_APPROX((aff * pts2).colwise().hnormalized(), aff * pts2.colwise().hnormalized());+ VERIFY_IS_APPROX((caff * pts2).colwise().hnormalized(), caff * pts2.colwise().hnormalized());+ VERIFY_IS_APPROX((proj * pts2).colwise().hnormalized(), (proj * pts2.colwise().hnormalized().colwise().homogeneous()).colwise().hnormalized());+}++void test_geo_homogeneous()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1(( homogeneous<float,1>() ));+ CALL_SUBTEST_2(( homogeneous<double,3>() ));+ CALL_SUBTEST_3(( homogeneous<double,8>() ));+ }+}
+ eigen3/test/geo_hyperplane.cpp view
@@ -0,0 +1,185 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/Geometry>+#include <Eigen/LU>+#include <Eigen/QR>++template<typename HyperplaneType> void hyperplane(const HyperplaneType& _plane)+{+ /* this test covers the following files:+ Hyperplane.h+ */+ typedef typename HyperplaneType::Index Index;+ const Index dim = _plane.dim();+ enum { Options = HyperplaneType::Options };+ typedef typename HyperplaneType::Scalar Scalar;+ typedef Matrix<Scalar, HyperplaneType::AmbientDimAtCompileTime, 1> VectorType;+ typedef Matrix<Scalar, HyperplaneType::AmbientDimAtCompileTime,+ HyperplaneType::AmbientDimAtCompileTime> MatrixType;++ VectorType p0 = VectorType::Random(dim);+ VectorType p1 = VectorType::Random(dim);++ VectorType n0 = VectorType::Random(dim).normalized();+ VectorType n1 = VectorType::Random(dim).normalized();++ HyperplaneType pl0(n0, p0);+ HyperplaneType pl1(n1, p1);+ HyperplaneType pl2 = pl1;++ Scalar s0 = internal::random<Scalar>();+ Scalar s1 = internal::random<Scalar>();++ VERIFY_IS_APPROX( n1.dot(n1), Scalar(1) );++ VERIFY_IS_MUCH_SMALLER_THAN( pl0.absDistance(p0), Scalar(1) );+ VERIFY_IS_APPROX( pl1.signedDistance(p1 + n1 * s0), s0 );+ VERIFY_IS_MUCH_SMALLER_THAN( pl1.signedDistance(pl1.projection(p0)), Scalar(1) );+ VERIFY_IS_MUCH_SMALLER_THAN( pl1.absDistance(p1 + pl1.normal().unitOrthogonal() * s1), Scalar(1) );++ // transform+ if (!NumTraits<Scalar>::IsComplex)+ {+ MatrixType rot = MatrixType::Random(dim,dim).householderQr().householderQ();+ DiagonalMatrix<Scalar,HyperplaneType::AmbientDimAtCompileTime> scaling(VectorType::Random());+ Translation<Scalar,HyperplaneType::AmbientDimAtCompileTime> translation(VectorType::Random());++ pl2 = pl1;+ VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot).absDistance(rot * p1), Scalar(1) );+ pl2 = pl1;+ VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot,Isometry).absDistance(rot * p1), Scalar(1) );+ pl2 = pl1;+ VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot*scaling).absDistance((rot*scaling) * p1), Scalar(1) );+ pl2 = pl1;+ VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot*scaling*translation)+ .absDistance((rot*scaling*translation) * p1), Scalar(1) );+ pl2 = pl1;+ VERIFY_IS_MUCH_SMALLER_THAN( pl2.transform(rot*translation,Isometry)+ .absDistance((rot*translation) * p1), Scalar(1) );+ }++ // casting+ const int Dim = HyperplaneType::AmbientDimAtCompileTime;+ typedef typename GetDifferentType<Scalar>::type OtherScalar;+ Hyperplane<OtherScalar,Dim,Options> hp1f = pl1.template cast<OtherScalar>();+ VERIFY_IS_APPROX(hp1f.template cast<Scalar>(),pl1);+ Hyperplane<Scalar,Dim,Options> hp1d = pl1.template cast<Scalar>();+ VERIFY_IS_APPROX(hp1d.template cast<Scalar>(),pl1);+}++template<typename Scalar> void lines()+{+ using std::abs;+ typedef Hyperplane<Scalar, 2> HLine;+ typedef ParametrizedLine<Scalar, 2> PLine;+ typedef Matrix<Scalar,2,1> Vector;+ typedef Matrix<Scalar,3,1> CoeffsType;++ for(int i = 0; i < 10; i++)+ {+ Vector center = Vector::Random();+ Vector u = Vector::Random();+ Vector v = Vector::Random();+ Scalar a = internal::random<Scalar>();+ while (abs(a-1) < 1e-4) a = internal::random<Scalar>();+ while (u.norm() < 1e-4) u = Vector::Random();+ while (v.norm() < 1e-4) v = Vector::Random();++ HLine line_u = HLine::Through(center + u, center + a*u);+ HLine line_v = HLine::Through(center + v, center + a*v);++ // the line equations should be normalized so that a^2+b^2=1+ VERIFY_IS_APPROX(line_u.normal().norm(), Scalar(1));+ VERIFY_IS_APPROX(line_v.normal().norm(), Scalar(1));++ Vector result = line_u.intersection(line_v);++ // the lines should intersect at the point we called "center"+ VERIFY_IS_APPROX(result, center);++ // check conversions between two types of lines+ PLine pl(line_u); // gcc 3.3 will commit suicide if we don't name this variable+ CoeffsType converted_coeffs = HLine(pl).coeffs();+ converted_coeffs *= (line_u.coeffs()[0])/(converted_coeffs[0]);+ VERIFY(line_u.coeffs().isApprox(converted_coeffs));+ }+}++template<typename Scalar> void planes()+{+ using std::abs;+ typedef Hyperplane<Scalar, 3> Plane;+ typedef Matrix<Scalar,3,1> Vector;++ for(int i = 0; i < 10; i++)+ {+ Vector v0 = Vector::Random();+ Vector v1(v0), v2(v0);+ if(internal::random<double>(0,1)>0.25)+ v1 += Vector::Random();+ if(internal::random<double>(0,1)>0.25)+ v2 += v1 * std::pow(internal::random<Scalar>(0,1),internal::random<int>(1,16));+ if(internal::random<double>(0,1)>0.25)+ v2 += Vector::Random() * std::pow(internal::random<Scalar>(0,1),internal::random<int>(1,16));++ Plane p0 = Plane::Through(v0, v1, v2);++ VERIFY_IS_APPROX(p0.normal().norm(), Scalar(1));+ VERIFY_IS_MUCH_SMALLER_THAN(p0.absDistance(v0), Scalar(1));+ VERIFY_IS_MUCH_SMALLER_THAN(p0.absDistance(v1), Scalar(1));+ VERIFY_IS_MUCH_SMALLER_THAN(p0.absDistance(v2), Scalar(1));+ }+}++template<typename Scalar> void hyperplane_alignment()+{+ typedef Hyperplane<Scalar,3,AutoAlign> Plane3a;+ typedef Hyperplane<Scalar,3,DontAlign> Plane3u;++ EIGEN_ALIGN16 Scalar array1[4];+ EIGEN_ALIGN16 Scalar array2[4];+ EIGEN_ALIGN16 Scalar array3[4+1];+ Scalar* array3u = array3+1;++ Plane3a *p1 = ::new(reinterpret_cast<void*>(array1)) Plane3a;+ Plane3u *p2 = ::new(reinterpret_cast<void*>(array2)) Plane3u;+ Plane3u *p3 = ::new(reinterpret_cast<void*>(array3u)) Plane3u;+ + p1->coeffs().setRandom();+ *p2 = *p1;+ *p3 = *p1;++ VERIFY_IS_APPROX(p1->coeffs(), p2->coeffs());+ VERIFY_IS_APPROX(p1->coeffs(), p3->coeffs());+ + #if defined(EIGEN_VECTORIZE) && EIGEN_ALIGN_STATICALLY+ if(internal::packet_traits<Scalar>::Vectorizable)+ VERIFY_RAISES_ASSERT((::new(reinterpret_cast<void*>(array3u)) Plane3a));+ #endif+}+++void test_geo_hyperplane()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( hyperplane(Hyperplane<float,2>()) );+ CALL_SUBTEST_2( hyperplane(Hyperplane<float,3>()) );+ CALL_SUBTEST_2( hyperplane(Hyperplane<float,3,DontAlign>()) );+ CALL_SUBTEST_2( hyperplane_alignment<float>() );+ CALL_SUBTEST_3( hyperplane(Hyperplane<double,4>()) );+ CALL_SUBTEST_4( hyperplane(Hyperplane<std::complex<double>,5>()) );+ CALL_SUBTEST_1( lines<float>() );+ CALL_SUBTEST_3( lines<double>() );+ CALL_SUBTEST_2( planes<float>() );+ CALL_SUBTEST_5( planes<double>() );+ }+}
+ eigen3/test/geo_orthomethods.cpp view
@@ -0,0 +1,121 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/Geometry>+#include <Eigen/LU>+#include <Eigen/SVD>++/* this test covers the following files:+ Geometry/OrthoMethods.h+*/++template<typename Scalar> void orthomethods_3()+{+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar,3,3> Matrix3;+ typedef Matrix<Scalar,3,1> Vector3;++ typedef Matrix<Scalar,4,1> Vector4;++ Vector3 v0 = Vector3::Random(),+ v1 = Vector3::Random(),+ v2 = Vector3::Random();++ // cross product+ VERIFY_IS_MUCH_SMALLER_THAN(v1.cross(v2).dot(v1), Scalar(1));+ VERIFY_IS_MUCH_SMALLER_THAN(v1.dot(v1.cross(v2)), Scalar(1));+ VERIFY_IS_MUCH_SMALLER_THAN(v1.cross(v2).dot(v2), Scalar(1));+ VERIFY_IS_MUCH_SMALLER_THAN(v2.dot(v1.cross(v2)), Scalar(1));+ Matrix3 mat3;+ mat3 << v0.normalized(),+ (v0.cross(v1)).normalized(),+ (v0.cross(v1).cross(v0)).normalized();+ VERIFY(mat3.isUnitary());+++ // colwise/rowwise cross product+ mat3.setRandom();+ Vector3 vec3 = Vector3::Random();+ Matrix3 mcross;+ int i = internal::random<int>(0,2);+ mcross = mat3.colwise().cross(vec3);+ VERIFY_IS_APPROX(mcross.col(i), mat3.col(i).cross(vec3));+ mcross = mat3.rowwise().cross(vec3);+ VERIFY_IS_APPROX(mcross.row(i), mat3.row(i).cross(vec3));++ // cross3+ Vector4 v40 = Vector4::Random(),+ v41 = Vector4::Random(),+ v42 = Vector4::Random();+ v40.w() = v41.w() = v42.w() = 0;+ v42.template head<3>() = v40.template head<3>().cross(v41.template head<3>());+ VERIFY_IS_APPROX(v40.cross3(v41), v42);+ + // check mixed product+ typedef Matrix<RealScalar, 3, 1> RealVector3;+ RealVector3 rv1 = RealVector3::Random();+ VERIFY_IS_APPROX(v1.cross(rv1.template cast<Scalar>()), v1.cross(rv1));+ VERIFY_IS_APPROX(rv1.template cast<Scalar>().cross(v1), rv1.cross(v1));+}++template<typename Scalar, int Size> void orthomethods(int size=Size)+{+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar,Size,1> VectorType;+ typedef Matrix<Scalar,3,Size> Matrix3N;+ typedef Matrix<Scalar,Size,3> MatrixN3;+ typedef Matrix<Scalar,3,1> Vector3;++ VectorType v0 = VectorType::Random(size);++ // unitOrthogonal+ VERIFY_IS_MUCH_SMALLER_THAN(v0.unitOrthogonal().dot(v0), Scalar(1));+ VERIFY_IS_APPROX(v0.unitOrthogonal().norm(), RealScalar(1));++ if (size>=3)+ {+ v0.template head<2>().setZero();+ v0.tail(size-2).setRandom();++ VERIFY_IS_MUCH_SMALLER_THAN(v0.unitOrthogonal().dot(v0), Scalar(1));+ VERIFY_IS_APPROX(v0.unitOrthogonal().norm(), RealScalar(1));+ }++ // colwise/rowwise cross product+ Vector3 vec3 = Vector3::Random();+ int i = internal::random<int>(0,size-1);++ Matrix3N mat3N(3,size), mcross3N(3,size);+ mat3N.setRandom();+ mcross3N = mat3N.colwise().cross(vec3);+ VERIFY_IS_APPROX(mcross3N.col(i), mat3N.col(i).cross(vec3));++ MatrixN3 matN3(size,3), mcrossN3(size,3);+ matN3.setRandom();+ mcrossN3 = matN3.rowwise().cross(vec3);+ VERIFY_IS_APPROX(mcrossN3.row(i), matN3.row(i).cross(vec3));+}++void test_geo_orthomethods()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( orthomethods_3<float>() );+ CALL_SUBTEST_2( orthomethods_3<double>() );+ CALL_SUBTEST_4( orthomethods_3<std::complex<double> >() );+ CALL_SUBTEST_1( (orthomethods<float,2>()) );+ CALL_SUBTEST_2( (orthomethods<double,2>()) );+ CALL_SUBTEST_1( (orthomethods<float,3>()) );+ CALL_SUBTEST_2( (orthomethods<double,3>()) );+ CALL_SUBTEST_3( (orthomethods<float,7>()) );+ CALL_SUBTEST_4( (orthomethods<std::complex<double>,8>()) );+ CALL_SUBTEST_5( (orthomethods<float,Dynamic>(36)) );+ CALL_SUBTEST_6( (orthomethods<double,Dynamic>(35)) );+ }+}
+ eigen3/test/geo_parametrizedline.cpp view
@@ -0,0 +1,104 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/Geometry>+#include <Eigen/LU>+#include <Eigen/QR>++template<typename LineType> void parametrizedline(const LineType& _line)+{+ /* this test covers the following files:+ ParametrizedLine.h+ */+ using std::abs;+ typedef typename LineType::Index Index;+ const Index dim = _line.dim();+ typedef typename LineType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, LineType::AmbientDimAtCompileTime, 1> VectorType;+ typedef Hyperplane<Scalar,LineType::AmbientDimAtCompileTime> HyperplaneType;++ VectorType p0 = VectorType::Random(dim);+ VectorType p1 = VectorType::Random(dim);++ VectorType d0 = VectorType::Random(dim).normalized();++ LineType l0(p0, d0);++ Scalar s0 = internal::random<Scalar>();+ Scalar s1 = abs(internal::random<Scalar>());++ VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(p0), RealScalar(1) );+ VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(p0+s0*d0), RealScalar(1) );+ VERIFY_IS_APPROX( (l0.projection(p1)-p1).norm(), l0.distance(p1) );+ VERIFY_IS_MUCH_SMALLER_THAN( l0.distance(l0.projection(p1)), RealScalar(1) );+ VERIFY_IS_APPROX( Scalar(l0.distance((p0+s0*d0) + d0.unitOrthogonal() * s1)), s1 );++ // casting+ const int Dim = LineType::AmbientDimAtCompileTime;+ typedef typename GetDifferentType<Scalar>::type OtherScalar;+ ParametrizedLine<OtherScalar,Dim> hp1f = l0.template cast<OtherScalar>();+ VERIFY_IS_APPROX(hp1f.template cast<Scalar>(),l0);+ ParametrizedLine<Scalar,Dim> hp1d = l0.template cast<Scalar>();+ VERIFY_IS_APPROX(hp1d.template cast<Scalar>(),l0);++ // intersections+ VectorType p2 = VectorType::Random(dim);+ VectorType n2 = VectorType::Random(dim).normalized();+ HyperplaneType hp(p2,n2);+ Scalar t = l0.intersectionParameter(hp);+ VectorType pi = l0.pointAt(t);+ VERIFY_IS_MUCH_SMALLER_THAN(hp.signedDistance(pi), RealScalar(1));+ VERIFY_IS_MUCH_SMALLER_THAN(l0.distance(pi), RealScalar(1));+ VERIFY_IS_APPROX(l0.intersectionPoint(hp), pi);+}++template<typename Scalar> void parametrizedline_alignment()+{+ typedef ParametrizedLine<Scalar,4,AutoAlign> Line4a;+ typedef ParametrizedLine<Scalar,4,DontAlign> Line4u;++ EIGEN_ALIGN16 Scalar array1[8];+ EIGEN_ALIGN16 Scalar array2[8];+ EIGEN_ALIGN16 Scalar array3[8+1];+ Scalar* array3u = array3+1;++ Line4a *p1 = ::new(reinterpret_cast<void*>(array1)) Line4a;+ Line4u *p2 = ::new(reinterpret_cast<void*>(array2)) Line4u;+ Line4u *p3 = ::new(reinterpret_cast<void*>(array3u)) Line4u;+ + p1->origin().setRandom();+ p1->direction().setRandom();+ *p2 = *p1;+ *p3 = *p1;++ VERIFY_IS_APPROX(p1->origin(), p2->origin());+ VERIFY_IS_APPROX(p1->origin(), p3->origin());+ VERIFY_IS_APPROX(p1->direction(), p2->direction());+ VERIFY_IS_APPROX(p1->direction(), p3->direction());+ + #if defined(EIGEN_VECTORIZE) && EIGEN_ALIGN_STATICALLY+ if(internal::packet_traits<Scalar>::Vectorizable)+ VERIFY_RAISES_ASSERT((::new(reinterpret_cast<void*>(array3u)) Line4a));+ #endif+}++void test_geo_parametrizedline()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( parametrizedline(ParametrizedLine<float,2>()) );+ CALL_SUBTEST_2( parametrizedline(ParametrizedLine<float,3>()) );+ CALL_SUBTEST_2( parametrizedline_alignment<float>() );+ CALL_SUBTEST_3( parametrizedline(ParametrizedLine<double,4>()) );+ CALL_SUBTEST_3( parametrizedline_alignment<double>() );+ CALL_SUBTEST_4( parametrizedline(ParametrizedLine<std::complex<double>,5>()) );+ }+}
+ eigen3/test/geo_quaternion.cpp view
@@ -0,0 +1,284 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2009 Mathieu Gautier <mathieu.gautier@cea.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/Geometry>+#include <Eigen/LU>+#include <Eigen/SVD>++template<typename T> T bounded_acos(T v)+{+ using std::acos;+ using std::min;+ using std::max;+ return acos((max)(T(-1),(min)(v,T(1))));+}++template<typename QuatType> void check_slerp(const QuatType& q0, const QuatType& q1)+{+ using std::abs;+ typedef typename QuatType::Scalar Scalar;+ typedef AngleAxis<Scalar> AA;++ Scalar largeEps = test_precision<Scalar>();++ Scalar theta_tot = AA(q1*q0.inverse()).angle();+ if(theta_tot>M_PI)+ theta_tot = Scalar(2.*M_PI)-theta_tot;+ for(Scalar t=0; t<=Scalar(1.001); t+=Scalar(0.1))+ {+ QuatType q = q0.slerp(t,q1);+ Scalar theta = AA(q*q0.inverse()).angle();+ VERIFY(abs(q.norm() - 1) < largeEps);+ if(theta_tot==0) VERIFY(theta_tot==0);+ else VERIFY(abs(theta - t * theta_tot) < largeEps);+ }+}++template<typename Scalar, int Options> void quaternion(void)+{+ /* this test covers the following files:+ Quaternion.h+ */+ using std::abs;+ typedef Matrix<Scalar,3,1> Vector3;+ typedef Matrix<Scalar,4,1> Vector4;+ typedef Quaternion<Scalar,Options> Quaternionx;+ typedef AngleAxis<Scalar> AngleAxisx;++ Scalar largeEps = test_precision<Scalar>();+ if (internal::is_same<Scalar,float>::value)+ largeEps = 1e-3f;++ Scalar eps = internal::random<Scalar>() * Scalar(1e-2);++ Vector3 v0 = Vector3::Random(),+ v1 = Vector3::Random(),+ v2 = Vector3::Random(),+ v3 = Vector3::Random();++ Scalar a = internal::random<Scalar>(-Scalar(M_PI), Scalar(M_PI)),+ b = internal::random<Scalar>(-Scalar(M_PI), Scalar(M_PI));++ // Quaternion: Identity(), setIdentity();+ Quaternionx q1, q2;+ q2.setIdentity();+ VERIFY_IS_APPROX(Quaternionx(Quaternionx::Identity()).coeffs(), q2.coeffs());+ q1.coeffs().setRandom();+ VERIFY_IS_APPROX(q1.coeffs(), (q1*q2).coeffs());++ // concatenation+ q1 *= q2;++ q1 = AngleAxisx(a, v0.normalized());+ q2 = AngleAxisx(a, v1.normalized());++ // angular distance+ Scalar refangle = abs(AngleAxisx(q1.inverse()*q2).angle());+ if (refangle>Scalar(M_PI))+ refangle = Scalar(2)*Scalar(M_PI) - refangle;++ if((q1.coeffs()-q2.coeffs()).norm() > 10*largeEps)+ {+ VERIFY_IS_MUCH_SMALLER_THAN(abs(q1.angularDistance(q2) - refangle), Scalar(1));+ }++ // rotation matrix conversion+ VERIFY_IS_APPROX(q1 * v2, q1.toRotationMatrix() * v2);+ VERIFY_IS_APPROX(q1 * q2 * v2,+ q1.toRotationMatrix() * q2.toRotationMatrix() * v2);++ VERIFY( (q2*q1).isApprox(q1*q2, largeEps)+ || !(q2 * q1 * v2).isApprox(q1.toRotationMatrix() * q2.toRotationMatrix() * v2));++ q2 = q1.toRotationMatrix();+ VERIFY_IS_APPROX(q1*v1,q2*v1);+++ // angle-axis conversion+ AngleAxisx aa = AngleAxisx(q1);+ VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);++ // Do not execute the test if the rotation angle is almost zero, or+ // the rotation axis and v1 are almost parallel.+ if (abs(aa.angle()) > 5*test_precision<Scalar>()+ && (aa.axis() - v1.normalized()).norm() < 1.99+ && (aa.axis() + v1.normalized()).norm() < 1.99) + {+ VERIFY_IS_NOT_APPROX(q1 * v1, Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1);+ }++ // from two vector creation+ VERIFY_IS_APPROX( v2.normalized(),(q2.setFromTwoVectors(v1, v2)*v1).normalized());+ VERIFY_IS_APPROX( v1.normalized(),(q2.setFromTwoVectors(v1, v1)*v1).normalized());+ VERIFY_IS_APPROX(-v1.normalized(),(q2.setFromTwoVectors(v1,-v1)*v1).normalized());+ if (internal::is_same<Scalar,double>::value)+ {+ v3 = (v1.array()+eps).matrix();+ VERIFY_IS_APPROX( v3.normalized(),(q2.setFromTwoVectors(v1, v3)*v1).normalized());+ VERIFY_IS_APPROX(-v3.normalized(),(q2.setFromTwoVectors(v1,-v3)*v1).normalized());+ }++ // from two vector creation static function+ VERIFY_IS_APPROX( v2.normalized(),(Quaternionx::FromTwoVectors(v1, v2)*v1).normalized());+ VERIFY_IS_APPROX( v1.normalized(),(Quaternionx::FromTwoVectors(v1, v1)*v1).normalized());+ VERIFY_IS_APPROX(-v1.normalized(),(Quaternionx::FromTwoVectors(v1,-v1)*v1).normalized());+ if (internal::is_same<Scalar,double>::value)+ {+ v3 = (v1.array()+eps).matrix();+ VERIFY_IS_APPROX( v3.normalized(),(Quaternionx::FromTwoVectors(v1, v3)*v1).normalized());+ VERIFY_IS_APPROX(-v3.normalized(),(Quaternionx::FromTwoVectors(v1,-v3)*v1).normalized());+ }++ // inverse and conjugate+ VERIFY_IS_APPROX(q1 * (q1.inverse() * v1), v1);+ VERIFY_IS_APPROX(q1 * (q1.conjugate() * v1), v1);++ // test casting+ Quaternion<float> q1f = q1.template cast<float>();+ VERIFY_IS_APPROX(q1f.template cast<Scalar>(),q1);+ Quaternion<double> q1d = q1.template cast<double>();+ VERIFY_IS_APPROX(q1d.template cast<Scalar>(),q1);++ // test bug 369 - improper alignment.+ Quaternionx *q = new Quaternionx;+ delete q;++ q1 = AngleAxisx(a, v0.normalized());+ q2 = AngleAxisx(b, v1.normalized());+ check_slerp(q1,q2);++ q1 = AngleAxisx(b, v1.normalized());+ q2 = AngleAxisx(b+Scalar(M_PI), v1.normalized());+ check_slerp(q1,q2);++ q1 = AngleAxisx(b, v1.normalized());+ q2 = AngleAxisx(-b, -v1.normalized());+ check_slerp(q1,q2);++ q1.coeffs() = Vector4::Random().normalized();+ q2.coeffs() = -q1.coeffs();+ check_slerp(q1,q2);+}++template<typename Scalar> void mapQuaternion(void){+ typedef Map<Quaternion<Scalar>, Aligned> MQuaternionA;+ typedef Map<const Quaternion<Scalar>, Aligned> MCQuaternionA;+ typedef Map<Quaternion<Scalar> > MQuaternionUA;+ typedef Map<const Quaternion<Scalar> > MCQuaternionUA;+ typedef Quaternion<Scalar> Quaternionx;+ typedef Matrix<Scalar,3,1> Vector3;+ typedef AngleAxis<Scalar> AngleAxisx;+ + Vector3 v0 = Vector3::Random(),+ v1 = Vector3::Random();+ Scalar a = internal::random<Scalar>(-Scalar(M_PI), Scalar(M_PI));++ EIGEN_ALIGN16 Scalar array1[4];+ EIGEN_ALIGN16 Scalar array2[4];+ EIGEN_ALIGN16 Scalar array3[4+1];+ Scalar* array3unaligned = array3+1;+ + MQuaternionA mq1(array1);+ MCQuaternionA mcq1(array1);+ MQuaternionA mq2(array2);+ MQuaternionUA mq3(array3unaligned);+ MCQuaternionUA mcq3(array3unaligned);++// std::cerr << array1 << " " << array2 << " " << array3 << "\n";+ mq1 = AngleAxisx(a, v0.normalized());+ mq2 = mq1;+ mq3 = mq1;++ Quaternionx q1 = mq1;+ Quaternionx q2 = mq2;+ Quaternionx q3 = mq3;+ Quaternionx q4 = MCQuaternionUA(array3unaligned);++ VERIFY_IS_APPROX(q1.coeffs(), q2.coeffs());+ VERIFY_IS_APPROX(q1.coeffs(), q3.coeffs());+ VERIFY_IS_APPROX(q4.coeffs(), q3.coeffs());+ #ifdef EIGEN_VECTORIZE+ if(internal::packet_traits<Scalar>::Vectorizable)+ VERIFY_RAISES_ASSERT((MQuaternionA(array3unaligned)));+ #endif+ + VERIFY_IS_APPROX(mq1 * (mq1.inverse() * v1), v1);+ VERIFY_IS_APPROX(mq1 * (mq1.conjugate() * v1), v1);+ + VERIFY_IS_APPROX(mcq1 * (mcq1.inverse() * v1), v1);+ VERIFY_IS_APPROX(mcq1 * (mcq1.conjugate() * v1), v1);+ + VERIFY_IS_APPROX(mq3 * (mq3.inverse() * v1), v1);+ VERIFY_IS_APPROX(mq3 * (mq3.conjugate() * v1), v1);+ + VERIFY_IS_APPROX(mcq3 * (mcq3.inverse() * v1), v1);+ VERIFY_IS_APPROX(mcq3 * (mcq3.conjugate() * v1), v1);+ + VERIFY_IS_APPROX(mq1*mq2, q1*q2);+ VERIFY_IS_APPROX(mq3*mq2, q3*q2);+ VERIFY_IS_APPROX(mcq1*mq2, q1*q2);+ VERIFY_IS_APPROX(mcq3*mq2, q3*q2);+}++template<typename Scalar> void quaternionAlignment(void){+ typedef Quaternion<Scalar,AutoAlign> QuaternionA;+ typedef Quaternion<Scalar,DontAlign> QuaternionUA;++ EIGEN_ALIGN16 Scalar array1[4];+ EIGEN_ALIGN16 Scalar array2[4];+ EIGEN_ALIGN16 Scalar array3[4+1];+ Scalar* arrayunaligned = array3+1;++ QuaternionA *q1 = ::new(reinterpret_cast<void*>(array1)) QuaternionA;+ QuaternionUA *q2 = ::new(reinterpret_cast<void*>(array2)) QuaternionUA;+ QuaternionUA *q3 = ::new(reinterpret_cast<void*>(arrayunaligned)) QuaternionUA;++ q1->coeffs().setRandom();+ *q2 = *q1;+ *q3 = *q1;++ VERIFY_IS_APPROX(q1->coeffs(), q2->coeffs());+ VERIFY_IS_APPROX(q1->coeffs(), q3->coeffs());+ #if defined(EIGEN_VECTORIZE) && EIGEN_ALIGN_STATICALLY+ if(internal::packet_traits<Scalar>::Vectorizable)+ VERIFY_RAISES_ASSERT((::new(reinterpret_cast<void*>(arrayunaligned)) QuaternionA));+ #endif+}++template<typename PlainObjectType> void check_const_correctness(const PlainObjectType&)+{+ // there's a lot that we can't test here while still having this test compile!+ // the only possible approach would be to run a script trying to compile stuff and checking that it fails.+ // CMake can help with that.++ // verify that map-to-const don't have LvalueBit+ typedef typename internal::add_const<PlainObjectType>::type ConstPlainObjectType;+ VERIFY( !(internal::traits<Map<ConstPlainObjectType> >::Flags & LvalueBit) );+ VERIFY( !(internal::traits<Map<ConstPlainObjectType, Aligned> >::Flags & LvalueBit) );+ VERIFY( !(Map<ConstPlainObjectType>::Flags & LvalueBit) );+ VERIFY( !(Map<ConstPlainObjectType, Aligned>::Flags & LvalueBit) );+}++void test_geo_quaternion()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1(( quaternion<float,AutoAlign>() ));+ CALL_SUBTEST_1( check_const_correctness(Quaternionf()) );+ CALL_SUBTEST_2(( quaternion<double,AutoAlign>() ));+ CALL_SUBTEST_2( check_const_correctness(Quaterniond()) );+ CALL_SUBTEST_3(( quaternion<float,DontAlign>() ));+ CALL_SUBTEST_4(( quaternion<double,DontAlign>() ));+ CALL_SUBTEST_5(( quaternionAlignment<float>() ));+ CALL_SUBTEST_6(( quaternionAlignment<double>() ));+ CALL_SUBTEST_1( mapQuaternion<float>() );+ CALL_SUBTEST_2( mapQuaternion<double>() );+ }+}
+ eigen3/test/geo_transformations.cpp view
@@ -0,0 +1,521 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/Geometry>+#include <Eigen/LU>+#include <Eigen/SVD>++template<typename Scalar, int Mode, int Options> void non_projective_only()+{+ /* this test covers the following files:+ Cross.h Quaternion.h, Transform.cpp+ */+ typedef Matrix<Scalar,3,1> Vector3;+ typedef Quaternion<Scalar> Quaternionx;+ typedef AngleAxis<Scalar> AngleAxisx;+ typedef Transform<Scalar,3,Mode,Options> Transform3;+ typedef DiagonalMatrix<Scalar,3> AlignedScaling3;+ typedef Translation<Scalar,3> Translation3;++ Vector3 v0 = Vector3::Random(),+ v1 = Vector3::Random();++ Transform3 t0, t1, t2;++ Scalar a = internal::random<Scalar>(-Scalar(M_PI), Scalar(M_PI));++ Quaternionx q1, q2;++ q1 = AngleAxisx(a, v0.normalized());++ t0 = Transform3::Identity();+ VERIFY_IS_APPROX(t0.matrix(), Transform3::MatrixType::Identity());++ t0.linear() = q1.toRotationMatrix();++ v0 << 50, 2, 1;+ t0.scale(v0);++ VERIFY_IS_APPROX( (t0 * Vector3(1,0,0)).template head<3>().norm(), v0.x());++ t0.setIdentity();+ t1.setIdentity();+ v1 << 1, 2, 3;+ t0.linear() = q1.toRotationMatrix();+ t0.pretranslate(v0);+ t0.scale(v1);+ t1.linear() = q1.conjugate().toRotationMatrix();+ t1.prescale(v1.cwiseInverse());+ t1.translate(-v0);++ VERIFY((t0 * t1).matrix().isIdentity(test_precision<Scalar>()));++ t1.fromPositionOrientationScale(v0, q1, v1);+ VERIFY_IS_APPROX(t1.matrix(), t0.matrix());+ VERIFY_IS_APPROX(t1*v1, t0*v1);++ // translation * vector+ t0.setIdentity();+ t0.translate(v0);+ VERIFY_IS_APPROX((t0 * v1).template head<3>(), Translation3(v0) * v1);++ // AlignedScaling * vector+ t0.setIdentity();+ t0.scale(v0);+ VERIFY_IS_APPROX((t0 * v1).template head<3>(), AlignedScaling3(v0) * v1);+}++template<typename Scalar, int Mode, int Options> void transformations()+{+ /* this test covers the following files:+ Cross.h Quaternion.h, Transform.cpp+ */+ using std::cos;+ using std::abs;+ typedef Matrix<Scalar,3,3> Matrix3;+ typedef Matrix<Scalar,4,4> Matrix4;+ typedef Matrix<Scalar,2,1> Vector2;+ typedef Matrix<Scalar,3,1> Vector3;+ typedef Matrix<Scalar,4,1> Vector4;+ typedef Quaternion<Scalar> Quaternionx;+ typedef AngleAxis<Scalar> AngleAxisx;+ typedef Transform<Scalar,2,Mode,Options> Transform2;+ typedef Transform<Scalar,3,Mode,Options> Transform3;+ typedef typename Transform3::MatrixType MatrixType;+ typedef DiagonalMatrix<Scalar,3> AlignedScaling3;+ typedef Translation<Scalar,2> Translation2;+ typedef Translation<Scalar,3> Translation3;++ Vector3 v0 = Vector3::Random(),+ v1 = Vector3::Random();+ Matrix3 matrot1, m;++ Scalar a = internal::random<Scalar>(-Scalar(M_PI), Scalar(M_PI));+ Scalar s0 = internal::random<Scalar>(),+ s1 = internal::random<Scalar>();+ + while(v0.norm() < test_precision<Scalar>()) v0 = Vector3::Random();+ while(v1.norm() < test_precision<Scalar>()) v1 = Vector3::Random();+ ++ VERIFY_IS_APPROX(v0, AngleAxisx(a, v0.normalized()) * v0);+ VERIFY_IS_APPROX(-v0, AngleAxisx(Scalar(M_PI), v0.unitOrthogonal()) * v0);+ if(abs(cos(a)) > test_precision<Scalar>())+ {+ VERIFY_IS_APPROX(cos(a)*v0.squaredNorm(), v0.dot(AngleAxisx(a, v0.unitOrthogonal()) * v0));+ }+ m = AngleAxisx(a, v0.normalized()).toRotationMatrix().adjoint();+ VERIFY_IS_APPROX(Matrix3::Identity(), m * AngleAxisx(a, v0.normalized()));+ VERIFY_IS_APPROX(Matrix3::Identity(), AngleAxisx(a, v0.normalized()) * m);++ Quaternionx q1, q2;+ q1 = AngleAxisx(a, v0.normalized());+ q2 = AngleAxisx(a, v1.normalized());++ // rotation matrix conversion+ matrot1 = AngleAxisx(Scalar(0.1), Vector3::UnitX())+ * AngleAxisx(Scalar(0.2), Vector3::UnitY())+ * AngleAxisx(Scalar(0.3), Vector3::UnitZ());+ VERIFY_IS_APPROX(matrot1 * v1,+ AngleAxisx(Scalar(0.1), Vector3(1,0,0)).toRotationMatrix()+ * (AngleAxisx(Scalar(0.2), Vector3(0,1,0)).toRotationMatrix()+ * (AngleAxisx(Scalar(0.3), Vector3(0,0,1)).toRotationMatrix() * v1)));++ // angle-axis conversion+ AngleAxisx aa = AngleAxisx(q1);+ VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);+ + if(abs(aa.angle()) > NumTraits<Scalar>::dummy_precision())+ {+ VERIFY( !(q1 * v1).isApprox(Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1) );+ }++ aa.fromRotationMatrix(aa.toRotationMatrix());+ VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);+ if(abs(aa.angle()) > NumTraits<Scalar>::dummy_precision())+ {+ VERIFY( !(q1 * v1).isApprox(Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1) );+ }++ // AngleAxis+ VERIFY_IS_APPROX(AngleAxisx(a,v1.normalized()).toRotationMatrix(),+ Quaternionx(AngleAxisx(a,v1.normalized())).toRotationMatrix());++ AngleAxisx aa1;+ m = q1.toRotationMatrix();+ aa1 = m;+ VERIFY_IS_APPROX(AngleAxisx(m).toRotationMatrix(),+ Quaternionx(m).toRotationMatrix());++ // Transform+ // TODO complete the tests !+ a = 0;+ while (abs(a)<Scalar(0.1))+ a = internal::random<Scalar>(-Scalar(0.4)*Scalar(M_PI), Scalar(0.4)*Scalar(M_PI));+ q1 = AngleAxisx(a, v0.normalized());+ Transform3 t0, t1, t2;++ // first test setIdentity() and Identity()+ t0.setIdentity();+ VERIFY_IS_APPROX(t0.matrix(), Transform3::MatrixType::Identity());+ t0.matrix().setZero();+ t0 = Transform3::Identity();+ VERIFY_IS_APPROX(t0.matrix(), Transform3::MatrixType::Identity());++ t0.setIdentity();+ t1.setIdentity();+ v1 << 1, 2, 3;+ t0.linear() = q1.toRotationMatrix();+ t0.pretranslate(v0);+ t0.scale(v1);+ t1.linear() = q1.conjugate().toRotationMatrix();+ t1.prescale(v1.cwiseInverse());+ t1.translate(-v0);++ VERIFY((t0 * t1).matrix().isIdentity(test_precision<Scalar>()));++ t1.fromPositionOrientationScale(v0, q1, v1);+ VERIFY_IS_APPROX(t1.matrix(), t0.matrix());++ t0.setIdentity(); t0.scale(v0).rotate(q1.toRotationMatrix());+ t1.setIdentity(); t1.scale(v0).rotate(q1);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ t0.setIdentity(); t0.scale(v0).rotate(AngleAxisx(q1));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ VERIFY_IS_APPROX(t0.scale(a).matrix(), t1.scale(Vector3::Constant(a)).matrix());+ VERIFY_IS_APPROX(t0.prescale(a).matrix(), t1.prescale(Vector3::Constant(a)).matrix());++ // More transform constructors, operator=, operator*=++ Matrix3 mat3 = Matrix3::Random();+ Matrix4 mat4;+ mat4 << mat3 , Vector3::Zero() , Vector4::Zero().transpose();+ Transform3 tmat3(mat3), tmat4(mat4);+ if(Mode!=int(AffineCompact))+ tmat4.matrix()(3,3) = Scalar(1);+ VERIFY_IS_APPROX(tmat3.matrix(), tmat4.matrix());++ Scalar a3 = internal::random<Scalar>(-Scalar(M_PI), Scalar(M_PI));+ Vector3 v3 = Vector3::Random().normalized();+ AngleAxisx aa3(a3, v3);+ Transform3 t3(aa3);+ Transform3 t4;+ t4 = aa3;+ VERIFY_IS_APPROX(t3.matrix(), t4.matrix());+ t4.rotate(AngleAxisx(-a3,v3));+ VERIFY_IS_APPROX(t4.matrix(), MatrixType::Identity());+ t4 *= aa3;+ VERIFY_IS_APPROX(t3.matrix(), t4.matrix());++ v3 = Vector3::Random();+ Translation3 tv3(v3);+ Transform3 t5(tv3);+ t4 = tv3;+ VERIFY_IS_APPROX(t5.matrix(), t4.matrix());+ t4.translate(-v3);+ VERIFY_IS_APPROX(t4.matrix(), MatrixType::Identity());+ t4 *= tv3;+ VERIFY_IS_APPROX(t5.matrix(), t4.matrix());++ AlignedScaling3 sv3(v3);+ Transform3 t6(sv3);+ t4 = sv3;+ VERIFY_IS_APPROX(t6.matrix(), t4.matrix());+ t4.scale(v3.cwiseInverse());+ VERIFY_IS_APPROX(t4.matrix(), MatrixType::Identity());+ t4 *= sv3;+ VERIFY_IS_APPROX(t6.matrix(), t4.matrix());++ // matrix * transform+ VERIFY_IS_APPROX((t3.matrix()*t4).matrix(), (t3*t4).matrix());++ // chained Transform product+ VERIFY_IS_APPROX(((t3*t4)*t5).matrix(), (t3*(t4*t5)).matrix());++ // check that Transform product doesn't have aliasing problems+ t5 = t4;+ t5 = t5*t5;+ VERIFY_IS_APPROX(t5, t4*t4);++ // 2D transformation+ Transform2 t20, t21;+ Vector2 v20 = Vector2::Random();+ Vector2 v21 = Vector2::Random();+ for (int k=0; k<2; ++k)+ if (abs(v21[k])<Scalar(1e-3)) v21[k] = Scalar(1e-3);+ t21.setIdentity();+ t21.linear() = Rotation2D<Scalar>(a).toRotationMatrix();+ VERIFY_IS_APPROX(t20.fromPositionOrientationScale(v20,a,v21).matrix(),+ t21.pretranslate(v20).scale(v21).matrix());++ t21.setIdentity();+ t21.linear() = Rotation2D<Scalar>(-a).toRotationMatrix();+ VERIFY( (t20.fromPositionOrientationScale(v20,a,v21)+ * (t21.prescale(v21.cwiseInverse()).translate(-v20))).matrix().isIdentity(test_precision<Scalar>()) );++ // Transform - new API+ // 3D+ t0.setIdentity();+ t0.rotate(q1).scale(v0).translate(v0);+ // mat * aligned scaling and mat * translation+ t1 = (Matrix3(q1) * AlignedScaling3(v0)) * Translation3(v0);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ t1 = (Matrix3(q1) * Eigen::Scaling(v0)) * Translation3(v0);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ t1 = (q1 * Eigen::Scaling(v0)) * Translation3(v0);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ // mat * transformation and aligned scaling * translation+ t1 = Matrix3(q1) * (AlignedScaling3(v0) * Translation3(v0));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+++ t0.setIdentity();+ t0.scale(s0).translate(v0);+ t1 = Eigen::Scaling(s0) * Translation3(v0);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ t0.prescale(s0);+ t1 = Eigen::Scaling(s0) * t1;+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ + t0 = t3;+ t0.scale(s0);+ t1 = t3 * Eigen::Scaling(s0,s0,s0);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ t0.prescale(s0);+ t1 = Eigen::Scaling(s0,s0,s0) * t1;+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ t0 = t3;+ t0.scale(s0);+ t1 = t3 * Eigen::Scaling(s0);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ t0.prescale(s0);+ t1 = Eigen::Scaling(s0) * t1;+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ t0.setIdentity();+ t0.prerotate(q1).prescale(v0).pretranslate(v0);+ // translation * aligned scaling and transformation * mat+ t1 = (Translation3(v0) * AlignedScaling3(v0)) * Transform3(q1);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ // scaling * mat and translation * mat+ t1 = Translation3(v0) * (AlignedScaling3(v0) * Transform3(q1));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ t0.setIdentity();+ t0.scale(v0).translate(v0).rotate(q1);+ // translation * mat and aligned scaling * transformation+ t1 = AlignedScaling3(v0) * (Translation3(v0) * Transform3(q1));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ // transformation * aligned scaling+ t0.scale(v0);+ t1 *= AlignedScaling3(v0);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ // transformation * translation+ t0.translate(v0);+ t1 = t1 * Translation3(v0);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());+ // translation * transformation+ t0.pretranslate(v0);+ t1 = Translation3(v0) * t1;+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // transform * quaternion+ t0.rotate(q1);+ t1 = t1 * q1;+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // translation * quaternion+ t0.translate(v1).rotate(q1);+ t1 = t1 * (Translation3(v1) * q1);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // aligned scaling * quaternion+ t0.scale(v1).rotate(q1);+ t1 = t1 * (AlignedScaling3(v1) * q1);+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // quaternion * transform+ t0.prerotate(q1);+ t1 = q1 * t1;+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // quaternion * translation+ t0.rotate(q1).translate(v1);+ t1 = t1 * (q1 * Translation3(v1));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // quaternion * aligned scaling+ t0.rotate(q1).scale(v1);+ t1 = t1 * (q1 * AlignedScaling3(v1));+ VERIFY_IS_APPROX(t0.matrix(), t1.matrix());++ // test transform inversion+ t0.setIdentity();+ t0.translate(v0);+ do {+ t0.linear().setRandom();+ } while(t0.linear().jacobiSvd().singularValues()(2)<test_precision<Scalar>());+ Matrix4 t044 = Matrix4::Zero();+ t044(3,3) = 1;+ t044.block(0,0,t0.matrix().rows(),4) = t0.matrix();+ VERIFY_IS_APPROX(t0.inverse(Affine).matrix(), t044.inverse().block(0,0,t0.matrix().rows(),4));+ t0.setIdentity();+ t0.translate(v0).rotate(q1);+ t044 = Matrix4::Zero();+ t044(3,3) = 1;+ t044.block(0,0,t0.matrix().rows(),4) = t0.matrix();+ VERIFY_IS_APPROX(t0.inverse(Isometry).matrix(), t044.inverse().block(0,0,t0.matrix().rows(),4));++ Matrix3 mat_rotation, mat_scaling;+ t0.setIdentity();+ t0.translate(v0).rotate(q1).scale(v1);+ t0.computeRotationScaling(&mat_rotation, &mat_scaling);+ VERIFY_IS_APPROX(t0.linear(), mat_rotation * mat_scaling);+ VERIFY_IS_APPROX(mat_rotation*mat_rotation.adjoint(), Matrix3::Identity());+ VERIFY_IS_APPROX(mat_rotation.determinant(), Scalar(1));+ t0.computeScalingRotation(&mat_scaling, &mat_rotation);+ VERIFY_IS_APPROX(t0.linear(), mat_scaling * mat_rotation);+ VERIFY_IS_APPROX(mat_rotation*mat_rotation.adjoint(), Matrix3::Identity());+ VERIFY_IS_APPROX(mat_rotation.determinant(), Scalar(1));++ // test casting+ Transform<float,3,Mode> t1f = t1.template cast<float>();+ VERIFY_IS_APPROX(t1f.template cast<Scalar>(),t1);+ Transform<double,3,Mode> t1d = t1.template cast<double>();+ VERIFY_IS_APPROX(t1d.template cast<Scalar>(),t1);++ Translation3 tr1(v0);+ Translation<float,3> tr1f = tr1.template cast<float>();+ VERIFY_IS_APPROX(tr1f.template cast<Scalar>(),tr1);+ Translation<double,3> tr1d = tr1.template cast<double>();+ VERIFY_IS_APPROX(tr1d.template cast<Scalar>(),tr1);++ AngleAxis<float> aa1f = aa1.template cast<float>();+ VERIFY_IS_APPROX(aa1f.template cast<Scalar>(),aa1);+ AngleAxis<double> aa1d = aa1.template cast<double>();+ VERIFY_IS_APPROX(aa1d.template cast<Scalar>(),aa1);++ Rotation2D<Scalar> r2d1(internal::random<Scalar>());+ Rotation2D<float> r2d1f = r2d1.template cast<float>();+ VERIFY_IS_APPROX(r2d1f.template cast<Scalar>(),r2d1);+ Rotation2D<double> r2d1d = r2d1.template cast<double>();+ VERIFY_IS_APPROX(r2d1d.template cast<Scalar>(),r2d1);++ t20 = Translation2(v20) * (Rotation2D<Scalar>(s0) * Eigen::Scaling(s0));+ t21 = Translation2(v20) * Rotation2D<Scalar>(s0) * Eigen::Scaling(s0);+ VERIFY_IS_APPROX(t20,t21);+ + Rotation2D<Scalar> R0(s0), R1(s1);+ t20 = Translation2(v20) * (R0 * Eigen::Scaling(s0));+ t21 = Translation2(v20) * R0 * Eigen::Scaling(s0);+ VERIFY_IS_APPROX(t20,t21);+ + t20 = Translation2(v20) * (R0 * R0.inverse() * Eigen::Scaling(s0));+ t21 = Translation2(v20) * Eigen::Scaling(s0);+ VERIFY_IS_APPROX(t20,t21);+ + VERIFY_IS_APPROX(s0, (R0.slerp(0, R1)).angle());+ VERIFY_IS_APPROX(s1, (R0.slerp(1, R1)).angle());+ VERIFY_IS_APPROX(s0, (R0.slerp(0.5, R0)).angle());+ VERIFY_IS_APPROX(Scalar(0), (R0.slerp(0.5, R0.inverse())).angle());+ + // check basic features+ {+ Rotation2D<Scalar> r1; // default ctor+ r1 = Rotation2D<Scalar>(s0); // copy assignment+ VERIFY_IS_APPROX(r1.angle(),s0);+ Rotation2D<Scalar> r2(r1); // copy ctor+ VERIFY_IS_APPROX(r2.angle(),s0);+ }+}++template<typename Scalar> void transform_alignment()+{+ typedef Transform<Scalar,3,Projective,AutoAlign> Projective3a;+ typedef Transform<Scalar,3,Projective,DontAlign> Projective3u;++ EIGEN_ALIGN16 Scalar array1[16];+ EIGEN_ALIGN16 Scalar array2[16];+ EIGEN_ALIGN16 Scalar array3[16+1];+ Scalar* array3u = array3+1;++ Projective3a *p1 = ::new(reinterpret_cast<void*>(array1)) Projective3a;+ Projective3u *p2 = ::new(reinterpret_cast<void*>(array2)) Projective3u;+ Projective3u *p3 = ::new(reinterpret_cast<void*>(array3u)) Projective3u;+ + p1->matrix().setRandom();+ *p2 = *p1;+ *p3 = *p1;++ VERIFY_IS_APPROX(p1->matrix(), p2->matrix());+ VERIFY_IS_APPROX(p1->matrix(), p3->matrix());+ + VERIFY_IS_APPROX( (*p1) * (*p1), (*p2)*(*p3));+ + #if defined(EIGEN_VECTORIZE) && EIGEN_ALIGN_STATICALLY+ if(internal::packet_traits<Scalar>::Vectorizable)+ VERIFY_RAISES_ASSERT((::new(reinterpret_cast<void*>(array3u)) Projective3a));+ #endif+}++template<typename Scalar, int Dim, int Options> void transform_products()+{+ typedef Matrix<Scalar,Dim+1,Dim+1> Mat;+ typedef Transform<Scalar,Dim,Projective,Options> Proj;+ typedef Transform<Scalar,Dim,Affine,Options> Aff;+ typedef Transform<Scalar,Dim,AffineCompact,Options> AffC;++ Proj p; p.matrix().setRandom();+ Aff a; a.linear().setRandom(); a.translation().setRandom();+ AffC ac = a;++ Mat p_m(p.matrix()), a_m(a.matrix());++ VERIFY_IS_APPROX((p*p).matrix(), p_m*p_m);+ VERIFY_IS_APPROX((a*a).matrix(), a_m*a_m);+ VERIFY_IS_APPROX((p*a).matrix(), p_m*a_m);+ VERIFY_IS_APPROX((a*p).matrix(), a_m*p_m);+ VERIFY_IS_APPROX((ac*a).matrix(), a_m*a_m);+ VERIFY_IS_APPROX((a*ac).matrix(), a_m*a_m);+ VERIFY_IS_APPROX((p*ac).matrix(), p_m*a_m);+ VERIFY_IS_APPROX((ac*p).matrix(), a_m*p_m);+}++void test_geo_transformations()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1(( transformations<double,Affine,AutoAlign>() ));+ CALL_SUBTEST_1(( non_projective_only<double,Affine,AutoAlign>() ));+ + CALL_SUBTEST_2(( transformations<float,AffineCompact,AutoAlign>() ));+ CALL_SUBTEST_2(( non_projective_only<float,AffineCompact,AutoAlign>() ));+ CALL_SUBTEST_2(( transform_alignment<float>() ));+ + CALL_SUBTEST_3(( transformations<double,Projective,AutoAlign>() ));+ CALL_SUBTEST_3(( transformations<double,Projective,DontAlign>() ));+ CALL_SUBTEST_3(( transform_alignment<double>() ));+ + CALL_SUBTEST_4(( transformations<float,Affine,RowMajor|AutoAlign>() ));+ CALL_SUBTEST_4(( non_projective_only<float,Affine,RowMajor>() ));+ + CALL_SUBTEST_5(( transformations<double,AffineCompact,RowMajor|AutoAlign>() ));+ CALL_SUBTEST_5(( non_projective_only<double,AffineCompact,RowMajor>() ));++ CALL_SUBTEST_6(( transformations<double,Projective,RowMajor|AutoAlign>() ));+ CALL_SUBTEST_6(( transformations<double,Projective,RowMajor|DontAlign>() ));+++ CALL_SUBTEST_7(( transform_products<double,3,RowMajor|AutoAlign>() ));+ CALL_SUBTEST_7(( transform_products<float,2,AutoAlign>() ));+ }+}
+ eigen3/test/hessenberg.cpp view
@@ -0,0 +1,62 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/Eigenvalues>++template<typename Scalar,int Size> void hessenberg(int size = Size)+{+ typedef Matrix<Scalar,Size,Size> MatrixType;++ // Test basic functionality: A = U H U* and H is Hessenberg+ for(int counter = 0; counter < g_repeat; ++counter) {+ MatrixType m = MatrixType::Random(size,size);+ HessenbergDecomposition<MatrixType> hess(m);+ MatrixType Q = hess.matrixQ();+ MatrixType H = hess.matrixH();+ VERIFY_IS_APPROX(m, Q * H * Q.adjoint());+ for(int row = 2; row < size; ++row) {+ for(int col = 0; col < row-1; ++col) {+ VERIFY(H(row,col) == (typename MatrixType::Scalar)0);+ }+ }+ }++ // Test whether compute() and constructor returns same result+ MatrixType A = MatrixType::Random(size, size);+ HessenbergDecomposition<MatrixType> cs1;+ cs1.compute(A);+ HessenbergDecomposition<MatrixType> cs2(A);+ VERIFY_IS_EQUAL(cs1.matrixH().eval(), cs2.matrixH().eval());+ MatrixType cs1Q = cs1.matrixQ();+ MatrixType cs2Q = cs2.matrixQ(); + VERIFY_IS_EQUAL(cs1Q, cs2Q);++ // Test assertions for when used uninitialized+ HessenbergDecomposition<MatrixType> hessUninitialized;+ VERIFY_RAISES_ASSERT( hessUninitialized.matrixH() );+ VERIFY_RAISES_ASSERT( hessUninitialized.matrixQ() );+ VERIFY_RAISES_ASSERT( hessUninitialized.householderCoefficients() );+ VERIFY_RAISES_ASSERT( hessUninitialized.packedMatrix() );++ // TODO: Add tests for packedMatrix() and householderCoefficients()+}++void test_hessenberg()+{+ CALL_SUBTEST_1(( hessenberg<std::complex<double>,1>() ));+ CALL_SUBTEST_2(( hessenberg<std::complex<double>,2>() ));+ CALL_SUBTEST_3(( hessenberg<std::complex<float>,4>() ));+ CALL_SUBTEST_4(( hessenberg<float,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)) ));+ CALL_SUBTEST_5(( hessenberg<std::complex<double>,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)) ));++ // Test problem size constructors+ CALL_SUBTEST_6(HessenbergDecomposition<MatrixXf>(10));+}
+ eigen3/test/householder.cpp view
@@ -0,0 +1,138 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/QR>++template<typename MatrixType> void householder(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ static bool even = true;+ even = !even;+ /* this test covers the following files:+ Householder.h+ */+ Index rows = m.rows();+ Index cols = m.cols();++ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;+ typedef Matrix<Scalar, internal::decrement_size<MatrixType::RowsAtCompileTime>::ret, 1> EssentialVectorType;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;+ typedef Matrix<Scalar, Dynamic, MatrixType::ColsAtCompileTime> HBlockMatrixType;+ typedef Matrix<Scalar, Dynamic, 1> HCoeffsVectorType;++ typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, MatrixType::RowsAtCompileTime> TMatrixType;+ + Matrix<Scalar, EIGEN_SIZE_MAX(MatrixType::RowsAtCompileTime,MatrixType::ColsAtCompileTime), 1> _tmp((std::max)(rows,cols));+ Scalar* tmp = &_tmp.coeffRef(0,0);++ Scalar beta;+ RealScalar alpha;+ EssentialVectorType essential;++ VectorType v1 = VectorType::Random(rows), v2;+ v2 = v1;+ v1.makeHouseholder(essential, beta, alpha);+ v1.applyHouseholderOnTheLeft(essential,beta,tmp);+ VERIFY_IS_APPROX(v1.norm(), v2.norm());+ if(rows>=2) VERIFY_IS_MUCH_SMALLER_THAN(v1.tail(rows-1).norm(), v1.norm());+ v1 = VectorType::Random(rows);+ v2 = v1;+ v1.applyHouseholderOnTheLeft(essential,beta,tmp);+ VERIFY_IS_APPROX(v1.norm(), v2.norm());++ MatrixType m1(rows, cols),+ m2(rows, cols);++ v1 = VectorType::Random(rows);+ if(even) v1.tail(rows-1).setZero();+ m1.colwise() = v1;+ m2 = m1;+ m1.col(0).makeHouseholder(essential, beta, alpha);+ m1.applyHouseholderOnTheLeft(essential,beta,tmp);+ VERIFY_IS_APPROX(m1.norm(), m2.norm());+ if(rows>=2) VERIFY_IS_MUCH_SMALLER_THAN(m1.block(1,0,rows-1,cols).norm(), m1.norm());+ VERIFY_IS_MUCH_SMALLER_THAN(numext::imag(m1(0,0)), numext::real(m1(0,0)));+ VERIFY_IS_APPROX(numext::real(m1(0,0)), alpha);++ v1 = VectorType::Random(rows);+ if(even) v1.tail(rows-1).setZero();+ SquareMatrixType m3(rows,rows), m4(rows,rows);+ m3.rowwise() = v1.transpose();+ m4 = m3;+ m3.row(0).makeHouseholder(essential, beta, alpha);+ m3.applyHouseholderOnTheRight(essential,beta,tmp);+ VERIFY_IS_APPROX(m3.norm(), m4.norm());+ if(rows>=2) VERIFY_IS_MUCH_SMALLER_THAN(m3.block(0,1,rows,rows-1).norm(), m3.norm());+ VERIFY_IS_MUCH_SMALLER_THAN(numext::imag(m3(0,0)), numext::real(m3(0,0)));+ VERIFY_IS_APPROX(numext::real(m3(0,0)), alpha);++ // test householder sequence on the left with a shift++ Index shift = internal::random<Index>(0, std::max<Index>(rows-2,0));+ Index brows = rows - shift;+ m1.setRandom(rows, cols);+ HBlockMatrixType hbm = m1.block(shift,0,brows,cols);+ HouseholderQR<HBlockMatrixType> qr(hbm);+ m2 = m1;+ m2.block(shift,0,brows,cols) = qr.matrixQR();+ HCoeffsVectorType hc = qr.hCoeffs().conjugate();+ HouseholderSequence<MatrixType, HCoeffsVectorType> hseq(m2, hc);+ hseq.setLength(hc.size()).setShift(shift);+ VERIFY(hseq.length() == hc.size());+ VERIFY(hseq.shift() == shift);+ + MatrixType m5 = m2;+ m5.block(shift,0,brows,cols).template triangularView<StrictlyLower>().setZero();+ VERIFY_IS_APPROX(hseq * m5, m1); // test applying hseq directly+ m3 = hseq;+ VERIFY_IS_APPROX(m3 * m5, m1); // test evaluating hseq to a dense matrix, then applying+ + SquareMatrixType hseq_mat = hseq;+ SquareMatrixType hseq_mat_conj = hseq.conjugate();+ SquareMatrixType hseq_mat_adj = hseq.adjoint();+ SquareMatrixType hseq_mat_trans = hseq.transpose();+ SquareMatrixType m6 = SquareMatrixType::Random(rows, rows);+ VERIFY_IS_APPROX(hseq_mat.adjoint(), hseq_mat_adj);+ VERIFY_IS_APPROX(hseq_mat.conjugate(), hseq_mat_conj);+ VERIFY_IS_APPROX(hseq_mat.transpose(), hseq_mat_trans);+ VERIFY_IS_APPROX(hseq_mat * m6, hseq_mat * m6);+ VERIFY_IS_APPROX(hseq_mat.adjoint() * m6, hseq_mat_adj * m6);+ VERIFY_IS_APPROX(hseq_mat.conjugate() * m6, hseq_mat_conj * m6);+ VERIFY_IS_APPROX(hseq_mat.transpose() * m6, hseq_mat_trans * m6);+ VERIFY_IS_APPROX(m6 * hseq_mat, m6 * hseq_mat);+ VERIFY_IS_APPROX(m6 * hseq_mat.adjoint(), m6 * hseq_mat_adj);+ VERIFY_IS_APPROX(m6 * hseq_mat.conjugate(), m6 * hseq_mat_conj);+ VERIFY_IS_APPROX(m6 * hseq_mat.transpose(), m6 * hseq_mat_trans);++ // test householder sequence on the right with a shift++ TMatrixType tm2 = m2.transpose();+ HouseholderSequence<TMatrixType, HCoeffsVectorType, OnTheRight> rhseq(tm2, hc);+ rhseq.setLength(hc.size()).setShift(shift);+ VERIFY_IS_APPROX(rhseq * m5, m1); // test applying rhseq directly+ m3 = rhseq;+ VERIFY_IS_APPROX(m3 * m5, m1); // test evaluating rhseq to a dense matrix, then applying+}++void test_householder()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( householder(Matrix<double,2,2>()) );+ CALL_SUBTEST_2( householder(Matrix<float,2,3>()) );+ CALL_SUBTEST_3( householder(Matrix<double,3,5>()) );+ CALL_SUBTEST_4( householder(Matrix<float,4,4>()) );+ CALL_SUBTEST_5( householder(MatrixXd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_6( householder(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_7( householder(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_8( householder(Matrix<double,1,1>()) );+ }+}
+ eigen3/test/integer_types.cpp view
@@ -0,0 +1,161 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN_NO_STATIC_ASSERT++#include "main.h"++#undef VERIFY_IS_APPROX+#define VERIFY_IS_APPROX(a, b) VERIFY((a)==(b));+#undef VERIFY_IS_NOT_APPROX+#define VERIFY_IS_NOT_APPROX(a, b) VERIFY((a)!=(b));++template<typename MatrixType> void signed_integer_type_tests(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;++ enum { is_signed = (Scalar(-1) > Scalar(0)) ? 0 : 1 };+ VERIFY(is_signed == 1);++ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ mzero = MatrixType::Zero(rows, cols);++ do {+ m1 = MatrixType::Random(rows, cols);+ } while(m1 == mzero || m1 == m2);++ // check linear structure++ Scalar s1;+ do {+ s1 = internal::random<Scalar>();+ } while(s1 == 0);++ VERIFY_IS_EQUAL(-(-m1), m1);+ VERIFY_IS_EQUAL(-m2+m1+m2, m1);+ VERIFY_IS_EQUAL((-m1+m2)*s1, -s1*m1+s1*m2);+}++template<typename MatrixType> void integer_type_tests(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;++ VERIFY(NumTraits<Scalar>::IsInteger);+ enum { is_signed = (Scalar(-1) > Scalar(0)) ? 0 : 1 };+ VERIFY(int(NumTraits<Scalar>::IsSigned) == is_signed);++ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ Index rows = m.rows();+ Index cols = m.cols();++ // this test relies a lot on Random.h, and there's not much more that we can do+ // to test it, hence I consider that we will have tested Random.h+ MatrixType m1(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols),+ mzero = MatrixType::Zero(rows, cols);++ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> SquareMatrixType;+ SquareMatrixType identity = SquareMatrixType::Identity(rows, rows),+ square = SquareMatrixType::Random(rows, rows);+ VectorType v1(rows),+ v2 = VectorType::Random(rows),+ vzero = VectorType::Zero(rows);++ do {+ m1 = MatrixType::Random(rows, cols);+ } while(m1 == mzero || m1 == m2);++ do {+ v1 = VectorType::Random(rows);+ } while(v1 == vzero || v1 == v2);++ VERIFY_IS_APPROX( v1, v1);+ VERIFY_IS_NOT_APPROX( v1, 2*v1);+ VERIFY_IS_APPROX( vzero, v1-v1);+ VERIFY_IS_APPROX( m1, m1);+ VERIFY_IS_NOT_APPROX( m1, 2*m1);+ VERIFY_IS_APPROX( mzero, m1-m1);++ VERIFY_IS_APPROX(m3 = m1,m1);+ MatrixType m4;+ VERIFY_IS_APPROX(m4 = m1,m1);++ m3.real() = m1.real();+ VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), static_cast<const MatrixType&>(m1).real());+ VERIFY_IS_APPROX(static_cast<const MatrixType&>(m3).real(), m1.real());++ // check == / != operators+ VERIFY(m1==m1);+ VERIFY(m1!=m2);+ VERIFY(!(m1==m2));+ VERIFY(!(m1!=m1));+ m1 = m2;+ VERIFY(m1==m2);+ VERIFY(!(m1!=m2));++ // check linear structure++ Scalar s1;+ do {+ s1 = internal::random<Scalar>();+ } while(s1 == 0);++ VERIFY_IS_EQUAL(m1+m1, 2*m1);+ VERIFY_IS_EQUAL(m1+m2-m1, m2);+ VERIFY_IS_EQUAL(m1*s1, s1*m1);+ VERIFY_IS_EQUAL((m1+m2)*s1, s1*m1+s1*m2);+ m3 = m2; m3 += m1;+ VERIFY_IS_EQUAL(m3, m1+m2);+ m3 = m2; m3 -= m1;+ VERIFY_IS_EQUAL(m3, m2-m1);+ m3 = m2; m3 *= s1;+ VERIFY_IS_EQUAL(m3, s1*m2);++ // check matrix product.++ VERIFY_IS_APPROX(identity * m1, m1);+ VERIFY_IS_APPROX(square * (m1 + m2), square * m1 + square * m2);+ VERIFY_IS_APPROX((m1 + m2).transpose() * square, m1.transpose() * square + m2.transpose() * square);+ VERIFY_IS_APPROX((m1 * m2.transpose()) * m1, m1 * (m2.transpose() * m1));+}++void test_integer_types()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( integer_type_tests(Matrix<unsigned int, 1, 1>()) );+ CALL_SUBTEST_1( integer_type_tests(Matrix<unsigned long, 3, 4>()) );++ CALL_SUBTEST_2( integer_type_tests(Matrix<long, 2, 2>()) );+ CALL_SUBTEST_2( signed_integer_type_tests(Matrix<long, 2, 2>()) );++ CALL_SUBTEST_3( integer_type_tests(Matrix<char, 2, Dynamic>(2, 10)) );+ CALL_SUBTEST_3( signed_integer_type_tests(Matrix<signed char, 2, Dynamic>(2, 10)) );++ CALL_SUBTEST_4( integer_type_tests(Matrix<unsigned char, 3, 3>()) );+ CALL_SUBTEST_4( integer_type_tests(Matrix<unsigned char, Dynamic, Dynamic>(20, 20)) );++ CALL_SUBTEST_5( integer_type_tests(Matrix<short, Dynamic, 4>(7, 4)) );+ CALL_SUBTEST_5( signed_integer_type_tests(Matrix<short, Dynamic, 4>(7, 4)) );++ CALL_SUBTEST_6( integer_type_tests(Matrix<unsigned short, 4, 4>()) );++ CALL_SUBTEST_7( integer_type_tests(Matrix<long long, 11, 13>()) );+ CALL_SUBTEST_7( signed_integer_type_tests(Matrix<long long, 11, 13>()) );++ CALL_SUBTEST_8( integer_type_tests(Matrix<unsigned long long, Dynamic, 5>(1, 5)) );+ }+}
+ eigen3/test/inverse.cpp view
@@ -0,0 +1,104 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/LU>++template<typename MatrixType> void inverse(const MatrixType& m)+{+ using std::abs;+ typedef typename MatrixType::Index Index;+ /* this test covers the following files:+ Inverse.h+ */+ Index rows = m.rows();+ Index cols = m.cols();++ typedef typename MatrixType::Scalar Scalar;++ MatrixType m1(rows, cols),+ m2(rows, cols),+ identity = MatrixType::Identity(rows, rows);+ createRandomPIMatrixOfRank(rows,rows,rows,m1);+ m2 = m1.inverse();+ VERIFY_IS_APPROX(m1, m2.inverse() );++ VERIFY_IS_APPROX((Scalar(2)*m2).inverse(), m2.inverse()*Scalar(0.5));++ VERIFY_IS_APPROX(identity, m1.inverse() * m1 );+ VERIFY_IS_APPROX(identity, m1 * m1.inverse() );++ VERIFY_IS_APPROX(m1, m1.inverse().inverse() );++ // since for the general case we implement separately row-major and col-major, test that+ VERIFY_IS_APPROX(MatrixType(m1.transpose().inverse()), MatrixType(m1.inverse().transpose()));++#if !defined(EIGEN_TEST_PART_5) && !defined(EIGEN_TEST_PART_6)+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> VectorType;+ + //computeInverseAndDetWithCheck tests+ //First: an invertible matrix+ bool invertible;+ RealScalar det;++ m2.setZero();+ m1.computeInverseAndDetWithCheck(m2, det, invertible);+ VERIFY(invertible);+ VERIFY_IS_APPROX(identity, m1*m2);+ VERIFY_IS_APPROX(det, m1.determinant());++ m2.setZero();+ m1.computeInverseWithCheck(m2, invertible);+ VERIFY(invertible);+ VERIFY_IS_APPROX(identity, m1*m2);++ //Second: a rank one matrix (not invertible, except for 1x1 matrices)+ VectorType v3 = VectorType::Random(rows);+ MatrixType m3 = v3*v3.transpose(), m4(rows,cols);+ m3.computeInverseAndDetWithCheck(m4, det, invertible);+ VERIFY( rows==1 ? invertible : !invertible );+ VERIFY_IS_MUCH_SMALLER_THAN(abs(det-m3.determinant()), RealScalar(1));+ m3.computeInverseWithCheck(m4, invertible);+ VERIFY( rows==1 ? invertible : !invertible );+#endif++ // check in-place inversion+ if(MatrixType::RowsAtCompileTime>=2 && MatrixType::RowsAtCompileTime<=4)+ {+ // in-place is forbidden+ VERIFY_RAISES_ASSERT(m1 = m1.inverse());+ }+ else+ {+ m2 = m1.inverse();+ m1 = m1.inverse();+ VERIFY_IS_APPROX(m1,m2);+ }+}++void test_inverse()+{+ int s = 0;+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( inverse(Matrix<double,1,1>()) );+ CALL_SUBTEST_2( inverse(Matrix2d()) );+ CALL_SUBTEST_3( inverse(Matrix3f()) );+ CALL_SUBTEST_4( inverse(Matrix4f()) );+ CALL_SUBTEST_4( inverse(Matrix<float,4,4,DontAlign>()) );+ s = internal::random<int>(50,320); + CALL_SUBTEST_5( inverse(MatrixXf(s,s)) );+ s = internal::random<int>(25,100);+ CALL_SUBTEST_6( inverse(MatrixXcd(s,s)) );+ CALL_SUBTEST_7( inverse(Matrix4d()) );+ CALL_SUBTEST_7( inverse(Matrix<double,4,4,DontAlign>()) );+ }+ TEST_SET_BUT_UNUSED_VARIABLE(s)+}
+ eigen3/test/jacobi.cpp view
@@ -0,0 +1,81 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/SVD>++template<typename MatrixType, typename JacobiScalar>+void jacobi(const MatrixType& m = MatrixType())+{+ typedef typename MatrixType::Index Index;+ Index rows = m.rows();+ Index cols = m.cols();++ enum {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,+ ColsAtCompileTime = MatrixType::ColsAtCompileTime+ };++ typedef Matrix<JacobiScalar, 2, 1> JacobiVector;++ const MatrixType a(MatrixType::Random(rows, cols));++ JacobiVector v = JacobiVector::Random().normalized();+ JacobiScalar c = v.x(), s = v.y();+ JacobiRotation<JacobiScalar> rot(c, s);++ {+ Index p = internal::random<Index>(0, rows-1);+ Index q;+ do {+ q = internal::random<Index>(0, rows-1);+ } while (q == p);++ MatrixType b = a;+ b.applyOnTheLeft(p, q, rot);+ VERIFY_IS_APPROX(b.row(p), c * a.row(p) + numext::conj(s) * a.row(q));+ VERIFY_IS_APPROX(b.row(q), -s * a.row(p) + numext::conj(c) * a.row(q));+ }++ {+ Index p = internal::random<Index>(0, cols-1);+ Index q;+ do {+ q = internal::random<Index>(0, cols-1);+ } while (q == p);++ MatrixType b = a;+ b.applyOnTheRight(p, q, rot);+ VERIFY_IS_APPROX(b.col(p), c * a.col(p) - s * a.col(q));+ VERIFY_IS_APPROX(b.col(q), numext::conj(s) * a.col(p) + numext::conj(c) * a.col(q));+ }+}++void test_jacobi()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1(( jacobi<Matrix3f, float>() ));+ CALL_SUBTEST_2(( jacobi<Matrix4d, double>() ));+ CALL_SUBTEST_3(( jacobi<Matrix4cf, float>() ));+ CALL_SUBTEST_3(( jacobi<Matrix4cf, std::complex<float> >() ));++ int r = internal::random<int>(2, internal::random<int>(1,EIGEN_TEST_MAX_SIZE)/2),+ c = internal::random<int>(2, internal::random<int>(1,EIGEN_TEST_MAX_SIZE)/2);+ CALL_SUBTEST_4(( jacobi<MatrixXf, float>(MatrixXf(r,c)) ));+ CALL_SUBTEST_5(( jacobi<MatrixXcd, double>(MatrixXcd(r,c)) ));+ CALL_SUBTEST_5(( jacobi<MatrixXcd, std::complex<double> >(MatrixXcd(r,c)) ));+ // complex<float> is really important to test as it is the only way to cover conjugation issues in certain unaligned paths+ CALL_SUBTEST_6(( jacobi<MatrixXcf, float>(MatrixXcf(r,c)) ));+ CALL_SUBTEST_6(( jacobi<MatrixXcf, std::complex<float> >(MatrixXcf(r,c)) ));+ + TEST_SET_BUT_UNUSED_VARIABLE(r);+ TEST_SET_BUT_UNUSED_VARIABLE(c);+ }+}
+ eigen3/test/jacobisvd.cpp view
@@ -0,0 +1,462 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++// discard stack allocation as that too bypasses malloc+#define EIGEN_STACK_ALLOCATION_LIMIT 0+#define EIGEN_RUNTIME_NO_MALLOC+#include "main.h"+#include <Eigen/SVD>++template<typename MatrixType, int QRPreconditioner>+void jacobisvd_check_full(const MatrixType& m, const JacobiSVD<MatrixType, QRPreconditioner>& svd)+{+ typedef typename MatrixType::Index Index;+ Index rows = m.rows();+ Index cols = m.cols();++ enum {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,+ ColsAtCompileTime = MatrixType::ColsAtCompileTime+ };++ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime> MatrixUType;+ typedef Matrix<Scalar, ColsAtCompileTime, ColsAtCompileTime> MatrixVType;++ MatrixType sigma = MatrixType::Zero(rows,cols);+ sigma.diagonal() = svd.singularValues().template cast<Scalar>();+ MatrixUType u = svd.matrixU();+ MatrixVType v = svd.matrixV();++ VERIFY_IS_APPROX(m, u * sigma * v.adjoint());+ VERIFY_IS_UNITARY(u);+ VERIFY_IS_UNITARY(v);+}++template<typename MatrixType, int QRPreconditioner>+void jacobisvd_compare_to_full(const MatrixType& m,+ unsigned int computationOptions,+ const JacobiSVD<MatrixType, QRPreconditioner>& referenceSvd)+{+ typedef typename MatrixType::Index Index;+ Index rows = m.rows();+ Index cols = m.cols();+ Index diagSize = (std::min)(rows, cols);++ JacobiSVD<MatrixType, QRPreconditioner> svd(m, computationOptions);++ VERIFY_IS_APPROX(svd.singularValues(), referenceSvd.singularValues());+ if(computationOptions & ComputeFullU)+ VERIFY_IS_APPROX(svd.matrixU(), referenceSvd.matrixU());+ if(computationOptions & ComputeThinU)+ VERIFY_IS_APPROX(svd.matrixU(), referenceSvd.matrixU().leftCols(diagSize));+ if(computationOptions & ComputeFullV)+ VERIFY_IS_APPROX(svd.matrixV(), referenceSvd.matrixV());+ if(computationOptions & ComputeThinV)+ VERIFY_IS_APPROX(svd.matrixV(), referenceSvd.matrixV().leftCols(diagSize));+}++template<typename MatrixType, int QRPreconditioner>+void jacobisvd_solve(const MatrixType& m, unsigned int computationOptions)+{+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::RealScalar RealScalar;+ typedef typename MatrixType::Index Index;+ Index rows = m.rows();+ Index cols = m.cols();++ enum {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,+ ColsAtCompileTime = MatrixType::ColsAtCompileTime+ };++ typedef Matrix<Scalar, RowsAtCompileTime, Dynamic> RhsType;+ typedef Matrix<Scalar, ColsAtCompileTime, Dynamic> SolutionType;++ RhsType rhs = RhsType::Random(rows, internal::random<Index>(1, cols));+ JacobiSVD<MatrixType, QRPreconditioner> svd(m, computationOptions);++ if(internal::is_same<RealScalar,double>::value) svd.setThreshold(1e-8);+ else if(internal::is_same<RealScalar,float>::value) svd.setThreshold(1e-4);+ + SolutionType x = svd.solve(rhs);+ + RealScalar residual = (m*x-rhs).norm();+ // Check that there is no significantly better solution in the neighborhood of x+ if(!test_isMuchSmallerThan(residual,rhs.norm()))+ {+ // If the residual is very small, then we have an exact solution, so we are already good.+ for(int k=0;k<x.rows();++k)+ {+ SolutionType y(x);+ y.row(k).array() += 2*NumTraits<RealScalar>::epsilon();+ RealScalar residual_y = (m*y-rhs).norm();+ VERIFY( test_isApprox(residual_y,residual) || residual < residual_y );+ + y.row(k) = x.row(k).array() - 2*NumTraits<RealScalar>::epsilon();+ residual_y = (m*y-rhs).norm();+ VERIFY( test_isApprox(residual_y,residual) || residual < residual_y );+ }+ }+ + // evaluate normal equation which works also for least-squares solutions+ if(internal::is_same<RealScalar,double>::value)+ {+ // This test is not stable with single precision.+ // This is probably because squaring m signicantly affects the precision.+ VERIFY_IS_APPROX(m.adjoint()*m*x,m.adjoint()*rhs);+ }+ + // check minimal norm solutions+ {+ // generate a full-rank m x n problem with m<n+ enum {+ RankAtCompileTime2 = ColsAtCompileTime==Dynamic ? Dynamic : (ColsAtCompileTime)/2+1,+ RowsAtCompileTime3 = ColsAtCompileTime==Dynamic ? Dynamic : ColsAtCompileTime+1+ };+ typedef Matrix<Scalar, RankAtCompileTime2, ColsAtCompileTime> MatrixType2;+ typedef Matrix<Scalar, RankAtCompileTime2, 1> RhsType2;+ typedef Matrix<Scalar, ColsAtCompileTime, RankAtCompileTime2> MatrixType2T;+ Index rank = RankAtCompileTime2==Dynamic ? internal::random<Index>(1,cols) : Index(RankAtCompileTime2);+ MatrixType2 m2(rank,cols);+ int guard = 0;+ do {+ m2.setRandom();+ } while(m2.jacobiSvd().setThreshold(test_precision<Scalar>()).rank()!=rank && (++guard)<10);+ VERIFY(guard<10);+ RhsType2 rhs2 = RhsType2::Random(rank);+ // use QR to find a reference minimal norm solution+ HouseholderQR<MatrixType2T> qr(m2.adjoint());+ Matrix<Scalar,Dynamic,1> tmp = qr.matrixQR().topLeftCorner(rank,rank).template triangularView<Upper>().adjoint().solve(rhs2);+ tmp.conservativeResize(cols);+ tmp.tail(cols-rank).setZero();+ SolutionType x21 = qr.householderQ() * tmp;+ // now check with SVD+ JacobiSVD<MatrixType2, ColPivHouseholderQRPreconditioner> svd2(m2, computationOptions);+ SolutionType x22 = svd2.solve(rhs2);+ VERIFY_IS_APPROX(m2*x21, rhs2);+ VERIFY_IS_APPROX(m2*x22, rhs2);+ VERIFY_IS_APPROX(x21, x22);+ + // Now check with a rank deficient matrix+ typedef Matrix<Scalar, RowsAtCompileTime3, ColsAtCompileTime> MatrixType3;+ typedef Matrix<Scalar, RowsAtCompileTime3, 1> RhsType3;+ Index rows3 = RowsAtCompileTime3==Dynamic ? internal::random<Index>(rank+1,2*cols) : Index(RowsAtCompileTime3);+ Matrix<Scalar,RowsAtCompileTime3,Dynamic> C = Matrix<Scalar,RowsAtCompileTime3,Dynamic>::Random(rows3,rank);+ MatrixType3 m3 = C * m2;+ RhsType3 rhs3 = C * rhs2;+ JacobiSVD<MatrixType3, ColPivHouseholderQRPreconditioner> svd3(m3, computationOptions);+ SolutionType x3 = svd3.solve(rhs3);+ if(svd3.rank()!=rank) {+ std::cout << m3 << "\n\n";+ std::cout << svd3.singularValues().transpose() << "\n";+ std::cout << svd3.rank() << " == " << rank << "\n";+ std::cout << x21.norm() << " == " << x3.norm() << "\n";+ }+// VERIFY_IS_APPROX(m3*x3, rhs3);+ VERIFY_IS_APPROX(m3*x21, rhs3);+ VERIFY_IS_APPROX(m2*x3, rhs2);+ + VERIFY_IS_APPROX(x21, x3);+ }+}++template<typename MatrixType, int QRPreconditioner>+void jacobisvd_test_all_computation_options(const MatrixType& m)+{+ if (QRPreconditioner == NoQRPreconditioner && m.rows() != m.cols())+ return;+ JacobiSVD<MatrixType, QRPreconditioner> fullSvd(m, ComputeFullU|ComputeFullV);+ CALL_SUBTEST(( jacobisvd_check_full(m, fullSvd) ));+ CALL_SUBTEST(( jacobisvd_solve<MatrixType, QRPreconditioner>(m, ComputeFullU | ComputeFullV) ));+ + #if defined __INTEL_COMPILER+ // remark #111: statement is unreachable+ #pragma warning disable 111+ #endif+ if(QRPreconditioner == FullPivHouseholderQRPreconditioner)+ return;++ CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeFullU, fullSvd) ));+ CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeFullV, fullSvd) ));+ CALL_SUBTEST(( jacobisvd_compare_to_full(m, 0, fullSvd) ));++ if (MatrixType::ColsAtCompileTime == Dynamic) {+ // thin U/V are only available with dynamic number of columns+ CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeFullU|ComputeThinV, fullSvd) ));+ CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeThinV, fullSvd) ));+ CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeThinU|ComputeFullV, fullSvd) ));+ CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeThinU , fullSvd) ));+ CALL_SUBTEST(( jacobisvd_compare_to_full(m, ComputeThinU|ComputeThinV, fullSvd) ));+ CALL_SUBTEST(( jacobisvd_solve<MatrixType, QRPreconditioner>(m, ComputeFullU | ComputeThinV) ));+ CALL_SUBTEST(( jacobisvd_solve<MatrixType, QRPreconditioner>(m, ComputeThinU | ComputeFullV) ));+ CALL_SUBTEST(( jacobisvd_solve<MatrixType, QRPreconditioner>(m, ComputeThinU | ComputeThinV) ));++ // test reconstruction+ typedef typename MatrixType::Index Index;+ Index diagSize = (std::min)(m.rows(), m.cols());+ JacobiSVD<MatrixType, QRPreconditioner> svd(m, ComputeThinU | ComputeThinV);+ VERIFY_IS_APPROX(m, svd.matrixU().leftCols(diagSize) * svd.singularValues().asDiagonal() * svd.matrixV().leftCols(diagSize).adjoint());+ }+}++template<typename MatrixType>+void jacobisvd(const MatrixType& a = MatrixType(), bool pickrandom = true)+{+ MatrixType m = a;+ if(pickrandom)+ {+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::RealScalar RealScalar;+ typedef typename MatrixType::Index Index;+ Index diagSize = (std::min)(a.rows(), a.cols());+ RealScalar s = std::numeric_limits<RealScalar>::max_exponent10/4;+ s = internal::random<RealScalar>(1,s);+ Matrix<RealScalar,Dynamic,1> d = Matrix<RealScalar,Dynamic,1>::Random(diagSize);+ for(Index k=0; k<diagSize; ++k)+ d(k) = d(k)*std::pow(RealScalar(10),internal::random<RealScalar>(-s,s));+ m = Matrix<Scalar,Dynamic,Dynamic>::Random(a.rows(),diagSize) * d.asDiagonal() * Matrix<Scalar,Dynamic,Dynamic>::Random(diagSize,a.cols());+ // cancel some coeffs+ Index n = internal::random<Index>(0,m.size()-1);+ for(Index i=0; i<n; ++i)+ m(internal::random<Index>(0,m.rows()-1), internal::random<Index>(0,m.cols()-1)) = Scalar(0);+ }++ CALL_SUBTEST(( jacobisvd_test_all_computation_options<MatrixType, FullPivHouseholderQRPreconditioner>(m) ));+ CALL_SUBTEST(( jacobisvd_test_all_computation_options<MatrixType, ColPivHouseholderQRPreconditioner>(m) ));+ CALL_SUBTEST(( jacobisvd_test_all_computation_options<MatrixType, HouseholderQRPreconditioner>(m) ));+ CALL_SUBTEST(( jacobisvd_test_all_computation_options<MatrixType, NoQRPreconditioner>(m) ));+}++template<typename MatrixType> void jacobisvd_verify_assert(const MatrixType& m)+{+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::Index Index;+ Index rows = m.rows();+ Index cols = m.cols();++ enum {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,+ ColsAtCompileTime = MatrixType::ColsAtCompileTime+ };++ typedef Matrix<Scalar, RowsAtCompileTime, 1> RhsType;++ RhsType rhs(rows);++ JacobiSVD<MatrixType> svd;+ VERIFY_RAISES_ASSERT(svd.matrixU())+ VERIFY_RAISES_ASSERT(svd.singularValues())+ VERIFY_RAISES_ASSERT(svd.matrixV())+ VERIFY_RAISES_ASSERT(svd.solve(rhs))++ MatrixType a = MatrixType::Zero(rows, cols);+ a.setZero();+ svd.compute(a, 0);+ VERIFY_RAISES_ASSERT(svd.matrixU())+ VERIFY_RAISES_ASSERT(svd.matrixV())+ svd.singularValues();+ VERIFY_RAISES_ASSERT(svd.solve(rhs))++ if (ColsAtCompileTime == Dynamic)+ {+ svd.compute(a, ComputeThinU);+ svd.matrixU();+ VERIFY_RAISES_ASSERT(svd.matrixV())+ VERIFY_RAISES_ASSERT(svd.solve(rhs))++ svd.compute(a, ComputeThinV);+ svd.matrixV();+ VERIFY_RAISES_ASSERT(svd.matrixU())+ VERIFY_RAISES_ASSERT(svd.solve(rhs))++ JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner> svd_fullqr;+ VERIFY_RAISES_ASSERT(svd_fullqr.compute(a, ComputeFullU|ComputeThinV))+ VERIFY_RAISES_ASSERT(svd_fullqr.compute(a, ComputeThinU|ComputeThinV))+ VERIFY_RAISES_ASSERT(svd_fullqr.compute(a, ComputeThinU|ComputeFullV))+ }+ else+ {+ VERIFY_RAISES_ASSERT(svd.compute(a, ComputeThinU))+ VERIFY_RAISES_ASSERT(svd.compute(a, ComputeThinV))+ }+}++template<typename MatrixType>+void jacobisvd_method()+{+ enum { Size = MatrixType::RowsAtCompileTime };+ typedef typename MatrixType::RealScalar RealScalar;+ typedef Matrix<RealScalar, Size, 1> RealVecType;+ MatrixType m = MatrixType::Identity();+ VERIFY_IS_APPROX(m.jacobiSvd().singularValues(), RealVecType::Ones());+ VERIFY_RAISES_ASSERT(m.jacobiSvd().matrixU());+ VERIFY_RAISES_ASSERT(m.jacobiSvd().matrixV());+ VERIFY_IS_APPROX(m.jacobiSvd(ComputeFullU|ComputeFullV).solve(m), m);+}++// work around stupid msvc error when constructing at compile time an expression that involves+// a division by zero, even if the numeric type has floating point+template<typename Scalar>+EIGEN_DONT_INLINE Scalar zero() { return Scalar(0); }++// workaround aggressive optimization in ICC+template<typename T> EIGEN_DONT_INLINE T sub(T a, T b) { return a - b; }++template<typename MatrixType>+void jacobisvd_inf_nan()+{+ // all this function does is verify we don't iterate infinitely on nan/inf values++ JacobiSVD<MatrixType> svd;+ typedef typename MatrixType::Scalar Scalar;+ Scalar some_inf = Scalar(1) / zero<Scalar>();+ VERIFY(sub(some_inf, some_inf) != sub(some_inf, some_inf));+ svd.compute(MatrixType::Constant(10,10,some_inf), ComputeFullU | ComputeFullV);++ Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();+ VERIFY(nan != nan);+ svd.compute(MatrixType::Constant(10,10,nan), ComputeFullU | ComputeFullV);++ MatrixType m = MatrixType::Zero(10,10);+ m(internal::random<int>(0,9), internal::random<int>(0,9)) = some_inf;+ svd.compute(m, ComputeFullU | ComputeFullV);++ m = MatrixType::Zero(10,10);+ m(internal::random<int>(0,9), internal::random<int>(0,9)) = nan;+ svd.compute(m, ComputeFullU | ComputeFullV);+ + // regression test for bug 791+ m.resize(3,3);+ m << 0, 2*NumTraits<Scalar>::epsilon(), 0.5,+ 0, -0.5, 0,+ nan, 0, 0;+ svd.compute(m, ComputeFullU | ComputeFullV);+}++// Regression test for bug 286: JacobiSVD loops indefinitely with some+// matrices containing denormal numbers.+void jacobisvd_bug286()+{+#if defined __INTEL_COMPILER+// shut up warning #239: floating point underflow+#pragma warning push+#pragma warning disable 239+#endif+ Matrix2d M;+ M << -7.90884e-313, -4.94e-324,+ 0, 5.60844e-313;+#if defined __INTEL_COMPILER+#pragma warning pop+#endif+ JacobiSVD<Matrix2d> svd;+ svd.compute(M); // just check we don't loop indefinitely+}++void jacobisvd_preallocate()+{+ Vector3f v(3.f, 2.f, 1.f);+ MatrixXf m = v.asDiagonal();++ internal::set_is_malloc_allowed(false);+ VERIFY_RAISES_ASSERT(VectorXf tmp(10);)+ JacobiSVD<MatrixXf> svd;+ internal::set_is_malloc_allowed(true);+ svd.compute(m);+ VERIFY_IS_APPROX(svd.singularValues(), v);++ JacobiSVD<MatrixXf> svd2(3,3);+ internal::set_is_malloc_allowed(false);+ svd2.compute(m);+ internal::set_is_malloc_allowed(true);+ VERIFY_IS_APPROX(svd2.singularValues(), v);+ VERIFY_RAISES_ASSERT(svd2.matrixU());+ VERIFY_RAISES_ASSERT(svd2.matrixV());+ svd2.compute(m, ComputeFullU | ComputeFullV);+ VERIFY_IS_APPROX(svd2.matrixU(), Matrix3f::Identity());+ VERIFY_IS_APPROX(svd2.matrixV(), Matrix3f::Identity());+ internal::set_is_malloc_allowed(false);+ svd2.compute(m);+ internal::set_is_malloc_allowed(true);++ JacobiSVD<MatrixXf> svd3(3,3,ComputeFullU|ComputeFullV);+ internal::set_is_malloc_allowed(false);+ svd2.compute(m);+ internal::set_is_malloc_allowed(true);+ VERIFY_IS_APPROX(svd2.singularValues(), v);+ VERIFY_IS_APPROX(svd2.matrixU(), Matrix3f::Identity());+ VERIFY_IS_APPROX(svd2.matrixV(), Matrix3f::Identity());+ internal::set_is_malloc_allowed(false);+ svd2.compute(m, ComputeFullU|ComputeFullV);+ internal::set_is_malloc_allowed(true);+}++void test_jacobisvd()+{+ CALL_SUBTEST_3(( jacobisvd_verify_assert(Matrix3f()) ));+ CALL_SUBTEST_4(( jacobisvd_verify_assert(Matrix4d()) ));+ CALL_SUBTEST_7(( jacobisvd_verify_assert(MatrixXf(10,12)) ));+ CALL_SUBTEST_8(( jacobisvd_verify_assert(MatrixXcd(7,5)) ));++ for(int i = 0; i < g_repeat; i++) {+ Matrix2cd m;+ m << 0, 1,+ 0, 1;+ CALL_SUBTEST_1(( jacobisvd(m, false) ));+ m << 1, 0,+ 1, 0;+ CALL_SUBTEST_1(( jacobisvd(m, false) ));++ Matrix2d n;+ n << 0, 0,+ 0, 0;+ CALL_SUBTEST_2(( jacobisvd(n, false) ));+ n << 0, 0,+ 0, 1;+ CALL_SUBTEST_2(( jacobisvd(n, false) ));+ + CALL_SUBTEST_3(( jacobisvd<Matrix3f>() ));+ CALL_SUBTEST_4(( jacobisvd<Matrix4d>() ));+ CALL_SUBTEST_5(( jacobisvd<Matrix<float,3,5> >() ));+ CALL_SUBTEST_6(( jacobisvd<Matrix<double,Dynamic,2> >(Matrix<double,Dynamic,2>(10,2)) ));++ int r = internal::random<int>(1, 30),+ c = internal::random<int>(1, 30);+ + TEST_SET_BUT_UNUSED_VARIABLE(r)+ TEST_SET_BUT_UNUSED_VARIABLE(c)+ + CALL_SUBTEST_10(( jacobisvd<MatrixXd>(MatrixXd(r,c)) ));+ CALL_SUBTEST_7(( jacobisvd<MatrixXf>(MatrixXf(r,c)) ));+ CALL_SUBTEST_8(( jacobisvd<MatrixXcd>(MatrixXcd(r,c)) ));+ (void) r;+ (void) c;++ // Test on inf/nan matrix+ CALL_SUBTEST_7( jacobisvd_inf_nan<MatrixXf>() );+ CALL_SUBTEST_10( jacobisvd_inf_nan<MatrixXd>() );+ }++ CALL_SUBTEST_7(( jacobisvd<MatrixXf>(MatrixXf(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2))) ));+ CALL_SUBTEST_8(( jacobisvd<MatrixXcd>(MatrixXcd(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/3), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/3))) ));++ // test matrixbase method+ CALL_SUBTEST_1(( jacobisvd_method<Matrix2cd>() ));+ CALL_SUBTEST_3(( jacobisvd_method<Matrix3f>() ));++ // Test problem size constructors+ CALL_SUBTEST_7( JacobiSVD<MatrixXf>(10,10) );++ // Check that preallocation avoids subsequent mallocs+ CALL_SUBTEST_9( jacobisvd_preallocate() );++ // Regression check for bug 286+ CALL_SUBTEST_2( jacobisvd_bug286() );+}
+ eigen3/test/linearstructure.cpp view
@@ -0,0 +1,84 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void linearStructure(const MatrixType& m)+{+ using std::abs;+ /* this test covers the following files:+ CwiseUnaryOp.h, CwiseBinaryOp.h, SelfCwiseBinaryOp.h + */+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;++ Index rows = m.rows();+ Index cols = m.cols();++ // this test relies a lot on Random.h, and there's not much more that we can do+ // to test it, hence I consider that we will have tested Random.h+ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols);++ Scalar s1 = internal::random<Scalar>();+ while (abs(s1)<1e-3) s1 = internal::random<Scalar>();++ Index r = internal::random<Index>(0, rows-1),+ c = internal::random<Index>(0, cols-1);++ VERIFY_IS_APPROX(-(-m1), m1);+ VERIFY_IS_APPROX(m1+m1, 2*m1);+ VERIFY_IS_APPROX(m1+m2-m1, m2);+ VERIFY_IS_APPROX(-m2+m1+m2, m1);+ VERIFY_IS_APPROX(m1*s1, s1*m1);+ VERIFY_IS_APPROX((m1+m2)*s1, s1*m1+s1*m2);+ VERIFY_IS_APPROX((-m1+m2)*s1, -s1*m1+s1*m2);+ m3 = m2; m3 += m1;+ VERIFY_IS_APPROX(m3, m1+m2);+ m3 = m2; m3 -= m1;+ VERIFY_IS_APPROX(m3, m2-m1);+ m3 = m2; m3 *= s1;+ VERIFY_IS_APPROX(m3, s1*m2);+ if(!NumTraits<Scalar>::IsInteger)+ {+ m3 = m2; m3 /= s1;+ VERIFY_IS_APPROX(m3, m2/s1);+ }++ // again, test operator() to check const-qualification+ VERIFY_IS_APPROX((-m1)(r,c), -(m1(r,c)));+ VERIFY_IS_APPROX((m1-m2)(r,c), (m1(r,c))-(m2(r,c)));+ VERIFY_IS_APPROX((m1+m2)(r,c), (m1(r,c))+(m2(r,c)));+ VERIFY_IS_APPROX((s1*m1)(r,c), s1*(m1(r,c)));+ VERIFY_IS_APPROX((m1*s1)(r,c), (m1(r,c))*s1);+ if(!NumTraits<Scalar>::IsInteger)+ VERIFY_IS_APPROX((m1/s1)(r,c), (m1(r,c))/s1);++ // use .block to disable vectorization and compare to the vectorized version+ VERIFY_IS_APPROX(m1+m1.block(0,0,rows,cols), m1+m1);+ VERIFY_IS_APPROX(m1.cwiseProduct(m1.block(0,0,rows,cols)), m1.cwiseProduct(m1));+ VERIFY_IS_APPROX(m1 - m1.block(0,0,rows,cols), m1 - m1);+ VERIFY_IS_APPROX(m1.block(0,0,rows,cols) * s1, m1 * s1);+}++void test_linearstructure()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( linearStructure(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( linearStructure(Matrix2f()) );+ CALL_SUBTEST_3( linearStructure(Vector3d()) );+ CALL_SUBTEST_4( linearStructure(Matrix4d()) );+ CALL_SUBTEST_5( linearStructure(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );+ CALL_SUBTEST_6( linearStructure(MatrixXf (internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_7( linearStructure(MatrixXi (internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_8( linearStructure(MatrixXcd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );+ CALL_SUBTEST_9( linearStructure(ArrayXXf (internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ }+}
+ eigen3/test/lu.cpp view
@@ -0,0 +1,210 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/LU>+using namespace std;++template<typename MatrixType> void lu_non_invertible()+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::RealScalar RealScalar;+ /* this test covers the following files:+ LU.h+ */+ Index rows, cols, cols2;+ if(MatrixType::RowsAtCompileTime==Dynamic)+ {+ rows = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE);+ }+ else+ {+ rows = MatrixType::RowsAtCompileTime;+ }+ if(MatrixType::ColsAtCompileTime==Dynamic)+ {+ cols = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE);+ cols2 = internal::random<int>(2,EIGEN_TEST_MAX_SIZE);+ }+ else+ {+ cols2 = cols = MatrixType::ColsAtCompileTime;+ }++ enum {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,+ ColsAtCompileTime = MatrixType::ColsAtCompileTime+ };+ typedef typename internal::kernel_retval_base<FullPivLU<MatrixType> >::ReturnType KernelMatrixType;+ typedef typename internal::image_retval_base<FullPivLU<MatrixType> >::ReturnType ImageMatrixType;+ typedef Matrix<typename MatrixType::Scalar, ColsAtCompileTime, ColsAtCompileTime>+ CMatrixType;+ typedef Matrix<typename MatrixType::Scalar, RowsAtCompileTime, RowsAtCompileTime>+ RMatrixType;++ Index rank = internal::random<Index>(1, (std::min)(rows, cols)-1);++ // The image of the zero matrix should consist of a single (zero) column vector+ VERIFY((MatrixType::Zero(rows,cols).fullPivLu().image(MatrixType::Zero(rows,cols)).cols() == 1));++ MatrixType m1(rows, cols), m3(rows, cols2);+ CMatrixType m2(cols, cols2);+ createRandomPIMatrixOfRank(rank, rows, cols, m1);++ FullPivLU<MatrixType> lu;++ // The special value 0.01 below works well in tests. Keep in mind that we're only computing the rank+ // of singular values are either 0 or 1.+ // So it's not clear at all that the epsilon should play any role there.+ lu.setThreshold(RealScalar(0.01));+ lu.compute(m1);++ MatrixType u(rows,cols);+ u = lu.matrixLU().template triangularView<Upper>();+ RMatrixType l = RMatrixType::Identity(rows,rows);+ l.block(0,0,rows,(std::min)(rows,cols)).template triangularView<StrictlyLower>()+ = lu.matrixLU().block(0,0,rows,(std::min)(rows,cols));++ VERIFY_IS_APPROX(lu.permutationP() * m1 * lu.permutationQ(), l*u);++ KernelMatrixType m1kernel = lu.kernel();+ ImageMatrixType m1image = lu.image(m1);++ VERIFY_IS_APPROX(m1, lu.reconstructedMatrix());+ VERIFY(rank == lu.rank());+ VERIFY(cols - lu.rank() == lu.dimensionOfKernel());+ VERIFY(!lu.isInjective());+ VERIFY(!lu.isInvertible());+ VERIFY(!lu.isSurjective());+ VERIFY((m1 * m1kernel).isMuchSmallerThan(m1));+ VERIFY(m1image.fullPivLu().rank() == rank);+ VERIFY_IS_APPROX(m1 * m1.adjoint() * m1image, m1image);++ m2 = CMatrixType::Random(cols,cols2);+ m3 = m1*m2;+ m2 = CMatrixType::Random(cols,cols2);+ // test that the code, which does resize(), may be applied to an xpr+ m2.block(0,0,m2.rows(),m2.cols()) = lu.solve(m3);+ VERIFY_IS_APPROX(m3, m1*m2);+}++template<typename MatrixType> void lu_invertible()+{+ /* this test covers the following files:+ LU.h+ */+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;+ DenseIndex size = MatrixType::RowsAtCompileTime;+ if( size==Dynamic)+ size = internal::random<DenseIndex>(1,EIGEN_TEST_MAX_SIZE);++ MatrixType m1(size, size), m2(size, size), m3(size, size);+ FullPivLU<MatrixType> lu;+ lu.setThreshold(RealScalar(0.01));+ do {+ m1 = MatrixType::Random(size,size);+ lu.compute(m1);+ } while(!lu.isInvertible());++ VERIFY_IS_APPROX(m1, lu.reconstructedMatrix());+ VERIFY(0 == lu.dimensionOfKernel());+ VERIFY(lu.kernel().cols() == 1); // the kernel() should consist of a single (zero) column vector+ VERIFY(size == lu.rank());+ VERIFY(lu.isInjective());+ VERIFY(lu.isSurjective());+ VERIFY(lu.isInvertible());+ VERIFY(lu.image(m1).fullPivLu().isInvertible());+ m3 = MatrixType::Random(size,size);+ m2 = lu.solve(m3);+ VERIFY_IS_APPROX(m3, m1*m2);+ VERIFY_IS_APPROX(m2, lu.inverse()*m3);++ // Regression test for Bug 302+ MatrixType m4 = MatrixType::Random(size,size);+ VERIFY_IS_APPROX(lu.solve(m3*m4), lu.solve(m3)*m4);+}++template<typename MatrixType> void lu_partial_piv()+{+ /* this test covers the following files:+ PartialPivLU.h+ */+ typedef typename MatrixType::Index Index;+ Index rows = internal::random<Index>(1,4);+ Index cols = rows;++ MatrixType m1(cols, rows);+ m1.setRandom();+ PartialPivLU<MatrixType> plu(m1);++ VERIFY_IS_APPROX(m1, plu.reconstructedMatrix());+}++template<typename MatrixType> void lu_verify_assert()+{+ MatrixType tmp;++ FullPivLU<MatrixType> lu;+ VERIFY_RAISES_ASSERT(lu.matrixLU())+ VERIFY_RAISES_ASSERT(lu.permutationP())+ VERIFY_RAISES_ASSERT(lu.permutationQ())+ VERIFY_RAISES_ASSERT(lu.kernel())+ VERIFY_RAISES_ASSERT(lu.image(tmp))+ VERIFY_RAISES_ASSERT(lu.solve(tmp))+ VERIFY_RAISES_ASSERT(lu.determinant())+ VERIFY_RAISES_ASSERT(lu.rank())+ VERIFY_RAISES_ASSERT(lu.dimensionOfKernel())+ VERIFY_RAISES_ASSERT(lu.isInjective())+ VERIFY_RAISES_ASSERT(lu.isSurjective())+ VERIFY_RAISES_ASSERT(lu.isInvertible())+ VERIFY_RAISES_ASSERT(lu.inverse())++ PartialPivLU<MatrixType> plu;+ VERIFY_RAISES_ASSERT(plu.matrixLU())+ VERIFY_RAISES_ASSERT(plu.permutationP())+ VERIFY_RAISES_ASSERT(plu.solve(tmp))+ VERIFY_RAISES_ASSERT(plu.determinant())+ VERIFY_RAISES_ASSERT(plu.inverse())+}++void test_lu()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( lu_non_invertible<Matrix3f>() );+ CALL_SUBTEST_1( lu_invertible<Matrix3f>() );+ CALL_SUBTEST_1( lu_verify_assert<Matrix3f>() );++ CALL_SUBTEST_2( (lu_non_invertible<Matrix<double, 4, 6> >()) );+ CALL_SUBTEST_2( (lu_verify_assert<Matrix<double, 4, 6> >()) );++ CALL_SUBTEST_3( lu_non_invertible<MatrixXf>() );+ CALL_SUBTEST_3( lu_invertible<MatrixXf>() );+ CALL_SUBTEST_3( lu_verify_assert<MatrixXf>() );++ CALL_SUBTEST_4( lu_non_invertible<MatrixXd>() );+ CALL_SUBTEST_4( lu_invertible<MatrixXd>() );+ CALL_SUBTEST_4( lu_partial_piv<MatrixXd>() );+ CALL_SUBTEST_4( lu_verify_assert<MatrixXd>() );++ CALL_SUBTEST_5( lu_non_invertible<MatrixXcf>() );+ CALL_SUBTEST_5( lu_invertible<MatrixXcf>() );+ CALL_SUBTEST_5( lu_verify_assert<MatrixXcf>() );++ CALL_SUBTEST_6( lu_non_invertible<MatrixXcd>() );+ CALL_SUBTEST_6( lu_invertible<MatrixXcd>() );+ CALL_SUBTEST_6( lu_partial_piv<MatrixXcd>() );+ CALL_SUBTEST_6( lu_verify_assert<MatrixXcd>() );++ CALL_SUBTEST_7(( lu_non_invertible<Matrix<float,Dynamic,16> >() ));++ // Test problem size constructors+ CALL_SUBTEST_9( PartialPivLU<MatrixXf>(10) );+ CALL_SUBTEST_9( FullPivLU<MatrixXf>(10, 20); );+ }+}
+ eigen3/test/main.h view
@@ -0,0 +1,552 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include <cstdlib>+#include <cerrno>+#include <ctime>+#include <iostream>+#include <fstream>+#include <string>+#include <sstream>+#include <vector>+#include <typeinfo>++// The following includes of STL headers have to be done _before_ the+// definition of macros min() and max(). The reason is that many STL+// implementations will not work properly as the min and max symbols collide+// with the STL functions std:min() and std::max(). The STL headers may check+// for the macro definition of min/max and issue a warning or undefine the+// macros.+//+// Still, Windows defines min() and max() in windef.h as part of the regular+// Windows system interfaces and many other Windows APIs depend on these+// macros being available. To prevent the macro expansion of min/max and to+// make Eigen compatible with the Windows environment all function calls of+// std::min() and std::max() have to be written with parenthesis around the+// function name.+//+// All STL headers used by Eigen should be included here. Because main.h is+// included before any Eigen header and because the STL headers are guarded+// against multiple inclusions, no STL header will see our own min/max macro+// definitions.+#include <limits>+#include <algorithm>+#include <complex>+#include <deque>+#include <queue>+#include <list>++// To test that all calls from Eigen code to std::min() and std::max() are+// protected by parenthesis against macro expansion, the min()/max() macros+// are defined here and any not-parenthesized min/max call will cause a+// compiler error.+#define min(A,B) please_protect_your_min_with_parentheses+#define max(A,B) please_protect_your_max_with_parentheses++#define FORBIDDEN_IDENTIFIER (this_identifier_is_forbidden_to_avoid_clashes) this_identifier_is_forbidden_to_avoid_clashes+// B0 is defined in POSIX header termios.h+#define B0 FORBIDDEN_IDENTIFIER+++// shuts down ICC's remark #593: variable "XXX" was set but never used+#define TEST_SET_BUT_UNUSED_VARIABLE(X) X = X + 0;++// the following file is automatically generated by cmake+#include "split_test_helper.h"++#ifdef NDEBUG+#undef NDEBUG+#endif++// On windows CE, NDEBUG is automatically defined <assert.h> if NDEBUG is not defined.+#ifndef DEBUG+#define DEBUG+#endif++// bounds integer values for AltiVec+#ifdef __ALTIVEC__+#define EIGEN_MAKING_DOCS+#endif++#ifndef EIGEN_TEST_FUNC+#error EIGEN_TEST_FUNC must be defined+#endif++#define DEFAULT_REPEAT 10++namespace Eigen+{+ static std::vector<std::string> g_test_stack;+ static int g_repeat;+ static unsigned int g_seed;+ static bool g_has_set_repeat, g_has_set_seed;+}++#define EI_PP_MAKE_STRING2(S) #S+#define EI_PP_MAKE_STRING(S) EI_PP_MAKE_STRING2(S)++#define EIGEN_DEFAULT_IO_FORMAT IOFormat(4, 0, " ", "\n", "", "", "", "")++#ifndef EIGEN_NO_ASSERTION_CHECKING++ namespace Eigen+ {+ static const bool should_raise_an_assert = false;++ // Used to avoid to raise two exceptions at a time in which+ // case the exception is not properly caught.+ // This may happen when a second exceptions is triggered in a destructor.+ static bool no_more_assert = false;+ static bool report_on_cerr_on_assert_failure = true;++ struct eigen_assert_exception+ {+ eigen_assert_exception(void) {}+ ~eigen_assert_exception() { Eigen::no_more_assert = false; }+ };+ }+ // If EIGEN_DEBUG_ASSERTS is defined and if no assertion is triggered while+ // one should have been, then the list of excecuted assertions is printed out.+ //+ // EIGEN_DEBUG_ASSERTS is not enabled by default as it+ // significantly increases the compilation time+ // and might even introduce side effects that would hide+ // some memory errors.+ #ifdef EIGEN_DEBUG_ASSERTS++ namespace Eigen+ {+ namespace internal+ {+ static bool push_assert = false;+ }+ static std::vector<std::string> eigen_assert_list;+ }+ #define eigen_assert(a) \+ if( (!(a)) && (!no_more_assert) ) \+ { \+ if(report_on_cerr_on_assert_failure) \+ std::cerr << #a << " " __FILE__ << "(" << __LINE__ << ")\n"; \+ Eigen::no_more_assert = true; \+ throw Eigen::eigen_assert_exception(); \+ } \+ else if (Eigen::internal::push_assert) \+ { \+ eigen_assert_list.push_back(std::string(EI_PP_MAKE_STRING(__FILE__) " (" EI_PP_MAKE_STRING(__LINE__) ") : " #a) ); \+ }++ #define VERIFY_RAISES_ASSERT(a) \+ { \+ Eigen::no_more_assert = false; \+ Eigen::eigen_assert_list.clear(); \+ Eigen::internal::push_assert = true; \+ Eigen::report_on_cerr_on_assert_failure = false; \+ try { \+ a; \+ std::cerr << "One of the following asserts should have been triggered:\n"; \+ for (uint ai=0 ; ai<eigen_assert_list.size() ; ++ai) \+ std::cerr << " " << eigen_assert_list[ai] << "\n"; \+ VERIFY(Eigen::should_raise_an_assert && # a); \+ } catch (Eigen::eigen_assert_exception) { \+ Eigen::internal::push_assert = false; VERIFY(true); \+ } \+ Eigen::report_on_cerr_on_assert_failure = true; \+ Eigen::internal::push_assert = false; \+ }++ #else // EIGEN_DEBUG_ASSERTS+ // see bug 89. The copy_bool here is working around a bug in gcc <= 4.3+ #define eigen_assert(a) \+ if( (!Eigen::internal::copy_bool(a)) && (!no_more_assert) )\+ { \+ Eigen::no_more_assert = true; \+ if(report_on_cerr_on_assert_failure) \+ eigen_plain_assert(a); \+ else \+ throw Eigen::eigen_assert_exception(); \+ }+ #define VERIFY_RAISES_ASSERT(a) { \+ Eigen::no_more_assert = false; \+ Eigen::report_on_cerr_on_assert_failure = false; \+ try { \+ a; \+ VERIFY(Eigen::should_raise_an_assert && # a); \+ } \+ catch (Eigen::eigen_assert_exception&) { VERIFY(true); } \+ Eigen::report_on_cerr_on_assert_failure = true; \+ }++ #endif // EIGEN_DEBUG_ASSERTS++ #define EIGEN_USE_CUSTOM_ASSERT++#else // EIGEN_NO_ASSERTION_CHECKING++ #define VERIFY_RAISES_ASSERT(a) {}++#endif // EIGEN_NO_ASSERTION_CHECKING+++#define EIGEN_INTERNAL_DEBUGGING+#include <Eigen/QR> // required for createRandomPIMatrixOfRank++inline void verify_impl(bool condition, const char *testname, const char *file, int line, const char *condition_as_string)+{+ if (!condition)+ {+ std::cerr << "Test " << testname << " failed in " << file << " (" << line << ")"+ << std::endl << " " << condition_as_string << std::endl;+ std::cerr << "Stack:\n";+ const int test_stack_size = static_cast<int>(Eigen::g_test_stack.size());+ for(int i=test_stack_size-1; i>=0; --i)+ std::cerr << " - " << Eigen::g_test_stack[i] << "\n";+ std::cerr << "\n";+ abort();+ }+}++#define VERIFY(a) ::verify_impl(a, g_test_stack.back().c_str(), __FILE__, __LINE__, EI_PP_MAKE_STRING(a))++#define VERIFY_IS_EQUAL(a, b) VERIFY(test_is_equal(a, b))+#define VERIFY_IS_APPROX(a, b) VERIFY(test_isApprox(a, b))+#define VERIFY_IS_NOT_APPROX(a, b) VERIFY(!test_isApprox(a, b))+#define VERIFY_IS_MUCH_SMALLER_THAN(a, b) VERIFY(test_isMuchSmallerThan(a, b))+#define VERIFY_IS_NOT_MUCH_SMALLER_THAN(a, b) VERIFY(!test_isMuchSmallerThan(a, b))+#define VERIFY_IS_APPROX_OR_LESS_THAN(a, b) VERIFY(test_isApproxOrLessThan(a, b))+#define VERIFY_IS_NOT_APPROX_OR_LESS_THAN(a, b) VERIFY(!test_isApproxOrLessThan(a, b))++#define VERIFY_IS_UNITARY(a) VERIFY(test_isUnitary(a))++#define CALL_SUBTEST(FUNC) do { \+ g_test_stack.push_back(EI_PP_MAKE_STRING(FUNC)); \+ FUNC; \+ g_test_stack.pop_back(); \+ } while (0)+++namespace Eigen {++template<typename T> inline typename NumTraits<T>::Real test_precision() { return NumTraits<T>::dummy_precision(); }+template<> inline float test_precision<float>() { return 1e-3f; }+template<> inline double test_precision<double>() { return 1e-6; }+template<> inline float test_precision<std::complex<float> >() { return test_precision<float>(); }+template<> inline double test_precision<std::complex<double> >() { return test_precision<double>(); }+template<> inline long double test_precision<long double>() { return 1e-6; }++inline bool test_isApprox(const int& a, const int& b)+{ return internal::isApprox(a, b, test_precision<int>()); }+inline bool test_isMuchSmallerThan(const int& a, const int& b)+{ return internal::isMuchSmallerThan(a, b, test_precision<int>()); }+inline bool test_isApproxOrLessThan(const int& a, const int& b)+{ return internal::isApproxOrLessThan(a, b, test_precision<int>()); }++inline bool test_isApprox(const float& a, const float& b)+{ return internal::isApprox(a, b, test_precision<float>()); }+inline bool test_isMuchSmallerThan(const float& a, const float& b)+{ return internal::isMuchSmallerThan(a, b, test_precision<float>()); }+inline bool test_isApproxOrLessThan(const float& a, const float& b)+{ return internal::isApproxOrLessThan(a, b, test_precision<float>()); }+inline bool test_isApprox(const double& a, const double& b)+{ return internal::isApprox(a, b, test_precision<double>()); }++inline bool test_isMuchSmallerThan(const double& a, const double& b)+{ return internal::isMuchSmallerThan(a, b, test_precision<double>()); }+inline bool test_isApproxOrLessThan(const double& a, const double& b)+{ return internal::isApproxOrLessThan(a, b, test_precision<double>()); }++inline bool test_isApprox(const std::complex<float>& a, const std::complex<float>& b)+{ return internal::isApprox(a, b, test_precision<std::complex<float> >()); }+inline bool test_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b)+{ return internal::isMuchSmallerThan(a, b, test_precision<std::complex<float> >()); }++inline bool test_isApprox(const std::complex<double>& a, const std::complex<double>& b)+{ return internal::isApprox(a, b, test_precision<std::complex<double> >()); }+inline bool test_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b)+{ return internal::isMuchSmallerThan(a, b, test_precision<std::complex<double> >()); }++inline bool test_isApprox(const long double& a, const long double& b)+{+ bool ret = internal::isApprox(a, b, test_precision<long double>());+ if (!ret) std::cerr+ << std::endl << " actual = " << a+ << std::endl << " expected = " << b << std::endl << std::endl;+ return ret;+}++inline bool test_isMuchSmallerThan(const long double& a, const long double& b)+{ return internal::isMuchSmallerThan(a, b, test_precision<long double>()); }+inline bool test_isApproxOrLessThan(const long double& a, const long double& b)+{ return internal::isApproxOrLessThan(a, b, test_precision<long double>()); }++template<typename Type1, typename Type2>+inline bool test_isApprox(const Type1& a, const Type2& b)+{+ return a.isApprox(b, test_precision<typename Type1::Scalar>());+}++// The idea behind this function is to compare the two scalars a and b where+// the scalar ref is a hint about the expected order of magnitude of a and b.+// WARNING: the scalar a and b must be positive+// Therefore, if for some reason a and b are very small compared to ref,+// we won't issue a false negative.+// This test could be: abs(a-b) <= eps * ref+// However, it seems that simply comparing a+ref and b+ref is more sensitive to true error.+template<typename Scalar,typename ScalarRef>+inline bool test_isApproxWithRef(const Scalar& a, const Scalar& b, const ScalarRef& ref)+{+ return test_isApprox(a+ref, b+ref);+}++template<typename Derived1, typename Derived2>+inline bool test_isMuchSmallerThan(const MatrixBase<Derived1>& m1,+ const MatrixBase<Derived2>& m2)+{+ return m1.isMuchSmallerThan(m2, test_precision<typename internal::traits<Derived1>::Scalar>());+}++template<typename Derived>+inline bool test_isMuchSmallerThan(const MatrixBase<Derived>& m,+ const typename NumTraits<typename internal::traits<Derived>::Scalar>::Real& s)+{+ return m.isMuchSmallerThan(s, test_precision<typename internal::traits<Derived>::Scalar>());+}++template<typename Derived>+inline bool test_isUnitary(const MatrixBase<Derived>& m)+{+ return m.isUnitary(test_precision<typename internal::traits<Derived>::Scalar>());+}++// Forward declaration to avoid ICC warning+template<typename T, typename U>+bool test_is_equal(const T& actual, const U& expected);++template<typename T, typename U>+bool test_is_equal(const T& actual, const U& expected)+{+ if (actual==expected)+ return true;+ // false:+ std::cerr+ << std::endl << " actual = " << actual+ << std::endl << " expected = " << expected << std::endl << std::endl;+ return false;+}++/** Creates a random Partial Isometry matrix of given rank.+ *+ * A partial isometry is a matrix all of whose singular values are either 0 or 1.+ * This is very useful to test rank-revealing algorithms.+ */+// Forward declaration to avoid ICC warning+template<typename MatrixType>+void createRandomPIMatrixOfRank(typename MatrixType::Index desired_rank, typename MatrixType::Index rows, typename MatrixType::Index cols, MatrixType& m);+template<typename MatrixType>+void createRandomPIMatrixOfRank(typename MatrixType::Index desired_rank, typename MatrixType::Index rows, typename MatrixType::Index cols, MatrixType& m)+{+ typedef typename internal::traits<MatrixType>::Index Index;+ typedef typename internal::traits<MatrixType>::Scalar Scalar;+ enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };++ typedef Matrix<Scalar, Dynamic, 1> VectorType;+ typedef Matrix<Scalar, Rows, Rows> MatrixAType;+ typedef Matrix<Scalar, Cols, Cols> MatrixBType;++ if(desired_rank == 0)+ {+ m.setZero(rows,cols);+ return;+ }++ if(desired_rank == 1)+ {+ // here we normalize the vectors to get a partial isometry+ m = VectorType::Random(rows).normalized() * VectorType::Random(cols).normalized().transpose();+ return;+ }++ MatrixAType a = MatrixAType::Random(rows,rows);+ MatrixType d = MatrixType::Identity(rows,cols);+ MatrixBType b = MatrixBType::Random(cols,cols);++ // set the diagonal such that only desired_rank non-zero entries reamain+ const Index diag_size = (std::min)(d.rows(),d.cols());+ if(diag_size != desired_rank)+ d.diagonal().segment(desired_rank, diag_size-desired_rank) = VectorType::Zero(diag_size-desired_rank);++ HouseholderQR<MatrixAType> qra(a);+ HouseholderQR<MatrixBType> qrb(b);+ m = qra.householderQ() * d * qrb.householderQ();+}++// Forward declaration to avoid ICC warning+template<typename PermutationVectorType>+void randomPermutationVector(PermutationVectorType& v, typename PermutationVectorType::Index size);+template<typename PermutationVectorType>+void randomPermutationVector(PermutationVectorType& v, typename PermutationVectorType::Index size)+{+ typedef typename PermutationVectorType::Index Index;+ typedef typename PermutationVectorType::Scalar Scalar;+ v.resize(size);+ for(Index i = 0; i < size; ++i) v(i) = Scalar(i);+ if(size == 1) return;+ for(Index n = 0; n < 3 * size; ++n)+ {+ Index i = internal::random<Index>(0, size-1);+ Index j;+ do j = internal::random<Index>(0, size-1); while(j==i);+ std::swap(v(i), v(j));+ }+}++template<typename T> bool isNotNaN(const T& x)+{+ return x==x;+}++template<typename T> bool isNaN(const T& x)+{+ return x!=x;+}++template<typename T> bool isInf(const T& x)+{+ return x > NumTraits<T>::highest();+}++template<typename T> bool isMinusInf(const T& x)+{+ return x < NumTraits<T>::lowest();+}++} // end namespace Eigen++template<typename T> struct GetDifferentType;++template<> struct GetDifferentType<float> { typedef double type; };+template<> struct GetDifferentType<double> { typedef float type; };+template<typename T> struct GetDifferentType<std::complex<T> >+{ typedef std::complex<typename GetDifferentType<T>::type> type; };++// Forward declaration to avoid ICC warning+template<typename T> std::string type_name();+template<typename T> std::string type_name() { return "other"; }+template<> std::string type_name<float>() { return "float"; }+template<> std::string type_name<double>() { return "double"; }+template<> std::string type_name<int>() { return "int"; }+template<> std::string type_name<std::complex<float> >() { return "complex<float>"; }+template<> std::string type_name<std::complex<double> >() { return "complex<double>"; }+template<> std::string type_name<std::complex<int> >() { return "complex<int>"; }++// forward declaration of the main test function+void EIGEN_CAT(test_,EIGEN_TEST_FUNC)();++using namespace Eigen;++inline void set_repeat_from_string(const char *str)+{+ errno = 0;+ g_repeat = int(strtoul(str, 0, 10));+ if(errno || g_repeat <= 0)+ {+ std::cout << "Invalid repeat value " << str << std::endl;+ exit(EXIT_FAILURE);+ }+ g_has_set_repeat = true;+}++inline void set_seed_from_string(const char *str)+{+ errno = 0;+ g_seed = int(strtoul(str, 0, 10));+ if(errno || g_seed == 0)+ {+ std::cout << "Invalid seed value " << str << std::endl;+ exit(EXIT_FAILURE);+ }+ g_has_set_seed = true;+}++int main(int argc, char *argv[])+{+ g_has_set_repeat = false;+ g_has_set_seed = false;+ bool need_help = false;++ for(int i = 1; i < argc; i++)+ {+ if(argv[i][0] == 'r')+ {+ if(g_has_set_repeat)+ {+ std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;+ return 1;+ }+ set_repeat_from_string(argv[i]+1);+ }+ else if(argv[i][0] == 's')+ {+ if(g_has_set_seed)+ {+ std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;+ return 1;+ }+ set_seed_from_string(argv[i]+1);+ }+ else+ {+ need_help = true;+ }+ }++ if(need_help)+ {+ std::cout << "This test application takes the following optional arguments:" << std::endl;+ std::cout << " rN Repeat each test N times (default: " << DEFAULT_REPEAT << ")" << std::endl;+ std::cout << " sN Use N as seed for random numbers (default: based on current time)" << std::endl;+ std::cout << std::endl;+ std::cout << "If defined, the environment variables EIGEN_REPEAT and EIGEN_SEED" << std::endl;+ std::cout << "will be used as default values for these parameters." << std::endl;+ return 1;+ }++ char *env_EIGEN_REPEAT = getenv("EIGEN_REPEAT");+ if(!g_has_set_repeat && env_EIGEN_REPEAT)+ set_repeat_from_string(env_EIGEN_REPEAT);+ char *env_EIGEN_SEED = getenv("EIGEN_SEED");+ if(!g_has_set_seed && env_EIGEN_SEED)+ set_seed_from_string(env_EIGEN_SEED);++ if(!g_has_set_seed) g_seed = (unsigned int) time(NULL);+ if(!g_has_set_repeat) g_repeat = DEFAULT_REPEAT;++ std::cout << "Initializing random number generator with seed " << g_seed << std::endl;+ std::stringstream ss;+ ss << "Seed: " << g_seed;+ g_test_stack.push_back(ss.str());+ srand(g_seed);+ std::cout << "Repeating each test " << g_repeat << " times" << std::endl;++ Eigen::g_test_stack.push_back(std::string(EI_PP_MAKE_STRING(EIGEN_TEST_FUNC)));++ EIGEN_CAT(test_,EIGEN_TEST_FUNC)();+ return 0;+}++// These warning are disabled here such that they are still ON when parsing Eigen's header files.+#if defined __INTEL_COMPILER+ // remark #383: value copied to temporary, reference to temporary used+ // -> this warning is raised even for legal usage as: g_test_stack.push_back("foo"); where g_test_stack is a std::vector<std::string>+ // remark #1418: external function definition with no prior declaration+ // -> this warning is raised for all our test functions. Declaring them static would fix the issue.+ // warning #279: controlling expression is constant+ // remark #1572: floating-point equality and inequality comparisons are unreliable+ #pragma warning disable 279 383 1418 1572+#endif
+ eigen3/test/mapped_matrix.cpp view
@@ -0,0 +1,165 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_NO_STATIC_ASSERT+#define EIGEN_NO_STATIC_ASSERT // turn static asserts into runtime asserts in order to check them+#endif++#include "main.h"++template<typename VectorType> void map_class_vector(const VectorType& m)+{+ typedef typename VectorType::Index Index;+ typedef typename VectorType::Scalar Scalar;++ Index size = m.size();++ // test Map.h+ Scalar* array1 = internal::aligned_new<Scalar>(size);+ Scalar* array2 = internal::aligned_new<Scalar>(size);+ Scalar* array3 = new Scalar[size+1];+ Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;++ Map<VectorType, Aligned>(array1, size) = VectorType::Random(size);+ Map<VectorType, Aligned>(array2, size) = Map<VectorType,Aligned>(array1, size);+ Map<VectorType>(array3unaligned, size) = Map<VectorType>(array1, size);+ VectorType ma1 = Map<VectorType, Aligned>(array1, size);+ VectorType ma2 = Map<VectorType, Aligned>(array2, size);+ VectorType ma3 = Map<VectorType>(array3unaligned, size);+ VERIFY_IS_EQUAL(ma1, ma2);+ VERIFY_IS_EQUAL(ma1, ma3);+ #ifdef EIGEN_VECTORIZE+ if(internal::packet_traits<Scalar>::Vectorizable)+ VERIFY_RAISES_ASSERT((Map<VectorType,Aligned>(array3unaligned, size)))+ #endif++ internal::aligned_delete(array1, size);+ internal::aligned_delete(array2, size);+ delete[] array3;+}++template<typename MatrixType> void map_class_matrix(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;++ Index rows = m.rows(), cols = m.cols(), size = rows*cols;++ // test Map.h+ Scalar* array1 = internal::aligned_new<Scalar>(size);+ for(int i = 0; i < size; i++) array1[i] = Scalar(1);+ Scalar* array2 = internal::aligned_new<Scalar>(size);+ for(int i = 0; i < size; i++) array2[i] = Scalar(1);+ Scalar* array3 = new Scalar[size+1];+ for(int i = 0; i < size+1; i++) array3[i] = Scalar(1);+ Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;+ Map<MatrixType, Aligned>(array1, rows, cols) = MatrixType::Ones(rows,cols);+ Map<MatrixType>(array2, rows, cols) = Map<MatrixType>(array1, rows, cols);+ Map<MatrixType>(array3unaligned, rows, cols) = Map<MatrixType>(array1, rows, cols);+ MatrixType ma1 = Map<MatrixType>(array1, rows, cols);+ MatrixType ma2 = Map<MatrixType, Aligned>(array2, rows, cols);+ VERIFY_IS_EQUAL(ma1, ma2);+ MatrixType ma3 = Map<MatrixType>(array3unaligned, rows, cols);+ VERIFY_IS_EQUAL(ma1, ma3);++ internal::aligned_delete(array1, size);+ internal::aligned_delete(array2, size);+ delete[] array3;+}++template<typename VectorType> void map_static_methods(const VectorType& m)+{+ typedef typename VectorType::Index Index;+ typedef typename VectorType::Scalar Scalar;++ Index size = m.size();++ // test Map.h+ Scalar* array1 = internal::aligned_new<Scalar>(size);+ Scalar* array2 = internal::aligned_new<Scalar>(size);+ Scalar* array3 = new Scalar[size+1];+ Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;++ VectorType::MapAligned(array1, size) = VectorType::Random(size);+ VectorType::Map(array2, size) = VectorType::Map(array1, size);+ VectorType::Map(array3unaligned, size) = VectorType::Map(array1, size);+ VectorType ma1 = VectorType::Map(array1, size);+ VectorType ma2 = VectorType::MapAligned(array2, size);+ VectorType ma3 = VectorType::Map(array3unaligned, size);+ VERIFY_IS_EQUAL(ma1, ma2);+ VERIFY_IS_EQUAL(ma1, ma3);++ internal::aligned_delete(array1, size);+ internal::aligned_delete(array2, size);+ delete[] array3;+}++template<typename PlainObjectType> void check_const_correctness(const PlainObjectType&)+{+ // there's a lot that we can't test here while still having this test compile!+ // the only possible approach would be to run a script trying to compile stuff and checking that it fails.+ // CMake can help with that.++ // verify that map-to-const don't have LvalueBit+ typedef typename internal::add_const<PlainObjectType>::type ConstPlainObjectType;+ VERIFY( !(internal::traits<Map<ConstPlainObjectType> >::Flags & LvalueBit) );+ VERIFY( !(internal::traits<Map<ConstPlainObjectType, Aligned> >::Flags & LvalueBit) );+ VERIFY( !(Map<ConstPlainObjectType>::Flags & LvalueBit) );+ VERIFY( !(Map<ConstPlainObjectType, Aligned>::Flags & LvalueBit) );+}++template<typename Scalar>+void map_not_aligned_on_scalar()+{+ typedef Matrix<Scalar,Dynamic,Dynamic> MatrixType;+ typedef typename MatrixType::Index Index;+ Index size = 11;+ Scalar* array1 = internal::aligned_new<Scalar>((size+1)*(size+1)+1);+ Scalar* array2 = reinterpret_cast<Scalar*>(sizeof(Scalar)/2+std::size_t(array1));+ Map<MatrixType,0,OuterStride<> > map2(array2, size, size, OuterStride<>(size+1));+ MatrixType m2 = MatrixType::Random(size,size);+ map2 = m2;+ VERIFY_IS_EQUAL(m2, map2);+ + typedef Matrix<Scalar,Dynamic,1> VectorType;+ Map<VectorType> map3(array2, size);+ MatrixType v3 = VectorType::Random(size);+ map3 = v3;+ VERIFY_IS_EQUAL(v3, map3);+ + internal::aligned_delete(array1, (size+1)*(size+1)+1);+}++void test_mapped_matrix()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( map_class_vector(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_1( check_const_correctness(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( map_class_vector(Vector4d()) );+ CALL_SUBTEST_2( check_const_correctness(Matrix4d()) );+ CALL_SUBTEST_3( map_class_vector(RowVector4f()) );+ CALL_SUBTEST_4( map_class_vector(VectorXcf(8)) );+ CALL_SUBTEST_5( map_class_vector(VectorXi(12)) );+ CALL_SUBTEST_5( check_const_correctness(VectorXi(12)) );++ CALL_SUBTEST_1( map_class_matrix(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( map_class_matrix(Matrix4d()) );+ CALL_SUBTEST_11( map_class_matrix(Matrix<float,3,5>()) );+ CALL_SUBTEST_4( map_class_matrix(MatrixXcf(internal::random<int>(1,10),internal::random<int>(1,10))) );+ CALL_SUBTEST_5( map_class_matrix(MatrixXi(internal::random<int>(1,10),internal::random<int>(1,10))) );++ CALL_SUBTEST_6( map_static_methods(Matrix<double, 1, 1>()) );+ CALL_SUBTEST_7( map_static_methods(Vector3f()) );+ CALL_SUBTEST_8( map_static_methods(RowVector3d()) );+ CALL_SUBTEST_9( map_static_methods(VectorXcd(8)) );+ CALL_SUBTEST_10( map_static_methods(VectorXf(12)) );+ + CALL_SUBTEST_11( map_not_aligned_on_scalar<double>() );+ }+}
+ eigen3/test/mapstaticmethods.cpp view
@@ -0,0 +1,173 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++float *ptr;+const float *const_ptr;++template<typename PlainObjectType,+ bool IsDynamicSize = PlainObjectType::SizeAtCompileTime == Dynamic,+ bool IsVector = PlainObjectType::IsVectorAtCompileTime+>+struct mapstaticmethods_impl {};++template<typename PlainObjectType, bool IsVector>+struct mapstaticmethods_impl<PlainObjectType, false, IsVector>+{+ static void run(const PlainObjectType& m)+ {+ mapstaticmethods_impl<PlainObjectType, true, IsVector>::run(m);++ int i = internal::random<int>(2,5), j = internal::random<int>(2,5);++ PlainObjectType::Map(ptr).setZero();+ PlainObjectType::MapAligned(ptr).setZero();+ PlainObjectType::Map(const_ptr).sum();+ PlainObjectType::MapAligned(const_ptr).sum();++ PlainObjectType::Map(ptr, InnerStride<>(i)).setZero();+ PlainObjectType::MapAligned(ptr, InnerStride<>(i)).setZero();+ PlainObjectType::Map(const_ptr, InnerStride<>(i)).sum();+ PlainObjectType::MapAligned(const_ptr, InnerStride<>(i)).sum();++ PlainObjectType::Map(ptr, InnerStride<2>()).setZero();+ PlainObjectType::MapAligned(ptr, InnerStride<3>()).setZero();+ PlainObjectType::Map(const_ptr, InnerStride<4>()).sum();+ PlainObjectType::MapAligned(const_ptr, InnerStride<5>()).sum();++ PlainObjectType::Map(ptr, OuterStride<>(i)).setZero();+ PlainObjectType::MapAligned(ptr, OuterStride<>(i)).setZero();+ PlainObjectType::Map(const_ptr, OuterStride<>(i)).sum();+ PlainObjectType::MapAligned(const_ptr, OuterStride<>(i)).sum();++ PlainObjectType::Map(ptr, OuterStride<2>()).setZero();+ PlainObjectType::MapAligned(ptr, OuterStride<3>()).setZero();+ PlainObjectType::Map(const_ptr, OuterStride<4>()).sum();+ PlainObjectType::MapAligned(const_ptr, OuterStride<5>()).sum();++ PlainObjectType::Map(ptr, Stride<Dynamic, Dynamic>(i,j)).setZero();+ PlainObjectType::MapAligned(ptr, Stride<2,Dynamic>(2,i)).setZero();+ PlainObjectType::Map(const_ptr, Stride<Dynamic,3>(i,3)).sum();+ PlainObjectType::MapAligned(const_ptr, Stride<Dynamic, Dynamic>(i,j)).sum();++ PlainObjectType::Map(ptr, Stride<2,3>()).setZero();+ PlainObjectType::MapAligned(ptr, Stride<3,4>()).setZero();+ PlainObjectType::Map(const_ptr, Stride<2,4>()).sum();+ PlainObjectType::MapAligned(const_ptr, Stride<5,3>()).sum();+ }+};++template<typename PlainObjectType>+struct mapstaticmethods_impl<PlainObjectType, true, false>+{+ static void run(const PlainObjectType& m)+ {+ int rows = m.rows(), cols = m.cols();++ int i = internal::random<int>(2,5), j = internal::random<int>(2,5);++ PlainObjectType::Map(ptr, rows, cols).setZero();+ PlainObjectType::MapAligned(ptr, rows, cols).setZero();+ PlainObjectType::Map(const_ptr, rows, cols).sum();+ PlainObjectType::MapAligned(const_ptr, rows, cols).sum();++ PlainObjectType::Map(ptr, rows, cols, InnerStride<>(i)).setZero();+ PlainObjectType::MapAligned(ptr, rows, cols, InnerStride<>(i)).setZero();+ PlainObjectType::Map(const_ptr, rows, cols, InnerStride<>(i)).sum();+ PlainObjectType::MapAligned(const_ptr, rows, cols, InnerStride<>(i)).sum();++ PlainObjectType::Map(ptr, rows, cols, InnerStride<2>()).setZero();+ PlainObjectType::MapAligned(ptr, rows, cols, InnerStride<3>()).setZero();+ PlainObjectType::Map(const_ptr, rows, cols, InnerStride<4>()).sum();+ PlainObjectType::MapAligned(const_ptr, rows, cols, InnerStride<5>()).sum();++ PlainObjectType::Map(ptr, rows, cols, OuterStride<>(i)).setZero();+ PlainObjectType::MapAligned(ptr, rows, cols, OuterStride<>(i)).setZero();+ PlainObjectType::Map(const_ptr, rows, cols, OuterStride<>(i)).sum();+ PlainObjectType::MapAligned(const_ptr, rows, cols, OuterStride<>(i)).sum();++ PlainObjectType::Map(ptr, rows, cols, OuterStride<2>()).setZero();+ PlainObjectType::MapAligned(ptr, rows, cols, OuterStride<3>()).setZero();+ PlainObjectType::Map(const_ptr, rows, cols, OuterStride<4>()).sum();+ PlainObjectType::MapAligned(const_ptr, rows, cols, OuterStride<5>()).sum();++ PlainObjectType::Map(ptr, rows, cols, Stride<Dynamic, Dynamic>(i,j)).setZero();+ PlainObjectType::MapAligned(ptr, rows, cols, Stride<2,Dynamic>(2,i)).setZero();+ PlainObjectType::Map(const_ptr, rows, cols, Stride<Dynamic,3>(i,3)).sum();+ PlainObjectType::MapAligned(const_ptr, rows, cols, Stride<Dynamic, Dynamic>(i,j)).sum();++ PlainObjectType::Map(ptr, rows, cols, Stride<2,3>()).setZero();+ PlainObjectType::MapAligned(ptr, rows, cols, Stride<3,4>()).setZero();+ PlainObjectType::Map(const_ptr, rows, cols, Stride<2,4>()).sum();+ PlainObjectType::MapAligned(const_ptr, rows, cols, Stride<5,3>()).sum();+ }+};++template<typename PlainObjectType>+struct mapstaticmethods_impl<PlainObjectType, true, true>+{+ static void run(const PlainObjectType& v)+ {+ int size = v.size();++ int i = internal::random<int>(2,5);++ PlainObjectType::Map(ptr, size).setZero();+ PlainObjectType::MapAligned(ptr, size).setZero();+ PlainObjectType::Map(const_ptr, size).sum();+ PlainObjectType::MapAligned(const_ptr, size).sum();++ PlainObjectType::Map(ptr, size, InnerStride<>(i)).setZero();+ PlainObjectType::MapAligned(ptr, size, InnerStride<>(i)).setZero();+ PlainObjectType::Map(const_ptr, size, InnerStride<>(i)).sum();+ PlainObjectType::MapAligned(const_ptr, size, InnerStride<>(i)).sum();++ PlainObjectType::Map(ptr, size, InnerStride<2>()).setZero();+ PlainObjectType::MapAligned(ptr, size, InnerStride<3>()).setZero();+ PlainObjectType::Map(const_ptr, size, InnerStride<4>()).sum();+ PlainObjectType::MapAligned(const_ptr, size, InnerStride<5>()).sum();+ }+};++template<typename PlainObjectType>+void mapstaticmethods(const PlainObjectType& m)+{+ mapstaticmethods_impl<PlainObjectType>::run(m);+ VERIFY(true); // just to avoid 'unused function' warning+}++void test_mapstaticmethods()+{+ ptr = internal::aligned_new<float>(1000);+ for(int i = 0; i < 1000; i++) ptr[i] = float(i);++ const_ptr = ptr;++ CALL_SUBTEST_1(( mapstaticmethods(Matrix<float, 1, 1>()) ));+ CALL_SUBTEST_1(( mapstaticmethods(Vector2f()) ));+ CALL_SUBTEST_2(( mapstaticmethods(Vector3f()) ));+ CALL_SUBTEST_2(( mapstaticmethods(Matrix2f()) ));+ CALL_SUBTEST_3(( mapstaticmethods(Matrix4f()) ));+ CALL_SUBTEST_3(( mapstaticmethods(Array4f()) ));+ CALL_SUBTEST_4(( mapstaticmethods(Array3f()) ));+ CALL_SUBTEST_4(( mapstaticmethods(Array33f()) ));+ CALL_SUBTEST_5(( mapstaticmethods(Array44f()) ));+ CALL_SUBTEST_5(( mapstaticmethods(VectorXf(1)) ));+ CALL_SUBTEST_5(( mapstaticmethods(VectorXf(8)) ));+ CALL_SUBTEST_6(( mapstaticmethods(MatrixXf(1,1)) ));+ CALL_SUBTEST_6(( mapstaticmethods(MatrixXf(5,7)) ));+ CALL_SUBTEST_7(( mapstaticmethods(ArrayXf(1)) ));+ CALL_SUBTEST_7(( mapstaticmethods(ArrayXf(5)) ));+ CALL_SUBTEST_8(( mapstaticmethods(ArrayXXf(1,1)) ));+ CALL_SUBTEST_8(( mapstaticmethods(ArrayXXf(8,6)) ));++ internal::aligned_delete(ptr, 1000);+}+
+ eigen3/test/mapstride.cpp view
@@ -0,0 +1,148 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<int Alignment,typename VectorType> void map_class_vector(const VectorType& m)+{+ typedef typename VectorType::Index Index;+ typedef typename VectorType::Scalar Scalar;++ Index size = m.size();++ VectorType v = VectorType::Random(size);++ Index arraysize = 3*size;+ + Scalar* a_array = internal::aligned_new<Scalar>(arraysize+1);+ Scalar* array = a_array;+ if(Alignment!=Aligned)+ array = (Scalar*)(ptrdiff_t(a_array) + (internal::packet_traits<Scalar>::AlignedOnScalar?sizeof(Scalar):sizeof(typename NumTraits<Scalar>::Real)));++ {+ Map<VectorType, Alignment, InnerStride<3> > map(array, size);+ map = v;+ for(int i = 0; i < size; ++i)+ {+ VERIFY(array[3*i] == v[i]);+ VERIFY(map[i] == v[i]);+ }+ }++ {+ Map<VectorType, Unaligned, InnerStride<Dynamic> > map(array, size, InnerStride<Dynamic>(2));+ map = v;+ for(int i = 0; i < size; ++i)+ {+ VERIFY(array[2*i] == v[i]);+ VERIFY(map[i] == v[i]);+ }+ }++ internal::aligned_delete(a_array, arraysize+1);+}++template<int Alignment,typename MatrixType> void map_class_matrix(const MatrixType& _m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;++ Index rows = _m.rows(), cols = _m.cols();++ MatrixType m = MatrixType::Random(rows,cols);++ Index arraysize = 2*(rows+4)*(cols+4);++ Scalar* a_array = internal::aligned_new<Scalar>(arraysize+1);+ Scalar* array = a_array;+ if(Alignment!=Aligned)+ array = (Scalar*)(ptrdiff_t(a_array) + (internal::packet_traits<Scalar>::AlignedOnScalar?sizeof(Scalar):sizeof(typename NumTraits<Scalar>::Real)));++ // test no inner stride and some dynamic outer stride+ {+ Map<MatrixType, Alignment, OuterStride<Dynamic> > map(array, rows, cols, OuterStride<Dynamic>(m.innerSize()+1));+ map = m;+ VERIFY(map.outerStride() == map.innerSize()+1);+ for(int i = 0; i < m.outerSize(); ++i)+ for(int j = 0; j < m.innerSize(); ++j)+ {+ VERIFY(array[map.outerStride()*i+j] == m.coeffByOuterInner(i,j));+ VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j));+ }+ }++ // test no inner stride and an outer stride of +4. This is quite important as for fixed-size matrices,+ // this allows to hit the special case where it's vectorizable.+ {+ enum {+ InnerSize = MatrixType::InnerSizeAtCompileTime,+ OuterStrideAtCompileTime = InnerSize==Dynamic ? Dynamic : InnerSize+4+ };+ Map<MatrixType, Alignment, OuterStride<OuterStrideAtCompileTime> >+ map(array, rows, cols, OuterStride<OuterStrideAtCompileTime>(m.innerSize()+4));+ map = m;+ VERIFY(map.outerStride() == map.innerSize()+4);+ for(int i = 0; i < m.outerSize(); ++i)+ for(int j = 0; j < m.innerSize(); ++j)+ {+ VERIFY(array[map.outerStride()*i+j] == m.coeffByOuterInner(i,j));+ VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j));+ }+ }++ // test both inner stride and outer stride+ {+ Map<MatrixType, Alignment, Stride<Dynamic,Dynamic> > map(array, rows, cols, Stride<Dynamic,Dynamic>(2*m.innerSize()+1, 2));+ map = m;+ VERIFY(map.outerStride() == 2*map.innerSize()+1);+ VERIFY(map.innerStride() == 2);+ for(int i = 0; i < m.outerSize(); ++i)+ for(int j = 0; j < m.innerSize(); ++j)+ {+ VERIFY(array[map.outerStride()*i+map.innerStride()*j] == m.coeffByOuterInner(i,j));+ VERIFY(map.coeffByOuterInner(i,j) == m.coeffByOuterInner(i,j));+ }+ }++ internal::aligned_delete(a_array, arraysize+1);+}++void test_mapstride()+{+ for(int i = 0; i < g_repeat; i++) {+ int maxn = 30;+ CALL_SUBTEST_1( map_class_vector<Aligned>(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_1( map_class_vector<Unaligned>(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( map_class_vector<Aligned>(Vector4d()) );+ CALL_SUBTEST_2( map_class_vector<Unaligned>(Vector4d()) );+ CALL_SUBTEST_3( map_class_vector<Aligned>(RowVector4f()) );+ CALL_SUBTEST_3( map_class_vector<Unaligned>(RowVector4f()) );+ CALL_SUBTEST_4( map_class_vector<Aligned>(VectorXcf(internal::random<int>(1,maxn))) );+ CALL_SUBTEST_4( map_class_vector<Unaligned>(VectorXcf(internal::random<int>(1,maxn))) );+ CALL_SUBTEST_5( map_class_vector<Aligned>(VectorXi(internal::random<int>(1,maxn))) );+ CALL_SUBTEST_5( map_class_vector<Unaligned>(VectorXi(internal::random<int>(1,maxn))) );++ CALL_SUBTEST_1( map_class_matrix<Aligned>(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_1( map_class_matrix<Unaligned>(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( map_class_matrix<Aligned>(Matrix4d()) );+ CALL_SUBTEST_2( map_class_matrix<Unaligned>(Matrix4d()) );+ CALL_SUBTEST_3( map_class_matrix<Aligned>(Matrix<float,3,5>()) );+ CALL_SUBTEST_3( map_class_matrix<Unaligned>(Matrix<float,3,5>()) );+ CALL_SUBTEST_3( map_class_matrix<Aligned>(Matrix<float,4,8>()) );+ CALL_SUBTEST_3( map_class_matrix<Unaligned>(Matrix<float,4,8>()) );+ CALL_SUBTEST_4( map_class_matrix<Aligned>(MatrixXcf(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );+ CALL_SUBTEST_4( map_class_matrix<Unaligned>(MatrixXcf(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );+ CALL_SUBTEST_5( map_class_matrix<Aligned>(MatrixXi(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );+ CALL_SUBTEST_5( map_class_matrix<Unaligned>(MatrixXi(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );+ CALL_SUBTEST_6( map_class_matrix<Aligned>(MatrixXcd(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );+ CALL_SUBTEST_6( map_class_matrix<Unaligned>(MatrixXcd(internal::random<int>(1,maxn),internal::random<int>(1,maxn))) );+ + TEST_SET_BUT_UNUSED_VARIABLE(maxn);+ }+}
+ eigen3/test/meta.cpp view
@@ -0,0 +1,73 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++void test_meta()+{+ VERIFY((internal::conditional<(3<4),internal::true_type, internal::false_type>::type::value));+ VERIFY(( internal::is_same<float,float>::value));+ VERIFY((!internal::is_same<float,double>::value));+ VERIFY((!internal::is_same<float,float&>::value));+ VERIFY((!internal::is_same<float,const float&>::value));+ + VERIFY(( internal::is_same<float,internal::remove_all<const float&>::type >::value));+ VERIFY(( internal::is_same<float,internal::remove_all<const float*>::type >::value));+ VERIFY(( internal::is_same<float,internal::remove_all<const float*&>::type >::value));+ VERIFY(( internal::is_same<float,internal::remove_all<float**>::type >::value));+ VERIFY(( internal::is_same<float,internal::remove_all<float**&>::type >::value));+ VERIFY(( internal::is_same<float,internal::remove_all<float* const *&>::type >::value));+ VERIFY(( internal::is_same<float,internal::remove_all<float* const>::type >::value));++ // test add_const+ VERIFY(( internal::is_same< internal::add_const<float>::type, const float >::value));+ VERIFY(( internal::is_same< internal::add_const<float*>::type, float* const>::value));+ VERIFY(( internal::is_same< internal::add_const<float const*>::type, float const* const>::value));+ VERIFY(( internal::is_same< internal::add_const<float&>::type, float& >::value));++ // test remove_const+ VERIFY(( internal::is_same< internal::remove_const<float const* const>::type, float const* >::value));+ VERIFY(( internal::is_same< internal::remove_const<float const*>::type, float const* >::value));+ VERIFY(( internal::is_same< internal::remove_const<float* const>::type, float* >::value));++ // test add_const_on_value_type+ VERIFY(( internal::is_same< internal::add_const_on_value_type<float&>::type, float const& >::value));+ VERIFY(( internal::is_same< internal::add_const_on_value_type<float*>::type, float const* >::value));++ VERIFY(( internal::is_same< internal::add_const_on_value_type<float>::type, const float >::value));+ VERIFY(( internal::is_same< internal::add_const_on_value_type<const float>::type, const float >::value));++ VERIFY(( internal::is_same< internal::add_const_on_value_type<const float* const>::type, const float* const>::value));+ VERIFY(( internal::is_same< internal::add_const_on_value_type<float* const>::type, const float* const>::value));+ + VERIFY(( internal::is_same<float,internal::remove_reference<float&>::type >::value));+ VERIFY(( internal::is_same<const float,internal::remove_reference<const float&>::type >::value));+ VERIFY(( internal::is_same<float,internal::remove_pointer<float*>::type >::value));+ VERIFY(( internal::is_same<const float,internal::remove_pointer<const float*>::type >::value));+ VERIFY(( internal::is_same<float,internal::remove_pointer<float* const >::type >::value));+ + VERIFY(internal::meta_sqrt<1>::ret == 1);+ #define VERIFY_META_SQRT(X) VERIFY(internal::meta_sqrt<X>::ret == int(std::sqrt(double(X))))+ VERIFY_META_SQRT(2);+ VERIFY_META_SQRT(3);+ VERIFY_META_SQRT(4);+ VERIFY_META_SQRT(5);+ VERIFY_META_SQRT(6);+ VERIFY_META_SQRT(8);+ VERIFY_META_SQRT(9);+ VERIFY_META_SQRT(15);+ VERIFY_META_SQRT(16);+ VERIFY_META_SQRT(17);+ VERIFY_META_SQRT(255);+ VERIFY_META_SQRT(256);+ VERIFY_META_SQRT(257);+ VERIFY_META_SQRT(1023);+ VERIFY_META_SQRT(1024);+ VERIFY_META_SQRT(1025);+}
+ eigen3/test/metis_support.cpp view
@@ -0,0 +1,39 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>+//+// Eigen is free software; you can redistribute it and/or+// modify it under the terms of the GNU Lesser General Public+// License as published by the Free Software Foundation; either+// version 3 of the License, or (at your option) any later version.+//+// Alternatively, you can redistribute it and/or+// modify it under the terms of the GNU General Public License as+// published by the Free Software Foundation; either version 2 of+// the License, or (at your option) any later version.+//+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the+// GNU General Public License for more details.+//+// You should have received a copy of the GNU Lesser General Public+// License and a copy of the GNU General Public License along with+// Eigen. If not, see <http://www.gnu.org/licenses/>.+#include "sparse_solver.h"+#include <Eigen/SparseLU>+#include <Eigen/MetisSupport>+#include <unsupported/Eigen/SparseExtra>++template<typename T> void test_metis_T()+{+ SparseLU<SparseMatrix<T, ColMajor>, MetisOrdering<int> > sparselu_metis;+ + check_sparse_square_solving(sparselu_metis); +}++void test_metis_support()+{+ CALL_SUBTEST_1(test_metis_T<double>());+}
+ eigen3/test/miscmatrices.cpp view
@@ -0,0 +1,47 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void miscMatrices(const MatrixType& m)+{+ /* this test covers the following files:+ DiagonalMatrix.h Ones.h+ */+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;+ Index rows = m.rows();+ Index cols = m.cols();++ Index r = internal::random<Index>(0, rows-1), r2 = internal::random<Index>(0, rows-1), c = internal::random<Index>(0, cols-1);+ VERIFY_IS_APPROX(MatrixType::Ones(rows,cols)(r,c), static_cast<Scalar>(1));+ MatrixType m1 = MatrixType::Ones(rows,cols);+ VERIFY_IS_APPROX(m1(r,c), static_cast<Scalar>(1));+ VectorType v1 = VectorType::Random(rows);+ v1[0];+ Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime>+ square(v1.asDiagonal());+ if(r==r2) VERIFY_IS_APPROX(square(r,r2), v1[r]);+ else VERIFY_IS_MUCH_SMALLER_THAN(square(r,r2), static_cast<Scalar>(1));+ square = MatrixType::Zero(rows, rows);+ square.diagonal() = VectorType::Ones(rows);+ VERIFY_IS_APPROX(square, MatrixType::Identity(rows, rows));+}++void test_miscmatrices()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( miscMatrices(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( miscMatrices(Matrix4d()) );+ CALL_SUBTEST_3( miscMatrices(MatrixXcf(3, 3)) );+ CALL_SUBTEST_4( miscMatrices(MatrixXi(8, 12)) );+ CALL_SUBTEST_5( miscMatrices(MatrixXcd(20, 20)) );+ }+}
+ eigen3/test/mixingtypes.cpp view
@@ -0,0 +1,132 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++// work around "uninitialized" warnings and give that option some testing+#define EIGEN_INITIALIZE_MATRICES_BY_ZERO++#ifndef EIGEN_NO_STATIC_ASSERT+#define EIGEN_NO_STATIC_ASSERT // turn static asserts into runtime asserts in order to check them+#endif++// #ifndef EIGEN_DONT_VECTORIZE+// #define EIGEN_DONT_VECTORIZE // SSE intrinsics aren't designed to allow mixing types+// #endif++#include "main.h"++using namespace std;++template<int SizeAtCompileType> void mixingtypes(int size = SizeAtCompileType)+{+ typedef std::complex<float> CF;+ typedef std::complex<double> CD;+ typedef Matrix<float, SizeAtCompileType, SizeAtCompileType> Mat_f;+ typedef Matrix<double, SizeAtCompileType, SizeAtCompileType> Mat_d;+ typedef Matrix<std::complex<float>, SizeAtCompileType, SizeAtCompileType> Mat_cf;+ typedef Matrix<std::complex<double>, SizeAtCompileType, SizeAtCompileType> Mat_cd;+ typedef Matrix<float, SizeAtCompileType, 1> Vec_f;+ typedef Matrix<double, SizeAtCompileType, 1> Vec_d;+ typedef Matrix<std::complex<float>, SizeAtCompileType, 1> Vec_cf;+ typedef Matrix<std::complex<double>, SizeAtCompileType, 1> Vec_cd;++ Mat_f mf = Mat_f::Random(size,size);+ Mat_d md = mf.template cast<double>();+ Mat_cf mcf = Mat_cf::Random(size,size);+ Mat_cd mcd = mcf.template cast<complex<double> >();+ Vec_f vf = Vec_f::Random(size,1);+ Vec_d vd = vf.template cast<double>();+ Vec_cf vcf = Vec_cf::Random(size,1);+ Vec_cd vcd = vcf.template cast<complex<double> >();+ float sf = internal::random<float>();+ double sd = internal::random<double>();+ complex<float> scf = internal::random<complex<float> >();+ complex<double> scd = internal::random<complex<double> >();+++ mf+mf;+ VERIFY_RAISES_ASSERT(mf+md);+ VERIFY_RAISES_ASSERT(mf+mcf);+ VERIFY_RAISES_ASSERT(vf=vd);+ VERIFY_RAISES_ASSERT(vf+=vd);+ VERIFY_RAISES_ASSERT(mcd=md);++ // check scalar products+ VERIFY_IS_APPROX(vcf * sf , vcf * complex<float>(sf));+ VERIFY_IS_APPROX(sd * vcd, complex<double>(sd) * vcd);+ VERIFY_IS_APPROX(vf * scf , vf.template cast<complex<float> >() * scf);+ VERIFY_IS_APPROX(scd * vd, scd * vd.template cast<complex<double> >());++ // check dot product+ vf.dot(vf);+#if 0 // we get other compilation errors here than just static asserts+ VERIFY_RAISES_ASSERT(vd.dot(vf));+#endif+ VERIFY_IS_APPROX(vcf.dot(vf), vcf.dot(vf.template cast<complex<float> >()));++ // check diagonal product+ VERIFY_IS_APPROX(vf.asDiagonal() * mcf, vf.template cast<complex<float> >().asDiagonal() * mcf);+ VERIFY_IS_APPROX(vcd.asDiagonal() * md, vcd.asDiagonal() * md.template cast<complex<double> >());+ VERIFY_IS_APPROX(mcf * vf.asDiagonal(), mcf * vf.template cast<complex<float> >().asDiagonal());+ VERIFY_IS_APPROX(md * vcd.asDiagonal(), md.template cast<complex<double> >() * vcd.asDiagonal());+// vd.asDiagonal() * mf; // does not even compile+// vcd.asDiagonal() * mf; // does not even compile++ // check inner product+ VERIFY_IS_APPROX((vf.transpose() * vcf).value(), (vf.template cast<complex<float> >().transpose() * vcf).value());++ // check outer product+ VERIFY_IS_APPROX((vf * vcf.transpose()).eval(), (vf.template cast<complex<float> >() * vcf.transpose()).eval());++ // coeff wise product++ VERIFY_IS_APPROX((vf * vcf.transpose()).eval(), (vf.template cast<complex<float> >() * vcf.transpose()).eval());++ Mat_cd mcd2 = mcd;+ VERIFY_IS_APPROX(mcd.array() *= md.array(), mcd2.array() *= md.array().template cast<std::complex<double> >());+ + // check matrix-matrix products++ VERIFY_IS_APPROX(sd*md*mcd, (sd*md).template cast<CD>().eval()*mcd);+ VERIFY_IS_APPROX(sd*mcd*md, sd*mcd*md.template cast<CD>());+ VERIFY_IS_APPROX(scd*md*mcd, scd*md.template cast<CD>().eval()*mcd);+ VERIFY_IS_APPROX(scd*mcd*md, scd*mcd*md.template cast<CD>());++ VERIFY_IS_APPROX(sf*mf*mcf, sf*mf.template cast<CF>()*mcf);+ VERIFY_IS_APPROX(sf*mcf*mf, sf*mcf*mf.template cast<CF>());+ VERIFY_IS_APPROX(scf*mf*mcf, scf*mf.template cast<CF>()*mcf);+ VERIFY_IS_APPROX(scf*mcf*mf, scf*mcf*mf.template cast<CF>());++ VERIFY_IS_APPROX(sf*mf*vcf, (sf*mf).template cast<CF>().eval()*vcf);+ VERIFY_IS_APPROX(scf*mf*vcf,(scf*mf.template cast<CF>()).eval()*vcf);+ VERIFY_IS_APPROX(sf*mcf*vf, sf*mcf*vf.template cast<CF>());+ VERIFY_IS_APPROX(scf*mcf*vf,scf*mcf*vf.template cast<CF>());++ VERIFY_IS_APPROX(sf*vcf.adjoint()*mf, sf*vcf.adjoint()*mf.template cast<CF>().eval());+ VERIFY_IS_APPROX(scf*vcf.adjoint()*mf, scf*vcf.adjoint()*mf.template cast<CF>().eval());+ VERIFY_IS_APPROX(sf*vf.adjoint()*mcf, sf*vf.adjoint().template cast<CF>().eval()*mcf);+ VERIFY_IS_APPROX(scf*vf.adjoint()*mcf, scf*vf.adjoint().template cast<CF>().eval()*mcf);++ VERIFY_IS_APPROX(sd*md*vcd, (sd*md).template cast<CD>().eval()*vcd);+ VERIFY_IS_APPROX(scd*md*vcd,(scd*md.template cast<CD>()).eval()*vcd);+ VERIFY_IS_APPROX(sd*mcd*vd, sd*mcd*vd.template cast<CD>().eval());+ VERIFY_IS_APPROX(scd*mcd*vd,scd*mcd*vd.template cast<CD>().eval());++ VERIFY_IS_APPROX(sd*vcd.adjoint()*md, sd*vcd.adjoint()*md.template cast<CD>().eval());+ VERIFY_IS_APPROX(scd*vcd.adjoint()*md, scd*vcd.adjoint()*md.template cast<CD>().eval());+ VERIFY_IS_APPROX(sd*vd.adjoint()*mcd, sd*vd.adjoint().template cast<CD>().eval()*mcd);+ VERIFY_IS_APPROX(scd*vd.adjoint()*mcd, scd*vd.adjoint().template cast<CD>().eval()*mcd);+}++void test_mixingtypes()+{+ CALL_SUBTEST_1(mixingtypes<3>());+ CALL_SUBTEST_2(mixingtypes<4>());+ CALL_SUBTEST_3(mixingtypes<Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)));+}
+ eigen3/test/nesting_ops.cpp view
@@ -0,0 +1,33 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template <typename MatrixType> void run_nesting_ops(const MatrixType& _m)+{+ typename MatrixType::Nested m(_m);++ // Make really sure that we are in debug mode!+ VERIFY_RAISES_ASSERT(eigen_assert(false));++ // The only intention of these tests is to ensure that this code does+ // not trigger any asserts or segmentation faults... more to come.+ VERIFY_IS_APPROX( (m.transpose() * m).diagonal().sum(), (m.transpose() * m).diagonal().sum() );+ VERIFY_IS_APPROX( (m.transpose() * m).diagonal().array().abs().sum(), (m.transpose() * m).diagonal().array().abs().sum() );++ VERIFY_IS_APPROX( (m.transpose() * m).array().abs().sum(), (m.transpose() * m).array().abs().sum() );+}++void test_nesting_ops()+{+ CALL_SUBTEST_1(run_nesting_ops(MatrixXf::Random(25,25)));+ CALL_SUBTEST_2(run_nesting_ops(MatrixXd::Random(25,25)));+ CALL_SUBTEST_3(run_nesting_ops(Matrix4f::Random()));+ CALL_SUBTEST_4(run_nesting_ops(Matrix4d::Random()));+}
+ eigen3/test/nomalloc.cpp view
@@ -0,0 +1,212 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++// this hack is needed to make this file compiles with -pedantic (gcc)+#ifdef __GNUC__+#define throw(X)+#endif++#ifdef __INTEL_COMPILER+ // disable "warning #76: argument to macro is empty" produced by the above hack+ #pragma warning disable 76+#endif++// discard stack allocation as that too bypasses malloc+#define EIGEN_STACK_ALLOCATION_LIMIT 0+// any heap allocation will raise an assert+#define EIGEN_NO_MALLOC++#include "main.h"+#include <Eigen/Cholesky>+#include <Eigen/Eigenvalues>+#include <Eigen/LU>+#include <Eigen/QR>+#include <Eigen/SVD>++template<typename MatrixType> void nomalloc(const MatrixType& m)+{+ /* this test check no dynamic memory allocation are issued with fixed-size matrices+ */+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;++ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols);++ Scalar s1 = internal::random<Scalar>();++ Index r = internal::random<Index>(0, rows-1),+ c = internal::random<Index>(0, cols-1);++ VERIFY_IS_APPROX((m1+m2)*s1, s1*m1+s1*m2);+ VERIFY_IS_APPROX((m1+m2)(r,c), (m1(r,c))+(m2(r,c)));+ VERIFY_IS_APPROX(m1.cwiseProduct(m1.block(0,0,rows,cols)), (m1.array()*m1.array()).matrix());+ VERIFY_IS_APPROX((m1*m1.transpose())*m2, m1*(m1.transpose()*m2));+ + m2.col(0).noalias() = m1 * m1.col(0);+ m2.col(0).noalias() -= m1.adjoint() * m1.col(0);+ m2.col(0).noalias() -= m1 * m1.row(0).adjoint();+ m2.col(0).noalias() -= m1.adjoint() * m1.row(0).adjoint();++ m2.row(0).noalias() = m1.row(0) * m1;+ m2.row(0).noalias() -= m1.row(0) * m1.adjoint();+ m2.row(0).noalias() -= m1.col(0).adjoint() * m1;+ m2.row(0).noalias() -= m1.col(0).adjoint() * m1.adjoint();+ VERIFY_IS_APPROX(m2,m2);+ + m2.col(0).noalias() = m1.template triangularView<Upper>() * m1.col(0);+ m2.col(0).noalias() -= m1.adjoint().template triangularView<Upper>() * m1.col(0);+ m2.col(0).noalias() -= m1.template triangularView<Upper>() * m1.row(0).adjoint();+ m2.col(0).noalias() -= m1.adjoint().template triangularView<Upper>() * m1.row(0).adjoint();++ m2.row(0).noalias() = m1.row(0) * m1.template triangularView<Upper>();+ m2.row(0).noalias() -= m1.row(0) * m1.adjoint().template triangularView<Upper>();+ m2.row(0).noalias() -= m1.col(0).adjoint() * m1.template triangularView<Upper>();+ m2.row(0).noalias() -= m1.col(0).adjoint() * m1.adjoint().template triangularView<Upper>();+ VERIFY_IS_APPROX(m2,m2);+ + m2.col(0).noalias() = m1.template selfadjointView<Upper>() * m1.col(0);+ m2.col(0).noalias() -= m1.adjoint().template selfadjointView<Upper>() * m1.col(0);+ m2.col(0).noalias() -= m1.template selfadjointView<Upper>() * m1.row(0).adjoint();+ m2.col(0).noalias() -= m1.adjoint().template selfadjointView<Upper>() * m1.row(0).adjoint();++ m2.row(0).noalias() = m1.row(0) * m1.template selfadjointView<Upper>();+ m2.row(0).noalias() -= m1.row(0) * m1.adjoint().template selfadjointView<Upper>();+ m2.row(0).noalias() -= m1.col(0).adjoint() * m1.template selfadjointView<Upper>();+ m2.row(0).noalias() -= m1.col(0).adjoint() * m1.adjoint().template selfadjointView<Upper>();+ VERIFY_IS_APPROX(m2,m2);+ + m2.template selfadjointView<Lower>().rankUpdate(m1.col(0),-1);+ m2.template selfadjointView<Lower>().rankUpdate(m1.row(0),-1);++ // The following fancy matrix-matrix products are not safe yet regarding static allocation+// m1 += m1.template triangularView<Upper>() * m2.col(;+// m1.template selfadjointView<Lower>().rankUpdate(m2);+// m1 += m1.template triangularView<Upper>() * m2;+// m1 += m1.template selfadjointView<Lower>() * m2;+// VERIFY_IS_APPROX(m1,m1);+}++template<typename Scalar>+void ctms_decompositions()+{+ const int maxSize = 16;+ const int size = 12;++ typedef Eigen::Matrix<Scalar,+ Eigen::Dynamic, Eigen::Dynamic,+ 0,+ maxSize, maxSize> Matrix;++ typedef Eigen::Matrix<Scalar,+ Eigen::Dynamic, 1,+ 0,+ maxSize, 1> Vector;++ typedef Eigen::Matrix<std::complex<Scalar>,+ Eigen::Dynamic, Eigen::Dynamic,+ 0,+ maxSize, maxSize> ComplexMatrix;++ const Matrix A(Matrix::Random(size, size)), B(Matrix::Random(size, size));+ Matrix X(size,size);+ const ComplexMatrix complexA(ComplexMatrix::Random(size, size));+ const Matrix saA = A.adjoint() * A;+ const Vector b(Vector::Random(size));+ Vector x(size);++ // Cholesky module+ Eigen::LLT<Matrix> LLT; LLT.compute(A);+ X = LLT.solve(B);+ x = LLT.solve(b);+ Eigen::LDLT<Matrix> LDLT; LDLT.compute(A);+ X = LDLT.solve(B);+ x = LDLT.solve(b);++ // Eigenvalues module+ Eigen::HessenbergDecomposition<ComplexMatrix> hessDecomp; hessDecomp.compute(complexA);+ Eigen::ComplexSchur<ComplexMatrix> cSchur(size); cSchur.compute(complexA);+ Eigen::ComplexEigenSolver<ComplexMatrix> cEigSolver; cEigSolver.compute(complexA);+ Eigen::EigenSolver<Matrix> eigSolver; eigSolver.compute(A);+ Eigen::SelfAdjointEigenSolver<Matrix> saEigSolver(size); saEigSolver.compute(saA);+ Eigen::Tridiagonalization<Matrix> tridiag; tridiag.compute(saA);++ // LU module+ Eigen::PartialPivLU<Matrix> ppLU; ppLU.compute(A);+ X = ppLU.solve(B);+ x = ppLU.solve(b);+ Eigen::FullPivLU<Matrix> fpLU; fpLU.compute(A);+ X = fpLU.solve(B);+ x = fpLU.solve(b);++ // QR module+ Eigen::HouseholderQR<Matrix> hQR; hQR.compute(A);+ X = hQR.solve(B);+ x = hQR.solve(b);+ Eigen::ColPivHouseholderQR<Matrix> cpQR; cpQR.compute(A);+ X = cpQR.solve(B);+ x = cpQR.solve(b);+ Eigen::FullPivHouseholderQR<Matrix> fpQR; fpQR.compute(A);+ // FIXME X = fpQR.solve(B);+ x = fpQR.solve(b);++ // SVD module+ Eigen::JacobiSVD<Matrix> jSVD; jSVD.compute(A, ComputeFullU | ComputeFullV);+}++void test_zerosized() {+ // default constructors:+ Eigen::MatrixXd A;+ Eigen::VectorXd v;+ // explicit zero-sized:+ Eigen::ArrayXXd A0(0,0);+ Eigen::ArrayXd v0(std::ptrdiff_t(0)); // FIXME ArrayXd(0) is ambiguous++ // assigning empty objects to each other:+ A=A0;+ v=v0;+}++template<typename MatrixType> void test_reference(const MatrixType& m) {+ typedef typename MatrixType::Scalar Scalar;+ enum { Flag = MatrixType::IsRowMajor ? Eigen::RowMajor : Eigen::ColMajor};+ enum { TransposeFlag = !MatrixType::IsRowMajor ? Eigen::RowMajor : Eigen::ColMajor};+ typename MatrixType::Index rows = m.rows(), cols=m.cols();+ // Dynamic reference:+ typedef Eigen::Ref<const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Flag > > Ref;+ typedef Eigen::Ref<const Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, TransposeFlag> > RefT;++ Ref r1(m);+ Ref r2(m.block(rows/3, cols/4, rows/2, cols/2));+ RefT r3(m.transpose());+ RefT r4(m.topLeftCorner(rows/2, cols/2).transpose());++ VERIFY_RAISES_ASSERT(RefT r5(m));+ VERIFY_RAISES_ASSERT(Ref r6(m.transpose()));+ VERIFY_RAISES_ASSERT(Ref r7(Scalar(2) * m));+}++void test_nomalloc()+{+ // check that our operator new is indeed called:+ VERIFY_RAISES_ASSERT(MatrixXd dummy(MatrixXd::Random(3,3)));+ CALL_SUBTEST_1(nomalloc(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2(nomalloc(Matrix4d()) );+ CALL_SUBTEST_3(nomalloc(Matrix<float,32,32>()) );+ + // Check decomposition modules with dynamic matrices that have a known compile-time max size (ctms)+ CALL_SUBTEST_4(ctms_decompositions<float>());+ CALL_SUBTEST_5(test_zerosized());+ CALL_SUBTEST_6(test_reference(Matrix<float,32,32>()));+}
+ eigen3/test/nullary.cpp view
@@ -0,0 +1,131 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010-2011 Jitse Niesen <jitse@maths.leeds.ac.uk>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType>+bool equalsIdentity(const MatrixType& A)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ Scalar zero = static_cast<Scalar>(0);++ bool offDiagOK = true;+ for (Index i = 0; i < A.rows(); ++i) {+ for (Index j = i+1; j < A.cols(); ++j) {+ offDiagOK = offDiagOK && (A(i,j) == zero);+ }+ }+ for (Index i = 0; i < A.rows(); ++i) {+ for (Index j = 0; j < (std::min)(i, A.cols()); ++j) {+ offDiagOK = offDiagOK && (A(i,j) == zero);+ }+ }++ bool diagOK = (A.diagonal().array() == 1).all();+ return offDiagOK && diagOK;+}++template<typename VectorType>+void testVectorType(const VectorType& base)+{+ typedef typename internal::traits<VectorType>::Index Index;+ typedef typename internal::traits<VectorType>::Scalar Scalar;++ const Index size = base.size();+ + Scalar high = internal::random<Scalar>(-500,500);+ Scalar low = (size == 1 ? high : internal::random<Scalar>(-500,500));+ if (low>high) std::swap(low,high);++ const Scalar step = ((size == 1) ? 1 : (high-low)/(size-1));++ // check whether the result yields what we expect it to do+ VectorType m(base);+ m.setLinSpaced(size,low,high);++ VectorType n(size);+ for (int i=0; i<size; ++i)+ n(i) = low+i*step;++ VERIFY_IS_APPROX(m,n);++ // random access version+ m = VectorType::LinSpaced(size,low,high);+ VERIFY_IS_APPROX(m,n);++ // Assignment of a RowVectorXd to a MatrixXd (regression test for bug #79).+ VERIFY( (MatrixXd(RowVectorXd::LinSpaced(3, 0, 1)) - RowVector3d(0, 0.5, 1)).norm() < std::numeric_limits<Scalar>::epsilon() );++ // These guys sometimes fail! This is not good. Any ideas how to fix them!?+ //VERIFY( m(m.size()-1) == high );+ //VERIFY( m(0) == low );++ // sequential access version+ m = VectorType::LinSpaced(Sequential,size,low,high);+ VERIFY_IS_APPROX(m,n);++ // These guys sometimes fail! This is not good. Any ideas how to fix them!?+ //VERIFY( m(m.size()-1) == high );+ //VERIFY( m(0) == low );++ // check whether everything works with row and col major vectors+ Matrix<Scalar,Dynamic,1> row_vector(size);+ Matrix<Scalar,1,Dynamic> col_vector(size);+ row_vector.setLinSpaced(size,low,high);+ col_vector.setLinSpaced(size,low,high);+ // when using the extended precision (e.g., FPU) the relative error might exceed 1 bit+ // when computing the squared sum in isApprox, thus the 2x factor.+ VERIFY( row_vector.isApprox(col_vector.transpose(), Scalar(2)*NumTraits<Scalar>::epsilon()));++ Matrix<Scalar,Dynamic,1> size_changer(size+50);+ size_changer.setLinSpaced(size,low,high);+ VERIFY( size_changer.size() == size );++ typedef Matrix<Scalar,1,1> ScalarMatrix;+ ScalarMatrix scalar;+ scalar.setLinSpaced(1,low,high);+ VERIFY_IS_APPROX( scalar, ScalarMatrix::Constant(high) );+ VERIFY_IS_APPROX( ScalarMatrix::LinSpaced(1,low,high), ScalarMatrix::Constant(high) );++ // regression test for bug 526 (linear vectorized transversal)+ if (size > 1) {+ m.tail(size-1).setLinSpaced(low, high);+ VERIFY_IS_APPROX(m(size-1), high);+ }+}++template<typename MatrixType>+void testMatrixType(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ const Index rows = m.rows();+ const Index cols = m.cols();++ MatrixType A;+ A.setIdentity(rows, cols);+ VERIFY(equalsIdentity(A));+ VERIFY(equalsIdentity(MatrixType::Identity(rows, cols)));+}++void test_nullary()+{+ CALL_SUBTEST_1( testMatrixType(Matrix2d()) );+ CALL_SUBTEST_2( testMatrixType(MatrixXcf(internal::random<int>(1,300),internal::random<int>(1,300))) );+ CALL_SUBTEST_3( testMatrixType(MatrixXf(internal::random<int>(1,300),internal::random<int>(1,300))) );+ + for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_4( testVectorType(VectorXd(internal::random<int>(1,300))) );+ CALL_SUBTEST_5( testVectorType(Vector4d()) ); // regression test for bug 232+ CALL_SUBTEST_6( testVectorType(Vector3d()) );+ CALL_SUBTEST_7( testVectorType(VectorXf(internal::random<int>(1,300))) );+ CALL_SUBTEST_8( testVectorType(Vector3f()) );+ CALL_SUBTEST_8( testVectorType(Matrix<float,1,1>()) );+ }+}
+ eigen3/test/packetmath.cpp view
@@ -0,0 +1,385 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++// using namespace Eigen;++namespace Eigen {+namespace internal {+template<typename T> T negate(const T& x) { return -x; }+}+}++template<typename Scalar> bool isApproxAbs(const Scalar& a, const Scalar& b, const typename NumTraits<Scalar>::Real& refvalue)+{+ return internal::isMuchSmallerThan(a-b, refvalue);+}++template<typename Scalar> bool areApproxAbs(const Scalar* a, const Scalar* b, int size, const typename NumTraits<Scalar>::Real& refvalue)+{+ for (int i=0; i<size; ++i)+ {+ if (!isApproxAbs(a[i],b[i],refvalue))+ {+ std::cout << "[" << Map<const Matrix<Scalar,1,Dynamic> >(a,size) << "]" << " != " << Map<const Matrix<Scalar,1,Dynamic> >(b,size) << "\n";+ return false;+ }+ }+ return true;+}++template<typename Scalar> bool areApprox(const Scalar* a, const Scalar* b, int size)+{+ for (int i=0; i<size; ++i)+ {+ if (a[i]!=b[i] && !internal::isApprox(a[i],b[i]))+ {+ std::cout << "[" << Map<const Matrix<Scalar,1,Dynamic> >(a,size) << "]" << " != " << Map<const Matrix<Scalar,1,Dynamic> >(b,size) << "\n";+ return false;+ }+ }+ return true;+}+++#define CHECK_CWISE2(REFOP, POP) { \+ for (int i=0; i<PacketSize; ++i) \+ ref[i] = REFOP(data1[i], data1[i+PacketSize]); \+ internal::pstore(data2, POP(internal::pload<Packet>(data1), internal::pload<Packet>(data1+PacketSize))); \+ VERIFY(areApprox(ref, data2, PacketSize) && #POP); \+}++#define CHECK_CWISE1(REFOP, POP) { \+ for (int i=0; i<PacketSize; ++i) \+ ref[i] = REFOP(data1[i]); \+ internal::pstore(data2, POP(internal::pload<Packet>(data1))); \+ VERIFY(areApprox(ref, data2, PacketSize) && #POP); \+}++template<bool Cond,typename Packet>+struct packet_helper+{+ template<typename T>+ inline Packet load(const T* from) const { return internal::pload<Packet>(from); }++ template<typename T>+ inline void store(T* to, const Packet& x) const { internal::pstore(to,x); }+};++template<typename Packet>+struct packet_helper<false,Packet>+{+ template<typename T>+ inline T load(const T* from) const { return *from; }++ template<typename T>+ inline void store(T* to, const T& x) const { *to = x; }+};++#define CHECK_CWISE1_IF(COND, REFOP, POP) if(COND) { \+ packet_helper<COND,Packet> h; \+ for (int i=0; i<PacketSize; ++i) \+ ref[i] = REFOP(data1[i]); \+ h.store(data2, POP(h.load(data1))); \+ VERIFY(areApprox(ref, data2, PacketSize) && #POP); \+}++#define REF_ADD(a,b) ((a)+(b))+#define REF_SUB(a,b) ((a)-(b))+#define REF_MUL(a,b) ((a)*(b))+#define REF_DIV(a,b) ((a)/(b))++template<typename Scalar> void packetmath()+{+ using std::abs;+ typedef typename internal::packet_traits<Scalar>::type Packet;+ const int PacketSize = internal::packet_traits<Scalar>::size;+ typedef typename NumTraits<Scalar>::Real RealScalar;++ const int size = PacketSize*4;+ EIGEN_ALIGN16 Scalar data1[internal::packet_traits<Scalar>::size*4];+ EIGEN_ALIGN16 Scalar data2[internal::packet_traits<Scalar>::size*4];+ EIGEN_ALIGN16 Packet packets[PacketSize*2];+ EIGEN_ALIGN16 Scalar ref[internal::packet_traits<Scalar>::size*4];+ RealScalar refvalue = 0;+ for (int i=0; i<size; ++i)+ {+ data1[i] = internal::random<Scalar>()/RealScalar(PacketSize);+ data2[i] = internal::random<Scalar>()/RealScalar(PacketSize);+ refvalue = (std::max)(refvalue,abs(data1[i]));+ }++ internal::pstore(data2, internal::pload<Packet>(data1));+ VERIFY(areApprox(data1, data2, PacketSize) && "aligned load/store");++ for (int offset=0; offset<PacketSize; ++offset)+ {+ internal::pstore(data2, internal::ploadu<Packet>(data1+offset));+ VERIFY(areApprox(data1+offset, data2, PacketSize) && "internal::ploadu");+ }++ for (int offset=0; offset<PacketSize; ++offset)+ {+ internal::pstoreu(data2+offset, internal::pload<Packet>(data1));+ VERIFY(areApprox(data1, data2+offset, PacketSize) && "internal::pstoreu");+ }++ for (int offset=0; offset<PacketSize; ++offset)+ {+ packets[0] = internal::pload<Packet>(data1);+ packets[1] = internal::pload<Packet>(data1+PacketSize);+ if (offset==0) internal::palign<0>(packets[0], packets[1]);+ else if (offset==1) internal::palign<1>(packets[0], packets[1]);+ else if (offset==2) internal::palign<2>(packets[0], packets[1]);+ else if (offset==3) internal::palign<3>(packets[0], packets[1]);+ internal::pstore(data2, packets[0]);++ for (int i=0; i<PacketSize; ++i)+ ref[i] = data1[i+offset];++ VERIFY(areApprox(ref, data2, PacketSize) && "internal::palign");+ }++ CHECK_CWISE2(REF_ADD, internal::padd);+ CHECK_CWISE2(REF_SUB, internal::psub);+ CHECK_CWISE2(REF_MUL, internal::pmul);+ #ifndef EIGEN_VECTORIZE_ALTIVEC+ if (!internal::is_same<Scalar,int>::value)+ CHECK_CWISE2(REF_DIV, internal::pdiv);+ #endif+ CHECK_CWISE1(internal::negate, internal::pnegate);+ CHECK_CWISE1(numext::conj, internal::pconj);++ for(int offset=0;offset<3;++offset)+ {+ for (int i=0; i<PacketSize; ++i)+ ref[i] = data1[offset];+ internal::pstore(data2, internal::pset1<Packet>(data1[offset]));+ VERIFY(areApprox(ref, data2, PacketSize) && "internal::pset1");+ }+ + VERIFY(internal::isApprox(data1[0], internal::pfirst(internal::pload<Packet>(data1))) && "internal::pfirst");+ + if(PacketSize>1)+ {+ for(int offset=0;offset<4;++offset)+ {+ for(int i=0;i<PacketSize/2;++i)+ ref[2*i+0] = ref[2*i+1] = data1[offset+i];+ internal::pstore(data2,internal::ploaddup<Packet>(data1+offset));+ VERIFY(areApprox(ref, data2, PacketSize) && "ploaddup");+ }+ }++ ref[0] = 0;+ for (int i=0; i<PacketSize; ++i)+ ref[0] += data1[i];+ VERIFY(isApproxAbs(ref[0], internal::predux(internal::pload<Packet>(data1)), refvalue) && "internal::predux");++ ref[0] = 1;+ for (int i=0; i<PacketSize; ++i)+ ref[0] *= data1[i];+ VERIFY(internal::isApprox(ref[0], internal::predux_mul(internal::pload<Packet>(data1))) && "internal::predux_mul");++ for (int j=0; j<PacketSize; ++j)+ {+ ref[j] = 0;+ for (int i=0; i<PacketSize; ++i)+ ref[j] += data1[i+j*PacketSize];+ packets[j] = internal::pload<Packet>(data1+j*PacketSize);+ }+ internal::pstore(data2, internal::preduxp(packets));+ VERIFY(areApproxAbs(ref, data2, PacketSize, refvalue) && "internal::preduxp");++ for (int i=0; i<PacketSize; ++i)+ ref[i] = data1[PacketSize-i-1];+ internal::pstore(data2, internal::preverse(internal::pload<Packet>(data1)));+ VERIFY(areApprox(ref, data2, PacketSize) && "internal::preverse");+}++template<typename Scalar> void packetmath_real()+{+ using std::abs;+ typedef typename internal::packet_traits<Scalar>::type Packet;+ const int PacketSize = internal::packet_traits<Scalar>::size;++ const int size = PacketSize*4;+ EIGEN_ALIGN16 Scalar data1[internal::packet_traits<Scalar>::size*4];+ EIGEN_ALIGN16 Scalar data2[internal::packet_traits<Scalar>::size*4];+ EIGEN_ALIGN16 Scalar ref[internal::packet_traits<Scalar>::size*4];++ for (int i=0; i<size; ++i)+ {+ data1[i] = internal::random<Scalar>(-1,1) * std::pow(Scalar(10), internal::random<Scalar>(-3,3));+ data2[i] = internal::random<Scalar>(-1,1) * std::pow(Scalar(10), internal::random<Scalar>(-3,3));+ }+ CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasSin, std::sin, internal::psin);+ CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasCos, std::cos, internal::pcos);+ CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasTan, std::tan, internal::ptan);+ + for (int i=0; i<size; ++i)+ {+ data1[i] = internal::random<Scalar>(-1,1);+ data2[i] = internal::random<Scalar>(-1,1);+ }+ CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasASin, std::asin, internal::pasin);+ CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasACos, std::acos, internal::pacos);++ for (int i=0; i<size; ++i)+ {+ data1[i] = internal::random<Scalar>(-87,88);+ data2[i] = internal::random<Scalar>(-87,88);+ }+ CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasExp, std::exp, internal::pexp);+ {+ data1[0] = std::numeric_limits<Scalar>::quiet_NaN();+ packet_helper<internal::packet_traits<Scalar>::HasExp,Packet> h;+ h.store(data2, internal::pexp(h.load(data1))); + VERIFY(isNaN(data2[0]));+ }++ for (int i=0; i<size; ++i)+ {+ data1[i] = internal::random<Scalar>(0,1) * std::pow(Scalar(10), internal::random<Scalar>(-6,6));+ data2[i] = internal::random<Scalar>(0,1) * std::pow(Scalar(10), internal::random<Scalar>(-6,6));+ }+ if(internal::random<float>(0,1)<0.1)+ data1[internal::random<int>(0, PacketSize)] = 0;+ CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasSqrt, std::sqrt, internal::psqrt);+ CHECK_CWISE1_IF(internal::packet_traits<Scalar>::HasLog, std::log, internal::plog);+ {+ data1[0] = std::numeric_limits<Scalar>::quiet_NaN();+ packet_helper<internal::packet_traits<Scalar>::HasLog,Packet> h;+ h.store(data2, internal::plog(h.load(data1)));+ VERIFY(isNaN(data2[0]));+ data1[0] = -1.0f;+ h.store(data2, internal::plog(h.load(data1)));+ VERIFY(isNaN(data2[0]));+#if !EIGEN_FAST_MATH+ h.store(data2, internal::psqrt(h.load(data1)));+ VERIFY(isNaN(data2[0]));+ VERIFY(isNaN(data2[1]));+#endif+ }+}++template<typename Scalar> void packetmath_notcomplex()+{+ using std::abs;+ typedef typename internal::packet_traits<Scalar>::type Packet;+ const int PacketSize = internal::packet_traits<Scalar>::size;++ EIGEN_ALIGN16 Scalar data1[internal::packet_traits<Scalar>::size*4];+ EIGEN_ALIGN16 Scalar data2[internal::packet_traits<Scalar>::size*4];+ EIGEN_ALIGN16 Scalar ref[internal::packet_traits<Scalar>::size*4];+ + Array<Scalar,Dynamic,1>::Map(data1, internal::packet_traits<Scalar>::size*4).setRandom();++ ref[0] = data1[0];+ for (int i=0; i<PacketSize; ++i)+ ref[0] = (std::min)(ref[0],data1[i]);+ VERIFY(internal::isApprox(ref[0], internal::predux_min(internal::pload<Packet>(data1))) && "internal::predux_min");++ CHECK_CWISE2((std::min), internal::pmin);+ CHECK_CWISE2((std::max), internal::pmax);+ CHECK_CWISE1(abs, internal::pabs);++ ref[0] = data1[0];+ for (int i=0; i<PacketSize; ++i)+ ref[0] = (std::max)(ref[0],data1[i]);+ VERIFY(internal::isApprox(ref[0], internal::predux_max(internal::pload<Packet>(data1))) && "internal::predux_max");+ + for (int i=0; i<PacketSize; ++i)+ ref[i] = data1[0]+Scalar(i);+ internal::pstore(data2, internal::plset(data1[0]));+ VERIFY(areApprox(ref, data2, PacketSize) && "internal::plset");+}++template<typename Scalar,bool ConjLhs,bool ConjRhs> void test_conj_helper(Scalar* data1, Scalar* data2, Scalar* ref, Scalar* pval)+{+ typedef typename internal::packet_traits<Scalar>::type Packet;+ const int PacketSize = internal::packet_traits<Scalar>::size;+ + internal::conj_if<ConjLhs> cj0;+ internal::conj_if<ConjRhs> cj1;+ internal::conj_helper<Scalar,Scalar,ConjLhs,ConjRhs> cj;+ internal::conj_helper<Packet,Packet,ConjLhs,ConjRhs> pcj;+ + for(int i=0;i<PacketSize;++i)+ {+ ref[i] = cj0(data1[i]) * cj1(data2[i]);+ VERIFY(internal::isApprox(ref[i], cj.pmul(data1[i],data2[i])) && "conj_helper pmul");+ }+ internal::pstore(pval,pcj.pmul(internal::pload<Packet>(data1),internal::pload<Packet>(data2)));+ VERIFY(areApprox(ref, pval, PacketSize) && "conj_helper pmul");+ + for(int i=0;i<PacketSize;++i)+ {+ Scalar tmp = ref[i];+ ref[i] += cj0(data1[i]) * cj1(data2[i]);+ VERIFY(internal::isApprox(ref[i], cj.pmadd(data1[i],data2[i],tmp)) && "conj_helper pmadd");+ }+ internal::pstore(pval,pcj.pmadd(internal::pload<Packet>(data1),internal::pload<Packet>(data2),internal::pload<Packet>(pval)));+ VERIFY(areApprox(ref, pval, PacketSize) && "conj_helper pmadd");+}++template<typename Scalar> void packetmath_complex()+{+ typedef typename internal::packet_traits<Scalar>::type Packet;+ const int PacketSize = internal::packet_traits<Scalar>::size;++ const int size = PacketSize*4;+ EIGEN_ALIGN16 Scalar data1[PacketSize*4];+ EIGEN_ALIGN16 Scalar data2[PacketSize*4];+ EIGEN_ALIGN16 Scalar ref[PacketSize*4];+ EIGEN_ALIGN16 Scalar pval[PacketSize*4];++ for (int i=0; i<size; ++i)+ {+ data1[i] = internal::random<Scalar>() * Scalar(1e2);+ data2[i] = internal::random<Scalar>() * Scalar(1e2);+ }+ + test_conj_helper<Scalar,false,false> (data1,data2,ref,pval);+ test_conj_helper<Scalar,false,true> (data1,data2,ref,pval);+ test_conj_helper<Scalar,true,false> (data1,data2,ref,pval);+ test_conj_helper<Scalar,true,true> (data1,data2,ref,pval);+ + {+ for(int i=0;i<PacketSize;++i)+ ref[i] = Scalar(std::imag(data1[i]),std::real(data1[i]));+ internal::pstore(pval,internal::pcplxflip(internal::pload<Packet>(data1)));+ VERIFY(areApprox(ref, pval, PacketSize) && "pcplxflip");+ }+ + +}++void test_packetmath()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( packetmath<float>() );+ CALL_SUBTEST_2( packetmath<double>() );+ CALL_SUBTEST_3( packetmath<int>() );+ CALL_SUBTEST_1( packetmath<std::complex<float> >() );+ CALL_SUBTEST_2( packetmath<std::complex<double> >() );++ CALL_SUBTEST_1( packetmath_notcomplex<float>() );+ CALL_SUBTEST_2( packetmath_notcomplex<double>() );+ CALL_SUBTEST_3( packetmath_notcomplex<int>() );+ + CALL_SUBTEST_1( packetmath_real<float>() );+ CALL_SUBTEST_2( packetmath_real<double>() );++ CALL_SUBTEST_1( packetmath_complex<std::complex<float> >() );+ CALL_SUBTEST_2( packetmath_complex<std::complex<double> >() );+ }+}
+ eigen3/test/pardiso_support.cpp view
@@ -0,0 +1,29 @@+/* + Intel Copyright (C) ....+*/++#include "sparse_solver.h"+#include <Eigen/PardisoSupport>++template<typename T> void test_pardiso_T()+{+ PardisoLLT < SparseMatrix<T, RowMajor>, Lower> pardiso_llt_lower;+ PardisoLLT < SparseMatrix<T, RowMajor>, Upper> pardiso_llt_upper;+ PardisoLDLT < SparseMatrix<T, RowMajor>, Lower> pardiso_ldlt_lower;+ PardisoLDLT < SparseMatrix<T, RowMajor>, Upper> pardiso_ldlt_upper;+ PardisoLU < SparseMatrix<T, RowMajor> > pardiso_lu;++ check_sparse_spd_solving(pardiso_llt_lower);+ check_sparse_spd_solving(pardiso_llt_upper);+ check_sparse_spd_solving(pardiso_ldlt_lower);+ check_sparse_spd_solving(pardiso_ldlt_upper);+ check_sparse_square_solving(pardiso_lu);+}++void test_pardiso_support()+{+ CALL_SUBTEST_1(test_pardiso_T<float>());+ CALL_SUBTEST_2(test_pardiso_T<double>());+ CALL_SUBTEST_3(test_pardiso_T< std::complex<float> >());+ CALL_SUBTEST_4(test_pardiso_T< std::complex<double> >());+}
+ eigen3/test/pastix_support.cpp view
@@ -0,0 +1,44 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2012 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.+#include "sparse_solver.h"+#include <Eigen/PaStiXSupport>+#include <unsupported/Eigen/SparseExtra>+++template<typename T> void test_pastix_T()+{+ PastixLLT< SparseMatrix<T, ColMajor>, Eigen::Lower > pastix_llt_lower;+ PastixLDLT< SparseMatrix<T, ColMajor>, Eigen::Lower > pastix_ldlt_lower;+ PastixLLT< SparseMatrix<T, ColMajor>, Eigen::Upper > pastix_llt_upper;+ PastixLDLT< SparseMatrix<T, ColMajor>, Eigen::Upper > pastix_ldlt_upper;+ PastixLU< SparseMatrix<T, ColMajor> > pastix_lu;++ check_sparse_spd_solving(pastix_llt_lower);+ check_sparse_spd_solving(pastix_ldlt_lower);+ check_sparse_spd_solving(pastix_llt_upper);+ check_sparse_spd_solving(pastix_ldlt_upper);+ check_sparse_square_solving(pastix_lu);+}++// There is no support for selfadjoint matrices with PaStiX. +// Complex symmetric matrices should pass though+template<typename T> void test_pastix_T_LU()+{+ PastixLU< SparseMatrix<T, ColMajor> > pastix_lu;+ check_sparse_square_solving(pastix_lu);+}++void test_pastix_support()+{+ CALL_SUBTEST_1(test_pastix_T<float>());+ CALL_SUBTEST_2(test_pastix_T<double>());+ CALL_SUBTEST_3( (test_pastix_T_LU<std::complex<float> >()) );+ CALL_SUBTEST_4(test_pastix_T_LU<std::complex<double> >());+}
+ eigen3/test/permutationmatrices.cpp view
@@ -0,0 +1,116 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++using namespace std;+template<typename MatrixType> void permutationmatrices(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime,+ Options = MatrixType::Options };+ typedef PermutationMatrix<Rows> LeftPermutationType;+ typedef Matrix<int, Rows, 1> LeftPermutationVectorType;+ typedef Map<LeftPermutationType> MapLeftPerm;+ typedef PermutationMatrix<Cols> RightPermutationType;+ typedef Matrix<int, Cols, 1> RightPermutationVectorType;+ typedef Map<RightPermutationType> MapRightPerm;++ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m_original = MatrixType::Random(rows,cols);+ LeftPermutationVectorType lv;+ randomPermutationVector(lv, rows);+ LeftPermutationType lp(lv);+ RightPermutationVectorType rv;+ randomPermutationVector(rv, cols);+ RightPermutationType rp(rv);+ MatrixType m_permuted = lp * m_original * rp;++ for (int i=0; i<rows; i++)+ for (int j=0; j<cols; j++)+ VERIFY_IS_APPROX(m_permuted(lv(i),j), m_original(i,rv(j)));++ Matrix<Scalar,Rows,Rows> lm(lp);+ Matrix<Scalar,Cols,Cols> rm(rp);++ VERIFY_IS_APPROX(m_permuted, lm*m_original*rm);++ VERIFY_IS_APPROX(lp.inverse()*m_permuted*rp.inverse(), m_original);+ VERIFY_IS_APPROX(lv.asPermutation().inverse()*m_permuted*rv.asPermutation().inverse(), m_original);+ VERIFY_IS_APPROX(MapLeftPerm(lv.data(),lv.size()).inverse()*m_permuted*MapRightPerm(rv.data(),rv.size()).inverse(), m_original);+ + VERIFY((lp*lp.inverse()).toDenseMatrix().isIdentity());+ VERIFY((lv.asPermutation()*lv.asPermutation().inverse()).toDenseMatrix().isIdentity());+ VERIFY((MapLeftPerm(lv.data(),lv.size())*MapLeftPerm(lv.data(),lv.size()).inverse()).toDenseMatrix().isIdentity());++ LeftPermutationVectorType lv2;+ randomPermutationVector(lv2, rows);+ LeftPermutationType lp2(lv2);+ Matrix<Scalar,Rows,Rows> lm2(lp2);+ VERIFY_IS_APPROX((lp*lp2).toDenseMatrix().template cast<Scalar>(), lm*lm2);+ VERIFY_IS_APPROX((lv.asPermutation()*lv2.asPermutation()).toDenseMatrix().template cast<Scalar>(), lm*lm2);+ VERIFY_IS_APPROX((MapLeftPerm(lv.data(),lv.size())*MapLeftPerm(lv2.data(),lv2.size())).toDenseMatrix().template cast<Scalar>(), lm*lm2);++ LeftPermutationType identityp;+ identityp.setIdentity(rows);+ VERIFY_IS_APPROX(m_original, identityp*m_original);++ // check inplace permutations+ m_permuted = m_original;+ m_permuted = lp.inverse() * m_permuted;+ VERIFY_IS_APPROX(m_permuted, lp.inverse()*m_original);++ m_permuted = m_original;+ m_permuted = m_permuted * rp.inverse();+ VERIFY_IS_APPROX(m_permuted, m_original*rp.inverse());++ m_permuted = m_original;+ m_permuted = lp * m_permuted;+ VERIFY_IS_APPROX(m_permuted, lp*m_original);++ m_permuted = m_original;+ m_permuted = m_permuted * rp;+ VERIFY_IS_APPROX(m_permuted, m_original*rp);++ if(rows>1 && cols>1)+ {+ lp2 = lp;+ Index i = internal::random<Index>(0, rows-1);+ Index j;+ do j = internal::random<Index>(0, rows-1); while(j==i);+ lp2.applyTranspositionOnTheLeft(i, j);+ lm = lp;+ lm.row(i).swap(lm.row(j));+ VERIFY_IS_APPROX(lm, lp2.toDenseMatrix().template cast<Scalar>());++ RightPermutationType rp2 = rp;+ i = internal::random<Index>(0, cols-1);+ do j = internal::random<Index>(0, cols-1); while(j==i);+ rp2.applyTranspositionOnTheRight(i, j);+ rm = rp;+ rm.col(i).swap(rm.col(j));+ VERIFY_IS_APPROX(rm, rp2.toDenseMatrix().template cast<Scalar>());+ } +}++void test_permutationmatrices()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( permutationmatrices(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( permutationmatrices(Matrix3f()) );+ CALL_SUBTEST_3( permutationmatrices(Matrix<double,3,3,RowMajor>()) );+ CALL_SUBTEST_4( permutationmatrices(Matrix4d()) );+ CALL_SUBTEST_5( permutationmatrices(Matrix<double,40,60>()) );+ CALL_SUBTEST_6( permutationmatrices(Matrix<double,Dynamic,Dynamic,RowMajor>(20, 30)) );+ CALL_SUBTEST_7( permutationmatrices(MatrixXcf(15, 10)) );+ }+}
+ eigen3/test/prec_inverse_4x4.cpp view
@@ -0,0 +1,68 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/LU>+#include <algorithm>++template<typename MatrixType> void inverse_permutation_4x4()+{+ typedef typename MatrixType::Scalar Scalar;+ Vector4i indices(0,1,2,3);+ for(int i = 0; i < 24; ++i)+ {+ MatrixType m = PermutationMatrix<4>(indices);+ MatrixType inv = m.inverse();+ double error = double( (m*inv-MatrixType::Identity()).norm() / NumTraits<Scalar>::epsilon() );+ EIGEN_DEBUG_VAR(error)+ VERIFY(error == 0.0);+ std::next_permutation(indices.data(),indices.data()+4);+ }+}++template<typename MatrixType> void inverse_general_4x4(int repeat)+{+ using std::abs;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::RealScalar RealScalar;+ double error_sum = 0., error_max = 0.;+ for(int i = 0; i < repeat; ++i)+ {+ MatrixType m;+ RealScalar absdet;+ do {+ m = MatrixType::Random();+ absdet = abs(m.determinant());+ } while(absdet < NumTraits<Scalar>::epsilon());+ MatrixType inv = m.inverse();+ double error = double( (m*inv-MatrixType::Identity()).norm() * absdet / NumTraits<Scalar>::epsilon() );+ error_sum += error;+ error_max = (std::max)(error_max, error);+ }+ std::cerr << "inverse_general_4x4, Scalar = " << type_name<Scalar>() << std::endl;+ double error_avg = error_sum / repeat;+ EIGEN_DEBUG_VAR(error_avg);+ EIGEN_DEBUG_VAR(error_max);+ // FIXME that 1.25 used to be a 1.0 until the NumTraits changes on 28 April 2010, what's going wrong??+ // FIXME that 1.25 used to be 1.2 until we tested gcc 4.1 on 30 June 2010 and got 1.21.+ VERIFY(error_avg < (NumTraits<Scalar>::IsComplex ? 8.0 : 1.25));+ VERIFY(error_max < (NumTraits<Scalar>::IsComplex ? 64.0 : 20.0));+}++void test_prec_inverse_4x4()+{+ CALL_SUBTEST_1((inverse_permutation_4x4<Matrix4f>()));+ CALL_SUBTEST_1(( inverse_general_4x4<Matrix4f>(200000 * g_repeat) ));++ CALL_SUBTEST_2((inverse_permutation_4x4<Matrix<double,4,4,RowMajor> >()));+ CALL_SUBTEST_2(( inverse_general_4x4<Matrix<double,4,4,RowMajor> >(200000 * g_repeat) ));++ CALL_SUBTEST_3((inverse_permutation_4x4<Matrix4cf>()));+ CALL_SUBTEST_3((inverse_general_4x4<Matrix4cf>(50000 * g_repeat)));+}
+ eigen3/test/product.h view
@@ -0,0 +1,150 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/QR>++template<typename Derived1, typename Derived2>+bool areNotApprox(const MatrixBase<Derived1>& m1, const MatrixBase<Derived2>& m2, typename Derived1::RealScalar epsilon = NumTraits<typename Derived1::RealScalar>::dummy_precision())+{+ return !((m1-m2).cwiseAbs2().maxCoeff() < epsilon * epsilon+ * (std::max)(m1.cwiseAbs2().maxCoeff(), m2.cwiseAbs2().maxCoeff()));+}++template<typename MatrixType> void product(const MatrixType& m)+{+ /* this test covers the following files:+ Identity.h Product.h+ */+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> RowVectorType;+ typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, 1> ColVectorType;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> RowSquareMatrixType;+ typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime> ColSquareMatrixType;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime,+ MatrixType::Flags&RowMajorBit?ColMajor:RowMajor> OtherMajorMatrixType;++ Index rows = m.rows();+ Index cols = m.cols();++ // this test relies a lot on Random.h, and there's not much more that we can do+ // to test it, hence I consider that we will have tested Random.h+ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols);+ RowSquareMatrixType+ identity = RowSquareMatrixType::Identity(rows, rows),+ square = RowSquareMatrixType::Random(rows, rows),+ res = RowSquareMatrixType::Random(rows, rows);+ ColSquareMatrixType+ square2 = ColSquareMatrixType::Random(cols, cols),+ res2 = ColSquareMatrixType::Random(cols, cols);+ RowVectorType v1 = RowVectorType::Random(rows);+ ColVectorType vc2 = ColVectorType::Random(cols), vcres(cols);+ OtherMajorMatrixType tm1 = m1;++ Scalar s1 = internal::random<Scalar>();++ Index r = internal::random<Index>(0, rows-1),+ c = internal::random<Index>(0, cols-1),+ c2 = internal::random<Index>(0, cols-1);++ // begin testing Product.h: only associativity for now+ // (we use Transpose.h but this doesn't count as a test for it)+ VERIFY_IS_APPROX((m1*m1.transpose())*m2, m1*(m1.transpose()*m2));+ m3 = m1;+ m3 *= m1.transpose() * m2;+ VERIFY_IS_APPROX(m3, m1 * (m1.transpose()*m2));+ VERIFY_IS_APPROX(m3, m1 * (m1.transpose()*m2));++ // continue testing Product.h: distributivity+ VERIFY_IS_APPROX(square*(m1 + m2), square*m1+square*m2);+ VERIFY_IS_APPROX(square*(m1 - m2), square*m1-square*m2);++ // continue testing Product.h: compatibility with ScalarMultiple.h+ VERIFY_IS_APPROX(s1*(square*m1), (s1*square)*m1);+ VERIFY_IS_APPROX(s1*(square*m1), square*(m1*s1));++ // test Product.h together with Identity.h+ VERIFY_IS_APPROX(v1, identity*v1);+ VERIFY_IS_APPROX(v1.transpose(), v1.transpose() * identity);+ // again, test operator() to check const-qualification+ VERIFY_IS_APPROX(MatrixType::Identity(rows, cols)(r,c), static_cast<Scalar>(r==c));++ if (rows!=cols)+ VERIFY_RAISES_ASSERT(m3 = m1*m1);++ // test the previous tests were not screwed up because operator* returns 0+ // (we use the more accurate default epsilon)+ if (!NumTraits<Scalar>::IsInteger && (std::min)(rows,cols)>1)+ {+ VERIFY(areNotApprox(m1.transpose()*m2,m2.transpose()*m1));+ }++ // test optimized operator+= path+ res = square;+ res.noalias() += m1 * m2.transpose();+ VERIFY_IS_APPROX(res, square + m1 * m2.transpose());+ if (!NumTraits<Scalar>::IsInteger && (std::min)(rows,cols)>1)+ {+ VERIFY(areNotApprox(res,square + m2 * m1.transpose()));+ }+ vcres = vc2;+ vcres.noalias() += m1.transpose() * v1;+ VERIFY_IS_APPROX(vcres, vc2 + m1.transpose() * v1);++ // test optimized operator-= path+ res = square;+ res.noalias() -= m1 * m2.transpose();+ VERIFY_IS_APPROX(res, square - (m1 * m2.transpose()));+ if (!NumTraits<Scalar>::IsInteger && (std::min)(rows,cols)>1)+ {+ VERIFY(areNotApprox(res,square - m2 * m1.transpose()));+ }+ vcres = vc2;+ vcres.noalias() -= m1.transpose() * v1;+ VERIFY_IS_APPROX(vcres, vc2 - m1.transpose() * v1);++ tm1 = m1;+ VERIFY_IS_APPROX(tm1.transpose() * v1, m1.transpose() * v1);+ VERIFY_IS_APPROX(v1.transpose() * tm1, v1.transpose() * m1);++ // test submatrix and matrix/vector product+ for (int i=0; i<rows; ++i)+ res.row(i) = m1.row(i) * m2.transpose();+ VERIFY_IS_APPROX(res, m1 * m2.transpose());+ // the other way round:+ for (int i=0; i<rows; ++i)+ res.col(i) = m1 * m2.transpose().col(i);+ VERIFY_IS_APPROX(res, m1 * m2.transpose());++ res2 = square2;+ res2.noalias() += m1.transpose() * m2;+ VERIFY_IS_APPROX(res2, square2 + m1.transpose() * m2);+ if (!NumTraits<Scalar>::IsInteger && (std::min)(rows,cols)>1)+ {+ VERIFY(areNotApprox(res2,square2 + m2.transpose() * m1));+ }++ VERIFY_IS_APPROX(res.col(r).noalias() = square.adjoint() * square.col(r), (square.adjoint() * square.col(r)).eval());+ VERIFY_IS_APPROX(res.col(r).noalias() = square * square.col(r), (square * square.col(r)).eval());++ // inner product+ Scalar x = square2.row(c) * square2.col(c2);+ VERIFY_IS_APPROX(x, square2.row(c).transpose().cwiseProduct(square2.col(c2)).sum());+ + // outer product+ VERIFY_IS_APPROX(m1.col(c) * m1.row(r), m1.block(0,c,rows,1) * m1.block(r,0,1,cols));+ VERIFY_IS_APPROX(m1.row(r).transpose() * m1.col(c).transpose(), m1.block(r,0,1,cols).transpose() * m1.block(0,c,rows,1).transpose());+ VERIFY_IS_APPROX(m1.block(0,c,rows,1) * m1.row(r), m1.block(0,c,rows,1) * m1.block(r,0,1,cols));+ VERIFY_IS_APPROX(m1.col(c) * m1.block(r,0,1,cols), m1.block(0,c,rows,1) * m1.block(r,0,1,cols));+ VERIFY_IS_APPROX(m1.leftCols(1) * m1.row(r), m1.block(0,0,rows,1) * m1.block(r,0,1,cols));+ VERIFY_IS_APPROX(m1.col(c) * m1.topRows(1), m1.block(0,c,rows,1) * m1.block(0,0,1,cols)); +}
+ eigen3/test/product_extra.cpp view
@@ -0,0 +1,237 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void product_extra(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, 1, Dynamic> RowVectorType;+ typedef Matrix<Scalar, Dynamic, 1> ColVectorType;+ typedef Matrix<Scalar, Dynamic, Dynamic,+ MatrixType::Flags&RowMajorBit> OtherMajorMatrixType;++ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols),+ mzero = MatrixType::Zero(rows, cols),+ identity = MatrixType::Identity(rows, rows),+ square = MatrixType::Random(rows, rows),+ res = MatrixType::Random(rows, rows),+ square2 = MatrixType::Random(cols, cols),+ res2 = MatrixType::Random(cols, cols);+ RowVectorType v1 = RowVectorType::Random(rows), vrres(rows);+ ColVectorType vc2 = ColVectorType::Random(cols), vcres(cols);+ OtherMajorMatrixType tm1 = m1;++ Scalar s1 = internal::random<Scalar>(),+ s2 = internal::random<Scalar>(),+ s3 = internal::random<Scalar>();++ VERIFY_IS_APPROX(m3.noalias() = m1 * m2.adjoint(), m1 * m2.adjoint().eval());+ VERIFY_IS_APPROX(m3.noalias() = m1.adjoint() * square.adjoint(), m1.adjoint().eval() * square.adjoint().eval());+ VERIFY_IS_APPROX(m3.noalias() = m1.adjoint() * m2, m1.adjoint().eval() * m2);+ VERIFY_IS_APPROX(m3.noalias() = (s1 * m1.adjoint()) * m2, (s1 * m1.adjoint()).eval() * m2);+ VERIFY_IS_APPROX(m3.noalias() = ((s1 * m1).adjoint()) * m2, (numext::conj(s1) * m1.adjoint()).eval() * m2);+ VERIFY_IS_APPROX(m3.noalias() = (- m1.adjoint() * s1) * (s3 * m2), (- m1.adjoint() * s1).eval() * (s3 * m2).eval());+ VERIFY_IS_APPROX(m3.noalias() = (s2 * m1.adjoint() * s1) * m2, (s2 * m1.adjoint() * s1).eval() * m2);+ VERIFY_IS_APPROX(m3.noalias() = (-m1*s2) * s1*m2.adjoint(), (-m1*s2).eval() * (s1*m2.adjoint()).eval());++ // a very tricky case where a scale factor has to be automatically conjugated:+ VERIFY_IS_APPROX( m1.adjoint() * (s1*m2).conjugate(), (m1.adjoint()).eval() * ((s1*m2).conjugate()).eval());+++ // test all possible conjugate combinations for the four matrix-vector product cases:++ VERIFY_IS_APPROX((-m1.conjugate() * s2) * (s1 * vc2),+ (-m1.conjugate()*s2).eval() * (s1 * vc2).eval());+ VERIFY_IS_APPROX((-m1 * s2) * (s1 * vc2.conjugate()),+ (-m1*s2).eval() * (s1 * vc2.conjugate()).eval());+ VERIFY_IS_APPROX((-m1.conjugate() * s2) * (s1 * vc2.conjugate()),+ (-m1.conjugate()*s2).eval() * (s1 * vc2.conjugate()).eval());++ VERIFY_IS_APPROX((s1 * vc2.transpose()) * (-m1.adjoint() * s2),+ (s1 * vc2.transpose()).eval() * (-m1.adjoint()*s2).eval());+ VERIFY_IS_APPROX((s1 * vc2.adjoint()) * (-m1.transpose() * s2),+ (s1 * vc2.adjoint()).eval() * (-m1.transpose()*s2).eval());+ VERIFY_IS_APPROX((s1 * vc2.adjoint()) * (-m1.adjoint() * s2),+ (s1 * vc2.adjoint()).eval() * (-m1.adjoint()*s2).eval());++ VERIFY_IS_APPROX((-m1.adjoint() * s2) * (s1 * v1.transpose()),+ (-m1.adjoint()*s2).eval() * (s1 * v1.transpose()).eval());+ VERIFY_IS_APPROX((-m1.transpose() * s2) * (s1 * v1.adjoint()),+ (-m1.transpose()*s2).eval() * (s1 * v1.adjoint()).eval());+ VERIFY_IS_APPROX((-m1.adjoint() * s2) * (s1 * v1.adjoint()),+ (-m1.adjoint()*s2).eval() * (s1 * v1.adjoint()).eval());++ VERIFY_IS_APPROX((s1 * v1) * (-m1.conjugate() * s2),+ (s1 * v1).eval() * (-m1.conjugate()*s2).eval());+ VERIFY_IS_APPROX((s1 * v1.conjugate()) * (-m1 * s2),+ (s1 * v1.conjugate()).eval() * (-m1*s2).eval());+ VERIFY_IS_APPROX((s1 * v1.conjugate()) * (-m1.conjugate() * s2),+ (s1 * v1.conjugate()).eval() * (-m1.conjugate()*s2).eval());++ VERIFY_IS_APPROX((-m1.adjoint() * s2) * (s1 * v1.adjoint()),+ (-m1.adjoint()*s2).eval() * (s1 * v1.adjoint()).eval());++ // test the vector-matrix product with non aligned starts+ Index i = internal::random<Index>(0,m1.rows()-2);+ Index j = internal::random<Index>(0,m1.cols()-2);+ Index r = internal::random<Index>(1,m1.rows()-i);+ Index c = internal::random<Index>(1,m1.cols()-j);+ Index i2 = internal::random<Index>(0,m1.rows()-1);+ Index j2 = internal::random<Index>(0,m1.cols()-1);++ VERIFY_IS_APPROX(m1.col(j2).adjoint() * m1.block(0,j,m1.rows(),c), m1.col(j2).adjoint().eval() * m1.block(0,j,m1.rows(),c).eval());+ VERIFY_IS_APPROX(m1.block(i,0,r,m1.cols()) * m1.row(i2).adjoint(), m1.block(i,0,r,m1.cols()).eval() * m1.row(i2).adjoint().eval());+ + // regression test+ MatrixType tmp = m1 * m1.adjoint() * s1;+ VERIFY_IS_APPROX(tmp, m1 * m1.adjoint() * s1);+}++// Regression test for bug reported at http://forum.kde.org/viewtopic.php?f=74&t=96947+void mat_mat_scalar_scalar_product()+{+ Eigen::Matrix2Xd dNdxy(2, 3);+ dNdxy << -0.5, 0.5, 0,+ -0.3, 0, 0.3;+ double det = 6.0, wt = 0.5;+ VERIFY_IS_APPROX(dNdxy.transpose()*dNdxy*det*wt, det*wt*dNdxy.transpose()*dNdxy);+}++template <typename MatrixType> +void zero_sized_objects(const MatrixType& m)+{+ typedef typename MatrixType::Scalar Scalar;+ const int PacketSize = internal::packet_traits<Scalar>::size;+ const int PacketSize1 = PacketSize>1 ? PacketSize-1 : 1;+ DenseIndex rows = m.rows();+ DenseIndex cols = m.cols();+ + {+ MatrixType res, a(rows,0), b(0,cols);+ VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(rows,cols) );+ VERIFY_IS_APPROX( (res=a*a.transpose()), MatrixType::Zero(rows,rows) );+ VERIFY_IS_APPROX( (res=b.transpose()*b), MatrixType::Zero(cols,cols) );+ VERIFY_IS_APPROX( (res=b.transpose()*a.transpose()), MatrixType::Zero(cols,rows) );+ }+ + {+ MatrixType res, a(rows,cols), b(cols,0);+ res = a*b;+ VERIFY(res.rows()==rows && res.cols()==0);+ b.resize(0,rows);+ res = b*a;+ VERIFY(res.rows()==0 && res.cols()==cols);+ }+ + {+ Matrix<Scalar,PacketSize,0> a;+ Matrix<Scalar,0,1> b;+ Matrix<Scalar,PacketSize,1> res;+ VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(PacketSize,1) );+ VERIFY_IS_APPROX( (res=a.lazyProduct(b)), MatrixType::Zero(PacketSize,1) );+ }+ + {+ Matrix<Scalar,PacketSize1,0> a;+ Matrix<Scalar,0,1> b;+ Matrix<Scalar,PacketSize1,1> res;+ VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(PacketSize1,1) );+ VERIFY_IS_APPROX( (res=a.lazyProduct(b)), MatrixType::Zero(PacketSize1,1) );+ }+ + {+ Matrix<Scalar,PacketSize,Dynamic> a(PacketSize,0);+ Matrix<Scalar,Dynamic,1> b(0,1);+ Matrix<Scalar,PacketSize,1> res;+ VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(PacketSize,1) );+ VERIFY_IS_APPROX( (res=a.lazyProduct(b)), MatrixType::Zero(PacketSize,1) );+ }+ + {+ Matrix<Scalar,PacketSize1,Dynamic> a(PacketSize1,0);+ Matrix<Scalar,Dynamic,1> b(0,1);+ Matrix<Scalar,PacketSize1,1> res;+ VERIFY_IS_APPROX( (res=a*b), MatrixType::Zero(PacketSize1,1) );+ VERIFY_IS_APPROX( (res=a.lazyProduct(b)), MatrixType::Zero(PacketSize1,1) );+ }+}++void bug_127()+{+ // Bug 127+ //+ // a product of the form lhs*rhs with+ //+ // lhs:+ // rows = 1, cols = 4+ // RowsAtCompileTime = 1, ColsAtCompileTime = -1+ // MaxRowsAtCompileTime = 1, MaxColsAtCompileTime = 5+ //+ // rhs:+ // rows = 4, cols = 0+ // RowsAtCompileTime = -1, ColsAtCompileTime = -1+ // MaxRowsAtCompileTime = 5, MaxColsAtCompileTime = 1+ //+ // was failing on a runtime assertion, because it had been mis-compiled as a dot product because Product.h was using the+ // max-sizes to detect size 1 indicating vectors, and that didn't account for 0-sized object with max-size 1.++ Matrix<float,1,Dynamic,RowMajor,1,5> a(1,4);+ Matrix<float,Dynamic,Dynamic,ColMajor,5,1> b(4,0);+ a*b;+}++void unaligned_objects()+{+ // Regression test for the bug reported here:+ // http://forum.kde.org/viewtopic.php?f=74&t=107541+ // Recall the matrix*vector kernel avoid unaligned loads by loading two packets and then reassemble then.+ // There was a mistake in the computation of the valid range for fully unaligned objects: in some rare cases,+ // memory was read outside the allocated matrix memory. Though the values were not used, this might raise segfault.+ for(int m=450;m<460;++m)+ {+ for(int n=8;n<12;++n)+ {+ MatrixXf M(m, n);+ VectorXf v1(n), r1(500);+ RowVectorXf v2(m), r2(16);++ M.setRandom();+ v1.setRandom();+ v2.setRandom();+ for(int o=0; o<4; ++o)+ {+ r1.segment(o,m).noalias() = M * v1;+ VERIFY_IS_APPROX(r1.segment(o,m), M * MatrixXf(v1));+ r2.segment(o,n).noalias() = v2 * M;+ VERIFY_IS_APPROX(r2.segment(o,n), MatrixXf(v2) * M);+ }+ }+ }+}++void test_product_extra()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( product_extra(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_2( product_extra(MatrixXd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_2( mat_mat_scalar_scalar_product() );+ CALL_SUBTEST_3( product_extra(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );+ CALL_SUBTEST_4( product_extra(MatrixXcd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );+ CALL_SUBTEST_1( zero_sized_objects(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ }+ CALL_SUBTEST_5( bug_127() );+ CALL_SUBTEST_6( unaligned_objects() );+}
+ eigen3/test/product_large.cpp view
@@ -0,0 +1,64 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "product.h"++void test_product_large()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( product(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_2( product(MatrixXd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_3( product(MatrixXi(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_4( product(MatrixXcf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2), internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );+ CALL_SUBTEST_5( product(Matrix<float,Dynamic,Dynamic,RowMajor>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE), internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ }++#if defined EIGEN_TEST_PART_6+ {+ // test a specific issue in DiagonalProduct+ int N = 1000000;+ VectorXf v = VectorXf::Ones(N);+ MatrixXf m = MatrixXf::Ones(N,3);+ m = (v+v).asDiagonal() * m;+ VERIFY_IS_APPROX(m, MatrixXf::Constant(N,3,2));+ }++ {+ // test deferred resizing in Matrix::operator=+ MatrixXf a = MatrixXf::Random(10,4), b = MatrixXf::Random(4,10), c = a;+ VERIFY_IS_APPROX((a = a * b), (c * b).eval());+ }++ {+ // check the functions to setup blocking sizes compile and do not segfault+ // FIXME check they do what they are supposed to do !!+ std::ptrdiff_t l1 = internal::random<int>(10000,20000);+ std::ptrdiff_t l2 = internal::random<int>(1000000,2000000);+ setCpuCacheSizes(l1,l2);+ VERIFY(l1==l1CacheSize());+ VERIFY(l2==l2CacheSize());+ std::ptrdiff_t k1 = internal::random<int>(10,100)*16;+ std::ptrdiff_t m1 = internal::random<int>(10,100)*16;+ std::ptrdiff_t n1 = internal::random<int>(10,100)*16;+ // only makes sure it compiles fine+ internal::computeProductBlockingSizes<float,float>(k1,m1,n1);+ }++ {+ // test regression in row-vector by matrix (bad Map type)+ MatrixXf mat1(10,32); mat1.setRandom();+ MatrixXf mat2(32,32); mat2.setRandom();+ MatrixXf r1 = mat1.row(2)*mat2.transpose();+ VERIFY_IS_APPROX(r1, (mat1.row(2)*mat2.transpose()).eval());++ MatrixXf r2 = mat1.row(2)*mat2;+ VERIFY_IS_APPROX(r2, (mat1.row(2)*mat2).eval());+ }+#endif+}
+ eigen3/test/product_mmtr.cpp view
@@ -0,0 +1,63 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++#define CHECK_MMTR(DEST, TRI, OP) { \+ ref2 = ref1 = DEST; \+ DEST.template triangularView<TRI>() OP; \+ ref1 OP; \+ ref2.template triangularView<TRI>() = ref1; \+ VERIFY_IS_APPROX(DEST,ref2); \+ }++template<typename Scalar> void mmtr(int size)+{+ typedef Matrix<Scalar,Dynamic,Dynamic,ColMajor> MatrixColMaj;+ typedef Matrix<Scalar,Dynamic,Dynamic,RowMajor> MatrixRowMaj;++ DenseIndex othersize = internal::random<DenseIndex>(1,200);+ + MatrixColMaj matc = MatrixColMaj::Zero(size, size);+ MatrixRowMaj matr = MatrixRowMaj::Zero(size, size);+ MatrixColMaj ref1(size, size), ref2(size, size);+ + MatrixColMaj soc(size,othersize); soc.setRandom();+ MatrixColMaj osc(othersize,size); osc.setRandom();+ MatrixRowMaj sor(size,othersize); sor.setRandom();+ MatrixRowMaj osr(othersize,size); osr.setRandom();+ + Scalar s = internal::random<Scalar>();+ + CHECK_MMTR(matc, Lower, = s*soc*sor.adjoint());+ CHECK_MMTR(matc, Upper, = s*(soc*soc.adjoint()));+ CHECK_MMTR(matr, Lower, = s*soc*soc.adjoint());+ CHECK_MMTR(matr, Upper, = soc*(s*sor.adjoint()));+ + CHECK_MMTR(matc, Lower, += s*soc*soc.adjoint());+ CHECK_MMTR(matc, Upper, += s*(soc*sor.transpose()));+ CHECK_MMTR(matr, Lower, += s*sor*soc.adjoint());+ CHECK_MMTR(matr, Upper, += soc*(s*soc.adjoint()));+ + CHECK_MMTR(matc, Lower, -= s*soc*soc.adjoint());+ CHECK_MMTR(matc, Upper, -= s*(osc.transpose()*osc.conjugate()));+ CHECK_MMTR(matr, Lower, -= s*soc*soc.adjoint());+ CHECK_MMTR(matr, Upper, -= soc*(s*soc.adjoint()));+}++void test_product_mmtr()+{+ for(int i = 0; i < g_repeat ; i++)+ {+ CALL_SUBTEST_1((mmtr<float>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));+ CALL_SUBTEST_2((mmtr<double>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));+ CALL_SUBTEST_3((mmtr<std::complex<float> >(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))));+ CALL_SUBTEST_4((mmtr<std::complex<double> >(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))));+ }+}
+ eigen3/test/product_notemporary.cpp view
@@ -0,0 +1,141 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++static int nb_temporaries;++inline void on_temporary_creation(int size) {+ // here's a great place to set a breakpoint when debugging failures in this test!+ if(size!=0) nb_temporaries++;+}+ ++#define EIGEN_DENSE_STORAGE_CTOR_PLUGIN { on_temporary_creation(size); }++#include "main.h"++#define VERIFY_EVALUATION_COUNT(XPR,N) {\+ nb_temporaries = 0; \+ XPR; \+ if(nb_temporaries!=N) std::cerr << "nb_temporaries == " << nb_temporaries << "\n"; \+ VERIFY( (#XPR) && nb_temporaries==N ); \+ }++template<typename MatrixType> void product_notemporary(const MatrixType& m)+{+ /* This test checks the number of temporaries created+ * during the evaluation of a complex expression */+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::RealScalar RealScalar;+ typedef Matrix<Scalar, 1, Dynamic> RowVectorType;+ typedef Matrix<Scalar, Dynamic, 1> ColVectorType;+ typedef Matrix<Scalar, Dynamic, Dynamic, ColMajor> ColMajorMatrixType;+ typedef Matrix<Scalar, Dynamic, Dynamic, RowMajor> RowMajorMatrixType;++ Index rows = m.rows();+ Index cols = m.cols();++ ColMajorMatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols);+ RowVectorType rv1 = RowVectorType::Random(rows), rvres(rows);+ ColVectorType cv1 = ColVectorType::Random(cols), cvres(cols);+ RowMajorMatrixType rm3(rows, cols);++ Scalar s1 = internal::random<Scalar>(),+ s2 = internal::random<Scalar>(),+ s3 = internal::random<Scalar>();++ Index c0 = internal::random<Index>(4,cols-8),+ c1 = internal::random<Index>(8,cols-c0),+ r0 = internal::random<Index>(4,cols-8),+ r1 = internal::random<Index>(8,rows-r0);++ VERIFY_EVALUATION_COUNT( m3 = (m1 * m2.adjoint()), 1);+ VERIFY_EVALUATION_COUNT( m3.noalias() = m1 * m2.adjoint(), 0);++ VERIFY_EVALUATION_COUNT( m3.noalias() = s1 * (m1 * m2.transpose()), 0);++ VERIFY_EVALUATION_COUNT( m3.noalias() = s1 * m1 * s2 * m2.adjoint(), 0);+ VERIFY_EVALUATION_COUNT( m3.noalias() = s1 * m1 * s2 * (m1*s3+m2*s2).adjoint(), 1);+ VERIFY_EVALUATION_COUNT( m3.noalias() = (s1 * m1).adjoint() * s2 * m2, 0);+ VERIFY_EVALUATION_COUNT( m3.noalias() += s1 * (-m1*s3).adjoint() * (s2 * m2 * s3), 0);+ VERIFY_EVALUATION_COUNT( m3.noalias() -= s1 * (m1.transpose() * m2), 0);++ VERIFY_EVALUATION_COUNT(( m3.block(r0,r0,r1,r1).noalias() += -m1.block(r0,c0,r1,c1) * (s2*m2.block(r0,c0,r1,c1)).adjoint() ), 0);+ VERIFY_EVALUATION_COUNT(( m3.block(r0,r0,r1,r1).noalias() -= s1 * m1.block(r0,c0,r1,c1) * m2.block(c0,r0,c1,r1) ), 0);++ // NOTE this is because the Block expression is not handled yet by our expression analyser+ VERIFY_EVALUATION_COUNT(( m3.block(r0,r0,r1,r1).noalias() = s1 * m1.block(r0,c0,r1,c1) * (s1*m2).block(c0,r0,c1,r1) ), 1);++ VERIFY_EVALUATION_COUNT( m3.noalias() -= (s1 * m1).template triangularView<Lower>() * m2, 0);+ VERIFY_EVALUATION_COUNT( rm3.noalias() = (s1 * m1.adjoint()).template triangularView<Upper>() * (m2+m2), 1);+ VERIFY_EVALUATION_COUNT( rm3.noalias() = (s1 * m1.adjoint()).template triangularView<UnitUpper>() * m2.adjoint(), 0);+ + VERIFY_EVALUATION_COUNT( m3.template triangularView<Upper>() = (m1 * m2.adjoint()), 0);+ VERIFY_EVALUATION_COUNT( m3.template triangularView<Upper>() -= (m1 * m2.adjoint()), 0);++ // NOTE this is because the blas_traits require innerstride==1 to avoid a temporary, but that doesn't seem to be actually needed for the triangular products+ VERIFY_EVALUATION_COUNT( rm3.col(c0).noalias() = (s1 * m1.adjoint()).template triangularView<UnitUpper>() * (s2*m2.row(c0)).adjoint(), 1);++ VERIFY_EVALUATION_COUNT( m1.template triangularView<Lower>().solveInPlace(m3), 0);+ VERIFY_EVALUATION_COUNT( m1.adjoint().template triangularView<Lower>().solveInPlace(m3.transpose()), 0);++ VERIFY_EVALUATION_COUNT( m3.noalias() -= (s1 * m1).adjoint().template selfadjointView<Lower>() * (-m2*s3).adjoint(), 0);+ VERIFY_EVALUATION_COUNT( m3.noalias() = s2 * m2.adjoint() * (s1 * m1.adjoint()).template selfadjointView<Upper>(), 0);+ VERIFY_EVALUATION_COUNT( rm3.noalias() = (s1 * m1.adjoint()).template selfadjointView<Lower>() * m2.adjoint(), 0);++ // NOTE this is because the blas_traits require innerstride==1 to avoid a temporary, but that doesn't seem to be actually needed for the triangular products+ VERIFY_EVALUATION_COUNT( m3.col(c0).noalias() = (s1 * m1).adjoint().template selfadjointView<Lower>() * (-m2.row(c0)*s3).adjoint(), 1);+ VERIFY_EVALUATION_COUNT( m3.col(c0).noalias() -= (s1 * m1).adjoint().template selfadjointView<Upper>() * (-m2.row(c0)*s3).adjoint(), 1);++ VERIFY_EVALUATION_COUNT( m3.block(r0,c0,r1,c1).noalias() += m1.block(r0,r0,r1,r1).template selfadjointView<Upper>() * (s1*m2.block(r0,c0,r1,c1)), 0);+ VERIFY_EVALUATION_COUNT( m3.block(r0,c0,r1,c1).noalias() = m1.block(r0,r0,r1,r1).template selfadjointView<Upper>() * m2.block(r0,c0,r1,c1), 0);++ VERIFY_EVALUATION_COUNT( m3.template selfadjointView<Lower>().rankUpdate(m2.adjoint()), 0);++ // Here we will get 1 temporary for each resize operation of the lhs operator; resize(r1,c1) would lead to zero temporaries+ m3.resize(1,1);+ VERIFY_EVALUATION_COUNT( m3.noalias() = m1.block(r0,r0,r1,r1).template selfadjointView<Lower>() * m2.block(r0,c0,r1,c1), 1);+ m3.resize(1,1);+ VERIFY_EVALUATION_COUNT( m3.noalias() = m1.block(r0,r0,r1,r1).template triangularView<UnitUpper>() * m2.block(r0,c0,r1,c1), 1);++ // Zero temporaries for lazy products ...+ VERIFY_EVALUATION_COUNT( Scalar tmp = 0; tmp += Scalar(RealScalar(1)) / (m3.transpose().lazyProduct(m3)).diagonal().sum(), 0 );++ // ... and even no temporary for even deeply (>=2) nested products+ VERIFY_EVALUATION_COUNT( Scalar tmp = 0; tmp += Scalar(RealScalar(1)) / (m3.transpose() * m3).diagonal().sum(), 0 );+ VERIFY_EVALUATION_COUNT( Scalar tmp = 0; tmp += Scalar(RealScalar(1)) / (m3.transpose() * m3).diagonal().array().abs().sum(), 0 );++ // Zero temporaries for ... CoeffBasedProductMode+ // - does not work with GCC because of the <..>, we'ld need variadic macros ...+ //VERIFY_EVALUATION_COUNT( m3.col(0).head<5>() * m3.col(0).transpose() + m3.col(0).head<5>() * m3.col(0).transpose(), 0 );++ // Check matrix * vectors+ VERIFY_EVALUATION_COUNT( cvres.noalias() = m1 * cv1, 0 );+ VERIFY_EVALUATION_COUNT( cvres.noalias() -= m1 * cv1, 0 );+ VERIFY_EVALUATION_COUNT( cvres.noalias() -= m1 * m2.col(0), 0 );+ VERIFY_EVALUATION_COUNT( cvres.noalias() -= m1 * rv1.adjoint(), 0 );+ VERIFY_EVALUATION_COUNT( cvres.noalias() -= m1 * m2.row(0).transpose(), 0 );+}++void test_product_notemporary()+{+ int s;+ for(int i = 0; i < g_repeat; i++) {+ s = internal::random<int>(16,EIGEN_TEST_MAX_SIZE);+ CALL_SUBTEST_1( product_notemporary(MatrixXf(s, s)) );+ s = internal::random<int>(16,EIGEN_TEST_MAX_SIZE);+ CALL_SUBTEST_2( product_notemporary(MatrixXd(s, s)) );+ s = internal::random<int>(16,EIGEN_TEST_MAX_SIZE/2);+ CALL_SUBTEST_3( product_notemporary(MatrixXcf(s,s)) );+ s = internal::random<int>(16,EIGEN_TEST_MAX_SIZE/2);+ CALL_SUBTEST_4( product_notemporary(MatrixXcd(s,s)) );+ }+}
+ eigen3/test/product_selfadjoint.cpp view
@@ -0,0 +1,80 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void product_selfadjoint(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;+ typedef Matrix<Scalar, 1, MatrixType::RowsAtCompileTime> RowVectorType;++ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, Dynamic, RowMajor> RhsMatrixType;++ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3;+ VectorType v1 = VectorType::Random(rows),+ v2 = VectorType::Random(rows),+ v3(rows);+ RowVectorType r1 = RowVectorType::Random(rows),+ r2 = RowVectorType::Random(rows);+ RhsMatrixType m4 = RhsMatrixType::Random(rows,10);++ Scalar s1 = internal::random<Scalar>(),+ s2 = internal::random<Scalar>(),+ s3 = internal::random<Scalar>();++ m1 = (m1.adjoint() + m1).eval();++ // rank2 update+ m2 = m1.template triangularView<Lower>();+ m2.template selfadjointView<Lower>().rankUpdate(v1,v2);+ VERIFY_IS_APPROX(m2, (m1 + v1 * v2.adjoint()+ v2 * v1.adjoint()).template triangularView<Lower>().toDenseMatrix());++ m2 = m1.template triangularView<Upper>();+ m2.template selfadjointView<Upper>().rankUpdate(-v1,s2*v2,s3);+ VERIFY_IS_APPROX(m2, (m1 + (s3*(-v1)*(s2*v2).adjoint()+numext::conj(s3)*(s2*v2)*(-v1).adjoint())).template triangularView<Upper>().toDenseMatrix());++ m2 = m1.template triangularView<Upper>();+ m2.template selfadjointView<Upper>().rankUpdate(-s2*r1.adjoint(),r2.adjoint()*s3,s1);+ VERIFY_IS_APPROX(m2, (m1 + s1*(-s2*r1.adjoint())*(r2.adjoint()*s3).adjoint() + numext::conj(s1)*(r2.adjoint()*s3) * (-s2*r1.adjoint()).adjoint()).template triangularView<Upper>().toDenseMatrix());++ if (rows>1)+ {+ m2 = m1.template triangularView<Lower>();+ m2.block(1,1,rows-1,cols-1).template selfadjointView<Lower>().rankUpdate(v1.tail(rows-1),v2.head(cols-1));+ m3 = m1;+ m3.block(1,1,rows-1,cols-1) += v1.tail(rows-1) * v2.head(cols-1).adjoint()+ v2.head(cols-1) * v1.tail(rows-1).adjoint();+ VERIFY_IS_APPROX(m2, m3.template triangularView<Lower>().toDenseMatrix());+ }+}++void test_product_selfadjoint()+{+ int s = 0;+ for(int i = 0; i < g_repeat ; i++) {+ CALL_SUBTEST_1( product_selfadjoint(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( product_selfadjoint(Matrix<float, 2, 2>()) );+ CALL_SUBTEST_3( product_selfadjoint(Matrix3d()) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2);+ CALL_SUBTEST_4( product_selfadjoint(MatrixXcf(s, s)) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2);+ CALL_SUBTEST_5( product_selfadjoint(MatrixXcd(s,s)) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);+ CALL_SUBTEST_6( product_selfadjoint(MatrixXd(s,s)) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);+ CALL_SUBTEST_7( product_selfadjoint(Matrix<float,Dynamic,Dynamic,RowMajor>(s,s)) );+ }+ TEST_SET_BUT_UNUSED_VARIABLE(s)+}
+ eigen3/test/product_small.cpp view
@@ -0,0 +1,50 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN_NO_STATIC_ASSERT+#include "product.h"++// regression test for bug 447+void product1x1()+{+ Matrix<float,1,3> matAstatic;+ Matrix<float,3,1> matBstatic;+ matAstatic.setRandom();+ matBstatic.setRandom();+ VERIFY_IS_APPROX( (matAstatic * matBstatic).coeff(0,0), + matAstatic.cwiseProduct(matBstatic.transpose()).sum() );++ MatrixXf matAdynamic(1,3);+ MatrixXf matBdynamic(3,1);+ matAdynamic.setRandom();+ matBdynamic.setRandom();+ VERIFY_IS_APPROX( (matAdynamic * matBdynamic).coeff(0,0), + matAdynamic.cwiseProduct(matBdynamic.transpose()).sum() );+}+++void test_product_small()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( product(Matrix<float, 3, 2>()) );+ CALL_SUBTEST_2( product(Matrix<int, 3, 5>()) );+ CALL_SUBTEST_3( product(Matrix3d()) );+ CALL_SUBTEST_4( product(Matrix4d()) );+ CALL_SUBTEST_5( product(Matrix4f()) );+ CALL_SUBTEST_6( product1x1() );+ }++#ifdef EIGEN_TEST_PART_6+ {+ // test compilation of (outer_product) * vector+ Vector3f v = Vector3f::Random();+ VERIFY_IS_APPROX( (v * v.transpose()) * v, (v * v.transpose()).eval() * v);+ }+#endif+}
+ eigen3/test/product_symm.cpp view
@@ -0,0 +1,94 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename Scalar, int Size, int OtherSize> void symm(int size = Size, int othersize = OtherSize)+{+ typedef Matrix<Scalar, Size, Size> MatrixType;+ typedef Matrix<Scalar, Size, OtherSize> Rhs1;+ typedef Matrix<Scalar, OtherSize, Size> Rhs2;+ enum { order = OtherSize==1 ? 0 : RowMajor };+ typedef Matrix<Scalar, Size, OtherSize,order> Rhs3;+ typedef typename MatrixType::Index Index;++ Index rows = size;+ Index cols = size;++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols), m3;++ m1 = (m1+m1.adjoint()).eval();++ Rhs1 rhs1 = Rhs1::Random(cols, othersize), rhs12(cols, othersize), rhs13(cols, othersize);+ Rhs2 rhs2 = Rhs2::Random(othersize, rows), rhs22(othersize, rows), rhs23(othersize, rows);+ Rhs3 rhs3 = Rhs3::Random(cols, othersize), rhs32(cols, othersize), rhs33(cols, othersize);++ Scalar s1 = internal::random<Scalar>(),+ s2 = internal::random<Scalar>();++ m2 = m1.template triangularView<Lower>();+ m3 = m2.template selfadjointView<Lower>();+ VERIFY_IS_EQUAL(m1, m3);+ VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<Lower>() * (s2*rhs1),+ rhs13 = (s1*m1) * (s2*rhs1));++ m2 = m1.template triangularView<Upper>(); rhs12.setRandom(); rhs13 = rhs12;+ m3 = m2.template selfadjointView<Upper>();+ VERIFY_IS_EQUAL(m1, m3);+ VERIFY_IS_APPROX(rhs12 += (s1*m2).template selfadjointView<Upper>() * (s2*rhs1),+ rhs13 += (s1*m1) * (s2*rhs1));++ m2 = m1.template triangularView<Lower>();+ VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<Lower>() * (s2*rhs2.adjoint()),+ rhs13 = (s1*m1) * (s2*rhs2.adjoint()));++ m2 = m1.template triangularView<Upper>();+ VERIFY_IS_APPROX(rhs12 = (s1*m2).template selfadjointView<Upper>() * (s2*rhs2.adjoint()),+ rhs13 = (s1*m1) * (s2*rhs2.adjoint()));++ m2 = m1.template triangularView<Upper>();+ VERIFY_IS_APPROX(rhs12 = (s1*m2.adjoint()).template selfadjointView<Lower>() * (s2*rhs2.adjoint()),+ rhs13 = (s1*m1.adjoint()) * (s2*rhs2.adjoint()));++ // test row major = <...>+ m2 = m1.template triangularView<Lower>(); rhs12.setRandom(); rhs13 = rhs12;+ VERIFY_IS_APPROX(rhs12 -= (s1*m2).template selfadjointView<Lower>() * (s2*rhs3),+ rhs13 -= (s1*m1) * (s2 * rhs3));++ m2 = m1.template triangularView<Upper>();+ VERIFY_IS_APPROX(rhs12 = (s1*m2.adjoint()).template selfadjointView<Lower>() * (s2*rhs3).conjugate(),+ rhs13 = (s1*m1.adjoint()) * (s2*rhs3).conjugate());+++ m2 = m1.template triangularView<Upper>(); rhs13 = rhs12;+ VERIFY_IS_APPROX(rhs12.noalias() += s1 * ((m2.adjoint()).template selfadjointView<Lower>() * (s2*rhs3).conjugate()),+ rhs13 += (s1*m1.adjoint()) * (s2*rhs3).conjugate());++ m2 = m1.template triangularView<Lower>();+ VERIFY_IS_APPROX(rhs22 = (rhs2) * (m2).template selfadjointView<Lower>(), rhs23 = (rhs2) * (m1));+ VERIFY_IS_APPROX(rhs22 = (s2*rhs2) * (s1*m2).template selfadjointView<Lower>(), rhs23 = (s2*rhs2) * (s1*m1));++}++void test_product_symm()+{+ for(int i = 0; i < g_repeat ; i++)+ {+ CALL_SUBTEST_1(( symm<float,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE)) ));+ CALL_SUBTEST_2(( symm<double,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE)) ));+ CALL_SUBTEST_3(( symm<std::complex<float>,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2),internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2)) ));+ CALL_SUBTEST_4(( symm<std::complex<double>,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2),internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2)) ));++ CALL_SUBTEST_5(( symm<float,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)) ));+ CALL_SUBTEST_6(( symm<double,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)) ));+ CALL_SUBTEST_7(( symm<std::complex<float>,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)) ));+ CALL_SUBTEST_8(( symm<std::complex<double>,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE)) ));+ }+}
+ eigen3/test/product_syrk.cpp view
@@ -0,0 +1,135 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void syrk(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime, RowMajor> RMatrixType;+ typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, Dynamic> Rhs1;+ typedef Matrix<Scalar, Dynamic, MatrixType::RowsAtCompileTime> Rhs2;+ typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, Dynamic,RowMajor> Rhs3;++ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3 = MatrixType::Random(rows, cols);+ RMatrixType rm2 = MatrixType::Random(rows, cols);++ Rhs1 rhs1 = Rhs1::Random(internal::random<int>(1,320), cols); Rhs1 rhs11 = Rhs1::Random(rhs1.rows(), cols);+ Rhs2 rhs2 = Rhs2::Random(rows, internal::random<int>(1,320)); Rhs2 rhs22 = Rhs2::Random(rows, rhs2.cols());+ Rhs3 rhs3 = Rhs3::Random(internal::random<int>(1,320), rows);++ Scalar s1 = internal::random<Scalar>();+ + Index c = internal::random<Index>(0,cols-1);++ m2.setZero();+ VERIFY_IS_APPROX((m2.template selfadjointView<Lower>().rankUpdate(rhs2,s1)._expression()),+ ((s1 * rhs2 * rhs2.adjoint()).eval().template triangularView<Lower>().toDenseMatrix()));+ m2.setZero();+ VERIFY_IS_APPROX(((m2.template triangularView<Lower>() += s1 * rhs2 * rhs22.adjoint()).nestedExpression()),+ ((s1 * rhs2 * rhs22.adjoint()).eval().template triangularView<Lower>().toDenseMatrix()));++ + m2.setZero();+ VERIFY_IS_APPROX(m2.template selfadjointView<Upper>().rankUpdate(rhs2,s1)._expression(),+ (s1 * rhs2 * rhs2.adjoint()).eval().template triangularView<Upper>().toDenseMatrix());+ m2.setZero();+ VERIFY_IS_APPROX((m2.template triangularView<Upper>() += s1 * rhs22 * rhs2.adjoint()).nestedExpression(),+ (s1 * rhs22 * rhs2.adjoint()).eval().template triangularView<Upper>().toDenseMatrix());++ + m2.setZero();+ VERIFY_IS_APPROX(m2.template selfadjointView<Lower>().rankUpdate(rhs1.adjoint(),s1)._expression(),+ (s1 * rhs1.adjoint() * rhs1).eval().template triangularView<Lower>().toDenseMatrix());+ m2.setZero();+ VERIFY_IS_APPROX((m2.template triangularView<Lower>() += s1 * rhs11.adjoint() * rhs1).nestedExpression(),+ (s1 * rhs11.adjoint() * rhs1).eval().template triangularView<Lower>().toDenseMatrix());+ + + m2.setZero();+ VERIFY_IS_APPROX(m2.template selfadjointView<Upper>().rankUpdate(rhs1.adjoint(),s1)._expression(),+ (s1 * rhs1.adjoint() * rhs1).eval().template triangularView<Upper>().toDenseMatrix());+ VERIFY_IS_APPROX((m2.template triangularView<Upper>() = s1 * rhs1.adjoint() * rhs11).nestedExpression(),+ (s1 * rhs1.adjoint() * rhs11).eval().template triangularView<Upper>().toDenseMatrix());++ + m2.setZero();+ VERIFY_IS_APPROX(m2.template selfadjointView<Lower>().rankUpdate(rhs3.adjoint(),s1)._expression(),+ (s1 * rhs3.adjoint() * rhs3).eval().template triangularView<Lower>().toDenseMatrix());++ m2.setZero();+ VERIFY_IS_APPROX(m2.template selfadjointView<Upper>().rankUpdate(rhs3.adjoint(),s1)._expression(),+ (s1 * rhs3.adjoint() * rhs3).eval().template triangularView<Upper>().toDenseMatrix());+ + m2.setZero();+ VERIFY_IS_APPROX((m2.template selfadjointView<Lower>().rankUpdate(m1.col(c),s1)._expression()),+ ((s1 * m1.col(c) * m1.col(c).adjoint()).eval().template triangularView<Lower>().toDenseMatrix()));+ + m2.setZero();+ VERIFY_IS_APPROX((m2.template selfadjointView<Upper>().rankUpdate(m1.col(c),s1)._expression()),+ ((s1 * m1.col(c) * m1.col(c).adjoint()).eval().template triangularView<Upper>().toDenseMatrix()));+ rm2.setZero();+ VERIFY_IS_APPROX((rm2.template selfadjointView<Upper>().rankUpdate(m1.col(c),s1)._expression()),+ ((s1 * m1.col(c) * m1.col(c).adjoint()).eval().template triangularView<Upper>().toDenseMatrix()));+ m2.setZero();+ VERIFY_IS_APPROX((m2.template triangularView<Upper>() += s1 * m3.col(c) * m1.col(c).adjoint()).nestedExpression(),+ ((s1 * m3.col(c) * m1.col(c).adjoint()).eval().template triangularView<Upper>().toDenseMatrix()));+ rm2.setZero();+ VERIFY_IS_APPROX((rm2.template triangularView<Upper>() += s1 * m1.col(c) * m3.col(c).adjoint()).nestedExpression(),+ ((s1 * m1.col(c) * m3.col(c).adjoint()).eval().template triangularView<Upper>().toDenseMatrix()));+ + m2.setZero();+ VERIFY_IS_APPROX((m2.template selfadjointView<Lower>().rankUpdate(m1.col(c).conjugate(),s1)._expression()),+ ((s1 * m1.col(c).conjugate() * m1.col(c).conjugate().adjoint()).eval().template triangularView<Lower>().toDenseMatrix()));+ + m2.setZero();+ VERIFY_IS_APPROX((m2.template selfadjointView<Upper>().rankUpdate(m1.col(c).conjugate(),s1)._expression()),+ ((s1 * m1.col(c).conjugate() * m1.col(c).conjugate().adjoint()).eval().template triangularView<Upper>().toDenseMatrix()));+ + + m2.setZero();+ VERIFY_IS_APPROX((m2.template selfadjointView<Lower>().rankUpdate(m1.row(c),s1)._expression()),+ ((s1 * m1.row(c).transpose() * m1.row(c).transpose().adjoint()).eval().template triangularView<Lower>().toDenseMatrix()));+ rm2.setZero();+ VERIFY_IS_APPROX((rm2.template selfadjointView<Lower>().rankUpdate(m1.row(c),s1)._expression()),+ ((s1 * m1.row(c).transpose() * m1.row(c).transpose().adjoint()).eval().template triangularView<Lower>().toDenseMatrix()));+ m2.setZero();+ VERIFY_IS_APPROX((m2.template triangularView<Lower>() += s1 * m3.row(c).transpose() * m1.row(c).transpose().adjoint()).nestedExpression(),+ ((s1 * m3.row(c).transpose() * m1.row(c).transpose().adjoint()).eval().template triangularView<Lower>().toDenseMatrix()));+ rm2.setZero();+ VERIFY_IS_APPROX((rm2.template triangularView<Lower>() += s1 * m3.row(c).transpose() * m1.row(c).transpose().adjoint()).nestedExpression(),+ ((s1 * m3.row(c).transpose() * m1.row(c).transpose().adjoint()).eval().template triangularView<Lower>().toDenseMatrix()));+ + + m2.setZero();+ VERIFY_IS_APPROX((m2.template selfadjointView<Upper>().rankUpdate(m1.row(c).adjoint(),s1)._expression()),+ ((s1 * m1.row(c).adjoint() * m1.row(c).adjoint().adjoint()).eval().template triangularView<Upper>().toDenseMatrix()));+}++void test_product_syrk()+{+ for(int i = 0; i < g_repeat ; i++)+ {+ int s;+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);+ CALL_SUBTEST_1( syrk(MatrixXf(s, s)) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);+ CALL_SUBTEST_2( syrk(MatrixXd(s, s)) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2);+ CALL_SUBTEST_3( syrk(MatrixXcf(s, s)) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2);+ CALL_SUBTEST_4( syrk(MatrixXcd(s, s)) );+ }+}
+ eigen3/test/product_trmm.cpp view
@@ -0,0 +1,107 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename Scalar, int Mode, int TriOrder, int OtherOrder, int ResOrder, int OtherCols>+void trmm(int rows=internal::random<int>(1,EIGEN_TEST_MAX_SIZE),+ int cols=internal::random<int>(1,EIGEN_TEST_MAX_SIZE),+ int otherCols = OtherCols==Dynamic?internal::random<int>(1,EIGEN_TEST_MAX_SIZE):OtherCols)+{+ typedef Matrix<Scalar,Dynamic,Dynamic,TriOrder> TriMatrix;+ typedef Matrix<Scalar,Dynamic,OtherCols,OtherCols==1?ColMajor:OtherOrder> OnTheRight;+ typedef Matrix<Scalar,OtherCols,Dynamic,OtherCols==1?RowMajor:OtherOrder> OnTheLeft;+ + typedef Matrix<Scalar,Dynamic,OtherCols,OtherCols==1?ColMajor:ResOrder> ResXS;+ typedef Matrix<Scalar,OtherCols,Dynamic,OtherCols==1?RowMajor:ResOrder> ResSX;++ TriMatrix mat(rows,cols), tri(rows,cols), triTr(cols,rows);+ + OnTheRight ge_right(cols,otherCols);+ OnTheLeft ge_left(otherCols,rows);+ ResSX ge_sx, ge_sx_save;+ ResXS ge_xs, ge_xs_save;++ Scalar s1 = internal::random<Scalar>(),+ s2 = internal::random<Scalar>();++ mat.setRandom();+ tri = mat.template triangularView<Mode>();+ triTr = mat.transpose().template triangularView<Mode>();+ ge_right.setRandom();+ ge_left.setRandom();++ VERIFY_IS_APPROX( ge_xs = mat.template triangularView<Mode>() * ge_right, tri * ge_right);+ VERIFY_IS_APPROX( ge_sx = ge_left * mat.template triangularView<Mode>(), ge_left * tri);+ + VERIFY_IS_APPROX( ge_xs.noalias() = mat.template triangularView<Mode>() * ge_right, tri * ge_right);+ VERIFY_IS_APPROX( ge_sx.noalias() = ge_left * mat.template triangularView<Mode>(), ge_left * tri);+ + VERIFY_IS_APPROX( ge_xs.noalias() = (s1*mat.adjoint()).template triangularView<Mode>() * (s2*ge_left.transpose()), s1*triTr.conjugate() * (s2*ge_left.transpose()));+ VERIFY_IS_APPROX( ge_sx.noalias() = ge_right.transpose() * mat.adjoint().template triangularView<Mode>(), ge_right.transpose() * triTr.conjugate());+ + VERIFY_IS_APPROX( ge_xs.noalias() = (s1*mat.adjoint()).template triangularView<Mode>() * (s2*ge_left.adjoint()), s1*triTr.conjugate() * (s2*ge_left.adjoint()));+ VERIFY_IS_APPROX( ge_sx.noalias() = ge_right.adjoint() * mat.adjoint().template triangularView<Mode>(), ge_right.adjoint() * triTr.conjugate());+ + ge_xs_save = ge_xs;+ VERIFY_IS_APPROX( (ge_xs_save + s1*triTr.conjugate() * (s2*ge_left.adjoint())).eval(), ge_xs.noalias() += (s1*mat.adjoint()).template triangularView<Mode>() * (s2*ge_left.adjoint()) );+ ge_sx.setRandom();+ ge_sx_save = ge_sx;+ VERIFY_IS_APPROX( ge_sx_save - (ge_right.adjoint() * (-s1 * triTr).conjugate()).eval(), ge_sx.noalias() -= (ge_right.adjoint() * (-s1 * mat).adjoint().template triangularView<Mode>()).eval());+ + VERIFY_IS_APPROX( ge_xs = (s1*mat).adjoint().template triangularView<Mode>() * ge_left.adjoint(), numext::conj(s1) * triTr.conjugate() * ge_left.adjoint());+ + // TODO check with sub-matrix expressions ?+}++template<typename Scalar, int Mode, int TriOrder>+void trmv(int rows=internal::random<int>(1,EIGEN_TEST_MAX_SIZE), int cols=internal::random<int>(1,EIGEN_TEST_MAX_SIZE))+{+ trmm<Scalar,Mode,TriOrder,ColMajor,ColMajor,1>(rows,cols,1);+}++template<typename Scalar, int Mode, int TriOrder, int OtherOrder, int ResOrder>+void trmm(int rows=internal::random<int>(1,EIGEN_TEST_MAX_SIZE), int cols=internal::random<int>(1,EIGEN_TEST_MAX_SIZE), int otherCols = internal::random<int>(1,EIGEN_TEST_MAX_SIZE))+{+ trmm<Scalar,Mode,TriOrder,OtherOrder,ResOrder,Dynamic>(rows,cols,otherCols);+}++#define CALL_ALL_ORDERS(NB,SCALAR,MODE) \+ EIGEN_CAT(CALL_SUBTEST_,NB)((trmm<SCALAR, MODE, ColMajor,ColMajor,ColMajor>())); \+ EIGEN_CAT(CALL_SUBTEST_,NB)((trmm<SCALAR, MODE, ColMajor,ColMajor,RowMajor>())); \+ EIGEN_CAT(CALL_SUBTEST_,NB)((trmm<SCALAR, MODE, ColMajor,RowMajor,ColMajor>())); \+ EIGEN_CAT(CALL_SUBTEST_,NB)((trmm<SCALAR, MODE, ColMajor,RowMajor,RowMajor>())); \+ EIGEN_CAT(CALL_SUBTEST_,NB)((trmm<SCALAR, MODE, RowMajor,ColMajor,ColMajor>())); \+ EIGEN_CAT(CALL_SUBTEST_,NB)((trmm<SCALAR, MODE, RowMajor,ColMajor,RowMajor>())); \+ EIGEN_CAT(CALL_SUBTEST_,NB)((trmm<SCALAR, MODE, RowMajor,RowMajor,ColMajor>())); \+ EIGEN_CAT(CALL_SUBTEST_,NB)((trmm<SCALAR, MODE, RowMajor,RowMajor,RowMajor>())); \+ \+ EIGEN_CAT(CALL_SUBTEST_1,NB)((trmv<SCALAR, MODE, ColMajor>())); \+ EIGEN_CAT(CALL_SUBTEST_1,NB)((trmv<SCALAR, MODE, RowMajor>()));++ +#define CALL_ALL(NB,SCALAR) \+ CALL_ALL_ORDERS(EIGEN_CAT(1,NB),SCALAR,Upper) \+ CALL_ALL_ORDERS(EIGEN_CAT(2,NB),SCALAR,UnitUpper) \+ CALL_ALL_ORDERS(EIGEN_CAT(3,NB),SCALAR,StrictlyUpper) \+ CALL_ALL_ORDERS(EIGEN_CAT(1,NB),SCALAR,Lower) \+ CALL_ALL_ORDERS(EIGEN_CAT(2,NB),SCALAR,UnitLower) \+ CALL_ALL_ORDERS(EIGEN_CAT(3,NB),SCALAR,StrictlyLower)+ ++void test_product_trmm()+{+ for(int i = 0; i < g_repeat ; i++)+ {+ CALL_ALL(1,float); // EIGEN_SUFFIXES;11;111;21;121;31;131+ CALL_ALL(2,double); // EIGEN_SUFFIXES;12;112;22;122;32;132+ CALL_ALL(3,std::complex<float>); // EIGEN_SUFFIXES;13;113;23;123;33;133+ CALL_ALL(4,std::complex<double>); // EIGEN_SUFFIXES;14;114;24;124;34;134+ }+}
+ eigen3/test/product_trmv.cpp view
@@ -0,0 +1,89 @@+// This file is triangularView of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void trmv(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ RealScalar largerEps = 10*test_precision<RealScalar>();++ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m3(rows, cols);+ VectorType v1 = VectorType::Random(rows);++ Scalar s1 = internal::random<Scalar>();++ m1 = MatrixType::Random(rows, cols);++ // check with a column-major matrix+ m3 = m1.template triangularView<Eigen::Lower>();+ VERIFY((m3 * v1).isApprox(m1.template triangularView<Eigen::Lower>() * v1, largerEps));+ m3 = m1.template triangularView<Eigen::Upper>();+ VERIFY((m3 * v1).isApprox(m1.template triangularView<Eigen::Upper>() * v1, largerEps));+ m3 = m1.template triangularView<Eigen::UnitLower>();+ VERIFY((m3 * v1).isApprox(m1.template triangularView<Eigen::UnitLower>() * v1, largerEps));+ m3 = m1.template triangularView<Eigen::UnitUpper>();+ VERIFY((m3 * v1).isApprox(m1.template triangularView<Eigen::UnitUpper>() * v1, largerEps));++ // check conjugated and scalar multiple expressions (col-major)+ m3 = m1.template triangularView<Eigen::Lower>();+ VERIFY(((s1*m3).conjugate() * v1).isApprox((s1*m1).conjugate().template triangularView<Eigen::Lower>() * v1, largerEps));+ m3 = m1.template triangularView<Eigen::Upper>();+ VERIFY((m3.conjugate() * v1.conjugate()).isApprox(m1.conjugate().template triangularView<Eigen::Upper>() * v1.conjugate(), largerEps));++ // check with a row-major matrix+ m3 = m1.template triangularView<Eigen::Upper>();+ VERIFY((m3.transpose() * v1).isApprox(m1.transpose().template triangularView<Eigen::Lower>() * v1, largerEps));+ m3 = m1.template triangularView<Eigen::Lower>();+ VERIFY((m3.transpose() * v1).isApprox(m1.transpose().template triangularView<Eigen::Upper>() * v1, largerEps));+ m3 = m1.template triangularView<Eigen::UnitUpper>();+ VERIFY((m3.transpose() * v1).isApprox(m1.transpose().template triangularView<Eigen::UnitLower>() * v1, largerEps));+ m3 = m1.template triangularView<Eigen::UnitLower>();+ VERIFY((m3.transpose() * v1).isApprox(m1.transpose().template triangularView<Eigen::UnitUpper>() * v1, largerEps));++ // check conjugated and scalar multiple expressions (row-major)+ m3 = m1.template triangularView<Eigen::Upper>();+ VERIFY((m3.adjoint() * v1).isApprox(m1.adjoint().template triangularView<Eigen::Lower>() * v1, largerEps));+ m3 = m1.template triangularView<Eigen::Lower>();+ VERIFY((m3.adjoint() * (s1*v1.conjugate())).isApprox(m1.adjoint().template triangularView<Eigen::Upper>() * (s1*v1.conjugate()), largerEps));+ m3 = m1.template triangularView<Eigen::UnitUpper>();++ // check transposed cases:+ m3 = m1.template triangularView<Eigen::Lower>();+ VERIFY((v1.transpose() * m3).isApprox(v1.transpose() * m1.template triangularView<Eigen::Lower>(), largerEps));+ VERIFY((v1.adjoint() * m3).isApprox(v1.adjoint() * m1.template triangularView<Eigen::Lower>(), largerEps));+ VERIFY((v1.adjoint() * m3.adjoint()).isApprox(v1.adjoint() * m1.template triangularView<Eigen::Lower>().adjoint(), largerEps));++ // TODO check with sub-matrices+}++void test_product_trmv()+{+ int s = 0;+ for(int i = 0; i < g_repeat ; i++) {+ CALL_SUBTEST_1( trmv(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( trmv(Matrix<float, 2, 2>()) );+ CALL_SUBTEST_3( trmv(Matrix3d()) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2);+ CALL_SUBTEST_4( trmv(MatrixXcf(s,s)) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2);+ CALL_SUBTEST_5( trmv(MatrixXcd(s,s)) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);+ CALL_SUBTEST_6( trmv(Matrix<float,Dynamic,Dynamic,RowMajor>(s, s)) );+ }+ TEST_SET_BUT_UNUSED_VARIABLE(s);+}
+ eigen3/test/product_trsolve.cpp view
@@ -0,0 +1,93 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++#define VERIFY_TRSM(TRI,XB) { \+ (XB).setRandom(); ref = (XB); \+ (TRI).solveInPlace(XB); \+ VERIFY_IS_APPROX((TRI).toDenseMatrix() * (XB), ref); \+ (XB).setRandom(); ref = (XB); \+ (XB) = (TRI).solve(XB); \+ VERIFY_IS_APPROX((TRI).toDenseMatrix() * (XB), ref); \+ }++#define VERIFY_TRSM_ONTHERIGHT(TRI,XB) { \+ (XB).setRandom(); ref = (XB); \+ (TRI).transpose().template solveInPlace<OnTheRight>(XB.transpose()); \+ VERIFY_IS_APPROX((XB).transpose() * (TRI).transpose().toDenseMatrix(), ref.transpose()); \+ (XB).setRandom(); ref = (XB); \+ (XB).transpose() = (TRI).transpose().template solve<OnTheRight>(XB.transpose()); \+ VERIFY_IS_APPROX((XB).transpose() * (TRI).transpose().toDenseMatrix(), ref.transpose()); \+ }++template<typename Scalar,int Size, int Cols> void trsolve(int size=Size,int cols=Cols)+{+ typedef typename NumTraits<Scalar>::Real RealScalar;++ Matrix<Scalar,Size,Size,ColMajor> cmLhs(size,size);+ Matrix<Scalar,Size,Size,RowMajor> rmLhs(size,size);++ enum { colmajor = Size==1 ? RowMajor : ColMajor,+ rowmajor = Cols==1 ? ColMajor : RowMajor };+ Matrix<Scalar,Size,Cols,colmajor> cmRhs(size,cols);+ Matrix<Scalar,Size,Cols,rowmajor> rmRhs(size,cols);+ Matrix<Scalar,Dynamic,Dynamic,colmajor> ref(size,cols);++ cmLhs.setRandom(); cmLhs *= static_cast<RealScalar>(0.1); cmLhs.diagonal().array() += static_cast<RealScalar>(1);+ rmLhs.setRandom(); rmLhs *= static_cast<RealScalar>(0.1); rmLhs.diagonal().array() += static_cast<RealScalar>(1);++ VERIFY_TRSM(cmLhs.conjugate().template triangularView<Lower>(), cmRhs);+ VERIFY_TRSM(cmLhs.adjoint() .template triangularView<Lower>(), cmRhs);+ VERIFY_TRSM(cmLhs .template triangularView<Upper>(), cmRhs);+ VERIFY_TRSM(cmLhs .template triangularView<Lower>(), rmRhs);+ VERIFY_TRSM(cmLhs.conjugate().template triangularView<Upper>(), rmRhs);+ VERIFY_TRSM(cmLhs.adjoint() .template triangularView<Upper>(), rmRhs);++ VERIFY_TRSM(cmLhs.conjugate().template triangularView<UnitLower>(), cmRhs);+ VERIFY_TRSM(cmLhs .template triangularView<UnitUpper>(), rmRhs);++ VERIFY_TRSM(rmLhs .template triangularView<Lower>(), cmRhs);+ VERIFY_TRSM(rmLhs.conjugate().template triangularView<UnitUpper>(), rmRhs);+++ VERIFY_TRSM_ONTHERIGHT(cmLhs.conjugate().template triangularView<Lower>(), cmRhs);+ VERIFY_TRSM_ONTHERIGHT(cmLhs .template triangularView<Upper>(), cmRhs);+ VERIFY_TRSM_ONTHERIGHT(cmLhs .template triangularView<Lower>(), rmRhs);+ VERIFY_TRSM_ONTHERIGHT(cmLhs.conjugate().template triangularView<Upper>(), rmRhs);++ VERIFY_TRSM_ONTHERIGHT(cmLhs.conjugate().template triangularView<UnitLower>(), cmRhs);+ VERIFY_TRSM_ONTHERIGHT(cmLhs .template triangularView<UnitUpper>(), rmRhs);++ VERIFY_TRSM_ONTHERIGHT(rmLhs .template triangularView<Lower>(), cmRhs);+ VERIFY_TRSM_ONTHERIGHT(rmLhs.conjugate().template triangularView<UnitUpper>(), rmRhs);++ int c = internal::random<int>(0,cols-1);+ VERIFY_TRSM(rmLhs.template triangularView<Lower>(), rmRhs.col(c));+ VERIFY_TRSM(cmLhs.template triangularView<Lower>(), rmRhs.col(c));+}++void test_product_trsolve()+{+ for(int i = 0; i < g_repeat ; i++)+ {+ // matrices+ CALL_SUBTEST_1((trsolve<float,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));+ CALL_SUBTEST_2((trsolve<double,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));+ CALL_SUBTEST_3((trsolve<std::complex<float>,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2),internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))));+ CALL_SUBTEST_4((trsolve<std::complex<double>,Dynamic,Dynamic>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2),internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))));++ // vectors+ CALL_SUBTEST_1((trsolve<float,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));+ CALL_SUBTEST_5((trsolve<std::complex<double>,Dynamic,1>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE))));+ CALL_SUBTEST_6((trsolve<float,1,1>()));+ CALL_SUBTEST_7((trsolve<float,1,2>()));+ CALL_SUBTEST_8((trsolve<std::complex<float>,4,1>()));+ }+}
+ eigen3/test/qr.cpp view
@@ -0,0 +1,127 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/QR>++template<typename MatrixType> void qr(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;++ Index rows = m.rows();+ Index cols = m.cols();++ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> MatrixQType;++ MatrixType a = MatrixType::Random(rows,cols);+ HouseholderQR<MatrixType> qrOfA(a);++ MatrixQType q = qrOfA.householderQ();+ VERIFY_IS_UNITARY(q);++ MatrixType r = qrOfA.matrixQR().template triangularView<Upper>();+ VERIFY_IS_APPROX(a, qrOfA.householderQ() * r);+}++template<typename MatrixType, int Cols2> void qr_fixedsize()+{+ enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };+ typedef typename MatrixType::Scalar Scalar;+ Matrix<Scalar,Rows,Cols> m1 = Matrix<Scalar,Rows,Cols>::Random();+ HouseholderQR<Matrix<Scalar,Rows,Cols> > qr(m1);++ Matrix<Scalar,Rows,Cols> r = qr.matrixQR();+ // FIXME need better way to construct trapezoid+ for(int i = 0; i < Rows; i++) for(int j = 0; j < Cols; j++) if(i>j) r(i,j) = Scalar(0);++ VERIFY_IS_APPROX(m1, qr.householderQ() * r);++ Matrix<Scalar,Cols,Cols2> m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);+ Matrix<Scalar,Rows,Cols2> m3 = m1*m2;+ m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);+ m2 = qr.solve(m3);+ VERIFY_IS_APPROX(m3, m1*m2);+}++template<typename MatrixType> void qr_invertible()+{+ using std::log;+ using std::abs;+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;+ typedef typename MatrixType::Scalar Scalar;++ int size = internal::random<int>(10,50);++ MatrixType m1(size, size), m2(size, size), m3(size, size);+ m1 = MatrixType::Random(size,size);++ if (internal::is_same<RealScalar,float>::value)+ {+ // let's build a matrix more stable to inverse+ MatrixType a = MatrixType::Random(size,size*2);+ m1 += a * a.adjoint();+ }++ HouseholderQR<MatrixType> qr(m1);+ m3 = MatrixType::Random(size,size);+ m2 = qr.solve(m3);+ VERIFY_IS_APPROX(m3, m1*m2);++ // now construct a matrix with prescribed determinant+ m1.setZero();+ for(int i = 0; i < size; i++) m1(i,i) = internal::random<Scalar>();+ RealScalar absdet = abs(m1.diagonal().prod());+ m3 = qr.householderQ(); // get a unitary+ m1 = m3 * m1 * m3;+ qr.compute(m1);+ VERIFY_IS_APPROX(absdet, qr.absDeterminant());+ VERIFY_IS_APPROX(log(absdet), qr.logAbsDeterminant());+}++template<typename MatrixType> void qr_verify_assert()+{+ MatrixType tmp;++ HouseholderQR<MatrixType> qr;+ VERIFY_RAISES_ASSERT(qr.matrixQR())+ VERIFY_RAISES_ASSERT(qr.solve(tmp))+ VERIFY_RAISES_ASSERT(qr.householderQ())+ VERIFY_RAISES_ASSERT(qr.absDeterminant())+ VERIFY_RAISES_ASSERT(qr.logAbsDeterminant())+}++void test_qr()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( qr(MatrixXf(internal::random<int>(1,EIGEN_TEST_MAX_SIZE),internal::random<int>(1,EIGEN_TEST_MAX_SIZE))) );+ CALL_SUBTEST_2( qr(MatrixXcd(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2),internal::random<int>(1,EIGEN_TEST_MAX_SIZE/2))) );+ CALL_SUBTEST_3(( qr_fixedsize<Matrix<float,3,4>, 2 >() ));+ CALL_SUBTEST_4(( qr_fixedsize<Matrix<double,6,2>, 4 >() ));+ CALL_SUBTEST_5(( qr_fixedsize<Matrix<double,2,5>, 7 >() ));+ CALL_SUBTEST_11( qr(Matrix<float,1,1>()) );+ }++ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( qr_invertible<MatrixXf>() );+ CALL_SUBTEST_6( qr_invertible<MatrixXd>() );+ CALL_SUBTEST_7( qr_invertible<MatrixXcf>() );+ CALL_SUBTEST_8( qr_invertible<MatrixXcd>() );+ }++ CALL_SUBTEST_9(qr_verify_assert<Matrix3f>());+ CALL_SUBTEST_10(qr_verify_assert<Matrix3d>());+ CALL_SUBTEST_1(qr_verify_assert<MatrixXf>());+ CALL_SUBTEST_6(qr_verify_assert<MatrixXd>());+ CALL_SUBTEST_7(qr_verify_assert<MatrixXcf>());+ CALL_SUBTEST_8(qr_verify_assert<MatrixXcd>());++ // Test problem size constructors+ CALL_SUBTEST_12(HouseholderQR<MatrixXf>(10, 20));+}
+ eigen3/test/qr_colpivoting.cpp view
@@ -0,0 +1,150 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/QR>++template<typename MatrixType> void qr()+{+ typedef typename MatrixType::Index Index;++ Index rows = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE), cols = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE), cols2 = internal::random<Index>(2,EIGEN_TEST_MAX_SIZE);+ Index rank = internal::random<Index>(1, (std::min)(rows, cols)-1);++ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> MatrixQType;+ MatrixType m1;+ createRandomPIMatrixOfRank(rank,rows,cols,m1);+ ColPivHouseholderQR<MatrixType> qr(m1);+ VERIFY(rank == qr.rank());+ VERIFY(cols - qr.rank() == qr.dimensionOfKernel());+ VERIFY(!qr.isInjective());+ VERIFY(!qr.isInvertible());+ VERIFY(!qr.isSurjective());++ MatrixQType q = qr.householderQ();+ VERIFY_IS_UNITARY(q);++ MatrixType r = qr.matrixQR().template triangularView<Upper>();+ MatrixType c = q * r * qr.colsPermutation().inverse();+ VERIFY_IS_APPROX(m1, c);++ MatrixType m2 = MatrixType::Random(cols,cols2);+ MatrixType m3 = m1*m2;+ m2 = MatrixType::Random(cols,cols2);+ m2 = qr.solve(m3);+ VERIFY_IS_APPROX(m3, m1*m2);+}++template<typename MatrixType, int Cols2> void qr_fixedsize()+{+ enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };+ typedef typename MatrixType::Scalar Scalar;+ int rank = internal::random<int>(1, (std::min)(int(Rows), int(Cols))-1);+ Matrix<Scalar,Rows,Cols> m1;+ createRandomPIMatrixOfRank(rank,Rows,Cols,m1);+ ColPivHouseholderQR<Matrix<Scalar,Rows,Cols> > qr(m1);+ VERIFY(rank == qr.rank());+ VERIFY(Cols - qr.rank() == qr.dimensionOfKernel());+ VERIFY(qr.isInjective() == (rank == Rows));+ VERIFY(qr.isSurjective() == (rank == Cols));+ VERIFY(qr.isInvertible() == (qr.isInjective() && qr.isSurjective()));++ Matrix<Scalar,Rows,Cols> r = qr.matrixQR().template triangularView<Upper>();+ Matrix<Scalar,Rows,Cols> c = qr.householderQ() * r * qr.colsPermutation().inverse();+ VERIFY_IS_APPROX(m1, c);++ Matrix<Scalar,Cols,Cols2> m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);+ Matrix<Scalar,Rows,Cols2> m3 = m1*m2;+ m2 = Matrix<Scalar,Cols,Cols2>::Random(Cols,Cols2);+ m2 = qr.solve(m3);+ VERIFY_IS_APPROX(m3, m1*m2);+}++template<typename MatrixType> void qr_invertible()+{+ using std::log;+ using std::abs;+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;+ typedef typename MatrixType::Scalar Scalar;++ int size = internal::random<int>(10,50);++ MatrixType m1(size, size), m2(size, size), m3(size, size);+ m1 = MatrixType::Random(size,size);++ if (internal::is_same<RealScalar,float>::value)+ {+ // let's build a matrix more stable to inverse+ MatrixType a = MatrixType::Random(size,size*2);+ m1 += a * a.adjoint();+ }++ ColPivHouseholderQR<MatrixType> qr(m1);+ m3 = MatrixType::Random(size,size);+ m2 = qr.solve(m3);+ //VERIFY_IS_APPROX(m3, m1*m2);++ // now construct a matrix with prescribed determinant+ m1.setZero();+ for(int i = 0; i < size; i++) m1(i,i) = internal::random<Scalar>();+ RealScalar absdet = abs(m1.diagonal().prod());+ m3 = qr.householderQ(); // get a unitary+ m1 = m3 * m1 * m3;+ qr.compute(m1);+ VERIFY_IS_APPROX(absdet, qr.absDeterminant());+ VERIFY_IS_APPROX(log(absdet), qr.logAbsDeterminant());+}++template<typename MatrixType> void qr_verify_assert()+{+ MatrixType tmp;++ ColPivHouseholderQR<MatrixType> qr;+ VERIFY_RAISES_ASSERT(qr.matrixQR())+ VERIFY_RAISES_ASSERT(qr.solve(tmp))+ VERIFY_RAISES_ASSERT(qr.householderQ())+ VERIFY_RAISES_ASSERT(qr.dimensionOfKernel())+ VERIFY_RAISES_ASSERT(qr.isInjective())+ VERIFY_RAISES_ASSERT(qr.isSurjective())+ VERIFY_RAISES_ASSERT(qr.isInvertible())+ VERIFY_RAISES_ASSERT(qr.inverse())+ VERIFY_RAISES_ASSERT(qr.absDeterminant())+ VERIFY_RAISES_ASSERT(qr.logAbsDeterminant())+}++void test_qr_colpivoting()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( qr<MatrixXf>() );+ CALL_SUBTEST_2( qr<MatrixXd>() );+ CALL_SUBTEST_3( qr<MatrixXcd>() );+ CALL_SUBTEST_4(( qr_fixedsize<Matrix<float,3,5>, 4 >() ));+ CALL_SUBTEST_5(( qr_fixedsize<Matrix<double,6,2>, 3 >() ));+ CALL_SUBTEST_5(( qr_fixedsize<Matrix<double,1,1>, 1 >() ));+ }++ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( qr_invertible<MatrixXf>() );+ CALL_SUBTEST_2( qr_invertible<MatrixXd>() );+ CALL_SUBTEST_6( qr_invertible<MatrixXcf>() );+ CALL_SUBTEST_3( qr_invertible<MatrixXcd>() );+ }++ CALL_SUBTEST_7(qr_verify_assert<Matrix3f>());+ CALL_SUBTEST_8(qr_verify_assert<Matrix3d>());+ CALL_SUBTEST_1(qr_verify_assert<MatrixXf>());+ CALL_SUBTEST_2(qr_verify_assert<MatrixXd>());+ CALL_SUBTEST_6(qr_verify_assert<MatrixXcf>());+ CALL_SUBTEST_3(qr_verify_assert<MatrixXcd>());++ // Test problem size constructors+ CALL_SUBTEST_9(ColPivHouseholderQR<MatrixXf>(10, 20));+}
+ eigen3/test/qr_fullpivoting.cpp view
@@ -0,0 +1,137 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/QR>++template<typename MatrixType> void qr()+{+ typedef typename MatrixType::Index Index;++ Index rows = internal::random<Index>(20,200), cols = internal::random<int>(20,200), cols2 = internal::random<int>(20,200);+ Index rank = internal::random<Index>(1, (std::min)(rows, cols)-1);++ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> MatrixQType;+ MatrixType m1;+ createRandomPIMatrixOfRank(rank,rows,cols,m1);+ FullPivHouseholderQR<MatrixType> qr(m1);+ VERIFY(rank == qr.rank());+ VERIFY(cols - qr.rank() == qr.dimensionOfKernel());+ VERIFY(!qr.isInjective());+ VERIFY(!qr.isInvertible());+ VERIFY(!qr.isSurjective());++ MatrixType r = qr.matrixQR();+ + MatrixQType q = qr.matrixQ();+ VERIFY_IS_UNITARY(q);+ + // FIXME need better way to construct trapezoid+ for(int i = 0; i < rows; i++) for(int j = 0; j < cols; j++) if(i>j) r(i,j) = Scalar(0);++ MatrixType c = qr.matrixQ() * r * qr.colsPermutation().inverse();++ VERIFY_IS_APPROX(m1, c);++ MatrixType m2 = MatrixType::Random(cols,cols2);+ MatrixType m3 = m1*m2;+ m2 = MatrixType::Random(cols,cols2);+ m2 = qr.solve(m3);+ VERIFY_IS_APPROX(m3, m1*m2);+}++template<typename MatrixType> void qr_invertible()+{+ using std::log;+ using std::abs;+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;+ typedef typename MatrixType::Scalar Scalar;++ int size = internal::random<int>(10,50);++ MatrixType m1(size, size), m2(size, size), m3(size, size);+ m1 = MatrixType::Random(size,size);++ if (internal::is_same<RealScalar,float>::value)+ {+ // let's build a matrix more stable to inverse+ MatrixType a = MatrixType::Random(size,size*2);+ m1 += a * a.adjoint();+ }++ FullPivHouseholderQR<MatrixType> qr(m1);+ VERIFY(qr.isInjective());+ VERIFY(qr.isInvertible());+ VERIFY(qr.isSurjective());++ m3 = MatrixType::Random(size,size);+ m2 = qr.solve(m3);+ VERIFY_IS_APPROX(m3, m1*m2);++ // now construct a matrix with prescribed determinant+ m1.setZero();+ for(int i = 0; i < size; i++) m1(i,i) = internal::random<Scalar>();+ RealScalar absdet = abs(m1.diagonal().prod());+ m3 = qr.matrixQ(); // get a unitary+ m1 = m3 * m1 * m3;+ qr.compute(m1);+ VERIFY_IS_APPROX(absdet, qr.absDeterminant());+ VERIFY_IS_APPROX(log(absdet), qr.logAbsDeterminant());+}++template<typename MatrixType> void qr_verify_assert()+{+ MatrixType tmp;++ FullPivHouseholderQR<MatrixType> qr;+ VERIFY_RAISES_ASSERT(qr.matrixQR())+ VERIFY_RAISES_ASSERT(qr.solve(tmp))+ VERIFY_RAISES_ASSERT(qr.matrixQ())+ VERIFY_RAISES_ASSERT(qr.dimensionOfKernel())+ VERIFY_RAISES_ASSERT(qr.isInjective())+ VERIFY_RAISES_ASSERT(qr.isSurjective())+ VERIFY_RAISES_ASSERT(qr.isInvertible())+ VERIFY_RAISES_ASSERT(qr.inverse())+ VERIFY_RAISES_ASSERT(qr.absDeterminant())+ VERIFY_RAISES_ASSERT(qr.logAbsDeterminant())+}++void test_qr_fullpivoting()+{+ for(int i = 0; i < 1; i++) {+ // FIXME : very weird bug here+// CALL_SUBTEST(qr(Matrix2f()) );+ CALL_SUBTEST_1( qr<MatrixXf>() );+ CALL_SUBTEST_2( qr<MatrixXd>() );+ CALL_SUBTEST_3( qr<MatrixXcd>() );+ }++ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( qr_invertible<MatrixXf>() );+ CALL_SUBTEST_2( qr_invertible<MatrixXd>() );+ CALL_SUBTEST_4( qr_invertible<MatrixXcf>() );+ CALL_SUBTEST_3( qr_invertible<MatrixXcd>() );+ }++ CALL_SUBTEST_5(qr_verify_assert<Matrix3f>());+ CALL_SUBTEST_6(qr_verify_assert<Matrix3d>());+ CALL_SUBTEST_1(qr_verify_assert<MatrixXf>());+ CALL_SUBTEST_2(qr_verify_assert<MatrixXd>());+ CALL_SUBTEST_4(qr_verify_assert<MatrixXcf>());+ CALL_SUBTEST_3(qr_verify_assert<MatrixXcd>());++ // Test problem size constructors+ CALL_SUBTEST_7(FullPivHouseholderQR<MatrixXf>(10, 20));+ CALL_SUBTEST_7((FullPivHouseholderQR<Matrix<float,10,20> >(10,20)));+ CALL_SUBTEST_7((FullPivHouseholderQR<Matrix<float,10,20> >(Matrix<float,10,20>::Random())));+ CALL_SUBTEST_7((FullPivHouseholderQR<Matrix<float,20,10> >(20,10)));+ CALL_SUBTEST_7((FullPivHouseholderQR<Matrix<float,20,10> >(Matrix<float,20,10>::Random())));+}
+ eigen3/test/qtvector.cpp view
@@ -0,0 +1,158 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN_WORK_AROUND_QT_BUG_CALLING_WRONG_OPERATOR_NEW_FIXED_IN_QT_4_5++#include "main.h"+#include <QtCore/QVector>+#include <Eigen/Geometry>+#include <Eigen/QtAlignedMalloc>++template<typename MatrixType>+void check_qtvector_matrix(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;++ Index rows = m.rows();+ Index cols = m.cols();+ MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols);+ QVector<MatrixType> v(10, MatrixType(rows,cols)), w(20, y);+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], y);+ }+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.fill(y,22);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(MatrixType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ MatrixType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(int i=23; i<v.size(); ++i)+ {+ VERIFY(v[i]==w[(i-23)%w.size()]);+ }+}++template<typename TransformType>+void check_qtvector_transform(const TransformType&)+{+ typedef typename TransformType::MatrixType MatrixType;+ TransformType x(MatrixType::Random()), y(MatrixType::Random());+ QVector<TransformType> v(10), w(20, y);+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.fill(y,22);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(TransformType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ TransformType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(unsigned int i=23; int(i)<v.size(); ++i)+ {+ VERIFY(v[i].matrix()==w[(i-23)%w.size()].matrix());+ }+}++template<typename QuaternionType>+void check_qtvector_quaternion(const QuaternionType&)+{+ typedef typename QuaternionType::Coefficients Coefficients;+ QuaternionType x(Coefficients::Random()), y(Coefficients::Random());+ QVector<QuaternionType> v(10), w(20, y);+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.fill(y,22);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(QuaternionType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ QuaternionType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(unsigned int i=23; int(i)<v.size(); ++i)+ {+ VERIFY(v[i].coeffs()==w[(i-23)%w.size()].coeffs());+ }+}++void test_qtvector()+{+ // some non vectorizable fixed sizes+ CALL_SUBTEST(check_qtvector_matrix(Vector2f()));+ CALL_SUBTEST(check_qtvector_matrix(Matrix3f()));+ CALL_SUBTEST(check_qtvector_matrix(Matrix3d()));++ // some vectorizable fixed sizes+ CALL_SUBTEST(check_qtvector_matrix(Matrix2f()));+ CALL_SUBTEST(check_qtvector_matrix(Vector4f()));+ CALL_SUBTEST(check_qtvector_matrix(Matrix4f()));+ CALL_SUBTEST(check_qtvector_matrix(Matrix4d()));++ // some dynamic sizes+ CALL_SUBTEST(check_qtvector_matrix(MatrixXd(1,1)));+ CALL_SUBTEST(check_qtvector_matrix(VectorXd(20)));+ CALL_SUBTEST(check_qtvector_matrix(RowVectorXf(20)));+ CALL_SUBTEST(check_qtvector_matrix(MatrixXcf(10,10)));++ // some Transform+ CALL_SUBTEST(check_qtvector_transform(Affine2f()));+ CALL_SUBTEST(check_qtvector_transform(Affine3f()));+ CALL_SUBTEST(check_qtvector_transform(Affine3d()));+ //CALL_SUBTEST(check_qtvector_transform(Transform4d()));++ // some Quaternion+ CALL_SUBTEST(check_qtvector_quaternion(Quaternionf()));+ CALL_SUBTEST(check_qtvector_quaternion(Quaternionf()));+}
+ eigen3/test/real_qz.cpp view
@@ -0,0 +1,81 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Alexey Korepanov <kaikaikai@yandex.ru>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <limits>+#include <Eigen/Eigenvalues>++template<typename MatrixType> void real_qz(const MatrixType& m)+{+ /* this test covers the following files:+ RealQZ.h+ */+ using std::abs;+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ + Index dim = m.cols();+ + MatrixType A = MatrixType::Random(dim,dim),+ B = MatrixType::Random(dim,dim);+++ // Regression test for bug 985: Randomly set rows or columns to zero+ Index k=internal::random<Index>(0, dim-1);+ switch(internal::random<int>(0,10)) {+ case 0:+ A.row(k).setZero(); break;+ case 1:+ A.col(k).setZero(); break;+ case 2:+ B.row(k).setZero(); break;+ case 3:+ B.col(k).setZero(); break;+ default:+ break;+ }++ RealQZ<MatrixType> qz(A,B);+ + VERIFY_IS_EQUAL(qz.info(), Success);+ // check for zeros+ bool all_zeros = true;+ for (Index i=0; i<A.cols(); i++)+ for (Index j=0; j<i; j++) {+ if (abs(qz.matrixT()(i,j))!=Scalar(0.0))+ all_zeros = false;+ if (j<i-1 && abs(qz.matrixS()(i,j))!=Scalar(0.0))+ all_zeros = false;+ if (j==i-1 && j>0 && abs(qz.matrixS()(i,j))!=Scalar(0.0) && abs(qz.matrixS()(i-1,j-1))!=Scalar(0.0))+ all_zeros = false;+ }+ VERIFY_IS_EQUAL(all_zeros, true);+ VERIFY_IS_APPROX(qz.matrixQ()*qz.matrixS()*qz.matrixZ(), A);+ VERIFY_IS_APPROX(qz.matrixQ()*qz.matrixT()*qz.matrixZ(), B);+ VERIFY_IS_APPROX(qz.matrixQ()*qz.matrixQ().adjoint(), MatrixType::Identity(dim,dim));+ VERIFY_IS_APPROX(qz.matrixZ()*qz.matrixZ().adjoint(), MatrixType::Identity(dim,dim));+}++void test_real_qz()+{+ int s = 0;+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( real_qz(Matrix4f()) );+ s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4);+ CALL_SUBTEST_2( real_qz(MatrixXd(s,s)) );++ // some trivial but implementation-wise tricky cases+ CALL_SUBTEST_2( real_qz(MatrixXd(1,1)) );+ CALL_SUBTEST_2( real_qz(MatrixXd(2,2)) );+ CALL_SUBTEST_3( real_qz(Matrix<double,1,1>()) );+ CALL_SUBTEST_4( real_qz(Matrix2d()) );+ }+ + TEST_SET_BUT_UNUSED_VARIABLE(s)+}
+ eigen3/test/redux.cpp view
@@ -0,0 +1,159 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void matrixRedux(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::RealScalar RealScalar;++ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols);++ // The entries of m1 are uniformly distributed in [0,1], so m1.prod() is very small. This may lead to test+ // failures if we underflow into denormals. Thus, we scale so that entires are close to 1.+ MatrixType m1_for_prod = MatrixType::Ones(rows, cols) + RealScalar(0.2) * m1;++ VERIFY_IS_MUCH_SMALLER_THAN(MatrixType::Zero(rows, cols).sum(), Scalar(1));+ VERIFY_IS_APPROX(MatrixType::Ones(rows, cols).sum(), Scalar(float(rows*cols))); // the float() here to shut up excessive MSVC warning about int->complex conversion being lossy+ Scalar s(0), p(1), minc(numext::real(m1.coeff(0))), maxc(numext::real(m1.coeff(0)));+ for(int j = 0; j < cols; j++)+ for(int i = 0; i < rows; i++)+ {+ s += m1(i,j);+ p *= m1_for_prod(i,j);+ minc = (std::min)(numext::real(minc), numext::real(m1(i,j)));+ maxc = (std::max)(numext::real(maxc), numext::real(m1(i,j)));+ }+ const Scalar mean = s/Scalar(RealScalar(rows*cols));++ VERIFY_IS_APPROX(m1.sum(), s);+ VERIFY_IS_APPROX(m1.mean(), mean);+ VERIFY_IS_APPROX(m1_for_prod.prod(), p);+ VERIFY_IS_APPROX(m1.real().minCoeff(), numext::real(minc));+ VERIFY_IS_APPROX(m1.real().maxCoeff(), numext::real(maxc));++ // test slice vectorization assuming assign is ok+ Index r0 = internal::random<Index>(0,rows-1);+ Index c0 = internal::random<Index>(0,cols-1);+ Index r1 = internal::random<Index>(r0+1,rows)-r0;+ Index c1 = internal::random<Index>(c0+1,cols)-c0;+ VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).sum(), m1.block(r0,c0,r1,c1).eval().sum());+ VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).mean(), m1.block(r0,c0,r1,c1).eval().mean());+ VERIFY_IS_APPROX(m1_for_prod.block(r0,c0,r1,c1).prod(), m1_for_prod.block(r0,c0,r1,c1).eval().prod());+ VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).real().minCoeff(), m1.block(r0,c0,r1,c1).real().eval().minCoeff());+ VERIFY_IS_APPROX(m1.block(r0,c0,r1,c1).real().maxCoeff(), m1.block(r0,c0,r1,c1).real().eval().maxCoeff());+ + // test empty objects+ VERIFY_IS_APPROX(m1.block(r0,c0,0,0).sum(), Scalar(0));+ VERIFY_IS_APPROX(m1.block(r0,c0,0,0).prod(), Scalar(1));+}++template<typename VectorType> void vectorRedux(const VectorType& w)+{+ using std::abs;+ typedef typename VectorType::Index Index;+ typedef typename VectorType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ Index size = w.size();++ VectorType v = VectorType::Random(size);+ VectorType v_for_prod = VectorType::Ones(size) + Scalar(0.2) * v; // see comment above declaration of m1_for_prod++ for(int i = 1; i < size; i++)+ {+ Scalar s(0), p(1);+ RealScalar minc(numext::real(v.coeff(0))), maxc(numext::real(v.coeff(0)));+ for(int j = 0; j < i; j++)+ {+ s += v[j];+ p *= v_for_prod[j];+ minc = (std::min)(minc, numext::real(v[j]));+ maxc = (std::max)(maxc, numext::real(v[j]));+ }+ VERIFY_IS_MUCH_SMALLER_THAN(abs(s - v.head(i).sum()), Scalar(1));+ VERIFY_IS_APPROX(p, v_for_prod.head(i).prod());+ VERIFY_IS_APPROX(minc, v.real().head(i).minCoeff());+ VERIFY_IS_APPROX(maxc, v.real().head(i).maxCoeff());+ }++ for(int i = 0; i < size-1; i++)+ {+ Scalar s(0), p(1);+ RealScalar minc(numext::real(v.coeff(i))), maxc(numext::real(v.coeff(i)));+ for(int j = i; j < size; j++)+ {+ s += v[j];+ p *= v_for_prod[j];+ minc = (std::min)(minc, numext::real(v[j]));+ maxc = (std::max)(maxc, numext::real(v[j]));+ }+ VERIFY_IS_MUCH_SMALLER_THAN(abs(s - v.tail(size-i).sum()), Scalar(1));+ VERIFY_IS_APPROX(p, v_for_prod.tail(size-i).prod());+ VERIFY_IS_APPROX(minc, v.real().tail(size-i).minCoeff());+ VERIFY_IS_APPROX(maxc, v.real().tail(size-i).maxCoeff());+ }++ for(int i = 0; i < size/2; i++)+ {+ Scalar s(0), p(1);+ RealScalar minc(numext::real(v.coeff(i))), maxc(numext::real(v.coeff(i)));+ for(int j = i; j < size-i; j++)+ {+ s += v[j];+ p *= v_for_prod[j];+ minc = (std::min)(minc, numext::real(v[j]));+ maxc = (std::max)(maxc, numext::real(v[j]));+ }+ VERIFY_IS_MUCH_SMALLER_THAN(abs(s - v.segment(i, size-2*i).sum()), Scalar(1));+ VERIFY_IS_APPROX(p, v_for_prod.segment(i, size-2*i).prod());+ VERIFY_IS_APPROX(minc, v.real().segment(i, size-2*i).minCoeff());+ VERIFY_IS_APPROX(maxc, v.real().segment(i, size-2*i).maxCoeff());+ }+ + // test empty objects+ VERIFY_IS_APPROX(v.head(0).sum(), Scalar(0));+ VERIFY_IS_APPROX(v.tail(0).prod(), Scalar(1));+ VERIFY_RAISES_ASSERT(v.head(0).mean());+ VERIFY_RAISES_ASSERT(v.head(0).minCoeff());+ VERIFY_RAISES_ASSERT(v.head(0).maxCoeff());+}++void test_redux()+{+ // the max size cannot be too large, otherwise reduxion operations obviously generate large errors.+ int maxsize = (std::min)(100,EIGEN_TEST_MAX_SIZE);+ TEST_SET_BUT_UNUSED_VARIABLE(maxsize);+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( matrixRedux(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_1( matrixRedux(Array<float, 1, 1>()) );+ CALL_SUBTEST_2( matrixRedux(Matrix2f()) );+ CALL_SUBTEST_2( matrixRedux(Array2f()) );+ CALL_SUBTEST_3( matrixRedux(Matrix4d()) );+ CALL_SUBTEST_3( matrixRedux(Array4d()) );+ CALL_SUBTEST_4( matrixRedux(MatrixXcf(internal::random<int>(1,maxsize), internal::random<int>(1,maxsize))) );+ CALL_SUBTEST_4( matrixRedux(ArrayXXcf(internal::random<int>(1,maxsize), internal::random<int>(1,maxsize))) );+ CALL_SUBTEST_5( matrixRedux(MatrixXd (internal::random<int>(1,maxsize), internal::random<int>(1,maxsize))) );+ CALL_SUBTEST_5( matrixRedux(ArrayXXd (internal::random<int>(1,maxsize), internal::random<int>(1,maxsize))) );+ CALL_SUBTEST_6( matrixRedux(MatrixXi (internal::random<int>(1,maxsize), internal::random<int>(1,maxsize))) );+ CALL_SUBTEST_6( matrixRedux(ArrayXXi (internal::random<int>(1,maxsize), internal::random<int>(1,maxsize))) );+ }+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_7( vectorRedux(Vector4f()) );+ CALL_SUBTEST_7( vectorRedux(Array4f()) );+ CALL_SUBTEST_5( vectorRedux(VectorXd(internal::random<int>(1,maxsize))) );+ CALL_SUBTEST_5( vectorRedux(ArrayXd(internal::random<int>(1,maxsize))) );+ CALL_SUBTEST_8( vectorRedux(VectorXf(internal::random<int>(1,maxsize))) );+ CALL_SUBTEST_8( vectorRedux(ArrayXf(internal::random<int>(1,maxsize))) );+ }+}
+ eigen3/test/ref.cpp view
@@ -0,0 +1,276 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 20013 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++// This unit test cannot be easily written to work with EIGEN_DEFAULT_TO_ROW_MAJOR+#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR+#undef EIGEN_DEFAULT_TO_ROW_MAJOR+#endif++static int nb_temporaries;++inline void on_temporary_creation(int) {+ // here's a great place to set a breakpoint when debugging failures in this test!+ nb_temporaries++;+}+ ++#define EIGEN_DENSE_STORAGE_CTOR_PLUGIN { on_temporary_creation(size); }++#include "main.h"++#define VERIFY_EVALUATION_COUNT(XPR,N) {\+ nb_temporaries = 0; \+ XPR; \+ if(nb_temporaries!=N) std::cerr << "nb_temporaries == " << nb_temporaries << "\n"; \+ VERIFY( (#XPR) && nb_temporaries==N ); \+ }+++// test Ref.h++template<typename MatrixType> void ref_matrix(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::RealScalar RealScalar;+ typedef Matrix<Scalar,Dynamic,Dynamic,MatrixType::Options> DynMatrixType;+ typedef Matrix<RealScalar,Dynamic,Dynamic,MatrixType::Options> RealDynMatrixType;+ + typedef Ref<MatrixType> RefMat;+ typedef Ref<DynMatrixType> RefDynMat;+ typedef Ref<const DynMatrixType> ConstRefDynMat;+ typedef Ref<RealDynMatrixType , 0, Stride<Dynamic,Dynamic> > RefRealMatWithStride;++ Index rows = m.rows(), cols = m.cols();+ + MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = m1;+ + Index i = internal::random<Index>(0,rows-1);+ Index j = internal::random<Index>(0,cols-1);+ Index brows = internal::random<Index>(1,rows-i);+ Index bcols = internal::random<Index>(1,cols-j);+ + RefMat rm0 = m1;+ VERIFY_IS_EQUAL(rm0, m1);+ RefDynMat rm1 = m1;+ VERIFY_IS_EQUAL(rm1, m1);+ RefDynMat rm2 = m1.block(i,j,brows,bcols);+ VERIFY_IS_EQUAL(rm2, m1.block(i,j,brows,bcols));+ rm2.setOnes();+ m2.block(i,j,brows,bcols).setOnes();+ VERIFY_IS_EQUAL(m1, m2);+ + m2.block(i,j,brows,bcols).setRandom();+ rm2 = m2.block(i,j,brows,bcols);+ VERIFY_IS_EQUAL(m1, m2);+ + + ConstRefDynMat rm3 = m1.block(i,j,brows,bcols);+ m1.block(i,j,brows,bcols) *= 2;+ m2.block(i,j,brows,bcols) *= 2;+ VERIFY_IS_EQUAL(rm3, m2.block(i,j,brows,bcols));+ RefRealMatWithStride rm4 = m1.real();+ VERIFY_IS_EQUAL(rm4, m2.real());+ rm4.array() += 1;+ m2.real().array() += 1;+ VERIFY_IS_EQUAL(m1, m2);+}++template<typename VectorType> void ref_vector(const VectorType& m)+{+ typedef typename VectorType::Index Index;+ typedef typename VectorType::Scalar Scalar;+ typedef typename VectorType::RealScalar RealScalar;+ typedef Matrix<Scalar,Dynamic,1,VectorType::Options> DynMatrixType;+ typedef Matrix<Scalar,Dynamic,Dynamic,ColMajor> MatrixType;+ typedef Matrix<RealScalar,Dynamic,1,VectorType::Options> RealDynMatrixType;+ + typedef Ref<VectorType> RefMat;+ typedef Ref<DynMatrixType> RefDynMat;+ typedef Ref<const DynMatrixType> ConstRefDynMat;+ typedef Ref<RealDynMatrixType , 0, InnerStride<> > RefRealMatWithStride;+ typedef Ref<DynMatrixType , 0, InnerStride<> > RefMatWithStride;++ Index size = m.size();+ + VectorType v1 = VectorType::Random(size),+ v2 = v1;+ MatrixType mat1 = MatrixType::Random(size,size),+ mat2 = mat1,+ mat3 = MatrixType::Random(size,size);+ + Index i = internal::random<Index>(0,size-1);+ Index bsize = internal::random<Index>(1,size-i);+ + RefMat rm0 = v1;+ VERIFY_IS_EQUAL(rm0, v1);+ RefDynMat rv1 = v1;+ VERIFY_IS_EQUAL(rv1, v1);+ RefDynMat rv2 = v1.segment(i,bsize);+ VERIFY_IS_EQUAL(rv2, v1.segment(i,bsize));+ rv2.setOnes();+ v2.segment(i,bsize).setOnes();+ VERIFY_IS_EQUAL(v1, v2);+ + v2.segment(i,bsize).setRandom();+ rv2 = v2.segment(i,bsize);+ VERIFY_IS_EQUAL(v1, v2);+ + ConstRefDynMat rm3 = v1.segment(i,bsize);+ v1.segment(i,bsize) *= 2;+ v2.segment(i,bsize) *= 2;+ VERIFY_IS_EQUAL(rm3, v2.segment(i,bsize));+ + RefRealMatWithStride rm4 = v1.real();+ VERIFY_IS_EQUAL(rm4, v2.real());+ rm4.array() += 1;+ v2.real().array() += 1;+ VERIFY_IS_EQUAL(v1, v2);+ + RefMatWithStride rm5 = mat1.row(i).transpose();+ VERIFY_IS_EQUAL(rm5, mat1.row(i).transpose());+ rm5.array() += 1;+ mat2.row(i).array() += 1;+ VERIFY_IS_EQUAL(mat1, mat2);+ rm5.noalias() = rm4.transpose() * mat3;+ mat2.row(i) = v2.real().transpose() * mat3;+ VERIFY_IS_APPROX(mat1, mat2);+}++template<typename PlainObjectType> void check_const_correctness(const PlainObjectType&)+{+ // verify that ref-to-const don't have LvalueBit+ typedef typename internal::add_const<PlainObjectType>::type ConstPlainObjectType;+ VERIFY( !(internal::traits<Ref<ConstPlainObjectType> >::Flags & LvalueBit) );+ VERIFY( !(internal::traits<Ref<ConstPlainObjectType, Aligned> >::Flags & LvalueBit) );+ VERIFY( !(Ref<ConstPlainObjectType>::Flags & LvalueBit) );+ VERIFY( !(Ref<ConstPlainObjectType, Aligned>::Flags & LvalueBit) );+}++template<typename B>+EIGEN_DONT_INLINE void call_ref_1(Ref<VectorXf> a, const B &b) { VERIFY_IS_EQUAL(a,b); }+template<typename B>+EIGEN_DONT_INLINE void call_ref_2(const Ref<const VectorXf>& a, const B &b) { VERIFY_IS_EQUAL(a,b); }+template<typename B>+EIGEN_DONT_INLINE void call_ref_3(Ref<VectorXf,0,InnerStride<> > a, const B &b) { VERIFY_IS_EQUAL(a,b); }+template<typename B>+EIGEN_DONT_INLINE void call_ref_4(const Ref<const VectorXf,0,InnerStride<> >& a, const B &b) { VERIFY_IS_EQUAL(a,b); }+template<typename B>+EIGEN_DONT_INLINE void call_ref_5(Ref<MatrixXf,0,OuterStride<> > a, const B &b) { VERIFY_IS_EQUAL(a,b); }+template<typename B>+EIGEN_DONT_INLINE void call_ref_6(const Ref<const MatrixXf,0,OuterStride<> >& a, const B &b) { VERIFY_IS_EQUAL(a,b); }+template<typename B>+EIGEN_DONT_INLINE void call_ref_7(Ref<Matrix<float,Dynamic,3> > a, const B &b) { VERIFY_IS_EQUAL(a,b); }++void call_ref()+{+ VectorXcf ca = VectorXcf::Random(10);+ VectorXf a = VectorXf::Random(10);+ RowVectorXf b = RowVectorXf::Random(10);+ MatrixXf A = MatrixXf::Random(10,10);+ RowVector3f c = RowVector3f::Random();+ const VectorXf& ac(a);+ VectorBlock<VectorXf> ab(a,0,3);+ const VectorBlock<VectorXf> abc(a,0,3);+ ++ VERIFY_EVALUATION_COUNT( call_ref_1(a,a), 0);+ VERIFY_EVALUATION_COUNT( call_ref_1(b,b.transpose()), 0);+// call_ref_1(ac,a<c); // does not compile because ac is const+ VERIFY_EVALUATION_COUNT( call_ref_1(ab,ab), 0);+ VERIFY_EVALUATION_COUNT( call_ref_1(a.head(4),a.head(4)), 0);+ VERIFY_EVALUATION_COUNT( call_ref_1(abc,abc), 0);+ VERIFY_EVALUATION_COUNT( call_ref_1(A.col(3),A.col(3)), 0);+// call_ref_1(A.row(3),A.row(3)); // does not compile because innerstride!=1+ VERIFY_EVALUATION_COUNT( call_ref_3(A.row(3),A.row(3).transpose()), 0);+ VERIFY_EVALUATION_COUNT( call_ref_4(A.row(3),A.row(3).transpose()), 0);+// call_ref_1(a+a, a+a); // does not compile for obvious reason++ MatrixXf tmp = A*A.col(1);+ VERIFY_EVALUATION_COUNT( call_ref_2(A*A.col(1), tmp), 1); // evaluated into a temp+ VERIFY_EVALUATION_COUNT( call_ref_2(ac.head(5),ac.head(5)), 0);+ VERIFY_EVALUATION_COUNT( call_ref_2(ac,ac), 0);+ VERIFY_EVALUATION_COUNT( call_ref_2(a,a), 0);+ VERIFY_EVALUATION_COUNT( call_ref_2(ab,ab), 0);+ VERIFY_EVALUATION_COUNT( call_ref_2(a.head(4),a.head(4)), 0);+ tmp = a+a;+ VERIFY_EVALUATION_COUNT( call_ref_2(a+a,tmp), 1); // evaluated into a temp+ VERIFY_EVALUATION_COUNT( call_ref_2(ca.imag(),ca.imag()), 1); // evaluated into a temp++ VERIFY_EVALUATION_COUNT( call_ref_4(ac.head(5),ac.head(5)), 0);+ tmp = a+a;+ VERIFY_EVALUATION_COUNT( call_ref_4(a+a,tmp), 1); // evaluated into a temp+ VERIFY_EVALUATION_COUNT( call_ref_4(ca.imag(),ca.imag()), 0);++ VERIFY_EVALUATION_COUNT( call_ref_5(a,a), 0);+ VERIFY_EVALUATION_COUNT( call_ref_5(a.head(3),a.head(3)), 0);+ VERIFY_EVALUATION_COUNT( call_ref_5(A,A), 0);+// call_ref_5(A.transpose(),A.transpose()); // does not compile because storage order does not match+ VERIFY_EVALUATION_COUNT( call_ref_5(A.block(1,1,2,2),A.block(1,1,2,2)), 0);+ VERIFY_EVALUATION_COUNT( call_ref_5(b,b), 0); // storage order do not match, but this is a degenerate case that should work+ VERIFY_EVALUATION_COUNT( call_ref_5(a.row(3),a.row(3)), 0);++ VERIFY_EVALUATION_COUNT( call_ref_6(a,a), 0);+ VERIFY_EVALUATION_COUNT( call_ref_6(a.head(3),a.head(3)), 0);+ VERIFY_EVALUATION_COUNT( call_ref_6(A.row(3),A.row(3)), 1); // evaluated into a temp thouth it could be avoided by viewing it as a 1xn matrix+ tmp = A+A;+ VERIFY_EVALUATION_COUNT( call_ref_6(A+A,tmp), 1); // evaluated into a temp+ VERIFY_EVALUATION_COUNT( call_ref_6(A,A), 0);+ VERIFY_EVALUATION_COUNT( call_ref_6(A.transpose(),A.transpose()), 1); // evaluated into a temp because the storage orders do not match+ VERIFY_EVALUATION_COUNT( call_ref_6(A.block(1,1,2,2),A.block(1,1,2,2)), 0);+ + VERIFY_EVALUATION_COUNT( call_ref_7(c,c), 0);+}++typedef Matrix<double,Dynamic,Dynamic,RowMajor> RowMatrixXd;+int test_ref_overload_fun1(Ref<MatrixXd> ) { return 1; }+int test_ref_overload_fun1(Ref<RowMatrixXd> ) { return 2; }+int test_ref_overload_fun1(Ref<MatrixXf> ) { return 3; }++int test_ref_overload_fun2(Ref<const MatrixXd> ) { return 4; }+int test_ref_overload_fun2(Ref<const MatrixXf> ) { return 5; }++// See also bug 969+void test_ref_overloads()+{+ MatrixXd Ad, Bd;+ RowMatrixXd rAd, rBd;+ VERIFY( test_ref_overload_fun1(Ad)==1 );+ VERIFY( test_ref_overload_fun1(rAd)==2 );+ + MatrixXf Af, Bf;+ VERIFY( test_ref_overload_fun2(Ad)==4 );+ VERIFY( test_ref_overload_fun2(Ad+Bd)==4 );+ VERIFY( test_ref_overload_fun2(Af+Bf)==5 );+}++void test_ref()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( ref_vector(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_1( check_const_correctness(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( ref_vector(Vector4d()) );+ CALL_SUBTEST_2( check_const_correctness(Matrix4d()) );+ CALL_SUBTEST_3( ref_vector(Vector4cf()) );+ CALL_SUBTEST_4( ref_vector(VectorXcf(8)) );+ CALL_SUBTEST_5( ref_vector(VectorXi(12)) );+ CALL_SUBTEST_5( check_const_correctness(VectorXi(12)) );++ CALL_SUBTEST_1( ref_matrix(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( ref_matrix(Matrix4d()) );+ CALL_SUBTEST_1( ref_matrix(Matrix<float,3,5>()) );+ CALL_SUBTEST_4( ref_matrix(MatrixXcf(internal::random<int>(1,10),internal::random<int>(1,10))) );+ CALL_SUBTEST_4( ref_matrix(Matrix<std::complex<double>,10,15>()) );+ CALL_SUBTEST_5( ref_matrix(MatrixXi(internal::random<int>(1,10),internal::random<int>(1,10))) );+ CALL_SUBTEST_6( call_ref() );+ }+ + CALL_SUBTEST_7( test_ref_overloads() );+}
+ eigen3/test/resize.cpp view
@@ -0,0 +1,41 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Keir Mierle <mierle@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<DenseIndex rows, DenseIndex cols>+void resizeLikeTest()+{+ MatrixXf A(rows, cols);+ MatrixXf B;+ Matrix<double, rows, cols> C;+ B.resizeLike(A);+ C.resizeLike(B); // Shouldn't crash.+ VERIFY(B.rows() == rows && B.cols() == cols);++ VectorXf x(rows);+ RowVectorXf y;+ y.resizeLike(x);+ VERIFY(y.rows() == 1 && y.cols() == rows);++ y.resize(cols);+ x.resizeLike(y);+ VERIFY(x.rows() == cols && x.cols() == 1);+}++void resizeLikeTest12() { resizeLikeTest<1,2>(); }+void resizeLikeTest1020() { resizeLikeTest<10,20>(); }+void resizeLikeTest31() { resizeLikeTest<3,1>(); }++void test_resize()+{+ CALL_SUBTEST(resizeLikeTest12() );+ CALL_SUBTEST(resizeLikeTest1020() );+ CALL_SUBTEST(resizeLikeTest31() );+}
+ eigen3/test/runtest.sh view
@@ -0,0 +1,20 @@+#!/bin/bash++black='\E[30m'+red='\E[31m'+green='\E[32m'+yellow='\E[33m'+blue='\E[34m'+magenta='\E[35m'+cyan='\E[36m'+white='\E[37m'++if ! ./$1 > /dev/null 2> .runtest.log ; then+ echo -e $red Test $1 failed: $black+ echo -e $blue+ cat .runtest.log+ echo -e $black+ exit 1+else+echo -e $green Test $1 passed$black+fi
+ eigen3/test/schur_complex.cpp view
@@ -0,0 +1,91 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <limits>+#include <Eigen/Eigenvalues>++template<typename MatrixType> void schur(int size = MatrixType::ColsAtCompileTime)+{+ typedef typename ComplexSchur<MatrixType>::ComplexScalar ComplexScalar;+ typedef typename ComplexSchur<MatrixType>::ComplexMatrixType ComplexMatrixType;++ // Test basic functionality: T is triangular and A = U T U*+ for(int counter = 0; counter < g_repeat; ++counter) {+ MatrixType A = MatrixType::Random(size, size);+ ComplexSchur<MatrixType> schurOfA(A);+ VERIFY_IS_EQUAL(schurOfA.info(), Success);+ ComplexMatrixType U = schurOfA.matrixU();+ ComplexMatrixType T = schurOfA.matrixT();+ for(int row = 1; row < size; ++row) {+ for(int col = 0; col < row; ++col) {+ VERIFY(T(row,col) == (typename MatrixType::Scalar)0);+ }+ }+ VERIFY_IS_APPROX(A.template cast<ComplexScalar>(), U * T * U.adjoint());+ }++ // Test asserts when not initialized+ ComplexSchur<MatrixType> csUninitialized;+ VERIFY_RAISES_ASSERT(csUninitialized.matrixT());+ VERIFY_RAISES_ASSERT(csUninitialized.matrixU());+ VERIFY_RAISES_ASSERT(csUninitialized.info());+ + // Test whether compute() and constructor returns same result+ MatrixType A = MatrixType::Random(size, size);+ ComplexSchur<MatrixType> cs1;+ cs1.compute(A);+ ComplexSchur<MatrixType> cs2(A);+ VERIFY_IS_EQUAL(cs1.info(), Success);+ VERIFY_IS_EQUAL(cs2.info(), Success);+ VERIFY_IS_EQUAL(cs1.matrixT(), cs2.matrixT());+ VERIFY_IS_EQUAL(cs1.matrixU(), cs2.matrixU());++ // Test maximum number of iterations+ ComplexSchur<MatrixType> cs3;+ cs3.setMaxIterations(ComplexSchur<MatrixType>::m_maxIterationsPerRow * size).compute(A);+ VERIFY_IS_EQUAL(cs3.info(), Success);+ VERIFY_IS_EQUAL(cs3.matrixT(), cs1.matrixT());+ VERIFY_IS_EQUAL(cs3.matrixU(), cs1.matrixU());+ cs3.setMaxIterations(1).compute(A);+ VERIFY_IS_EQUAL(cs3.info(), size > 1 ? NoConvergence : Success);+ VERIFY_IS_EQUAL(cs3.getMaxIterations(), 1);++ MatrixType Atriangular = A;+ Atriangular.template triangularView<StrictlyLower>().setZero(); + cs3.setMaxIterations(1).compute(Atriangular); // triangular matrices do not need any iterations+ VERIFY_IS_EQUAL(cs3.info(), Success);+ VERIFY_IS_EQUAL(cs3.matrixT(), Atriangular.template cast<ComplexScalar>());+ VERIFY_IS_EQUAL(cs3.matrixU(), ComplexMatrixType::Identity(size, size));++ // Test computation of only T, not U+ ComplexSchur<MatrixType> csOnlyT(A, false);+ VERIFY_IS_EQUAL(csOnlyT.info(), Success);+ VERIFY_IS_EQUAL(cs1.matrixT(), csOnlyT.matrixT());+ VERIFY_RAISES_ASSERT(csOnlyT.matrixU());++ if (size > 1)+ {+ // Test matrix with NaN+ A(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN();+ ComplexSchur<MatrixType> csNaN(A);+ VERIFY_IS_EQUAL(csNaN.info(), NoConvergence);+ }+}++void test_schur_complex()+{+ CALL_SUBTEST_1(( schur<Matrix4cd>() ));+ CALL_SUBTEST_2(( schur<MatrixXcf>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4)) ));+ CALL_SUBTEST_3(( schur<Matrix<std::complex<float>, 1, 1> >() ));+ CALL_SUBTEST_4(( schur<Matrix<float, 3, 3, Eigen::RowMajor> >() ));++ // Test problem size constructors+ CALL_SUBTEST_5(ComplexSchur<MatrixXf>(10));+}
+ eigen3/test/schur_real.cpp view
@@ -0,0 +1,112 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010,2012 Jitse Niesen <jitse@maths.leeds.ac.uk>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <limits>+#include <Eigen/Eigenvalues>++template<typename MatrixType> void verifyIsQuasiTriangular(const MatrixType& T)+{+ typedef typename MatrixType::Index Index;++ const Index size = T.cols();+ typedef typename MatrixType::Scalar Scalar;++ // Check T is lower Hessenberg+ for(int row = 2; row < size; ++row) {+ for(int col = 0; col < row - 1; ++col) {+ VERIFY(T(row,col) == Scalar(0));+ }+ }++ // Check that any non-zero on the subdiagonal is followed by a zero and is+ // part of a 2x2 diagonal block with imaginary eigenvalues.+ for(int row = 1; row < size; ++row) {+ if (T(row,row-1) != Scalar(0)) {+ VERIFY(row == size-1 || T(row+1,row) == 0);+ Scalar tr = T(row-1,row-1) + T(row,row);+ Scalar det = T(row-1,row-1) * T(row,row) - T(row-1,row) * T(row,row-1);+ VERIFY(4 * det > tr * tr);+ }+ }+}++template<typename MatrixType> void schur(int size = MatrixType::ColsAtCompileTime)+{+ // Test basic functionality: T is quasi-triangular and A = U T U*+ for(int counter = 0; counter < g_repeat; ++counter) {+ MatrixType A = MatrixType::Random(size, size);+ RealSchur<MatrixType> schurOfA(A);+ VERIFY_IS_EQUAL(schurOfA.info(), Success);+ MatrixType U = schurOfA.matrixU();+ MatrixType T = schurOfA.matrixT();+ verifyIsQuasiTriangular(T);+ VERIFY_IS_APPROX(A, U * T * U.transpose());+ }++ // Test asserts when not initialized+ RealSchur<MatrixType> rsUninitialized;+ VERIFY_RAISES_ASSERT(rsUninitialized.matrixT());+ VERIFY_RAISES_ASSERT(rsUninitialized.matrixU());+ VERIFY_RAISES_ASSERT(rsUninitialized.info());+ + // Test whether compute() and constructor returns same result+ MatrixType A = MatrixType::Random(size, size);+ RealSchur<MatrixType> rs1;+ rs1.compute(A);+ RealSchur<MatrixType> rs2(A);+ VERIFY_IS_EQUAL(rs1.info(), Success);+ VERIFY_IS_EQUAL(rs2.info(), Success);+ VERIFY_IS_EQUAL(rs1.matrixT(), rs2.matrixT());+ VERIFY_IS_EQUAL(rs1.matrixU(), rs2.matrixU());++ // Test maximum number of iterations+ RealSchur<MatrixType> rs3;+ rs3.setMaxIterations(RealSchur<MatrixType>::m_maxIterationsPerRow * size).compute(A);+ VERIFY_IS_EQUAL(rs3.info(), Success);+ VERIFY_IS_EQUAL(rs3.matrixT(), rs1.matrixT());+ VERIFY_IS_EQUAL(rs3.matrixU(), rs1.matrixU());+ if (size > 2) {+ rs3.setMaxIterations(1).compute(A);+ VERIFY_IS_EQUAL(rs3.info(), NoConvergence);+ VERIFY_IS_EQUAL(rs3.getMaxIterations(), 1);+ }++ MatrixType Atriangular = A;+ Atriangular.template triangularView<StrictlyLower>().setZero(); + rs3.setMaxIterations(1).compute(Atriangular); // triangular matrices do not need any iterations+ VERIFY_IS_EQUAL(rs3.info(), Success);+ VERIFY_IS_EQUAL(rs3.matrixT(), Atriangular);+ VERIFY_IS_EQUAL(rs3.matrixU(), MatrixType::Identity(size, size));++ // Test computation of only T, not U+ RealSchur<MatrixType> rsOnlyT(A, false);+ VERIFY_IS_EQUAL(rsOnlyT.info(), Success);+ VERIFY_IS_EQUAL(rs1.matrixT(), rsOnlyT.matrixT());+ VERIFY_RAISES_ASSERT(rsOnlyT.matrixU());++ if (size > 2)+ {+ // Test matrix with NaN+ A(0,0) = std::numeric_limits<typename MatrixType::Scalar>::quiet_NaN();+ RealSchur<MatrixType> rsNaN(A);+ VERIFY_IS_EQUAL(rsNaN.info(), NoConvergence);+ }+}++void test_schur_real()+{+ CALL_SUBTEST_1(( schur<Matrix4f>() ));+ CALL_SUBTEST_2(( schur<MatrixXd>(internal::random<int>(1,EIGEN_TEST_MAX_SIZE/4)) ));+ CALL_SUBTEST_3(( schur<Matrix<float, 1, 1> >() ));+ CALL_SUBTEST_4(( schur<Matrix<double, 3, 3, Eigen::RowMajor> >() ));++ // Test problem size constructors+ CALL_SUBTEST_5(RealSchur<MatrixXf>(10));+}
+ eigen3/test/selfadjoint.cpp view
@@ -0,0 +1,61 @@+// This file is triangularView of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++// This file tests the basic selfadjointView API,+// the related products and decompositions are tested in specific files.++template<typename MatrixType> void selfadjoint(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;++ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m3(rows, cols);++ m1.diagonal() = m1.diagonal().real().template cast<Scalar>();++ // check selfadjoint to dense+ m3 = m1.template selfadjointView<Upper>();+ VERIFY_IS_APPROX(MatrixType(m3.template triangularView<Upper>()), MatrixType(m1.template triangularView<Upper>()));+ VERIFY_IS_APPROX(m3, m3.adjoint());+++ m3 = m1.template selfadjointView<Lower>();+ VERIFY_IS_APPROX(MatrixType(m3.template triangularView<Lower>()), MatrixType(m1.template triangularView<Lower>()));+ VERIFY_IS_APPROX(m3, m3.adjoint());+}++void bug_159()+{+ Matrix3d m = Matrix3d::Random().selfadjointView<Lower>();+ EIGEN_UNUSED_VARIABLE(m)+}++void test_selfadjoint()+{+ for(int i = 0; i < g_repeat ; i++)+ {+ int s = internal::random<int>(1,EIGEN_TEST_MAX_SIZE);++ CALL_SUBTEST_1( selfadjoint(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( selfadjoint(Matrix<float, 2, 2>()) );+ CALL_SUBTEST_3( selfadjoint(Matrix3cf()) );+ CALL_SUBTEST_4( selfadjoint(MatrixXcd(s,s)) );+ CALL_SUBTEST_5( selfadjoint(Matrix<float,Dynamic,Dynamic,RowMajor>(s, s)) );+ + TEST_SET_BUT_UNUSED_VARIABLE(s)+ }+ + CALL_SUBTEST_1( bug_159() );+}
+ eigen3/test/simplicial_cholesky.cpp view
@@ -0,0 +1,45 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "sparse_solver.h"++template<typename T> void test_simplicial_cholesky_T()+{+ SimplicialCholesky<SparseMatrix<T>, Lower> chol_colmajor_lower_amd;+ SimplicialCholesky<SparseMatrix<T>, Upper> chol_colmajor_upper_amd;+ SimplicialLLT<SparseMatrix<T>, Lower> llt_colmajor_lower_amd;+ SimplicialLLT<SparseMatrix<T>, Upper> llt_colmajor_upper_amd;+ SimplicialLDLT<SparseMatrix<T>, Lower> ldlt_colmajor_lower_amd;+ SimplicialLDLT<SparseMatrix<T>, Upper> ldlt_colmajor_upper_amd;+ SimplicialLDLT<SparseMatrix<T>, Lower, NaturalOrdering<int> > ldlt_colmajor_lower_nat;+ SimplicialLDLT<SparseMatrix<T>, Upper, NaturalOrdering<int> > ldlt_colmajor_upper_nat;++ check_sparse_spd_solving(chol_colmajor_lower_amd);+ check_sparse_spd_solving(chol_colmajor_upper_amd);+ check_sparse_spd_solving(llt_colmajor_lower_amd);+ check_sparse_spd_solving(llt_colmajor_upper_amd);+ check_sparse_spd_solving(ldlt_colmajor_lower_amd);+ check_sparse_spd_solving(ldlt_colmajor_upper_amd);+ + check_sparse_spd_determinant(chol_colmajor_lower_amd);+ check_sparse_spd_determinant(chol_colmajor_upper_amd);+ check_sparse_spd_determinant(llt_colmajor_lower_amd);+ check_sparse_spd_determinant(llt_colmajor_upper_amd);+ check_sparse_spd_determinant(ldlt_colmajor_lower_amd);+ check_sparse_spd_determinant(ldlt_colmajor_upper_amd);+ + check_sparse_spd_solving(ldlt_colmajor_lower_nat);+ check_sparse_spd_solving(ldlt_colmajor_upper_nat);+}++void test_simplicial_cholesky()+{+ CALL_SUBTEST_1(test_simplicial_cholesky_T<double>());+ CALL_SUBTEST_2(test_simplicial_cholesky_T<std::complex<double> >());+}
+ eigen3/test/sizeof.cpp view
@@ -0,0 +1,34 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void verifySizeOf(const MatrixType&)+{+ typedef typename MatrixType::Scalar Scalar;+ if (MatrixType::RowsAtCompileTime!=Dynamic && MatrixType::ColsAtCompileTime!=Dynamic)+ VERIFY(std::ptrdiff_t(sizeof(MatrixType))==std::ptrdiff_t(sizeof(Scalar))*std::ptrdiff_t(MatrixType::SizeAtCompileTime));+ else+ VERIFY(sizeof(MatrixType)==sizeof(Scalar*) + 2 * sizeof(typename MatrixType::Index));+}++void test_sizeof()+{+ CALL_SUBTEST(verifySizeOf(Matrix<float, 1, 1>()) );+ CALL_SUBTEST(verifySizeOf(Matrix4d()) );+ CALL_SUBTEST(verifySizeOf(Matrix<double, 4, 2>()) );+ CALL_SUBTEST(verifySizeOf(Matrix<bool, 7, 5>()) );+ CALL_SUBTEST(verifySizeOf(MatrixXcf(3, 3)) );+ CALL_SUBTEST(verifySizeOf(MatrixXi(8, 12)) );+ CALL_SUBTEST(verifySizeOf(MatrixXcd(20, 20)) );+ CALL_SUBTEST(verifySizeOf(Matrix<float, 100, 100>()) );+ + VERIFY(sizeof(std::complex<float>) == 2*sizeof(float));+ VERIFY(sizeof(std::complex<double>) == 2*sizeof(double));+}
+ eigen3/test/sizeoverflow.cpp view
@@ -0,0 +1,66 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++#define VERIFY_THROWS_BADALLOC(a) { \+ bool threw = false; \+ try { \+ a; \+ } \+ catch (std::bad_alloc&) { threw = true; } \+ VERIFY(threw && "should have thrown bad_alloc: " #a); \+ }++typedef DenseIndex Index;++template<typename MatrixType>+void triggerMatrixBadAlloc(Index rows, Index cols)+{+ VERIFY_THROWS_BADALLOC( MatrixType m(rows, cols) );+ VERIFY_THROWS_BADALLOC( MatrixType m; m.resize(rows, cols) );+ VERIFY_THROWS_BADALLOC( MatrixType m; m.conservativeResize(rows, cols) );+}++template<typename VectorType>+void triggerVectorBadAlloc(Index size)+{+ VERIFY_THROWS_BADALLOC( VectorType v(size) );+ VERIFY_THROWS_BADALLOC( VectorType v; v.resize(size) );+ VERIFY_THROWS_BADALLOC( VectorType v; v.conservativeResize(size) );+}++void test_sizeoverflow()+{+ // there are 2 levels of overflow checking. first in PlainObjectBase.h we check for overflow in rows*cols computations.+ // this is tested in tests of the form times_itself_gives_0 * times_itself_gives_0+ // Then in Memory.h we check for overflow in size * sizeof(T) computations.+ // this is tested in tests of the form times_4_gives_0 * sizeof(float)+ + size_t times_itself_gives_0 = size_t(1) << (8 * sizeof(Index) / 2);+ VERIFY(times_itself_gives_0 * times_itself_gives_0 == 0);++ size_t times_4_gives_0 = size_t(1) << (8 * sizeof(Index) - 2);+ VERIFY(times_4_gives_0 * 4 == 0);++ size_t times_8_gives_0 = size_t(1) << (8 * sizeof(Index) - 3);+ VERIFY(times_8_gives_0 * 8 == 0);++ triggerMatrixBadAlloc<MatrixXf>(times_itself_gives_0, times_itself_gives_0);+ triggerMatrixBadAlloc<MatrixXf>(times_itself_gives_0 / 4, times_itself_gives_0);+ triggerMatrixBadAlloc<MatrixXf>(times_4_gives_0, 1);++ triggerMatrixBadAlloc<MatrixXd>(times_itself_gives_0, times_itself_gives_0);+ triggerMatrixBadAlloc<MatrixXd>(times_itself_gives_0 / 8, times_itself_gives_0);+ triggerMatrixBadAlloc<MatrixXd>(times_8_gives_0, 1);+ + triggerVectorBadAlloc<VectorXf>(times_4_gives_0);+ + triggerVectorBadAlloc<VectorXd>(times_8_gives_0);+}
+ eigen3/test/smallvectors.cpp view
@@ -0,0 +1,67 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN_NO_STATIC_ASSERT+#include "main.h"++template<typename Scalar> void smallVectors()+{+ typedef Matrix<Scalar, 1, 2> V2;+ typedef Matrix<Scalar, 3, 1> V3;+ typedef Matrix<Scalar, 1, 4> V4;+ typedef Matrix<Scalar, Dynamic, 1> VX;+ Scalar x1 = internal::random<Scalar>(),+ x2 = internal::random<Scalar>(),+ x3 = internal::random<Scalar>(),+ x4 = internal::random<Scalar>();+ V2 v2(x1, x2);+ V3 v3(x1, x2, x3);+ V4 v4(x1, x2, x3, x4);+ VERIFY_IS_APPROX(x1, v2.x());+ VERIFY_IS_APPROX(x1, v3.x());+ VERIFY_IS_APPROX(x1, v4.x());+ VERIFY_IS_APPROX(x2, v2.y());+ VERIFY_IS_APPROX(x2, v3.y());+ VERIFY_IS_APPROX(x2, v4.y());+ VERIFY_IS_APPROX(x3, v3.z());+ VERIFY_IS_APPROX(x3, v4.z());+ VERIFY_IS_APPROX(x4, v4.w());++ if (!NumTraits<Scalar>::IsInteger)+ {+ VERIFY_RAISES_ASSERT(V3(2, 1))+ VERIFY_RAISES_ASSERT(V3(3, 2))+ VERIFY_RAISES_ASSERT(V3(Scalar(3), 1))+ VERIFY_RAISES_ASSERT(V3(3, Scalar(1)))+ VERIFY_RAISES_ASSERT(V3(Scalar(3), Scalar(1)))+ VERIFY_RAISES_ASSERT(V3(Scalar(123), Scalar(123)))++ VERIFY_RAISES_ASSERT(V4(1, 3))+ VERIFY_RAISES_ASSERT(V4(2, 4))+ VERIFY_RAISES_ASSERT(V4(1, Scalar(4)))+ VERIFY_RAISES_ASSERT(V4(Scalar(1), 4))+ VERIFY_RAISES_ASSERT(V4(Scalar(1), Scalar(4)))+ VERIFY_RAISES_ASSERT(V4(Scalar(123), Scalar(123)))++ VERIFY_RAISES_ASSERT(VX(3, 2))+ VERIFY_RAISES_ASSERT(VX(Scalar(3), 1))+ VERIFY_RAISES_ASSERT(VX(3, Scalar(1)))+ VERIFY_RAISES_ASSERT(VX(Scalar(3), Scalar(1)))+ VERIFY_RAISES_ASSERT(VX(Scalar(123), Scalar(123)))+ }+}++void test_smallvectors()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST(smallVectors<int>() );+ CALL_SUBTEST(smallVectors<float>() );+ CALL_SUBTEST(smallVectors<double>() );+ }+}
+ eigen3/test/sparse.h view
@@ -0,0 +1,207 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_TESTSPARSE_H+#define EIGEN_TESTSPARSE_H++#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET++#include "main.h"++#if EIGEN_GNUC_AT_LEAST(4,0) && !defined __ICC && !defined(__clang__)++#ifdef min+#undef min+#endif++#ifdef max+#undef max+#endif++#include <tr1/unordered_map>+#define EIGEN_UNORDERED_MAP_SUPPORT+namespace std {+ using std::tr1::unordered_map;+}+#endif++#ifdef EIGEN_GOOGLEHASH_SUPPORT+ #include <google/sparse_hash_map>+#endif++#include <Eigen/Cholesky>+#include <Eigen/LU>+#include <Eigen/Sparse>++enum {+ ForceNonZeroDiag = 1,+ MakeLowerTriangular = 2,+ MakeUpperTriangular = 4,+ ForceRealDiag = 8+};++/* Initializes both a sparse and dense matrix with same random values,+ * and a ratio of \a density non zero entries.+ * \param flags is a union of ForceNonZeroDiag, MakeLowerTriangular and MakeUpperTriangular+ * allowing to control the shape of the matrix.+ * \param zeroCoords and nonzeroCoords allows to get the coordinate lists of the non zero,+ * and zero coefficients respectively.+ */+template<typename Scalar,int Opt1,int Opt2,typename Index> void+initSparse(double density,+ Matrix<Scalar,Dynamic,Dynamic,Opt1>& refMat,+ SparseMatrix<Scalar,Opt2,Index>& sparseMat,+ int flags = 0,+ std::vector<Matrix<Index,2,1> >* zeroCoords = 0,+ std::vector<Matrix<Index,2,1> >* nonzeroCoords = 0)+{+ enum { IsRowMajor = SparseMatrix<Scalar,Opt2,Index>::IsRowMajor };+ sparseMat.setZero();+ //sparseMat.reserve(int(refMat.rows()*refMat.cols()*density));+ sparseMat.reserve(VectorXi::Constant(IsRowMajor ? refMat.rows() : refMat.cols(), int((1.5*density)*(IsRowMajor?refMat.cols():refMat.rows()))));+ + for(Index j=0; j<sparseMat.outerSize(); j++)+ {+ //sparseMat.startVec(j);+ for(Index i=0; i<sparseMat.innerSize(); i++)+ {+ int ai(i), aj(j);+ if(IsRowMajor)+ std::swap(ai,aj);+ Scalar v = (internal::random<double>(0,1) < density) ? internal::random<Scalar>() : Scalar(0);+ if ((flags&ForceNonZeroDiag) && (i==j))+ {+ v = internal::random<Scalar>()*Scalar(3.);+ v = v*v + Scalar(5.);+ }+ if ((flags & MakeLowerTriangular) && aj>ai)+ v = Scalar(0);+ else if ((flags & MakeUpperTriangular) && aj<ai)+ v = Scalar(0);++ if ((flags&ForceRealDiag) && (i==j))+ v = numext::real(v);++ if (v!=Scalar(0))+ {+ //sparseMat.insertBackByOuterInner(j,i) = v;+ sparseMat.insertByOuterInner(j,i) = v;+ if (nonzeroCoords)+ nonzeroCoords->push_back(Matrix<Index,2,1> (ai,aj));+ }+ else if (zeroCoords)+ {+ zeroCoords->push_back(Matrix<Index,2,1> (ai,aj));+ }+ refMat(ai,aj) = v;+ }+ }+ //sparseMat.finalize();+}++template<typename Scalar,int Opt1,int Opt2,typename Index> void+initSparse(double density,+ Matrix<Scalar,Dynamic,Dynamic, Opt1>& refMat,+ DynamicSparseMatrix<Scalar, Opt2, Index>& sparseMat,+ int flags = 0,+ std::vector<Matrix<Index,2,1> >* zeroCoords = 0,+ std::vector<Matrix<Index,2,1> >* nonzeroCoords = 0)+{+ enum { IsRowMajor = DynamicSparseMatrix<Scalar,Opt2,Index>::IsRowMajor };+ sparseMat.setZero();+ sparseMat.reserve(int(refMat.rows()*refMat.cols()*density));+ for(int j=0; j<sparseMat.outerSize(); j++)+ {+ sparseMat.startVec(j); // not needed for DynamicSparseMatrix+ for(int i=0; i<sparseMat.innerSize(); i++)+ {+ int ai(i), aj(j);+ if(IsRowMajor)+ std::swap(ai,aj);+ Scalar v = (internal::random<double>(0,1) < density) ? internal::random<Scalar>() : Scalar(0);+ if ((flags&ForceNonZeroDiag) && (i==j))+ {+ v = internal::random<Scalar>()*Scalar(3.);+ v = v*v + Scalar(5.);+ }+ if ((flags & MakeLowerTriangular) && aj>ai)+ v = Scalar(0);+ else if ((flags & MakeUpperTriangular) && aj<ai)+ v = Scalar(0);++ if ((flags&ForceRealDiag) && (i==j))+ v = numext::real(v);++ if (v!=Scalar(0))+ {+ sparseMat.insertBackByOuterInner(j,i) = v;+ if (nonzeroCoords)+ nonzeroCoords->push_back(Matrix<Index,2,1> (ai,aj));+ }+ else if (zeroCoords)+ {+ zeroCoords->push_back(Matrix<Index,2,1> (ai,aj));+ }+ refMat(ai,aj) = v;+ }+ }+ sparseMat.finalize();+}++template<typename Scalar,int Options,typename Index> void+initSparse(double density,+ Matrix<Scalar,Dynamic,1>& refVec,+ SparseVector<Scalar,Options,Index>& sparseVec,+ std::vector<int>* zeroCoords = 0,+ std::vector<int>* nonzeroCoords = 0)+{+ sparseVec.reserve(int(refVec.size()*density));+ sparseVec.setZero();+ for(Index i=0; i<refVec.size(); i++)+ {+ Scalar v = (internal::random<double>(0,1) < density) ? internal::random<Scalar>() : Scalar(0);+ if (v!=Scalar(0))+ {+ sparseVec.insertBack(i) = v;+ if (nonzeroCoords)+ nonzeroCoords->push_back(i);+ }+ else if (zeroCoords)+ zeroCoords->push_back(i);+ refVec[i] = v;+ }+}++template<typename Scalar,int Options,typename Index> void+initSparse(double density,+ Matrix<Scalar,1,Dynamic>& refVec,+ SparseVector<Scalar,Options,Index>& sparseVec,+ std::vector<int>* zeroCoords = 0,+ std::vector<int>* nonzeroCoords = 0)+{+ sparseVec.reserve(int(refVec.size()*density));+ sparseVec.setZero();+ for(int i=0; i<refVec.size(); i++)+ {+ Scalar v = (internal::random<double>(0,1) < density) ? internal::random<Scalar>() : Scalar(0);+ if (v!=Scalar(0))+ {+ sparseVec.insertBack(i) = v;+ if (nonzeroCoords)+ nonzeroCoords->push_back(i);+ }+ else if (zeroCoords)+ zeroCoords->push_back(i);+ refVec[i] = v;+ }+}+++#include <unsupported/Eigen/SparseExtra>+#endif // EIGEN_TESTSPARSE_H
+ eigen3/test/sparseLM.cpp view
@@ -0,0 +1,176 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Desire Nuentsa <desire.nuentsa_wakam@inria.fr>+// Copyright (C) 2012 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.+#include <iostream>+#include <fstream>+#include <iomanip>++#include "main.h"+#include <Eigen/LevenbergMarquardt>++using namespace std;+using namespace Eigen;++template <typename Scalar>+struct sparseGaussianTest : SparseFunctor<Scalar, int>+{+ typedef Matrix<Scalar,Dynamic,1> VectorType;+ typedef SparseFunctor<Scalar,int> Base;+ typedef typename Base::JacobianType JacobianType;+ sparseGaussianTest(int inputs, int values) : SparseFunctor<Scalar,int>(inputs,values)+ { }+ + VectorType model(const VectorType& uv, VectorType& x)+ {+ VectorType y; //Change this to use expression template+ int m = Base::values(); + int n = Base::inputs();+ eigen_assert(uv.size()%2 == 0);+ eigen_assert(uv.size() == n);+ eigen_assert(x.size() == m);+ y.setZero(m);+ int half = n/2;+ VectorBlock<const VectorType> u(uv, 0, half);+ VectorBlock<const VectorType> v(uv, half, half);+ Scalar coeff;+ for (int j = 0; j < m; j++)+ {+ for (int i = 0; i < half; i++) + {+ coeff = (x(j)-i)/v(i);+ coeff *= coeff;+ if (coeff < 1. && coeff > 0.)+ y(j) += u(i)*std::pow((1-coeff), 2);+ }+ }+ return y;+ }+ void initPoints(VectorType& uv_ref, VectorType& x)+ {+ m_x = x;+ m_y = this->model(uv_ref,x);+ }+ int operator()(const VectorType& uv, VectorType& fvec)+ {+ int m = Base::values(); + int n = Base::inputs();+ eigen_assert(uv.size()%2 == 0);+ eigen_assert(uv.size() == n);+ int half = n/2;+ VectorBlock<const VectorType> u(uv, 0, half);+ VectorBlock<const VectorType> v(uv, half, half);+ fvec = m_y;+ Scalar coeff;+ for (int j = 0; j < m; j++)+ {+ for (int i = 0; i < half; i++)+ {+ coeff = (m_x(j)-i)/v(i);+ coeff *= coeff;+ if (coeff < 1. && coeff > 0.)+ fvec(j) -= u(i)*std::pow((1-coeff), 2);+ }+ }+ return 0;+ }+ + int df(const VectorType& uv, JacobianType& fjac)+ {+ int m = Base::values(); + int n = Base::inputs();+ eigen_assert(n == uv.size());+ eigen_assert(fjac.rows() == m);+ eigen_assert(fjac.cols() == n);+ int half = n/2;+ VectorBlock<const VectorType> u(uv, 0, half);+ VectorBlock<const VectorType> v(uv, half, half);+ Scalar coeff;+ + //Derivatives with respect to u+ for (int col = 0; col < half; col++)+ {+ for (int row = 0; row < m; row++)+ {+ coeff = (m_x(row)-col)/v(col);+ coeff = coeff*coeff;+ if(coeff < 1. && coeff > 0.)+ {+ fjac.coeffRef(row,col) = -(1-coeff)*(1-coeff);+ }+ }+ }+ //Derivatives with respect to v+ for (int col = 0; col < half; col++)+ {+ for (int row = 0; row < m; row++)+ {+ coeff = (m_x(row)-col)/v(col);+ coeff = coeff*coeff;+ if(coeff < 1. && coeff > 0.)+ {+ fjac.coeffRef(row,col+half) = -4 * (u(col)/v(col))*coeff*(1-coeff);+ }+ }+ }+ return 0;+ }+ + VectorType m_x, m_y; //Data points+};+++template<typename T>+void test_sparseLM_T()+{+ typedef Matrix<T,Dynamic,1> VectorType;+ + int inputs = 10;+ int values = 2000;+ sparseGaussianTest<T> sparse_gaussian(inputs, values);+ VectorType uv(inputs),uv_ref(inputs);+ VectorType x(values);+ // Generate the reference solution + uv_ref << -2, 1, 4 ,8, 6, 1.8, 1.2, 1.1, 1.9 , 3;+ //Generate the reference data points+ x.setRandom();+ x = 10*x;+ x.array() += 10;+ sparse_gaussian.initPoints(uv_ref, x);+ + + // Generate the initial parameters + VectorBlock<VectorType> u(uv, 0, inputs/2); + VectorBlock<VectorType> v(uv, inputs/2, inputs/2);+ v.setOnes();+ //Generate u or Solve for u from v+ u.setOnes();+ + // Solve the optimization problem+ LevenbergMarquardt<sparseGaussianTest<T> > lm(sparse_gaussian);+ int info;+// info = lm.minimize(uv);+ + VERIFY_IS_EQUAL(info,1);+ // Do a step by step solution and save the residual + int maxiter = 200;+ int iter = 0;+ MatrixXd Err(values, maxiter);+ MatrixXd Mod(values, maxiter);+ LevenbergMarquardtSpace::Status status; + status = lm.minimizeInit(uv);+ if (status==LevenbergMarquardtSpace::ImproperInputParameters)+ return ;++}+void test_sparseLM()+{+ CALL_SUBTEST_1(test_sparseLM_T<double>());+ + // CALL_SUBTEST_2(test_sparseLM_T<std::complex<double>());+}
+ eigen3/test/sparse_basic.cpp view
@@ -0,0 +1,550 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2008 Daniel Gomez Ferro <dgomezferro@gmail.com>+// Copyright (C) 2013 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "sparse.h"++template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& ref)+{+ typedef typename SparseMatrixType::Index Index;+ typedef Matrix<Index,2,1> Vector2;+ + const Index rows = ref.rows();+ const Index cols = ref.cols();+ typedef typename SparseMatrixType::Scalar Scalar;+ enum { Flags = SparseMatrixType::Flags };++ double density = (std::max)(8./(rows*cols), 0.01);+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;+ typedef Matrix<Scalar,Dynamic,1> DenseVector;+ typedef Matrix<Scalar,1,Dynamic> RowDenseVector;+ Scalar eps = 1e-6;++ Scalar s1 = internal::random<Scalar>();+ {+ SparseMatrixType m(rows, cols);+ DenseMatrix refMat = DenseMatrix::Zero(rows, cols);+ DenseVector vec1 = DenseVector::Random(rows);++ std::vector<Vector2> zeroCoords;+ std::vector<Vector2> nonzeroCoords;+ initSparse<Scalar>(density, refMat, m, 0, &zeroCoords, &nonzeroCoords);++ if (zeroCoords.size()==0 || nonzeroCoords.size()==0)+ return;++ // test coeff and coeffRef+ for (int i=0; i<(int)zeroCoords.size(); ++i)+ {+ VERIFY_IS_MUCH_SMALLER_THAN( m.coeff(zeroCoords[i].x(),zeroCoords[i].y()), eps );+ if(internal::is_same<SparseMatrixType,SparseMatrix<Scalar,Flags> >::value)+ VERIFY_RAISES_ASSERT( m.coeffRef(zeroCoords[0].x(),zeroCoords[0].y()) = 5 );+ }+ VERIFY_IS_APPROX(m, refMat);++ m.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);+ refMat.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);++ VERIFY_IS_APPROX(m, refMat);+ + // test InnerIterators and Block expressions+ for (int t=0; t<10; ++t)+ {+ int j = internal::random<int>(0,cols-1);+ int i = internal::random<int>(0,rows-1);+ int w = internal::random<int>(1,cols-j-1);+ int h = internal::random<int>(1,rows-i-1);++ VERIFY_IS_APPROX(m.block(i,j,h,w), refMat.block(i,j,h,w));+ for(int c=0; c<w; c++)+ {+ VERIFY_IS_APPROX(m.block(i,j,h,w).col(c), refMat.block(i,j,h,w).col(c));+ for(int r=0; r<h; r++)+ {+ VERIFY_IS_APPROX(m.block(i,j,h,w).col(c).coeff(r), refMat.block(i,j,h,w).col(c).coeff(r));+ VERIFY_IS_APPROX(m.block(i,j,h,w).coeff(r,c), refMat.block(i,j,h,w).coeff(r,c));+ }+ }+ for(int r=0; r<h; r++)+ {+ VERIFY_IS_APPROX(m.block(i,j,h,w).row(r), refMat.block(i,j,h,w).row(r));+ for(int c=0; c<w; c++)+ {+ VERIFY_IS_APPROX(m.block(i,j,h,w).row(r).coeff(c), refMat.block(i,j,h,w).row(r).coeff(c));+ VERIFY_IS_APPROX(m.block(i,j,h,w).coeff(r,c), refMat.block(i,j,h,w).coeff(r,c));+ }+ }+ + VERIFY_IS_APPROX(m.middleCols(j,w), refMat.middleCols(j,w));+ VERIFY_IS_APPROX(m.middleRows(i,h), refMat.middleRows(i,h));+ for(int r=0; r<h; r++)+ {+ VERIFY_IS_APPROX(m.middleCols(j,w).row(r), refMat.middleCols(j,w).row(r));+ VERIFY_IS_APPROX(m.middleRows(i,h).row(r), refMat.middleRows(i,h).row(r));+ for(int c=0; c<w; c++)+ {+ VERIFY_IS_APPROX(m.col(c).coeff(r), refMat.col(c).coeff(r));+ VERIFY_IS_APPROX(m.row(r).coeff(c), refMat.row(r).coeff(c));+ + VERIFY_IS_APPROX(m.middleCols(j,w).coeff(r,c), refMat.middleCols(j,w).coeff(r,c));+ VERIFY_IS_APPROX(m.middleRows(i,h).coeff(r,c), refMat.middleRows(i,h).coeff(r,c));+ if(m.middleCols(j,w).coeff(r,c) != Scalar(0))+ {+ VERIFY_IS_APPROX(m.middleCols(j,w).coeffRef(r,c), refMat.middleCols(j,w).coeff(r,c));+ }+ if(m.middleRows(i,h).coeff(r,c) != Scalar(0))+ {+ VERIFY_IS_APPROX(m.middleRows(i,h).coeff(r,c), refMat.middleRows(i,h).coeff(r,c));+ }+ }+ }+ for(int c=0; c<w; c++)+ {+ VERIFY_IS_APPROX(m.middleCols(j,w).col(c), refMat.middleCols(j,w).col(c));+ VERIFY_IS_APPROX(m.middleRows(i,h).col(c), refMat.middleRows(i,h).col(c));+ }+ }++ for(int c=0; c<cols; c++)+ {+ VERIFY_IS_APPROX(m.col(c) + m.col(c), (m + m).col(c));+ VERIFY_IS_APPROX(m.col(c) + m.col(c), refMat.col(c) + refMat.col(c));+ }++ for(int r=0; r<rows; r++)+ {+ VERIFY_IS_APPROX(m.row(r) + m.row(r), (m + m).row(r));+ VERIFY_IS_APPROX(m.row(r) + m.row(r), refMat.row(r) + refMat.row(r));+ }+ + + // test assertion+ VERIFY_RAISES_ASSERT( m.coeffRef(-1,1) = 0 );+ VERIFY_RAISES_ASSERT( m.coeffRef(0,m.cols()) = 0 );+ }++ // test insert (inner random)+ {+ DenseMatrix m1(rows,cols);+ m1.setZero();+ SparseMatrixType m2(rows,cols);+ if(internal::random<int>()%2)+ m2.reserve(VectorXi::Constant(m2.outerSize(), 2));+ for (Index j=0; j<cols; ++j)+ {+ for (Index k=0; k<rows/2; ++k)+ {+ Index i = internal::random<Index>(0,rows-1);+ if (m1.coeff(i,j)==Scalar(0))+ m2.insert(i,j) = m1(i,j) = internal::random<Scalar>();+ }+ }+ m2.finalize();+ VERIFY_IS_APPROX(m2,m1);+ }++ // test insert (fully random)+ {+ DenseMatrix m1(rows,cols);+ m1.setZero();+ SparseMatrixType m2(rows,cols);+ if(internal::random<int>()%2)+ m2.reserve(VectorXi::Constant(m2.outerSize(), 2));+ for (int k=0; k<rows*cols; ++k)+ {+ Index i = internal::random<Index>(0,rows-1);+ Index j = internal::random<Index>(0,cols-1);+ if ((m1.coeff(i,j)==Scalar(0)) && (internal::random<int>()%2))+ m2.insert(i,j) = m1(i,j) = internal::random<Scalar>();+ else+ {+ Scalar v = internal::random<Scalar>();+ m2.coeffRef(i,j) += v;+ m1(i,j) += v;+ }+ }+ VERIFY_IS_APPROX(m2,m1);+ }+ + // test insert (un-compressed)+ for(int mode=0;mode<4;++mode)+ {+ DenseMatrix m1(rows,cols);+ m1.setZero();+ SparseMatrixType m2(rows,cols);+ VectorXi r(VectorXi::Constant(m2.outerSize(), ((mode%2)==0) ? m2.innerSize() : std::max<int>(1,m2.innerSize()/8)));+ m2.reserve(r);+ for (int k=0; k<rows*cols; ++k)+ {+ Index i = internal::random<Index>(0,rows-1);+ Index j = internal::random<Index>(0,cols-1);+ if (m1.coeff(i,j)==Scalar(0))+ m2.insert(i,j) = m1(i,j) = internal::random<Scalar>();+ if(mode==3)+ m2.reserve(r);+ }+ if(internal::random<int>()%2)+ m2.makeCompressed();+ VERIFY_IS_APPROX(m2,m1);+ }++ // test innerVector()+ {+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);+ SparseMatrixType m2(rows, rows);+ initSparse<Scalar>(density, refMat2, m2);+ Index j0 = internal::random<Index>(0,rows-1);+ Index j1 = internal::random<Index>(0,rows-1);+ if(SparseMatrixType::IsRowMajor)+ VERIFY_IS_APPROX(m2.innerVector(j0), refMat2.row(j0));+ else+ VERIFY_IS_APPROX(m2.innerVector(j0), refMat2.col(j0));++ if(SparseMatrixType::IsRowMajor)+ VERIFY_IS_APPROX(m2.innerVector(j0)+m2.innerVector(j1), refMat2.row(j0)+refMat2.row(j1));+ else+ VERIFY_IS_APPROX(m2.innerVector(j0)+m2.innerVector(j1), refMat2.col(j0)+refMat2.col(j1));++ SparseMatrixType m3(rows,rows);+ m3.reserve(VectorXi::Constant(rows,rows/2));+ for(Index j=0; j<rows; ++j)+ for(Index k=0; k<j; ++k)+ m3.insertByOuterInner(j,k) = k+1;+ for(Index j=0; j<rows; ++j)+ {+ VERIFY(j==numext::real(m3.innerVector(j).nonZeros()));+ if(j>0)+ VERIFY(j==numext::real(m3.innerVector(j).lastCoeff()));+ }+ m3.makeCompressed();+ for(Index j=0; j<rows; ++j)+ {+ VERIFY(j==numext::real(m3.innerVector(j).nonZeros()));+ if(j>0)+ VERIFY(j==numext::real(m3.innerVector(j).lastCoeff()));+ }++ //m2.innerVector(j0) = 2*m2.innerVector(j1);+ //refMat2.col(j0) = 2*refMat2.col(j1);+ //VERIFY_IS_APPROX(m2, refMat2);+ }++ // test innerVectors()+ {+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);+ SparseMatrixType m2(rows, rows);+ initSparse<Scalar>(density, refMat2, m2);+ if(internal::random<float>(0,1)>0.5) m2.makeCompressed();+ + Index j0 = internal::random<Index>(0,rows-2);+ Index j1 = internal::random<Index>(0,rows-2);+ Index n0 = internal::random<Index>(1,rows-(std::max)(j0,j1));+ if(SparseMatrixType::IsRowMajor)+ VERIFY_IS_APPROX(m2.innerVectors(j0,n0), refMat2.block(j0,0,n0,cols));+ else+ VERIFY_IS_APPROX(m2.innerVectors(j0,n0), refMat2.block(0,j0,rows,n0));+ if(SparseMatrixType::IsRowMajor)+ VERIFY_IS_APPROX(m2.innerVectors(j0,n0)+m2.innerVectors(j1,n0),+ refMat2.middleRows(j0,n0)+refMat2.middleRows(j1,n0));+ else+ VERIFY_IS_APPROX(m2.innerVectors(j0,n0)+m2.innerVectors(j1,n0),+ refMat2.block(0,j0,rows,n0)+refMat2.block(0,j1,rows,n0));+ + VERIFY_IS_APPROX(m2, refMat2);+ + m2.innerVectors(j0,n0) = m2.innerVectors(j0,n0) + m2.innerVectors(j1,n0);+ if(SparseMatrixType::IsRowMajor)+ refMat2.middleRows(j0,n0) = (refMat2.middleRows(j0,n0) + refMat2.middleRows(j1,n0)).eval();+ else+ refMat2.middleCols(j0,n0) = (refMat2.middleCols(j0,n0) + refMat2.middleCols(j1,n0)).eval();+ + VERIFY_IS_APPROX(m2, refMat2);+ + }+ + // test basic computations+ {+ DenseMatrix refM1 = DenseMatrix::Zero(rows, rows);+ DenseMatrix refM2 = DenseMatrix::Zero(rows, rows);+ DenseMatrix refM3 = DenseMatrix::Zero(rows, rows);+ DenseMatrix refM4 = DenseMatrix::Zero(rows, rows);+ SparseMatrixType m1(rows, rows);+ SparseMatrixType m2(rows, rows);+ SparseMatrixType m3(rows, rows);+ SparseMatrixType m4(rows, rows);+ initSparse<Scalar>(density, refM1, m1);+ initSparse<Scalar>(density, refM2, m2);+ initSparse<Scalar>(density, refM3, m3);+ initSparse<Scalar>(density, refM4, m4);++ VERIFY_IS_APPROX(m1+m2, refM1+refM2);+ VERIFY_IS_APPROX(m1+m2+m3, refM1+refM2+refM3);+ VERIFY_IS_APPROX(m3.cwiseProduct(m1+m2), refM3.cwiseProduct(refM1+refM2));+ VERIFY_IS_APPROX(m1*s1-m2, refM1*s1-refM2);++ VERIFY_IS_APPROX(m1*=s1, refM1*=s1);+ VERIFY_IS_APPROX(m1/=s1, refM1/=s1);++ VERIFY_IS_APPROX(m1+=m2, refM1+=refM2);+ VERIFY_IS_APPROX(m1-=m2, refM1-=refM2);++ if(SparseMatrixType::IsRowMajor)+ VERIFY_IS_APPROX(m1.innerVector(0).dot(refM2.row(0)), refM1.row(0).dot(refM2.row(0)));+ else+ VERIFY_IS_APPROX(m1.innerVector(0).dot(refM2.row(0)), refM1.col(0).dot(refM2.row(0)));++ VERIFY_IS_APPROX(m1.conjugate(), refM1.conjugate());+ VERIFY_IS_APPROX(m1.real(), refM1.real());++ refM4.setRandom();+ // sparse cwise* dense+ VERIFY_IS_APPROX(m3.cwiseProduct(refM4), refM3.cwiseProduct(refM4));+// VERIFY_IS_APPROX(m3.cwise()/refM4, refM3.cwise()/refM4);++ // test aliasing+ VERIFY_IS_APPROX((m1 = -m1), (refM1 = -refM1));+ VERIFY_IS_APPROX((m1 = m1.transpose()), (refM1 = refM1.transpose().eval()));+ VERIFY_IS_APPROX((m1 = -m1.transpose()), (refM1 = -refM1.transpose().eval()));+ VERIFY_IS_APPROX((m1 += -m1), (refM1 += -refM1));+ }++ // test transpose+ {+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);+ SparseMatrixType m2(rows, rows);+ initSparse<Scalar>(density, refMat2, m2);+ VERIFY_IS_APPROX(m2.transpose().eval(), refMat2.transpose().eval());+ VERIFY_IS_APPROX(m2.transpose(), refMat2.transpose());++ VERIFY_IS_APPROX(SparseMatrixType(m2.adjoint()), refMat2.adjoint());+ }++ + + // test generic blocks+ {+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);+ SparseMatrixType m2(rows, rows);+ initSparse<Scalar>(density, refMat2, m2);+ Index j0 = internal::random<Index>(0,rows-2);+ Index j1 = internal::random<Index>(0,rows-2);+ Index n0 = internal::random<Index>(1,rows-(std::max)(j0,j1));+ if(SparseMatrixType::IsRowMajor)+ VERIFY_IS_APPROX(m2.block(j0,0,n0,cols), refMat2.block(j0,0,n0,cols));+ else+ VERIFY_IS_APPROX(m2.block(0,j0,rows,n0), refMat2.block(0,j0,rows,n0));+ + if(SparseMatrixType::IsRowMajor)+ VERIFY_IS_APPROX(m2.block(j0,0,n0,cols)+m2.block(j1,0,n0,cols),+ refMat2.block(j0,0,n0,cols)+refMat2.block(j1,0,n0,cols));+ else+ VERIFY_IS_APPROX(m2.block(0,j0,rows,n0)+m2.block(0,j1,rows,n0),+ refMat2.block(0,j0,rows,n0)+refMat2.block(0,j1,rows,n0));+ + Index i = internal::random<Index>(0,m2.outerSize()-1);+ if(SparseMatrixType::IsRowMajor) {+ m2.innerVector(i) = m2.innerVector(i) * s1;+ refMat2.row(i) = refMat2.row(i) * s1;+ VERIFY_IS_APPROX(m2,refMat2);+ } else {+ m2.innerVector(i) = m2.innerVector(i) * s1;+ refMat2.col(i) = refMat2.col(i) * s1;+ VERIFY_IS_APPROX(m2,refMat2);+ }+ + VERIFY_IS_APPROX(DenseVector(m2.col(j0)), refMat2.col(j0));+ VERIFY_IS_APPROX(m2.col(j0), refMat2.col(j0));+ + VERIFY_IS_APPROX(RowDenseVector(m2.row(j0)), refMat2.row(j0));+ VERIFY_IS_APPROX(m2.row(j0), refMat2.row(j0));+ + VERIFY_IS_APPROX(m2.block(j0,j1,n0,n0), refMat2.block(j0,j1,n0,n0));+ VERIFY_IS_APPROX((2*m2).block(j0,j1,n0,n0), (2*refMat2).block(j0,j1,n0,n0));+ }++ // test prune+ {+ SparseMatrixType m2(rows, rows);+ DenseMatrix refM2(rows, rows);+ refM2.setZero();+ int countFalseNonZero = 0;+ int countTrueNonZero = 0;+ for (Index j=0; j<m2.outerSize(); ++j)+ {+ m2.startVec(j);+ for (Index i=0; i<m2.innerSize(); ++i)+ {+ float x = internal::random<float>(0,1);+ if (x<0.1)+ {+ // do nothing+ }+ else if (x<0.5)+ {+ countFalseNonZero++;+ m2.insertBackByOuterInner(j,i) = Scalar(0);+ }+ else+ {+ countTrueNonZero++;+ m2.insertBackByOuterInner(j,i) = Scalar(1);+ if(SparseMatrixType::IsRowMajor)+ refM2(j,i) = Scalar(1);+ else+ refM2(i,j) = Scalar(1);+ }+ }+ }+ m2.finalize();+ VERIFY(countFalseNonZero+countTrueNonZero == m2.nonZeros());+ VERIFY_IS_APPROX(m2, refM2);+ m2.prune(Scalar(1));+ VERIFY(countTrueNonZero==m2.nonZeros());+ VERIFY_IS_APPROX(m2, refM2);+ }++ // test setFromTriplets+ {+ typedef Triplet<Scalar,Index> TripletType;+ std::vector<TripletType> triplets;+ int ntriplets = rows*cols;+ triplets.reserve(ntriplets);+ DenseMatrix refMat(rows,cols);+ refMat.setZero();+ for(int i=0;i<ntriplets;++i)+ {+ Index r = internal::random<Index>(0,rows-1);+ Index c = internal::random<Index>(0,cols-1);+ Scalar v = internal::random<Scalar>();+ triplets.push_back(TripletType(r,c,v));+ refMat(r,c) += v;+ }+ SparseMatrixType m(rows,cols);+ m.setFromTriplets(triplets.begin(), triplets.end());+ VERIFY_IS_APPROX(m, refMat);+ }++ // test triangularView+ {+ DenseMatrix refMat2(rows, rows), refMat3(rows, rows);+ SparseMatrixType m2(rows, rows), m3(rows, rows);+ initSparse<Scalar>(density, refMat2, m2);+ refMat3 = refMat2.template triangularView<Lower>();+ m3 = m2.template triangularView<Lower>();+ VERIFY_IS_APPROX(m3, refMat3);++ refMat3 = refMat2.template triangularView<Upper>();+ m3 = m2.template triangularView<Upper>();+ VERIFY_IS_APPROX(m3, refMat3);++ refMat3 = refMat2.template triangularView<UnitUpper>();+ m3 = m2.template triangularView<UnitUpper>();+ VERIFY_IS_APPROX(m3, refMat3);++ refMat3 = refMat2.template triangularView<UnitLower>();+ m3 = m2.template triangularView<UnitLower>();+ VERIFY_IS_APPROX(m3, refMat3);++ refMat3 = refMat2.template triangularView<StrictlyUpper>();+ m3 = m2.template triangularView<StrictlyUpper>();+ VERIFY_IS_APPROX(m3, refMat3);++ refMat3 = refMat2.template triangularView<StrictlyLower>();+ m3 = m2.template triangularView<StrictlyLower>();+ VERIFY_IS_APPROX(m3, refMat3);+ }+ + // test selfadjointView+ if(!SparseMatrixType::IsRowMajor)+ {+ DenseMatrix refMat2(rows, rows), refMat3(rows, rows);+ SparseMatrixType m2(rows, rows), m3(rows, rows);+ initSparse<Scalar>(density, refMat2, m2);+ refMat3 = refMat2.template selfadjointView<Lower>();+ m3 = m2.template selfadjointView<Lower>();+ VERIFY_IS_APPROX(m3, refMat3);+ }+ + // test sparseView+ {+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);+ SparseMatrixType m2(rows, rows);+ initSparse<Scalar>(density, refMat2, m2);+ VERIFY_IS_APPROX(m2.eval(), refMat2.sparseView().eval());+ }++ // test diagonal+ {+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);+ SparseMatrixType m2(rows, rows);+ initSparse<Scalar>(density, refMat2, m2);+ VERIFY_IS_APPROX(m2.diagonal(), refMat2.diagonal().eval());+ }+ + // test conservative resize+ {+ std::vector< std::pair<Index,Index> > inc;+ inc.push_back(std::pair<Index,Index>(-3,-2));+ inc.push_back(std::pair<Index,Index>(0,0));+ inc.push_back(std::pair<Index,Index>(3,2));+ inc.push_back(std::pair<Index,Index>(3,0));+ inc.push_back(std::pair<Index,Index>(0,3));+ + for(size_t i = 0; i< inc.size(); i++) {+ Index incRows = inc[i].first;+ Index incCols = inc[i].second;+ SparseMatrixType m1(rows, cols);+ DenseMatrix refMat1 = DenseMatrix::Zero(rows, cols);+ initSparse<Scalar>(density, refMat1, m1);+ + m1.conservativeResize(rows+incRows, cols+incCols);+ refMat1.conservativeResize(rows+incRows, cols+incCols);+ if (incRows > 0) refMat1.bottomRows(incRows).setZero();+ if (incCols > 0) refMat1.rightCols(incCols).setZero();+ + VERIFY_IS_APPROX(m1, refMat1);+ + // Insert new values+ if (incRows > 0) + m1.insert(m1.rows()-1, 0) = refMat1(refMat1.rows()-1, 0) = 1;+ if (incCols > 0) + m1.insert(0, m1.cols()-1) = refMat1(0, refMat1.cols()-1) = 1;+ + VERIFY_IS_APPROX(m1, refMat1);+ + + }+ }++ // test Identity matrix+ {+ DenseMatrix refMat1 = DenseMatrix::Identity(rows, rows);+ SparseMatrixType m1(rows, rows);+ m1.setIdentity();+ VERIFY_IS_APPROX(m1, refMat1);+ }+}++void test_sparse_basic()+{+ for(int i = 0; i < g_repeat; i++) {+ int s = Eigen::internal::random<int>(1,50);+ EIGEN_UNUSED_VARIABLE(s);+ CALL_SUBTEST_1(( sparse_basic(SparseMatrix<double>(8, 8)) ));+ CALL_SUBTEST_2(( sparse_basic(SparseMatrix<std::complex<double>, ColMajor>(s, s)) ));+ CALL_SUBTEST_2(( sparse_basic(SparseMatrix<std::complex<double>, RowMajor>(s, s)) ));+ CALL_SUBTEST_1(( sparse_basic(SparseMatrix<double>(s, s)) ));+ CALL_SUBTEST_1(( sparse_basic(SparseMatrix<double,ColMajor,long int>(s, s)) ));+ CALL_SUBTEST_1(( sparse_basic(SparseMatrix<double,RowMajor,long int>(s, s)) ));+ + CALL_SUBTEST_1(( sparse_basic(SparseMatrix<double,ColMajor,short int>(short(s), short(s))) ));+ CALL_SUBTEST_1(( sparse_basic(SparseMatrix<double,RowMajor,short int>(short(s), short(s))) ));+ }+}
+ eigen3/test/sparse_permutations.cpp view
@@ -0,0 +1,187 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "sparse.h"++template<int OtherStorage, typename SparseMatrixType> void sparse_permutations(const SparseMatrixType& ref)+{+ typedef typename SparseMatrixType::Index Index;++ const Index rows = ref.rows();+ const Index cols = ref.cols();+ typedef typename SparseMatrixType::Scalar Scalar;+ typedef typename SparseMatrixType::Index Index;+ typedef SparseMatrix<Scalar, OtherStorage, Index> OtherSparseMatrixType;+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;+ typedef Matrix<Index,Dynamic,1> VectorI;+ + double density = (std::max)(8./(rows*cols), 0.01);+ + SparseMatrixType mat(rows, cols), up(rows,cols), lo(rows,cols);+ OtherSparseMatrixType res;+ DenseMatrix mat_d = DenseMatrix::Zero(rows, cols), up_sym_d, lo_sym_d, res_d;+ + initSparse<Scalar>(density, mat_d, mat, 0);++ up = mat.template triangularView<Upper>();+ lo = mat.template triangularView<Lower>();+ + up_sym_d = mat_d.template selfadjointView<Upper>();+ lo_sym_d = mat_d.template selfadjointView<Lower>();+ + VERIFY_IS_APPROX(mat, mat_d);+ VERIFY_IS_APPROX(up, DenseMatrix(mat_d.template triangularView<Upper>()));+ VERIFY_IS_APPROX(lo, DenseMatrix(mat_d.template triangularView<Lower>()));+ + PermutationMatrix<Dynamic> p, p_null;+ VectorI pi;+ randomPermutationVector(pi, cols);+ p.indices() = pi;++ res = mat*p;+ res_d = mat_d*p;+ VERIFY(res.isApprox(res_d) && "mat*p");++ res = p*mat;+ res_d = p*mat_d;+ VERIFY(res.isApprox(res_d) && "p*mat");++ res = mat*p.inverse();+ res_d = mat*p.inverse();+ VERIFY(res.isApprox(res_d) && "mat*inv(p)");++ res = p.inverse()*mat;+ res_d = p.inverse()*mat_d;+ VERIFY(res.isApprox(res_d) && "inv(p)*mat");++ res = mat.twistedBy(p);+ res_d = (p * mat_d) * p.inverse();+ VERIFY(res.isApprox(res_d) && "p*mat*inv(p)");++ + res = mat.template selfadjointView<Upper>().twistedBy(p_null);+ res_d = up_sym_d;+ VERIFY(res.isApprox(res_d) && "full selfadjoint upper to full");+ + res = mat.template selfadjointView<Lower>().twistedBy(p_null);+ res_d = lo_sym_d;+ VERIFY(res.isApprox(res_d) && "full selfadjoint lower to full");+ + + res = up.template selfadjointView<Upper>().twistedBy(p_null);+ res_d = up_sym_d;+ VERIFY(res.isApprox(res_d) && "upper selfadjoint to full");+ + res = lo.template selfadjointView<Lower>().twistedBy(p_null);+ res_d = lo_sym_d;+ VERIFY(res.isApprox(res_d) && "lower selfadjoint full");+++ res = mat.template selfadjointView<Upper>();+ res_d = up_sym_d;+ VERIFY(res.isApprox(res_d) && "full selfadjoint upper to full");++ res = mat.template selfadjointView<Lower>();+ res_d = lo_sym_d;+ VERIFY(res.isApprox(res_d) && "full selfadjoint lower to full");++ res = up.template selfadjointView<Upper>();+ res_d = up_sym_d;+ VERIFY(res.isApprox(res_d) && "upper selfadjoint to full");++ res = lo.template selfadjointView<Lower>();+ res_d = lo_sym_d;+ VERIFY(res.isApprox(res_d) && "lower selfadjoint full");+++ res.template selfadjointView<Upper>() = mat.template selfadjointView<Upper>();+ res_d = up_sym_d.template triangularView<Upper>();+ VERIFY(res.isApprox(res_d) && "full selfadjoint upper to upper");++ res.template selfadjointView<Lower>() = mat.template selfadjointView<Upper>();+ res_d = up_sym_d.template triangularView<Lower>();+ VERIFY(res.isApprox(res_d) && "full selfadjoint upper to lower");++ res.template selfadjointView<Upper>() = mat.template selfadjointView<Lower>();+ res_d = lo_sym_d.template triangularView<Upper>();+ VERIFY(res.isApprox(res_d) && "full selfadjoint lower to upper");++ res.template selfadjointView<Lower>() = mat.template selfadjointView<Lower>();+ res_d = lo_sym_d.template triangularView<Lower>();+ VERIFY(res.isApprox(res_d) && "full selfadjoint lower to lower");++ + + res.template selfadjointView<Upper>() = mat.template selfadjointView<Upper>().twistedBy(p);+ res_d = ((p * up_sym_d) * p.inverse()).eval().template triangularView<Upper>();+ VERIFY(res.isApprox(res_d) && "full selfadjoint upper twisted to upper");+ + res.template selfadjointView<Upper>() = mat.template selfadjointView<Lower>().twistedBy(p);+ res_d = ((p * lo_sym_d) * p.inverse()).eval().template triangularView<Upper>();+ VERIFY(res.isApprox(res_d) && "full selfadjoint lower twisted to upper");+ + res.template selfadjointView<Lower>() = mat.template selfadjointView<Lower>().twistedBy(p);+ res_d = ((p * lo_sym_d) * p.inverse()).eval().template triangularView<Lower>();+ VERIFY(res.isApprox(res_d) && "full selfadjoint lower twisted to lower");+ + res.template selfadjointView<Lower>() = mat.template selfadjointView<Upper>().twistedBy(p);+ res_d = ((p * up_sym_d) * p.inverse()).eval().template triangularView<Lower>();+ VERIFY(res.isApprox(res_d) && "full selfadjoint upper twisted to lower");+ + + res.template selfadjointView<Upper>() = up.template selfadjointView<Upper>().twistedBy(p);+ res_d = ((p * up_sym_d) * p.inverse()).eval().template triangularView<Upper>();+ VERIFY(res.isApprox(res_d) && "upper selfadjoint twisted to upper");+ + res.template selfadjointView<Upper>() = lo.template selfadjointView<Lower>().twistedBy(p);+ res_d = ((p * lo_sym_d) * p.inverse()).eval().template triangularView<Upper>();+ VERIFY(res.isApprox(res_d) && "lower selfadjoint twisted to upper");+ + res.template selfadjointView<Lower>() = lo.template selfadjointView<Lower>().twistedBy(p);+ res_d = ((p * lo_sym_d) * p.inverse()).eval().template triangularView<Lower>();+ VERIFY(res.isApprox(res_d) && "lower selfadjoint twisted to lower");+ + res.template selfadjointView<Lower>() = up.template selfadjointView<Upper>().twistedBy(p);+ res_d = ((p * up_sym_d) * p.inverse()).eval().template triangularView<Lower>();+ VERIFY(res.isApprox(res_d) && "upper selfadjoint twisted to lower");++ + res = mat.template selfadjointView<Upper>().twistedBy(p);+ res_d = (p * up_sym_d) * p.inverse();+ VERIFY(res.isApprox(res_d) && "full selfadjoint upper twisted to full");+ + res = mat.template selfadjointView<Lower>().twistedBy(p);+ res_d = (p * lo_sym_d) * p.inverse();+ VERIFY(res.isApprox(res_d) && "full selfadjoint lower twisted to full");+ + res = up.template selfadjointView<Upper>().twistedBy(p);+ res_d = (p * up_sym_d) * p.inverse();+ VERIFY(res.isApprox(res_d) && "upper selfadjoint twisted to full");+ + res = lo.template selfadjointView<Lower>().twistedBy(p);+ res_d = (p * lo_sym_d) * p.inverse();+ VERIFY(res.isApprox(res_d) && "lower selfadjoint twisted to full");+}++template<typename Scalar> void sparse_permutations_all(int size)+{+ CALL_SUBTEST(( sparse_permutations<ColMajor>(SparseMatrix<Scalar, ColMajor>(size,size)) ));+ CALL_SUBTEST(( sparse_permutations<ColMajor>(SparseMatrix<Scalar, RowMajor>(size,size)) ));+ CALL_SUBTEST(( sparse_permutations<RowMajor>(SparseMatrix<Scalar, ColMajor>(size,size)) ));+ CALL_SUBTEST(( sparse_permutations<RowMajor>(SparseMatrix<Scalar, RowMajor>(size,size)) ));+}++void test_sparse_permutations()+{+ for(int i = 0; i < g_repeat; i++) {+ int s = Eigen::internal::random<int>(1,50);+ CALL_SUBTEST_1(( sparse_permutations_all<double>(s) ));+ CALL_SUBTEST_2(( sparse_permutations_all<std::complex<double> >(s) ));+ }+}
+ eigen3/test/sparse_product.cpp view
@@ -0,0 +1,252 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "sparse.h"++template<typename SparseMatrixType, typename DenseMatrix, bool IsRowMajor=SparseMatrixType::IsRowMajor> struct test_outer;++template<typename SparseMatrixType, typename DenseMatrix> struct test_outer<SparseMatrixType,DenseMatrix,false> {+ static void run(SparseMatrixType& m2, SparseMatrixType& m4, DenseMatrix& refMat2, DenseMatrix& refMat4) {+ typedef typename SparseMatrixType::Index Index;+ Index c = internal::random<Index>(0,m2.cols()-1);+ Index c1 = internal::random<Index>(0,m2.cols()-1);+ VERIFY_IS_APPROX(m4=m2.col(c)*refMat2.col(c1).transpose(), refMat4=refMat2.col(c)*refMat2.col(c1).transpose());+ VERIFY_IS_APPROX(m4=refMat2.col(c1)*m2.col(c).transpose(), refMat4=refMat2.col(c1)*refMat2.col(c).transpose());+ }+};++template<typename SparseMatrixType, typename DenseMatrix> struct test_outer<SparseMatrixType,DenseMatrix,true> {+ static void run(SparseMatrixType& m2, SparseMatrixType& m4, DenseMatrix& refMat2, DenseMatrix& refMat4) {+ typedef typename SparseMatrixType::Index Index;+ Index r = internal::random<Index>(0,m2.rows()-1);+ Index c1 = internal::random<Index>(0,m2.cols()-1);+ VERIFY_IS_APPROX(m4=m2.row(r).transpose()*refMat2.col(c1).transpose(), refMat4=refMat2.row(r).transpose()*refMat2.col(c1).transpose());+ VERIFY_IS_APPROX(m4=refMat2.col(c1)*m2.row(r), refMat4=refMat2.col(c1)*refMat2.row(r));+ }+};++// (m2,m4,refMat2,refMat4,dv1);+// VERIFY_IS_APPROX(m4=m2.innerVector(c)*dv1.transpose(), refMat4=refMat2.colVector(c)*dv1.transpose());+// VERIFY_IS_APPROX(m4=dv1*mcm.col(c).transpose(), refMat4=dv1*refMat2.col(c).transpose());++template<typename SparseMatrixType> void sparse_product()+{+ typedef typename SparseMatrixType::Index Index;+ Index n = 100;+ const Index rows = internal::random<Index>(1,n);+ const Index cols = internal::random<Index>(1,n);+ const Index depth = internal::random<Index>(1,n);+ typedef typename SparseMatrixType::Scalar Scalar;+ enum { Flags = SparseMatrixType::Flags };++ double density = (std::max)(8./(rows*cols), 0.1);+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;+ typedef Matrix<Scalar,Dynamic,1> DenseVector;+ typedef Matrix<Scalar,1,Dynamic> RowDenseVector;+ typedef SparseVector<Scalar,0,Index> ColSpVector;+ typedef SparseVector<Scalar,RowMajor,Index> RowSpVector;++ Scalar s1 = internal::random<Scalar>();+ Scalar s2 = internal::random<Scalar>();++ // test matrix-matrix product+ {+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, depth);+ DenseMatrix refMat2t = DenseMatrix::Zero(depth, rows);+ DenseMatrix refMat3 = DenseMatrix::Zero(depth, cols);+ DenseMatrix refMat3t = DenseMatrix::Zero(cols, depth);+ DenseMatrix refMat4 = DenseMatrix::Zero(rows, cols);+ DenseMatrix refMat4t = DenseMatrix::Zero(cols, rows);+ DenseMatrix refMat5 = DenseMatrix::Random(depth, cols);+ DenseMatrix refMat6 = DenseMatrix::Random(rows, rows);+ DenseMatrix dm4 = DenseMatrix::Zero(rows, rows);+// DenseVector dv1 = DenseVector::Random(rows);+ SparseMatrixType m2 (rows, depth);+ SparseMatrixType m2t(depth, rows);+ SparseMatrixType m3 (depth, cols);+ SparseMatrixType m3t(cols, depth);+ SparseMatrixType m4 (rows, cols);+ SparseMatrixType m4t(cols, rows);+ SparseMatrixType m6(rows, rows);+ initSparse(density, refMat2, m2);+ initSparse(density, refMat2t, m2t);+ initSparse(density, refMat3, m3);+ initSparse(density, refMat3t, m3t);+ initSparse(density, refMat4, m4);+ initSparse(density, refMat4t, m4t);+ initSparse(density, refMat6, m6);++// int c = internal::random<int>(0,depth-1);++ // sparse * sparse+ VERIFY_IS_APPROX(m4=m2*m3, refMat4=refMat2*refMat3);+ VERIFY_IS_APPROX(m4=m2t.transpose()*m3, refMat4=refMat2t.transpose()*refMat3);+ VERIFY_IS_APPROX(m4=m2t.transpose()*m3t.transpose(), refMat4=refMat2t.transpose()*refMat3t.transpose());+ VERIFY_IS_APPROX(m4=m2*m3t.transpose(), refMat4=refMat2*refMat3t.transpose());++ VERIFY_IS_APPROX(m4 = m2*m3/s1, refMat4 = refMat2*refMat3/s1);+ VERIFY_IS_APPROX(m4 = m2*m3*s1, refMat4 = refMat2*refMat3*s1);+ VERIFY_IS_APPROX(m4 = s2*m2*m3*s1, refMat4 = s2*refMat2*refMat3*s1);++ VERIFY_IS_APPROX(m4=(m2*m3).pruned(0), refMat4=refMat2*refMat3);+ VERIFY_IS_APPROX(m4=(m2t.transpose()*m3).pruned(0), refMat4=refMat2t.transpose()*refMat3);+ VERIFY_IS_APPROX(m4=(m2t.transpose()*m3t.transpose()).pruned(0), refMat4=refMat2t.transpose()*refMat3t.transpose());+ VERIFY_IS_APPROX(m4=(m2*m3t.transpose()).pruned(0), refMat4=refMat2*refMat3t.transpose());++ // test aliasing+ m4 = m2; refMat4 = refMat2;+ VERIFY_IS_APPROX(m4=m4*m3, refMat4=refMat4*refMat3);++ // sparse * dense+ VERIFY_IS_APPROX(dm4=m2*refMat3, refMat4=refMat2*refMat3);+ VERIFY_IS_APPROX(dm4=m2*refMat3t.transpose(), refMat4=refMat2*refMat3t.transpose());+ VERIFY_IS_APPROX(dm4=m2t.transpose()*refMat3, refMat4=refMat2t.transpose()*refMat3);+ VERIFY_IS_APPROX(dm4=m2t.transpose()*refMat3t.transpose(), refMat4=refMat2t.transpose()*refMat3t.transpose());++ VERIFY_IS_APPROX(dm4=m2*(refMat3+refMat3), refMat4=refMat2*(refMat3+refMat3));+ VERIFY_IS_APPROX(dm4=m2t.transpose()*(refMat3+refMat5)*0.5, refMat4=refMat2t.transpose()*(refMat3+refMat5)*0.5);++ // dense * sparse+ VERIFY_IS_APPROX(dm4=refMat2*m3, refMat4=refMat2*refMat3);+ VERIFY_IS_APPROX(dm4=refMat2*m3t.transpose(), refMat4=refMat2*refMat3t.transpose());+ VERIFY_IS_APPROX(dm4=refMat2t.transpose()*m3, refMat4=refMat2t.transpose()*refMat3);+ VERIFY_IS_APPROX(dm4=refMat2t.transpose()*m3t.transpose(), refMat4=refMat2t.transpose()*refMat3t.transpose());++ // sparse * dense and dense * sparse outer product+ test_outer<SparseMatrixType,DenseMatrix>::run(m2,m4,refMat2,refMat4);++ VERIFY_IS_APPROX(m6=m6*m6, refMat6=refMat6*refMat6);+ + // sparse matrix * sparse vector+ ColSpVector cv0(cols), cv1;+ DenseVector dcv0(cols), dcv1;+ initSparse(2*density,dcv0, cv0);+ + RowSpVector rv0(depth), rv1;+ RowDenseVector drv0(depth), drv1(rv1);+ initSparse(2*density,drv0, rv0);+ + VERIFY_IS_APPROX(cv1=rv0*m3, dcv1=drv0*refMat3);+ VERIFY_IS_APPROX(rv1=rv0*m3, drv1=drv0*refMat3);+ VERIFY_IS_APPROX(cv1=m3*cv0, dcv1=refMat3*dcv0);+ VERIFY_IS_APPROX(cv1=m3t.adjoint()*cv0, dcv1=refMat3t.adjoint()*dcv0);+ VERIFY_IS_APPROX(rv1=m3*cv0, drv1=refMat3*dcv0);+ }+ + // test matrix - diagonal product+ {+ DenseMatrix refM2 = DenseMatrix::Zero(rows, cols);+ DenseMatrix refM3 = DenseMatrix::Zero(rows, cols);+ DenseMatrix d3 = DenseMatrix::Zero(rows, cols);+ DiagonalMatrix<Scalar,Dynamic> d1(DenseVector::Random(cols));+ DiagonalMatrix<Scalar,Dynamic> d2(DenseVector::Random(rows));+ SparseMatrixType m2(rows, cols);+ SparseMatrixType m3(rows, cols);+ initSparse<Scalar>(density, refM2, m2);+ initSparse<Scalar>(density, refM3, m3);+ VERIFY_IS_APPROX(m3=m2*d1, refM3=refM2*d1);+ VERIFY_IS_APPROX(m3=m2.transpose()*d2, refM3=refM2.transpose()*d2);+ VERIFY_IS_APPROX(m3=d2*m2, refM3=d2*refM2);+ VERIFY_IS_APPROX(m3=d1*m2.transpose(), refM3=d1*refM2.transpose());+ + // also check with a SparseWrapper:+ DenseVector v1 = DenseVector::Random(cols);+ DenseVector v2 = DenseVector::Random(rows);+ VERIFY_IS_APPROX(m3=m2*v1.asDiagonal(), refM3=refM2*v1.asDiagonal());+ VERIFY_IS_APPROX(m3=m2.transpose()*v2.asDiagonal(), refM3=refM2.transpose()*v2.asDiagonal());+ VERIFY_IS_APPROX(m3=v2.asDiagonal()*m2, refM3=v2.asDiagonal()*refM2);+ VERIFY_IS_APPROX(m3=v1.asDiagonal()*m2.transpose(), refM3=v1.asDiagonal()*refM2.transpose());+ + VERIFY_IS_APPROX(m3=v2.asDiagonal()*m2*v1.asDiagonal(), refM3=v2.asDiagonal()*refM2*v1.asDiagonal());+ + // evaluate to a dense matrix to check the .row() and .col() iterator functions+ VERIFY_IS_APPROX(d3=m2*d1, refM3=refM2*d1);+ VERIFY_IS_APPROX(d3=m2.transpose()*d2, refM3=refM2.transpose()*d2);+ VERIFY_IS_APPROX(d3=d2*m2, refM3=d2*refM2);+ VERIFY_IS_APPROX(d3=d1*m2.transpose(), refM3=d1*refM2.transpose());+ }++ // test self adjoint products+ {+ DenseMatrix b = DenseMatrix::Random(rows, rows);+ DenseMatrix x = DenseMatrix::Random(rows, rows);+ DenseMatrix refX = DenseMatrix::Random(rows, rows);+ DenseMatrix refUp = DenseMatrix::Zero(rows, rows);+ DenseMatrix refLo = DenseMatrix::Zero(rows, rows);+ DenseMatrix refS = DenseMatrix::Zero(rows, rows);+ SparseMatrixType mUp(rows, rows);+ SparseMatrixType mLo(rows, rows);+ SparseMatrixType mS(rows, rows);+ do {+ initSparse<Scalar>(density, refUp, mUp, ForceRealDiag|/*ForceNonZeroDiag|*/MakeUpperTriangular);+ } while (refUp.isZero());+ refLo = refUp.adjoint();+ mLo = mUp.adjoint();+ refS = refUp + refLo;+ refS.diagonal() *= 0.5;+ mS = mUp + mLo;+ // TODO be able to address the diagonal....+ for (int k=0; k<mS.outerSize(); ++k)+ for (typename SparseMatrixType::InnerIterator it(mS,k); it; ++it)+ if (it.index() == k)+ it.valueRef() *= 0.5;++ VERIFY_IS_APPROX(refS.adjoint(), refS);+ VERIFY_IS_APPROX(mS.adjoint(), mS);+ VERIFY_IS_APPROX(mS, refS);+ VERIFY_IS_APPROX(x=mS*b, refX=refS*b);++ VERIFY_IS_APPROX(x=mUp.template selfadjointView<Upper>()*b, refX=refS*b);+ VERIFY_IS_APPROX(x=mLo.template selfadjointView<Lower>()*b, refX=refS*b);+ VERIFY_IS_APPROX(x=mS.template selfadjointView<Upper|Lower>()*b, refX=refS*b);+ + // sparse selfadjointView * sparse + SparseMatrixType mSres(rows,rows);+ VERIFY_IS_APPROX(mSres = mLo.template selfadjointView<Lower>()*mS,+ refX = refLo.template selfadjointView<Lower>()*refS);+ // sparse * sparse selfadjointview+ VERIFY_IS_APPROX(mSres = mS * mLo.template selfadjointView<Lower>(),+ refX = refS * refLo.template selfadjointView<Lower>());+ }+ +}++// New test for Bug in SparseTimeDenseProduct+template<typename SparseMatrixType, typename DenseMatrixType> void sparse_product_regression_test()+{+ // This code does not compile with afflicted versions of the bug+ SparseMatrixType sm1(3,2);+ DenseMatrixType m2(2,2);+ sm1.setZero();+ m2.setZero();++ DenseMatrixType m3 = sm1*m2;+++ // This code produces a segfault with afflicted versions of another SparseTimeDenseProduct+ // bug++ SparseMatrixType sm2(20000,2);+ sm2.setZero();+ DenseMatrixType m4(sm2*m2);++ VERIFY_IS_APPROX( m4(0,0), 0.0 );+}++void test_sparse_product()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( (sparse_product<SparseMatrix<double,ColMajor> >()) );+ CALL_SUBTEST_1( (sparse_product<SparseMatrix<double,RowMajor> >()) );+ CALL_SUBTEST_2( (sparse_product<SparseMatrix<std::complex<double>, ColMajor > >()) );+ CALL_SUBTEST_2( (sparse_product<SparseMatrix<std::complex<double>, RowMajor > >()) );+ CALL_SUBTEST_3( (sparse_product<SparseMatrix<float,ColMajor,long int> >()) );+ CALL_SUBTEST_4( (sparse_product_regression_test<SparseMatrix<double,RowMajor>, Matrix<double, Dynamic, Dynamic, RowMajor> >()) );+ }+}
+ eigen3/test/sparse_solver.h view
@@ -0,0 +1,362 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "sparse.h"+#include <Eigen/SparseCore>++template<typename Solver, typename Rhs, typename DenseMat, typename DenseRhs>+void check_sparse_solving(Solver& solver, const typename Solver::MatrixType& A, const Rhs& b, const DenseMat& dA, const DenseRhs& db)+{+ typedef typename Solver::MatrixType Mat;+ typedef typename Mat::Scalar Scalar;++ DenseRhs refX = dA.lu().solve(db);+ {+ Rhs x(b.rows(), b.cols());+ Rhs oldb = b;++ solver.compute(A);+ if (solver.info() != Success)+ {+ std::cerr << "sparse solver testing: factorization failed (check_sparse_solving)\n";+ exit(0);+ return;+ }+ x = solver.solve(b);+ if (solver.info() != Success)+ {+ std::cerr << "sparse solver testing: solving failed\n";+ return;+ }+ VERIFY(oldb.isApprox(b) && "sparse solver testing: the rhs should not be modified!");++ VERIFY(x.isApprox(refX,test_precision<Scalar>()));+ x.setZero();+ // test the analyze/factorize API+ solver.analyzePattern(A);+ solver.factorize(A);+ if (solver.info() != Success)+ {+ std::cerr << "sparse solver testing: factorization failed (check_sparse_solving)\n";+ exit(0);+ return;+ }+ x = solver.solve(b);+ if (solver.info() != Success)+ {+ std::cerr << "sparse solver testing: solving failed\n";+ return;+ }+ VERIFY(oldb.isApprox(b) && "sparse solver testing: the rhs should not be modified!");++ VERIFY(x.isApprox(refX,test_precision<Scalar>()));+ }+ + // test dense Block as the result and rhs:+ {+ DenseRhs x(db.rows(), db.cols());+ DenseRhs oldb(db);+ x.setZero();+ x.block(0,0,x.rows(),x.cols()) = solver.solve(db.block(0,0,db.rows(),db.cols()));+ VERIFY(oldb.isApprox(db) && "sparse solver testing: the rhs should not be modified!");+ VERIFY(x.isApprox(refX,test_precision<Scalar>()));+ }+}++template<typename Solver, typename Rhs>+void check_sparse_solving_real_cases(Solver& solver, const typename Solver::MatrixType& A, const Rhs& b, const Rhs& refX)+{+ typedef typename Solver::MatrixType Mat;+ typedef typename Mat::Scalar Scalar;+ typedef typename Mat::RealScalar RealScalar;+ + Rhs x(b.rows(), b.cols());+ + solver.compute(A);+ if (solver.info() != Success)+ {+ std::cerr << "sparse solver testing: factorization failed (check_sparse_solving_real_cases)\n";+ exit(0);+ return;+ }+ x = solver.solve(b);+ if (solver.info() != Success)+ {+ std::cerr << "sparse solver testing: solving failed\n";+ return;+ }+ + RealScalar res_error;+ // Compute the norm of the relative error+ if(refX.size() != 0)+ res_error = (refX - x).norm()/refX.norm();+ else+ { + // Compute the relative residual norm+ res_error = (b - A * x).norm()/b.norm();+ }+ if (res_error > test_precision<Scalar>() ){+ std::cerr << "Test " << g_test_stack.back() << " failed in "EI_PP_MAKE_STRING(__FILE__) + << " (" << EI_PP_MAKE_STRING(__LINE__) << ")" << std::endl << std::endl;+ abort();+ }+ +}+template<typename Solver, typename DenseMat>+void check_sparse_determinant(Solver& solver, const typename Solver::MatrixType& A, const DenseMat& dA)+{+ typedef typename Solver::MatrixType Mat;+ typedef typename Mat::Scalar Scalar;+ + solver.compute(A);+ if (solver.info() != Success)+ {+ std::cerr << "sparse solver testing: factorization failed (check_sparse_determinant)\n";+ return;+ }++ Scalar refDet = dA.determinant();+ VERIFY_IS_APPROX(refDet,solver.determinant());+}+template<typename Solver, typename DenseMat>+void check_sparse_abs_determinant(Solver& solver, const typename Solver::MatrixType& A, const DenseMat& dA)+{+ using std::abs;+ typedef typename Solver::MatrixType Mat;+ typedef typename Mat::Scalar Scalar;+ + solver.compute(A);+ if (solver.info() != Success)+ {+ std::cerr << "sparse solver testing: factorization failed (check_sparse_abs_determinant)\n";+ return;+ }++ Scalar refDet = abs(dA.determinant());+ VERIFY_IS_APPROX(refDet,solver.absDeterminant());+}++template<typename Solver, typename DenseMat>+int generate_sparse_spd_problem(Solver& , typename Solver::MatrixType& A, typename Solver::MatrixType& halfA, DenseMat& dA, int maxSize = 300)+{+ typedef typename Solver::MatrixType Mat;+ typedef typename Mat::Scalar Scalar;+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;++ int size = internal::random<int>(1,maxSize);+ double density = (std::max)(8./(size*size), 0.01);++ Mat M(size, size);+ DenseMatrix dM(size, size);++ initSparse<Scalar>(density, dM, M, ForceNonZeroDiag);++ A = M * M.adjoint();+ dA = dM * dM.adjoint();+ + halfA.resize(size,size);+ if(Solver::UpLo==(Lower|Upper))+ halfA = A;+ else+ halfA.template selfadjointView<Solver::UpLo>().rankUpdate(M);+ + return size;+}+++#ifdef TEST_REAL_CASES+template<typename Scalar>+inline std::string get_matrixfolder()+{+ std::string mat_folder = TEST_REAL_CASES; + if( internal::is_same<Scalar, std::complex<float> >::value || internal::is_same<Scalar, std::complex<double> >::value )+ mat_folder = mat_folder + static_cast<std::string>("/complex/");+ else+ mat_folder = mat_folder + static_cast<std::string>("/real/");+ return mat_folder;+}+#endif++template<typename Solver> void check_sparse_spd_solving(Solver& solver)+{+ typedef typename Solver::MatrixType Mat;+ typedef typename Mat::Scalar Scalar;+ typedef SparseMatrix<Scalar,ColMajor> SpMat;+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;+ typedef Matrix<Scalar,Dynamic,1> DenseVector;++ // generate the problem+ Mat A, halfA;+ DenseMatrix dA;+ for (int i = 0; i < g_repeat; i++) {+ int size = generate_sparse_spd_problem(solver, A, halfA, dA);++ // generate the right hand sides+ int rhsCols = internal::random<int>(1,16);+ double density = (std::max)(8./(size*rhsCols), 0.1);+ SpMat B(size,rhsCols);+ DenseVector b = DenseVector::Random(size);+ DenseMatrix dB(size,rhsCols);+ initSparse<Scalar>(density, dB, B, ForceNonZeroDiag);+ + check_sparse_solving(solver, A, b, dA, b);+ check_sparse_solving(solver, halfA, b, dA, b);+ check_sparse_solving(solver, A, dB, dA, dB);+ check_sparse_solving(solver, halfA, dB, dA, dB);+ check_sparse_solving(solver, A, B, dA, dB);+ check_sparse_solving(solver, halfA, B, dA, dB);+ + // check only once+ if(i==0)+ {+ b = DenseVector::Zero(size);+ check_sparse_solving(solver, A, b, dA, b);+ }+ }+ + // First, get the folder +#ifdef TEST_REAL_CASES + if (internal::is_same<Scalar, float>::value + || internal::is_same<Scalar, std::complex<float> >::value)+ return ;+ + std::string mat_folder = get_matrixfolder<Scalar>();+ MatrixMarketIterator<Scalar> it(mat_folder);+ for (; it; ++it)+ {+ if (it.sym() == SPD){+ Mat halfA;+ PermutationMatrix<Dynamic, Dynamic, Index> pnull;+ halfA.template selfadjointView<Solver::UpLo>() = it.matrix().template triangularView<Eigen::Lower>().twistedBy(pnull);+ + std::cout<< " ==== SOLVING WITH MATRIX " << it.matname() << " ==== \n";+ check_sparse_solving_real_cases(solver, it.matrix(), it.rhs(), it.refX());+ check_sparse_solving_real_cases(solver, halfA, it.rhs(), it.refX());+ }+ }+#endif+}++template<typename Solver> void check_sparse_spd_determinant(Solver& solver)+{+ typedef typename Solver::MatrixType Mat;+ typedef typename Mat::Scalar Scalar;+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;++ // generate the problem+ Mat A, halfA;+ DenseMatrix dA;+ generate_sparse_spd_problem(solver, A, halfA, dA, 30);+ + for (int i = 0; i < g_repeat; i++) {+ check_sparse_determinant(solver, A, dA);+ check_sparse_determinant(solver, halfA, dA );+ }+}++template<typename Solver, typename DenseMat>+int generate_sparse_square_problem(Solver&, typename Solver::MatrixType& A, DenseMat& dA, int maxSize = 300)+{+ typedef typename Solver::MatrixType Mat;+ typedef typename Mat::Scalar Scalar;++ int size = internal::random<int>(1,maxSize);+ double density = (std::max)(8./(size*size), 0.01);+ + A.resize(size,size);+ dA.resize(size,size);++ initSparse<Scalar>(density, dA, A, ForceNonZeroDiag);+ + return size;+}++template<typename Solver> void check_sparse_square_solving(Solver& solver)+{+ typedef typename Solver::MatrixType Mat;+ typedef typename Mat::Scalar Scalar;+ typedef SparseMatrix<Scalar,ColMajor> SpMat;+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;+ typedef Matrix<Scalar,Dynamic,1> DenseVector;++ int rhsCols = internal::random<int>(1,16);++ Mat A;+ DenseMatrix dA;+ for (int i = 0; i < g_repeat; i++) {+ int size = generate_sparse_square_problem(solver, A, dA);++ A.makeCompressed();+ DenseVector b = DenseVector::Random(size);+ DenseMatrix dB(size,rhsCols);+ SpMat B(size,rhsCols);+ double density = (std::max)(8./(size*rhsCols), 0.1);+ initSparse<Scalar>(density, dB, B, ForceNonZeroDiag);+ B.makeCompressed();+ check_sparse_solving(solver, A, b, dA, b);+ check_sparse_solving(solver, A, dB, dA, dB);+ check_sparse_solving(solver, A, B, dA, dB);+ + // check only once+ if(i==0)+ {+ b = DenseVector::Zero(size);+ check_sparse_solving(solver, A, b, dA, b);+ }+ }+ + // First, get the folder +#ifdef TEST_REAL_CASES+ if (internal::is_same<Scalar, float>::value + || internal::is_same<Scalar, std::complex<float> >::value)+ return ;+ + std::string mat_folder = get_matrixfolder<Scalar>();+ MatrixMarketIterator<Scalar> it(mat_folder);+ for (; it; ++it)+ {+ std::cout<< " ==== SOLVING WITH MATRIX " << it.matname() << " ==== \n";+ check_sparse_solving_real_cases(solver, it.matrix(), it.rhs(), it.refX());+ }+#endif++}++template<typename Solver> void check_sparse_square_determinant(Solver& solver)+{+ typedef typename Solver::MatrixType Mat;+ typedef typename Mat::Scalar Scalar;+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;++ // generate the problem+ Mat A;+ DenseMatrix dA;+ generate_sparse_square_problem(solver, A, dA, 30);+ A.makeCompressed();+ for (int i = 0; i < g_repeat; i++) {+ check_sparse_determinant(solver, A, dA);+ }+}++template<typename Solver> void check_sparse_square_abs_determinant(Solver& solver)+{+ typedef typename Solver::MatrixType Mat;+ typedef typename Mat::Scalar Scalar;+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;++ // generate the problem+ Mat A;+ DenseMatrix dA;+ generate_sparse_square_problem(solver, A, dA, 30);+ A.makeCompressed();+ for (int i = 0; i < g_repeat; i++) {+ check_sparse_abs_determinant(solver, A, dA);+ }+}+
+ eigen3/test/sparse_solvers.cpp view
@@ -0,0 +1,112 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "sparse.h"++template<typename Scalar> void+initSPD(double density,+ Matrix<Scalar,Dynamic,Dynamic>& refMat,+ SparseMatrix<Scalar>& sparseMat)+{+ Matrix<Scalar,Dynamic,Dynamic> aux(refMat.rows(),refMat.cols());+ initSparse(density,refMat,sparseMat);+ refMat = refMat * refMat.adjoint();+ for (int k=0; k<2; ++k)+ {+ initSparse(density,aux,sparseMat,ForceNonZeroDiag);+ refMat += aux * aux.adjoint();+ }+ sparseMat.setZero();+ for (int j=0 ; j<sparseMat.cols(); ++j)+ for (int i=j ; i<sparseMat.rows(); ++i)+ if (refMat(i,j)!=Scalar(0))+ sparseMat.insert(i,j) = refMat(i,j);+ sparseMat.finalize();+}++template<typename Scalar> void sparse_solvers(int rows, int cols)+{+ double density = (std::max)(8./(rows*cols), 0.01);+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;+ typedef Matrix<Scalar,Dynamic,1> DenseVector;+ // Scalar eps = 1e-6;++ DenseVector vec1 = DenseVector::Random(rows);++ std::vector<Vector2i> zeroCoords;+ std::vector<Vector2i> nonzeroCoords;++ // test triangular solver+ {+ DenseVector vec2 = vec1, vec3 = vec1;+ SparseMatrix<Scalar> m2(rows, cols);+ DenseMatrix refMat2 = DenseMatrix::Zero(rows, cols);++ // lower - dense+ initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeLowerTriangular, &zeroCoords, &nonzeroCoords);+ VERIFY_IS_APPROX(refMat2.template triangularView<Lower>().solve(vec2),+ m2.template triangularView<Lower>().solve(vec3));++ // upper - dense+ initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeUpperTriangular, &zeroCoords, &nonzeroCoords);+ VERIFY_IS_APPROX(refMat2.template triangularView<Upper>().solve(vec2),+ m2.template triangularView<Upper>().solve(vec3));+ VERIFY_IS_APPROX(refMat2.conjugate().template triangularView<Upper>().solve(vec2),+ m2.conjugate().template triangularView<Upper>().solve(vec3));+ {+ SparseMatrix<Scalar> cm2(m2);+ //Index rows, Index cols, Index nnz, Index* outerIndexPtr, Index* innerIndexPtr, Scalar* valuePtr+ MappedSparseMatrix<Scalar> mm2(rows, cols, cm2.nonZeros(), cm2.outerIndexPtr(), cm2.innerIndexPtr(), cm2.valuePtr());+ VERIFY_IS_APPROX(refMat2.conjugate().template triangularView<Upper>().solve(vec2),+ mm2.conjugate().template triangularView<Upper>().solve(vec3));+ }++ // lower - transpose+ initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeLowerTriangular, &zeroCoords, &nonzeroCoords);+ VERIFY_IS_APPROX(refMat2.transpose().template triangularView<Upper>().solve(vec2),+ m2.transpose().template triangularView<Upper>().solve(vec3));++ // upper - transpose+ initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeUpperTriangular, &zeroCoords, &nonzeroCoords);+ VERIFY_IS_APPROX(refMat2.transpose().template triangularView<Lower>().solve(vec2),+ m2.transpose().template triangularView<Lower>().solve(vec3));++ SparseMatrix<Scalar> matB(rows, rows);+ DenseMatrix refMatB = DenseMatrix::Zero(rows, rows);++ // lower - sparse+ initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeLowerTriangular);+ initSparse<Scalar>(density, refMatB, matB);+ refMat2.template triangularView<Lower>().solveInPlace(refMatB);+ m2.template triangularView<Lower>().solveInPlace(matB);+ VERIFY_IS_APPROX(matB.toDense(), refMatB);++ // upper - sparse+ initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeUpperTriangular);+ initSparse<Scalar>(density, refMatB, matB);+ refMat2.template triangularView<Upper>().solveInPlace(refMatB);+ m2.template triangularView<Upper>().solveInPlace(matB);+ VERIFY_IS_APPROX(matB, refMatB);++ // test deprecated API+ initSparse<Scalar>(density, refMat2, m2, ForceNonZeroDiag|MakeLowerTriangular, &zeroCoords, &nonzeroCoords);+ VERIFY_IS_APPROX(refMat2.template triangularView<Lower>().solve(vec2),+ m2.template triangularView<Lower>().solve(vec3));+ }+}++void test_sparse_solvers()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1(sparse_solvers<double>(8, 8) );+ int s = internal::random<int>(1,300);+ CALL_SUBTEST_2(sparse_solvers<std::complex<double> >(s,s) );+ CALL_SUBTEST_1(sparse_solvers<double>(s,s) );+ }+}
+ eigen3/test/sparse_vector.cpp view
@@ -0,0 +1,110 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "sparse.h"++template<typename Scalar,typename Index> void sparse_vector(int rows, int cols)+{+ double densityMat = (std::max)(8./(rows*cols), 0.01);+ double densityVec = (std::max)(8./float(rows), 0.1);+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;+ typedef Matrix<Scalar,Dynamic,1> DenseVector;+ typedef SparseVector<Scalar,0,Index> SparseVectorType;+ typedef SparseMatrix<Scalar,0,Index> SparseMatrixType;+ Scalar eps = 1e-6;++ SparseMatrixType m1(rows,rows);+ SparseVectorType v1(rows), v2(rows), v3(rows);+ DenseMatrix refM1 = DenseMatrix::Zero(rows, rows);+ DenseVector refV1 = DenseVector::Random(rows),+ refV2 = DenseVector::Random(rows),+ refV3 = DenseVector::Random(rows);++ std::vector<int> zerocoords, nonzerocoords;+ initSparse<Scalar>(densityVec, refV1, v1, &zerocoords, &nonzerocoords);+ initSparse<Scalar>(densityMat, refM1, m1);++ initSparse<Scalar>(densityVec, refV2, v2);+ initSparse<Scalar>(densityVec, refV3, v3);++ Scalar s1 = internal::random<Scalar>();++ // test coeff and coeffRef+ for (unsigned int i=0; i<zerocoords.size(); ++i)+ {+ VERIFY_IS_MUCH_SMALLER_THAN( v1.coeff(zerocoords[i]), eps );+ //VERIFY_RAISES_ASSERT( v1.coeffRef(zerocoords[i]) = 5 );+ }+ {+ VERIFY(int(nonzerocoords.size()) == v1.nonZeros());+ int j=0;+ for (typename SparseVectorType::InnerIterator it(v1); it; ++it,++j)+ {+ VERIFY(nonzerocoords[j]==it.index());+ VERIFY(it.value()==v1.coeff(it.index()));+ VERIFY(it.value()==refV1.coeff(it.index()));+ }+ }+ VERIFY_IS_APPROX(v1, refV1);++ v1.coeffRef(nonzerocoords[0]) = Scalar(5);+ refV1.coeffRef(nonzerocoords[0]) = Scalar(5);+ VERIFY_IS_APPROX(v1, refV1);++ VERIFY_IS_APPROX(v1+v2, refV1+refV2);+ VERIFY_IS_APPROX(v1+v2+v3, refV1+refV2+refV3);++ VERIFY_IS_APPROX(v1*s1-v2, refV1*s1-refV2);++ VERIFY_IS_APPROX(v1*=s1, refV1*=s1);+ VERIFY_IS_APPROX(v1/=s1, refV1/=s1);++ VERIFY_IS_APPROX(v1+=v2, refV1+=refV2);+ VERIFY_IS_APPROX(v1-=v2, refV1-=refV2);++ VERIFY_IS_APPROX(v1.dot(v2), refV1.dot(refV2));+ VERIFY_IS_APPROX(v1.dot(refV2), refV1.dot(refV2));++ VERIFY_IS_APPROX(v1.dot(m1*v2), refV1.dot(refM1*refV2));+ int i = internal::random<int>(0,rows-1);+ VERIFY_IS_APPROX(v1.dot(m1.col(i)), refV1.dot(refM1.col(i)));+++ VERIFY_IS_APPROX(v1.squaredNorm(), refV1.squaredNorm());+ + VERIFY_IS_APPROX(v1.blueNorm(), refV1.blueNorm());++ // test aliasing+ VERIFY_IS_APPROX((v1 = -v1), (refV1 = -refV1));+ VERIFY_IS_APPROX((v1 = v1.transpose()), (refV1 = refV1.transpose().eval()));+ VERIFY_IS_APPROX((v1 += -v1), (refV1 += -refV1));+ + // sparse matrix to sparse vector+ SparseMatrixType mv1;+ VERIFY_IS_APPROX((mv1=v1),v1);+ VERIFY_IS_APPROX(mv1,(v1=mv1));+ VERIFY_IS_APPROX(mv1,(v1=mv1.transpose()));+ + // check copy to dense vector with transpose+ refV3.resize(0);+ VERIFY_IS_APPROX(refV3 = v1.transpose(),v1.toDense()); + VERIFY_IS_APPROX(DenseVector(v1),v1.toDense()); ++}++void test_sparse_vector()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1(( sparse_vector<double,int>(8, 8) ));+ CALL_SUBTEST_2(( sparse_vector<std::complex<double>, int>(16, 16) ));+ CALL_SUBTEST_1(( sparse_vector<double,long int>(299, 535) ));+ CALL_SUBTEST_1(( sparse_vector<double,short>(299, 535) ));+ }+}+
+ eigen3/test/sparselu.cpp view
@@ -0,0 +1,61 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>+//+// Eigen is free software; you can redistribute it and/or+// modify it under the terms of the GNU Lesser General Public+// License as published by the Free Software Foundation; either+// version 3 of the License, or (at your option) any later version.+//+// Alternatively, you can redistribute it and/or+// modify it under the terms of the GNU General Public License as+// published by the Free Software Foundation; either version 2 of+// the License, or (at your option) any later version.+//+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the+// GNU General Public License for more details.+//+// You should have received a copy of the GNU Lesser General Public+// License and a copy of the GNU General Public License along with+// Eigen. If not, see <http://www.gnu.org/licenses/>.+++// SparseLU solve does not accept column major matrices for the destination.+// However, as expected, the generic check_sparse_square_solving routines produces row-major+// rhs and destination matrices when compiled with EIGEN_DEFAULT_TO_ROW_MAJOR++#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR+#undef EIGEN_DEFAULT_TO_ROW_MAJOR+#endif++#include "sparse_solver.h"+#include <Eigen/SparseLU>+#include <unsupported/Eigen/SparseExtra>++template<typename T> void test_sparselu_T()+{+ SparseLU<SparseMatrix<T, ColMajor> /*, COLAMDOrdering<int>*/ > sparselu_colamd; // COLAMDOrdering is the default+ SparseLU<SparseMatrix<T, ColMajor>, AMDOrdering<int> > sparselu_amd; + SparseLU<SparseMatrix<T, ColMajor, long int>, NaturalOrdering<long int> > sparselu_natural;+ + check_sparse_square_solving(sparselu_colamd); + check_sparse_square_solving(sparselu_amd);+ check_sparse_square_solving(sparselu_natural);+ + check_sparse_square_abs_determinant(sparselu_colamd);+ check_sparse_square_abs_determinant(sparselu_amd);+ + check_sparse_square_determinant(sparselu_colamd);+ check_sparse_square_determinant(sparselu_amd);+}++void test_sparselu()+{+ CALL_SUBTEST_1(test_sparselu_T<float>()); + CALL_SUBTEST_2(test_sparselu_T<double>());+ CALL_SUBTEST_3(test_sparselu_T<std::complex<float> >()); + CALL_SUBTEST_4(test_sparselu_T<std::complex<double> >());+}
+ eigen3/test/sparseqr.cpp view
@@ -0,0 +1,100 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Desire Nuentsa Wakam <desire.nuentsa_wakam@inria.fr>+// Copyright (C) 2014 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+#include "sparse.h"+#include <Eigen/SparseQR>++template<typename MatrixType,typename DenseMat>+int generate_sparse_rectangular_problem(MatrixType& A, DenseMat& dA, int maxRows = 300)+{+ typedef typename MatrixType::Scalar Scalar;+ int rows = internal::random<int>(1,maxRows);+ int cols = internal::random<int>(1,rows);+ double density = (std::max)(8./(rows*cols), 0.01);+ + A.resize(rows,cols);+ dA.resize(rows,cols);+ initSparse<Scalar>(density, dA, A,ForceNonZeroDiag);+ A.makeCompressed();+ int nop = internal::random<int>(0, internal::random<double>(0,1) > 0.5 ? cols/2 : 0);+ for(int k=0; k<nop; ++k)+ {+ int j0 = internal::random<int>(0,cols-1);+ int j1 = internal::random<int>(0,cols-1);+ Scalar s = internal::random<Scalar>();+ A.col(j0) = s * A.col(j1);+ dA.col(j0) = s * dA.col(j1);+ }+ +// if(rows<cols) {+// A.conservativeResize(cols,cols);+// dA.conservativeResize(cols,cols);+// dA.bottomRows(cols-rows).setZero();+// }+ + return rows;+}++template<typename Scalar> void test_sparseqr_scalar()+{+ typedef SparseMatrix<Scalar,ColMajor> MatrixType; + typedef Matrix<Scalar,Dynamic,Dynamic> DenseMat;+ typedef Matrix<Scalar,Dynamic,1> DenseVector;+ MatrixType A;+ DenseMat dA;+ DenseVector refX,x,b; + SparseQR<MatrixType, COLAMDOrdering<int> > solver; + generate_sparse_rectangular_problem(A,dA);+ + b = dA * DenseVector::Random(A.cols());+ solver.compute(A);+ if(internal::random<float>(0,1)>0.5)+ solver.factorize(A); // this checks that calling analyzePattern is not needed if the pattern do not change.+ if (solver.info() != Success)+ {+ std::cerr << "sparse QR factorization failed\n";+ exit(0);+ return;+ }+ x = solver.solve(b);+ if (solver.info() != Success)+ {+ std::cerr << "sparse QR factorization failed\n";+ exit(0);+ return;+ }+ + VERIFY_IS_APPROX(A * x, b);+ + //Compare with a dense QR solver+ ColPivHouseholderQR<DenseMat> dqr(dA);+ refX = dqr.solve(b);+ + VERIFY_IS_EQUAL(dqr.rank(), solver.rank());+ if(solver.rank()==A.cols()) // full rank+ VERIFY_IS_APPROX(x, refX);+// else+// VERIFY((dA * refX - b).norm() * 2 > (A * x - b).norm() );++ // Compute explicitly the matrix Q+ MatrixType Q, QtQ, idM;+ Q = solver.matrixQ();+ //Check ||Q' * Q - I ||+ QtQ = Q * Q.adjoint();+ idM.resize(Q.rows(), Q.rows()); idM.setIdentity();+ VERIFY(idM.isApprox(QtQ));+}+void test_sparseqr()+{+ for(int i=0; i<g_repeat; ++i)+ {+ CALL_SUBTEST_1(test_sparseqr_scalar<double>());+ CALL_SUBTEST_2(test_sparseqr_scalar<std::complex<double> >());+ }+}+
+ eigen3/test/special_numbers.cpp view
@@ -0,0 +1,58 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2013 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename Scalar> void special_numbers()+{+ typedef Matrix<Scalar, Dynamic,Dynamic> MatType;+ int rows = internal::random<int>(1,300);+ int cols = internal::random<int>(1,300);+ + Scalar nan = std::numeric_limits<Scalar>::quiet_NaN();+ Scalar inf = std::numeric_limits<Scalar>::infinity();+ Scalar s1 = internal::random<Scalar>();+ + MatType m1 = MatType::Random(rows,cols),+ mnan = MatType::Random(rows,cols),+ minf = MatType::Random(rows,cols),+ mboth = MatType::Random(rows,cols);+ + int n = internal::random<int>(1,10);+ for(int k=0; k<n; ++k)+ {+ mnan(internal::random<int>(0,rows-1), internal::random<int>(0,cols-1)) = nan;+ minf(internal::random<int>(0,rows-1), internal::random<int>(0,cols-1)) = inf;+ }+ mboth = mnan + minf;+ + VERIFY(!m1.hasNaN());+ VERIFY(m1.allFinite());+ + VERIFY(mnan.hasNaN());+ VERIFY((s1*mnan).hasNaN());+ VERIFY(!minf.hasNaN());+ VERIFY(!(2*minf).hasNaN());+ VERIFY(mboth.hasNaN());+ VERIFY(mboth.array().hasNaN());+ + VERIFY(!mnan.allFinite());+ VERIFY(!minf.allFinite());+ VERIFY(!(minf-mboth).allFinite());+ VERIFY(!mboth.allFinite());+ VERIFY(!mboth.array().allFinite());+}++void test_special_numbers()+{+ for(int i = 0; i < 10*g_repeat; i++) {+ CALL_SUBTEST_1( special_numbers<float>() );+ CALL_SUBTEST_1( special_numbers<double>() );+ }+}
+ eigen3/test/spqr_support.cpp view
@@ -0,0 +1,62 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Desire Nuentsa Wakam <desire.nuentsa_wakam@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+#include "sparse.h"+#include <Eigen/SPQRSupport>+++template<typename MatrixType,typename DenseMat>+int generate_sparse_rectangular_problem(MatrixType& A, DenseMat& dA, int maxRows = 300, int maxCols = 300)+{+ eigen_assert(maxRows >= maxCols);+ typedef typename MatrixType::Scalar Scalar;+ int rows = internal::random<int>(1,maxRows);+ int cols = internal::random<int>(1,rows);+ double density = (std::max)(8./(rows*cols), 0.01);+ + A.resize(rows,rows);+ dA.resize(rows,rows);+ initSparse<Scalar>(density, dA, A,ForceNonZeroDiag);+ A.makeCompressed();+ return rows;+}++template<typename Scalar> void test_spqr_scalar()+{+ typedef SparseMatrix<Scalar,ColMajor> MatrixType; + MatrixType A;+ Matrix<Scalar,Dynamic,Dynamic> dA;+ typedef Matrix<Scalar,Dynamic,1> DenseVector;+ DenseVector refX,x,b; + SPQR<MatrixType> solver; + generate_sparse_rectangular_problem(A,dA);+ + int m = A.rows();+ b = DenseVector::Random(m);+ solver.compute(A);+ if (solver.info() != Success)+ {+ std::cerr << "sparse QR factorization failed\n";+ exit(0);+ return;+ }+ x = solver.solve(b);+ if (solver.info() != Success)+ {+ std::cerr << "sparse QR factorization failed\n";+ exit(0);+ return;+ } + //Compare with a dense solver+ refX = dA.colPivHouseholderQr().solve(b);+ VERIFY(x.isApprox(refX,test_precision<Scalar>()));+}+void test_spqr_support()+{+ CALL_SUBTEST_1(test_spqr_scalar<double>());+ CALL_SUBTEST_2(test_spqr_scalar<std::complex<double> >());+}
+ eigen3/test/stable_norm.cpp view
@@ -0,0 +1,115 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++// workaround aggressive optimization in ICC+template<typename T> EIGEN_DONT_INLINE T sub(T a, T b) { return a - b; }++template<typename T> bool isFinite(const T& x)+{+ return isNotNaN(sub(x,x));+}++template<typename T> EIGEN_DONT_INLINE T copy(const T& x)+{+ return x;+}++template<typename MatrixType> void stable_norm(const MatrixType& m)+{+ /* this test covers the following files:+ StableNorm.h+ */+ using std::sqrt;+ using std::abs;+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;++ // Check the basic machine-dependent constants.+ {+ int ibeta, it, iemin, iemax;++ ibeta = std::numeric_limits<RealScalar>::radix; // base for floating-point numbers+ it = std::numeric_limits<RealScalar>::digits; // number of base-beta digits in mantissa+ iemin = std::numeric_limits<RealScalar>::min_exponent; // minimum exponent+ iemax = std::numeric_limits<RealScalar>::max_exponent; // maximum exponent++ VERIFY( (!(iemin > 1 - 2*it || 1+it>iemax || (it==2 && ibeta<5) || (it<=4 && ibeta <= 3 ) || it<2))+ && "the stable norm algorithm cannot be guaranteed on this computer");+ }+++ Index rows = m.rows();+ Index cols = m.cols();++ // get a non-zero random factor+ Scalar factor = internal::random<Scalar>();+ while(numext::abs2(factor)<RealScalar(1e-4))+ factor = internal::random<Scalar>();+ Scalar big = factor * ((std::numeric_limits<RealScalar>::max)() * RealScalar(1e-4));+ + factor = internal::random<Scalar>();+ while(numext::abs2(factor)<RealScalar(1e-4))+ factor = internal::random<Scalar>();+ Scalar small = factor * ((std::numeric_limits<RealScalar>::min)() * RealScalar(1e4));++ MatrixType vzero = MatrixType::Zero(rows, cols),+ vrand = MatrixType::Random(rows, cols),+ vbig(rows, cols),+ vsmall(rows,cols);++ vbig.fill(big);+ vsmall.fill(small);++ VERIFY_IS_MUCH_SMALLER_THAN(vzero.norm(), static_cast<RealScalar>(1));+ VERIFY_IS_APPROX(vrand.stableNorm(), vrand.norm());+ VERIFY_IS_APPROX(vrand.blueNorm(), vrand.norm());+ VERIFY_IS_APPROX(vrand.hypotNorm(), vrand.norm());++ RealScalar size = static_cast<RealScalar>(m.size());++ // test isFinite+ VERIFY(!isFinite( std::numeric_limits<RealScalar>::infinity()));+ VERIFY(!isFinite(sqrt(-abs(big))));++ // test overflow+ VERIFY(isFinite(sqrt(size)*abs(big)));+ VERIFY_IS_NOT_APPROX(sqrt(copy(vbig.squaredNorm())), abs(sqrt(size)*big)); // here the default norm must fail+ VERIFY_IS_APPROX(vbig.stableNorm(), sqrt(size)*abs(big));+ VERIFY_IS_APPROX(vbig.blueNorm(), sqrt(size)*abs(big));+ VERIFY_IS_APPROX(vbig.hypotNorm(), sqrt(size)*abs(big));++ // test underflow+ VERIFY(isFinite(sqrt(size)*abs(small)));+ VERIFY_IS_NOT_APPROX(sqrt(copy(vsmall.squaredNorm())), abs(sqrt(size)*small)); // here the default norm must fail+ VERIFY_IS_APPROX(vsmall.stableNorm(), sqrt(size)*abs(small));+ VERIFY_IS_APPROX(vsmall.blueNorm(), sqrt(size)*abs(small));+ VERIFY_IS_APPROX(vsmall.hypotNorm(), sqrt(size)*abs(small));++ // Test compilation of cwise() version+ VERIFY_IS_APPROX(vrand.colwise().stableNorm(), vrand.colwise().norm());+ VERIFY_IS_APPROX(vrand.colwise().blueNorm(), vrand.colwise().norm());+ VERIFY_IS_APPROX(vrand.colwise().hypotNorm(), vrand.colwise().norm());+ VERIFY_IS_APPROX(vrand.rowwise().stableNorm(), vrand.rowwise().norm());+ VERIFY_IS_APPROX(vrand.rowwise().blueNorm(), vrand.rowwise().norm());+ VERIFY_IS_APPROX(vrand.rowwise().hypotNorm(), vrand.rowwise().norm());+}++void test_stable_norm()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( stable_norm(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( stable_norm(Vector4d()) );+ CALL_SUBTEST_3( stable_norm(VectorXd(internal::random<int>(10,2000))) );+ CALL_SUBTEST_4( stable_norm(VectorXf(internal::random<int>(10,2000))) );+ CALL_SUBTEST_5( stable_norm(VectorXcd(internal::random<int>(10,2000))) );+ }+}
+ eigen3/test/stddeque.cpp view
@@ -0,0 +1,132 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+// Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/StdDeque>+#include <Eigen/Geometry>++template<typename MatrixType>+void check_stddeque_matrix(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ + Index rows = m.rows();+ Index cols = m.cols();+ MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols);+ std::deque<MatrixType,Eigen::aligned_allocator<MatrixType> > v(10, MatrixType(rows,cols)), w(20, y);+ v.front() = x;+ w.front() = w.back();+ VERIFY_IS_APPROX(w.front(), w.back());+ v = w;++ typename std::deque<MatrixType,Eigen::aligned_allocator<MatrixType> >::iterator vi = v.begin();+ typename std::deque<MatrixType,Eigen::aligned_allocator<MatrixType> >::iterator wi = w.begin();+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(*vi, *wi);+ ++vi;+ ++wi;+ }++ v.resize(21); + v.back() = x;+ VERIFY_IS_APPROX(v.back(), x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v.back(), y);+ v.push_back(x);+ VERIFY_IS_APPROX(v.back(), x);+}++template<typename TransformType>+void check_stddeque_transform(const TransformType&)+{+ typedef typename TransformType::MatrixType MatrixType;+ TransformType x(MatrixType::Random()), y(MatrixType::Random());+ std::deque<TransformType,Eigen::aligned_allocator<TransformType> > v(10), w(20, y);+ v.front() = x;+ w.front() = w.back();+ VERIFY_IS_APPROX(w.front(), w.back());+ v = w;++ typename std::deque<TransformType,Eigen::aligned_allocator<TransformType> >::iterator vi = v.begin();+ typename std::deque<TransformType,Eigen::aligned_allocator<TransformType> >::iterator wi = w.begin();+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(*vi, *wi);+ ++vi;+ ++wi;+ }++ v.resize(21);+ v.back() = x;+ VERIFY_IS_APPROX(v.back(), x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v.back(), y);+ v.push_back(x);+ VERIFY_IS_APPROX(v.back(), x);+}++template<typename QuaternionType>+void check_stddeque_quaternion(const QuaternionType&)+{+ typedef typename QuaternionType::Coefficients Coefficients;+ QuaternionType x(Coefficients::Random()), y(Coefficients::Random());+ std::deque<QuaternionType,Eigen::aligned_allocator<QuaternionType> > v(10), w(20, y);+ v.front() = x;+ w.front() = w.back();+ VERIFY_IS_APPROX(w.front(), w.back());+ v = w;++ typename std::deque<QuaternionType,Eigen::aligned_allocator<QuaternionType> >::iterator vi = v.begin();+ typename std::deque<QuaternionType,Eigen::aligned_allocator<QuaternionType> >::iterator wi = w.begin();+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(*vi, *wi);+ ++vi;+ ++wi;+ }++ v.resize(21);+ v.back() = x;+ VERIFY_IS_APPROX(v.back(), x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v.back(), y);+ v.push_back(x);+ VERIFY_IS_APPROX(v.back(), x);+}++void test_stddeque()+{+ // some non vectorizable fixed sizes+ CALL_SUBTEST_1(check_stddeque_matrix(Vector2f()));+ CALL_SUBTEST_1(check_stddeque_matrix(Matrix3f()));+ CALL_SUBTEST_2(check_stddeque_matrix(Matrix3d()));++ // some vectorizable fixed sizes+ CALL_SUBTEST_1(check_stddeque_matrix(Matrix2f()));+ CALL_SUBTEST_1(check_stddeque_matrix(Vector4f()));+ CALL_SUBTEST_1(check_stddeque_matrix(Matrix4f()));+ CALL_SUBTEST_2(check_stddeque_matrix(Matrix4d()));++ // some dynamic sizes+ CALL_SUBTEST_3(check_stddeque_matrix(MatrixXd(1,1)));+ CALL_SUBTEST_3(check_stddeque_matrix(VectorXd(20)));+ CALL_SUBTEST_3(check_stddeque_matrix(RowVectorXf(20)));+ CALL_SUBTEST_3(check_stddeque_matrix(MatrixXcf(10,10)));++ // some Transform+ CALL_SUBTEST_4(check_stddeque_transform(Affine2f()));+ CALL_SUBTEST_4(check_stddeque_transform(Affine3f()));+ CALL_SUBTEST_4(check_stddeque_transform(Affine3d()));++ // some Quaternion+ CALL_SUBTEST_5(check_stddeque_quaternion(Quaternionf()));+ CALL_SUBTEST_5(check_stddeque_quaternion(Quaterniond()));+}
+ eigen3/test/stdlist.cpp view
@@ -0,0 +1,132 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+// Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/StdList>+#include <Eigen/Geometry>++template<typename MatrixType>+void check_stdlist_matrix(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ + Index rows = m.rows();+ Index cols = m.cols();+ MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols);+ std::list<MatrixType,Eigen::aligned_allocator<MatrixType> > v(10, MatrixType(rows,cols)), w(20, y);+ v.front() = x;+ w.front() = w.back();+ VERIFY_IS_APPROX(w.front(), w.back());+ v = w;++ typename std::list<MatrixType,Eigen::aligned_allocator<MatrixType> >::iterator vi = v.begin();+ typename std::list<MatrixType,Eigen::aligned_allocator<MatrixType> >::iterator wi = w.begin();+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(*vi, *wi);+ ++vi;+ ++wi;+ }++ v.resize(21); + v.back() = x;+ VERIFY_IS_APPROX(v.back(), x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v.back(), y);+ v.push_back(x);+ VERIFY_IS_APPROX(v.back(), x);+}++template<typename TransformType>+void check_stdlist_transform(const TransformType&)+{+ typedef typename TransformType::MatrixType MatrixType;+ TransformType x(MatrixType::Random()), y(MatrixType::Random());+ std::list<TransformType,Eigen::aligned_allocator<TransformType> > v(10), w(20, y);+ v.front() = x;+ w.front() = w.back();+ VERIFY_IS_APPROX(w.front(), w.back());+ v = w;++ typename std::list<TransformType,Eigen::aligned_allocator<TransformType> >::iterator vi = v.begin();+ typename std::list<TransformType,Eigen::aligned_allocator<TransformType> >::iterator wi = w.begin();+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(*vi, *wi);+ ++vi;+ ++wi;+ }++ v.resize(21);+ v.back() = x;+ VERIFY_IS_APPROX(v.back(), x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v.back(), y);+ v.push_back(x);+ VERIFY_IS_APPROX(v.back(), x);+}++template<typename QuaternionType>+void check_stdlist_quaternion(const QuaternionType&)+{+ typedef typename QuaternionType::Coefficients Coefficients;+ QuaternionType x(Coefficients::Random()), y(Coefficients::Random());+ std::list<QuaternionType,Eigen::aligned_allocator<QuaternionType> > v(10), w(20, y);+ v.front() = x;+ w.front() = w.back();+ VERIFY_IS_APPROX(w.front(), w.back());+ v = w;++ typename std::list<QuaternionType,Eigen::aligned_allocator<QuaternionType> >::iterator vi = v.begin();+ typename std::list<QuaternionType,Eigen::aligned_allocator<QuaternionType> >::iterator wi = w.begin();+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(*vi, *wi);+ ++vi;+ ++wi;+ }++ v.resize(21);+ v.back() = x;+ VERIFY_IS_APPROX(v.back(), x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v.back(), y);+ v.push_back(x);+ VERIFY_IS_APPROX(v.back(), x);+}++void test_stdlist()+{+ // some non vectorizable fixed sizes+ CALL_SUBTEST_1(check_stdlist_matrix(Vector2f()));+ CALL_SUBTEST_1(check_stdlist_matrix(Matrix3f()));+ CALL_SUBTEST_2(check_stdlist_matrix(Matrix3d()));++ // some vectorizable fixed sizes+ CALL_SUBTEST_1(check_stdlist_matrix(Matrix2f()));+ CALL_SUBTEST_1(check_stdlist_matrix(Vector4f()));+ CALL_SUBTEST_1(check_stdlist_matrix(Matrix4f()));+ CALL_SUBTEST_2(check_stdlist_matrix(Matrix4d()));++ // some dynamic sizes+ CALL_SUBTEST_3(check_stdlist_matrix(MatrixXd(1,1)));+ CALL_SUBTEST_3(check_stdlist_matrix(VectorXd(20)));+ CALL_SUBTEST_3(check_stdlist_matrix(RowVectorXf(20)));+ CALL_SUBTEST_3(check_stdlist_matrix(MatrixXcf(10,10)));++ // some Transform+ CALL_SUBTEST_4(check_stdlist_transform(Affine2f()));+ CALL_SUBTEST_4(check_stdlist_transform(Affine3f()));+ CALL_SUBTEST_4(check_stdlist_transform(Affine3d()));++ // some Quaternion+ CALL_SUBTEST_5(check_stdlist_quaternion(Quaternionf()));+ CALL_SUBTEST_5(check_stdlist_quaternion(Quaterniond()));+}
+ eigen3/test/stdvector.cpp view
@@ -0,0 +1,148 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/StdVector>+#include <Eigen/Geometry>++template<typename MatrixType>+void check_stdvector_matrix(const MatrixType& m)+{+ typename MatrixType::Index rows = m.rows();+ typename MatrixType::Index cols = m.cols();+ MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols);+ std::vector<MatrixType,Eigen::aligned_allocator<MatrixType> > v(10, MatrixType(rows,cols)), w(20, y);+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(MatrixType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ MatrixType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(unsigned int i=23; i<v.size(); ++i)+ {+ VERIFY(v[i]==w[(i-23)%w.size()]);+ }+}++template<typename TransformType>+void check_stdvector_transform(const TransformType&)+{+ typedef typename TransformType::MatrixType MatrixType;+ TransformType x(MatrixType::Random()), y(MatrixType::Random());+ std::vector<TransformType,Eigen::aligned_allocator<TransformType> > v(10), w(20, y);+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(TransformType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ TransformType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(unsigned int i=23; i<v.size(); ++i)+ {+ VERIFY(v[i].matrix()==w[(i-23)%w.size()].matrix());+ }+}++template<typename QuaternionType>+void check_stdvector_quaternion(const QuaternionType&)+{+ typedef typename QuaternionType::Coefficients Coefficients;+ QuaternionType x(Coefficients::Random()), y(Coefficients::Random());+ std::vector<QuaternionType,Eigen::aligned_allocator<QuaternionType> > v(10), w(20, y);+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(QuaternionType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ QuaternionType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(unsigned int i=23; i<v.size(); ++i)+ {+ VERIFY(v[i].coeffs()==w[(i-23)%w.size()].coeffs());+ }+}++void test_stdvector()+{+ // some non vectorizable fixed sizes+ CALL_SUBTEST_1(check_stdvector_matrix(Vector2f()));+ CALL_SUBTEST_1(check_stdvector_matrix(Matrix3f()));+ CALL_SUBTEST_2(check_stdvector_matrix(Matrix3d()));++ // some vectorizable fixed sizes+ CALL_SUBTEST_1(check_stdvector_matrix(Matrix2f()));+ CALL_SUBTEST_1(check_stdvector_matrix(Vector4f()));+ CALL_SUBTEST_1(check_stdvector_matrix(Matrix4f()));+ CALL_SUBTEST_2(check_stdvector_matrix(Matrix4d()));++ // some dynamic sizes+ CALL_SUBTEST_3(check_stdvector_matrix(MatrixXd(1,1)));+ CALL_SUBTEST_3(check_stdvector_matrix(VectorXd(20)));+ CALL_SUBTEST_3(check_stdvector_matrix(RowVectorXf(20)));+ CALL_SUBTEST_3(check_stdvector_matrix(MatrixXcf(10,10)));++ // some Transform+ CALL_SUBTEST_4(check_stdvector_transform(Projective2f()));+ CALL_SUBTEST_4(check_stdvector_transform(Projective3f()));+ CALL_SUBTEST_4(check_stdvector_transform(Projective3d()));+ //CALL_SUBTEST(heck_stdvector_transform(Projective4d()));++ // some Quaternion+ CALL_SUBTEST_5(check_stdvector_quaternion(Quaternionf()));+ CALL_SUBTEST_5(check_stdvector_quaternion(Quaterniond()));+}
+ eigen3/test/stdvector_overload.cpp view
@@ -0,0 +1,161 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+// Copyright (C) 2010 Hauke Heibel <hauke.heibel@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++#include <Eigen/StdVector>+#include <Eigen/Geometry>++EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Vector4f)++EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Matrix2f)+EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Matrix4f)+EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Matrix4d)++EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Affine3f)+EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Affine3d)++EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Quaternionf)+EIGEN_DEFINE_STL_VECTOR_SPECIALIZATION(Quaterniond)++template<typename MatrixType>+void check_stdvector_matrix(const MatrixType& m)+{+ typename MatrixType::Index rows = m.rows();+ typename MatrixType::Index cols = m.cols();+ MatrixType x = MatrixType::Random(rows,cols), y = MatrixType::Random(rows,cols);+ std::vector<MatrixType> v(10, MatrixType(rows,cols)), w(20, y);+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(MatrixType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ MatrixType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(unsigned int i=23; i<v.size(); ++i)+ {+ VERIFY(v[i]==w[(i-23)%w.size()]);+ }+}++template<typename TransformType>+void check_stdvector_transform(const TransformType&)+{+ typedef typename TransformType::MatrixType MatrixType;+ TransformType x(MatrixType::Random()), y(MatrixType::Random());+ std::vector<TransformType> v(10), w(20, y);+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(TransformType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ TransformType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(unsigned int i=23; i<v.size(); ++i)+ {+ VERIFY(v[i].matrix()==w[(i-23)%w.size()].matrix());+ }+}++template<typename QuaternionType>+void check_stdvector_quaternion(const QuaternionType&)+{+ typedef typename QuaternionType::Coefficients Coefficients;+ QuaternionType x(Coefficients::Random()), y(Coefficients::Random());+ std::vector<QuaternionType> v(10), w(20, y);+ v[5] = x;+ w[6] = v[5];+ VERIFY_IS_APPROX(w[6], v[5]);+ v = w;+ for(int i = 0; i < 20; i++)+ {+ VERIFY_IS_APPROX(w[i], v[i]);+ }++ v.resize(21);+ v[20] = x;+ VERIFY_IS_APPROX(v[20], x);+ v.resize(22,y);+ VERIFY_IS_APPROX(v[21], y);+ v.push_back(x);+ VERIFY_IS_APPROX(v[22], x);+ VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(QuaternionType));++ // do a lot of push_back such that the vector gets internally resized+ // (with memory reallocation)+ QuaternionType* ref = &w[0];+ for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)+ v.push_back(w[i%w.size()]);+ for(unsigned int i=23; i<v.size(); ++i)+ {+ VERIFY(v[i].coeffs()==w[(i-23)%w.size()].coeffs());+ }+}++void test_stdvector_overload()+{+ // some non vectorizable fixed sizes+ CALL_SUBTEST_1(check_stdvector_matrix(Vector2f()));+ CALL_SUBTEST_1(check_stdvector_matrix(Matrix3f()));+ CALL_SUBTEST_2(check_stdvector_matrix(Matrix3d()));++ // some vectorizable fixed sizes+ CALL_SUBTEST_1(check_stdvector_matrix(Matrix2f()));+ CALL_SUBTEST_1(check_stdvector_matrix(Vector4f()));+ CALL_SUBTEST_1(check_stdvector_matrix(Matrix4f()));+ CALL_SUBTEST_2(check_stdvector_matrix(Matrix4d()));++ // some dynamic sizes+ CALL_SUBTEST_3(check_stdvector_matrix(MatrixXd(1,1)));+ CALL_SUBTEST_3(check_stdvector_matrix(VectorXd(20)));+ CALL_SUBTEST_3(check_stdvector_matrix(RowVectorXf(20)));+ CALL_SUBTEST_3(check_stdvector_matrix(MatrixXcf(10,10)));++ // some Transform+ CALL_SUBTEST_4(check_stdvector_transform(Affine2f())); // does not need the specialization (2+1)^2 = 9+ CALL_SUBTEST_4(check_stdvector_transform(Affine3f()));+ CALL_SUBTEST_4(check_stdvector_transform(Affine3d()));++ // some Quaternion+ CALL_SUBTEST_5(check_stdvector_quaternion(Quaternionf()));+ CALL_SUBTEST_5(check_stdvector_quaternion(Quaterniond()));+}
+ eigen3/test/superlu_support.cpp view
@@ -0,0 +1,22 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "sparse_solver.h"++#include <Eigen/SuperLUSupport>++void test_superlu_support()+{+ SuperLU<SparseMatrix<double> > superlu_double_colmajor;+ SuperLU<SparseMatrix<std::complex<double> > > superlu_cplxdouble_colmajor;+ CALL_SUBTEST_1( check_sparse_square_solving(superlu_double_colmajor) );+ CALL_SUBTEST_2( check_sparse_square_solving(superlu_cplxdouble_colmajor) );+ CALL_SUBTEST_1( check_sparse_square_determinant(superlu_double_colmajor) );+ CALL_SUBTEST_2( check_sparse_square_determinant(superlu_cplxdouble_colmajor) );+}
+ eigen3/test/swap.cpp view
@@ -0,0 +1,83 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN_NO_STATIC_ASSERT+#include "main.h"++template<typename T>+struct other_matrix_type+{+ typedef int type;+};++template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>+struct other_matrix_type<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >+{+ typedef Matrix<_Scalar, _Rows, _Cols, _Options^RowMajor, _MaxRows, _MaxCols> type;+};++template<typename MatrixType> void swap(const MatrixType& m)+{+ typedef typename other_matrix_type<MatrixType>::type OtherMatrixType;+ typedef typename MatrixType::Scalar Scalar;++ eigen_assert((!internal::is_same<MatrixType,OtherMatrixType>::value));+ typename MatrixType::Index rows = m.rows();+ typename MatrixType::Index cols = m.cols();+ + // construct 3 matrix guaranteed to be distinct+ MatrixType m1 = MatrixType::Random(rows,cols);+ MatrixType m2 = MatrixType::Random(rows,cols) + Scalar(100) * MatrixType::Identity(rows,cols);+ OtherMatrixType m3 = OtherMatrixType::Random(rows,cols) + Scalar(200) * OtherMatrixType::Identity(rows,cols);+ + MatrixType m1_copy = m1;+ MatrixType m2_copy = m2;+ OtherMatrixType m3_copy = m3;+ + // test swapping 2 matrices of same type+ m1.swap(m2);+ VERIFY_IS_APPROX(m1,m2_copy);+ VERIFY_IS_APPROX(m2,m1_copy);+ m1 = m1_copy;+ m2 = m2_copy;+ + // test swapping 2 matrices of different types+ m1.swap(m3);+ VERIFY_IS_APPROX(m1,m3_copy);+ VERIFY_IS_APPROX(m3,m1_copy);+ m1 = m1_copy;+ m3 = m3_copy;+ + // test swapping matrix with expression+ m1.swap(m2.block(0,0,rows,cols));+ VERIFY_IS_APPROX(m1,m2_copy);+ VERIFY_IS_APPROX(m2,m1_copy);+ m1 = m1_copy;+ m2 = m2_copy;++ // test swapping two expressions of different types+ m1.transpose().swap(m3.transpose());+ VERIFY_IS_APPROX(m1,m3_copy);+ VERIFY_IS_APPROX(m3,m1_copy);+ m1 = m1_copy;+ m3 = m3_copy;+ + // test assertion on mismatching size -- matrix case+ VERIFY_RAISES_ASSERT(m1.swap(m1.row(0)));+ // test assertion on mismatching size -- xpr case+ VERIFY_RAISES_ASSERT(m1.row(0).swap(m1));+}++void test_swap()+{+ CALL_SUBTEST_1( swap(Matrix3f()) ); // fixed size, no vectorization + CALL_SUBTEST_2( swap(Matrix4d()) ); // fixed size, possible vectorization + CALL_SUBTEST_3( swap(MatrixXd(3,3)) ); // dyn size, no vectorization + CALL_SUBTEST_4( swap(MatrixXf(30,30)) ); // dyn size, possible vectorization +}
+ eigen3/test/testsuite.cmake view
@@ -0,0 +1,229 @@++####################################################################+#+# Usage:+# - create a new folder, let's call it cdash+# - in that folder, do:+# ctest -S path/to/eigen/test/testsuite.cmake[,option1=value1[,option2=value2]]+#+# Options:+# - EIGEN_CXX: compiler, eg.: g++-4.2+# default: default c++ compiler+# - EIGEN_SITE: eg, INRIA-Bdx_pc-gael, or the name of the contributor, etc.+# default: hostname+# - EIGEN_BUILD_STRING: a string which identify the system/compiler. It should be formed like that:+# <OS_name>-<OS_version>-<arch>-<compiler-version>+# with:+# <OS_name> = opensuse, debian, osx, windows, cygwin, freebsd, solaris, etc.+# <OS_version> = 11.1, XP, vista, leopard, etc.+# <arch> = i386, x86_64, ia64, powerpc, etc.+# <compiler-version> = gcc-4.3.2, icc-11.0, MSVC-2008, etc.+# - EIGEN_EXPLICIT_VECTORIZATION: novec, SSE2, Altivec+# default: SSE2 for x86_64 systems, novec otherwise+# Its value is automatically appended to EIGEN_BUILD_STRING+# - EIGEN_CMAKE_DIR: path to cmake executable+# - EIGEN_MODE: dashboard model, can be Experimental, Nightly, or Continuous+# default: Nightly+# - EIGEN_WORK_DIR: directory used to download the source files and make the builds+# default: folder which contains this script+# - EIGEN_CMAKE_ARGS: additional arguments passed to cmake+# - EIGEN_GENERATOR_TYPE: allows to overwrite the generator type+# default: nmake (windows+# See http://www.cmake.org/cmake/help/cmake2.6docs.html#section_Generators for a complete+# list of supported generators.+# - EIGEN_NO_UPDATE: allows to submit dash boards from local repositories+# This might be interesting in case you want to submit dashboards+# including local changes.+# - CTEST_SOURCE_DIRECTORY: path to eigen's src (use a new and empty folder, not the one you are working on)+# default: <EIGEN_WORK_DIR>/src+# - CTEST_BINARY_DIRECTORY: build directory+# default: <EIGEN_WORK_DIR>/nightly-<EIGEN_CXX>+#+# Here is an example running several compilers on a linux system:+# #!/bin/bash+# ARCH=`uname -m`+# SITE=`hostname`+# VERSION=opensuse-11.1+# WORK_DIR=/home/gael/Coding/eigen/cdash+# # get the last version of the script+# wget http://bitbucket.org/eigen/eigen/raw/tip/test/testsuite.cmake -o $WORK_DIR/testsuite.cmake+# COMMON="ctest -S $WORK_DIR/testsuite.cmake,EIGEN_WORK_DIR=$WORK_DIR,EIGEN_SITE=$SITE,EIGEN_MODE=$1,EIGEN_BUILD_STRING=$OS_VERSION-$ARCH"+# $COMMON-gcc-3.4.6,EIGEN_CXX=g++-3.4+# $COMMON-gcc-4.0.1,EIGEN_CXX=g++-4.0.1+# $COMMON-gcc-4.3.2,EIGEN_CXX=g++-4.3,EIGEN_EXPLICIT_VECTORIZATION=novec+# $COMMON-gcc-4.3.2,EIGEN_CXX=g++-4.3,EIGEN_EXPLICIT_VECTORIZATION=SSE2+# $COMMON-icc-11.0,EIGEN_CXX=icpc+#+####################################################################++# process the arguments++set(ARGLIST ${CTEST_SCRIPT_ARG})+while(${ARGLIST} MATCHES ".+.*")++ # pick first+ string(REGEX MATCH "([^,]*)(,.*)?" DUMMY ${ARGLIST})+ SET(TOP ${CMAKE_MATCH_1})++ # remove first+ string(REGEX MATCHALL "[^,]*,(.*)" DUMMY ${ARGLIST})+ SET(ARGLIST ${CMAKE_MATCH_1})++ # decompose as a pair key=value+ string(REGEX MATCH "([^=]*)(=.*)?" DUMMY ${TOP})+ SET(KEY ${CMAKE_MATCH_1})++ string(REGEX MATCH "[^=]*=(.*)" DUMMY ${TOP})+ SET(VALUE ${CMAKE_MATCH_1})++ # set the variable to the specified value+ if(VALUE)+ SET(${KEY} ${VALUE})+ else(VALUE)+ SET(${KEY} ON)+ endif(VALUE)++endwhile(${ARGLIST} MATCHES ".+.*")++####################################################################+# Automatically set some user variables if they have not been defined manually+####################################################################+cmake_minimum_required(VERSION 2.6 FATAL_ERROR)++if(NOT EIGEN_SITE)+ site_name(EIGEN_SITE)+endif(NOT EIGEN_SITE)++if(NOT EIGEN_CMAKE_DIR)+ SET(EIGEN_CMAKE_DIR "")+endif(NOT EIGEN_CMAKE_DIR)++if(NOT EIGEN_BUILD_STRING)++ # let's try to find all information we need to make the build string ourself++ # OS+ build_name(EIGEN_OS_VERSION)++ # arch+ set(EIGEN_ARCH ${CMAKE_SYSTEM_PROCESSOR})+ if(WIN32)+ set(EIGEN_ARCH $ENV{PROCESSOR_ARCHITECTURE})+ else(WIN32)+ execute_process(COMMAND uname -m OUTPUT_VARIABLE EIGEN_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)+ endif(WIN32)++ set(EIGEN_BUILD_STRING ${EIGEN_OS_VERSION}${EIGEN_ARCH}-${EIGEN_CXX})++endif(NOT EIGEN_BUILD_STRING)++if(DEFINED EIGEN_EXPLICIT_VECTORIZATION)+ set(EIGEN_BUILD_STRING ${EIGEN_BUILD_STRING}-${EIGEN_EXPLICIT_VECTORIZATION})+endif(DEFINED EIGEN_EXPLICIT_VECTORIZATION)++if(NOT EIGEN_WORK_DIR)+ set(EIGEN_WORK_DIR ${CTEST_SCRIPT_DIRECTORY})+endif(NOT EIGEN_WORK_DIR)++if(NOT CTEST_SOURCE_DIRECTORY)+ SET (CTEST_SOURCE_DIRECTORY "${EIGEN_WORK_DIR}/src")+endif(NOT CTEST_SOURCE_DIRECTORY)++if(NOT CTEST_BINARY_DIRECTORY)+ SET (CTEST_BINARY_DIRECTORY "${EIGEN_WORK_DIR}/nightly_${EIGEN_CXX}")+endif(NOT CTEST_BINARY_DIRECTORY)++if(NOT EIGEN_MODE)+ set(EIGEN_MODE Nightly)+endif(NOT EIGEN_MODE)++## mandatory variables (the default should be ok in most cases):++if(NOT EIGEN_NO_UPDATE)+ SET (CTEST_CVS_COMMAND "hg")+ SET (CTEST_CVS_CHECKOUT "${CTEST_CVS_COMMAND} clone http://bitbucket.org/eigen/eigen \"${CTEST_SOURCE_DIRECTORY}\"")+ SET(CTEST_BACKUP_AND_RESTORE TRUE) # the backup is CVS related ...+endif(NOT EIGEN_NO_UPDATE)++# which ctest command to use for running the dashboard+SET (CTEST_COMMAND "${EIGEN_CMAKE_DIR}ctest -D ${EIGEN_MODE} --no-compress-output")+if($ENV{EIGEN_CTEST_ARGS})+SET (CTEST_COMMAND "${CTEST_COMMAND} $ENV{EIGEN_CTEST_ARGS}")+endif($ENV{EIGEN_CTEST_ARGS})+# what cmake command to use for configuring this dashboard+SET (CTEST_CMAKE_COMMAND "${EIGEN_CMAKE_DIR}cmake -DEIGEN_LEAVE_TEST_IN_ALL_TARGET=ON")++####################################################################+# The values in this section are optional you can either+# have them or leave them commented out+####################################################################++# this make sure we get consistent outputs+SET($ENV{LC_MESSAGES} "en_EN")++# should ctest wipe the binary tree before running+SET(CTEST_START_WITH_EMPTY_BINARY_DIRECTORY TRUE)++# raise the warning/error limit+set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS "33331")+set(CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS "33331")++# this is the initial cache to use for the binary tree, be careful to escape+# any quotes inside of this string if you use it+if(WIN32 AND NOT UNIX)+ #message(SEND_ERROR "win32")+ if(EIGEN_GENERATOR_TYPE)+ set(CTEST_CMAKE_COMMAND "${CTEST_CMAKE_COMMAND} -G \"${EIGEN_GENERATOR_TYPE}\"")+ SET (CTEST_INITIAL_CACHE "+ CMAKE_BUILD_TYPE:STRING=Release+ BUILDNAME:STRING=${EIGEN_BUILD_STRING}+ SITE:STRING=${EIGEN_SITE}+ ")+ else(EIGEN_GENERATOR_TYPE)+ set(CTEST_CMAKE_COMMAND "${CTEST_CMAKE_COMMAND} -G \"NMake Makefiles\" -DCMAKE_MAKE_PROGRAM=nmake")+ SET (CTEST_INITIAL_CACHE "+ MAKECOMMAND:STRING=nmake /i+ CMAKE_MAKE_PROGRAM:FILEPATH=nmake+ CMAKE_GENERATOR:INTERNAL=NMake Makefiles+ CMAKE_BUILD_TYPE:STRING=Release+ BUILDNAME:STRING=${EIGEN_BUILD_STRING}+ SITE:STRING=${EIGEN_SITE}+ ")+ endif(EIGEN_GENERATOR_TYPE)+else(WIN32 AND NOT UNIX)+ SET (CTEST_INITIAL_CACHE "+ BUILDNAME:STRING=${EIGEN_BUILD_STRING}+ SITE:STRING=${EIGEN_SITE}+ ")+endif(WIN32 AND NOT UNIX)++# set any extra environment variables to use during the execution of the script here:+# setting this variable on windows machines causes trouble ...++if(EIGEN_CXX AND NOT WIN32)+ set(CTEST_ENVIRONMENT "CXX=${EIGEN_CXX}")+endif(EIGEN_CXX AND NOT WIN32)++if(DEFINED EIGEN_EXPLICIT_VECTORIZATION)+ if(EIGEN_EXPLICIT_VECTORIZATION MATCHES SSE2)+ set(CTEST_CMAKE_COMMAND "${CTEST_CMAKE_COMMAND} -DEIGEN_TEST_SSE2=ON")+ elseif(EIGEN_EXPLICIT_VECTORIZATION MATCHES SSE3)+ set(CTEST_CMAKE_COMMAND "${CTEST_CMAKE_COMMAND} -DEIGEN_TEST_SSE2=ON -DEIGEN_TEST_SSE3=ON")+ elseif(EIGEN_EXPLICIT_VECTORIZATION MATCHES SSSE3)+ set(CTEST_CMAKE_COMMAND "${CTEST_CMAKE_COMMAND} -DEIGEN_TEST_SSE2=ON -DEIGEN_TEST_SSE3=ON -DEIGEN_TEST_SSSE3=ON") + elseif(EIGEN_EXPLICIT_VECTORIZATION MATCHES SSE4_1)+ set(CTEST_CMAKE_COMMAND "${CTEST_CMAKE_COMMAND} -DEIGEN_TEST_SSE2=ON -DEIGEN_TEST_SSE3=ON -DEIGEN_TEST_SSSE3=ON -DEIGEN_TEST_SSE4_1=ON")+ elseif(EIGEN_EXPLICIT_VECTORIZATION MATCHES SSE4_2)+ set(CTEST_CMAKE_COMMAND "${CTEST_CMAKE_COMMAND} -DEIGEN_TEST_SSE2=ON -DEIGEN_TEST_SSE3=ON -DEIGEN_TEST_SSSE3=ON -DEIGEN_TEST_SSE4_1=ON -DEIGEN_TEST_SSE4_2=ON")+ elseif(EIGEN_EXPLICIT_VECTORIZATION MATCHES Altivec)+ set(CTEST_CMAKE_COMMAND "${CTEST_CMAKE_COMMAND} -DEIGEN_TEST_ALTIVEC=ON")+ elseif(EIGEN_EXPLICIT_VECTORIZATION MATCHES novec)+ set(CTEST_CMAKE_COMMAND "${CTEST_CMAKE_COMMAND} -DEIGEN_TEST_NO_EXPLICIT_VECTORIZATION=ON")+ else(EIGEN_EXPLICIT_VECTORIZATION MATCHES SSE2)+ message(FATAL_ERROR "Invalid value for EIGEN_EXPLICIT_VECTORIZATION (${EIGEN_EXPLICIT_VECTORIZATION}), must be: novec, SSE2, SSE3, Altivec")+ endif(EIGEN_EXPLICIT_VECTORIZATION MATCHES SSE2)+endif(DEFINED EIGEN_EXPLICIT_VECTORIZATION)++if(DEFINED EIGEN_CMAKE_ARGS)+ set(CTEST_CMAKE_COMMAND "${CTEST_CMAKE_COMMAND} ${EIGEN_CMAKE_ARGS}")+endif(DEFINED EIGEN_CMAKE_ARGS)
+ eigen3/test/triangular.cpp view
@@ -0,0 +1,232 @@+// This file is triangularView of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++++template<typename MatrixType> void triangular_square(const MatrixType& m)+{+ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ RealScalar largerEps = 10*test_precision<RealScalar>();++ typename MatrixType::Index rows = m.rows();+ typename MatrixType::Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols),+ m4(rows, cols),+ r1(rows, cols),+ r2(rows, cols);+ VectorType v2 = VectorType::Random(rows);++ MatrixType m1up = m1.template triangularView<Upper>();+ MatrixType m2up = m2.template triangularView<Upper>();++ if (rows*cols>1)+ {+ VERIFY(m1up.isUpperTriangular());+ VERIFY(m2up.transpose().isLowerTriangular());+ VERIFY(!m2.isLowerTriangular());+ }++// VERIFY_IS_APPROX(m1up.transpose() * m2, m1.upper().transpose().lower() * m2);++ // test overloaded operator+=+ r1.setZero();+ r2.setZero();+ r1.template triangularView<Upper>() += m1;+ r2 += m1up;+ VERIFY_IS_APPROX(r1,r2);++ // test overloaded operator=+ m1.setZero();+ m1.template triangularView<Upper>() = m2.transpose() + m2;+ m3 = m2.transpose() + m2;+ VERIFY_IS_APPROX(m3.template triangularView<Lower>().transpose().toDenseMatrix(), m1);++ // test overloaded operator=+ m1.setZero();+ m1.template triangularView<Lower>() = m2.transpose() + m2;+ VERIFY_IS_APPROX(m3.template triangularView<Lower>().toDenseMatrix(), m1);++ VERIFY_IS_APPROX(m3.template triangularView<Lower>().conjugate().toDenseMatrix(),+ m3.conjugate().template triangularView<Lower>().toDenseMatrix());++ m1 = MatrixType::Random(rows, cols);+ for (int i=0; i<rows; ++i)+ while (numext::abs2(m1(i,i))<1e-1) m1(i,i) = internal::random<Scalar>();++ Transpose<MatrixType> trm4(m4);+ // test back and forward subsitution with a vector as the rhs+ m3 = m1.template triangularView<Upper>();+ VERIFY(v2.isApprox(m3.adjoint() * (m1.adjoint().template triangularView<Lower>().solve(v2)), largerEps));+ m3 = m1.template triangularView<Lower>();+ VERIFY(v2.isApprox(m3.transpose() * (m1.transpose().template triangularView<Upper>().solve(v2)), largerEps));+ m3 = m1.template triangularView<Upper>();+ VERIFY(v2.isApprox(m3 * (m1.template triangularView<Upper>().solve(v2)), largerEps));+ m3 = m1.template triangularView<Lower>();+ VERIFY(v2.isApprox(m3.conjugate() * (m1.conjugate().template triangularView<Lower>().solve(v2)), largerEps));++ // test back and forward subsitution with a matrix as the rhs+ m3 = m1.template triangularView<Upper>();+ VERIFY(m2.isApprox(m3.adjoint() * (m1.adjoint().template triangularView<Lower>().solve(m2)), largerEps));+ m3 = m1.template triangularView<Lower>();+ VERIFY(m2.isApprox(m3.transpose() * (m1.transpose().template triangularView<Upper>().solve(m2)), largerEps));+ m3 = m1.template triangularView<Upper>();+ VERIFY(m2.isApprox(m3 * (m1.template triangularView<Upper>().solve(m2)), largerEps));+ m3 = m1.template triangularView<Lower>();+ VERIFY(m2.isApprox(m3.conjugate() * (m1.conjugate().template triangularView<Lower>().solve(m2)), largerEps));++ // check M * inv(L) using in place API+ m4 = m3;+ m1.transpose().template triangularView<Eigen::Upper>().solveInPlace(trm4);+ VERIFY_IS_APPROX(m4 * m1.template triangularView<Eigen::Lower>(), m3);++ // check M * inv(U) using in place API+ m3 = m1.template triangularView<Upper>();+ m4 = m3;+ m3.transpose().template triangularView<Eigen::Lower>().solveInPlace(trm4);+ VERIFY_IS_APPROX(m4 * m1.template triangularView<Eigen::Upper>(), m3);++ // check solve with unit diagonal+ m3 = m1.template triangularView<UnitUpper>();+ VERIFY(m2.isApprox(m3 * (m1.template triangularView<UnitUpper>().solve(m2)), largerEps));++// VERIFY(( m1.template triangularView<Upper>()+// * m2.template triangularView<Upper>()).isUpperTriangular());++ // test swap+ m1.setOnes();+ m2.setZero();+ m2.template triangularView<Upper>().swap(m1);+ m3.setZero();+ m3.template triangularView<Upper>().setOnes();+ VERIFY_IS_APPROX(m2,m3);++}+++template<typename MatrixType> void triangular_rect(const MatrixType& m)+{+ typedef const typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ enum { Rows = MatrixType::RowsAtCompileTime, Cols = MatrixType::ColsAtCompileTime };++ Index rows = m.rows();+ Index cols = m.cols();++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2 = MatrixType::Random(rows, cols),+ m3(rows, cols),+ m4(rows, cols),+ r1(rows, cols),+ r2(rows, cols);++ MatrixType m1up = m1.template triangularView<Upper>();+ MatrixType m2up = m2.template triangularView<Upper>();++ if (rows>1 && cols>1)+ {+ VERIFY(m1up.isUpperTriangular());+ VERIFY(m2up.transpose().isLowerTriangular());+ VERIFY(!m2.isLowerTriangular());+ }++ // test overloaded operator+=+ r1.setZero();+ r2.setZero();+ r1.template triangularView<Upper>() += m1;+ r2 += m1up;+ VERIFY_IS_APPROX(r1,r2);++ // test overloaded operator=+ m1.setZero();+ m1.template triangularView<Upper>() = 3 * m2;+ m3 = 3 * m2;+ VERIFY_IS_APPROX(m3.template triangularView<Upper>().toDenseMatrix(), m1);+++ m1.setZero();+ m1.template triangularView<Lower>() = 3 * m2;+ VERIFY_IS_APPROX(m3.template triangularView<Lower>().toDenseMatrix(), m1);++ m1.setZero();+ m1.template triangularView<StrictlyUpper>() = 3 * m2;+ VERIFY_IS_APPROX(m3.template triangularView<StrictlyUpper>().toDenseMatrix(), m1);+++ m1.setZero();+ m1.template triangularView<StrictlyLower>() = 3 * m2;+ VERIFY_IS_APPROX(m3.template triangularView<StrictlyLower>().toDenseMatrix(), m1);+ m1.setRandom();+ m2 = m1.template triangularView<Upper>();+ VERIFY(m2.isUpperTriangular());+ VERIFY(!m2.isLowerTriangular());+ m2 = m1.template triangularView<StrictlyUpper>();+ VERIFY(m2.isUpperTriangular());+ VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));+ m2 = m1.template triangularView<UnitUpper>();+ VERIFY(m2.isUpperTriangular());+ m2.diagonal().array() -= Scalar(1);+ VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));+ m2 = m1.template triangularView<Lower>();+ VERIFY(m2.isLowerTriangular());+ VERIFY(!m2.isUpperTriangular());+ m2 = m1.template triangularView<StrictlyLower>();+ VERIFY(m2.isLowerTriangular());+ VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));+ m2 = m1.template triangularView<UnitLower>();+ VERIFY(m2.isLowerTriangular());+ m2.diagonal().array() -= Scalar(1);+ VERIFY(m2.diagonal().isMuchSmallerThan(RealScalar(1)));+ // test swap+ m1.setOnes();+ m2.setZero();+ m2.template triangularView<Upper>().swap(m1);+ m3.setZero();+ m3.template triangularView<Upper>().setOnes();+ VERIFY_IS_APPROX(m2,m3);+}++void bug_159()+{+ Matrix3d m = Matrix3d::Random().triangularView<Lower>();+ EIGEN_UNUSED_VARIABLE(m)+}++void test_triangular()+{+ int maxsize = (std::min)(EIGEN_TEST_MAX_SIZE,20);+ for(int i = 0; i < g_repeat ; i++)+ {+ int r = internal::random<int>(2,maxsize); TEST_SET_BUT_UNUSED_VARIABLE(r)+ int c = internal::random<int>(2,maxsize); TEST_SET_BUT_UNUSED_VARIABLE(c)++ CALL_SUBTEST_1( triangular_square(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( triangular_square(Matrix<float, 2, 2>()) );+ CALL_SUBTEST_3( triangular_square(Matrix3d()) );+ CALL_SUBTEST_4( triangular_square(Matrix<std::complex<float>,8, 8>()) );+ CALL_SUBTEST_5( triangular_square(MatrixXcd(r,r)) );+ CALL_SUBTEST_6( triangular_square(Matrix<float,Dynamic,Dynamic,RowMajor>(r, r)) );++ CALL_SUBTEST_7( triangular_rect(Matrix<float, 4, 5>()) );+ CALL_SUBTEST_8( triangular_rect(Matrix<double, 6, 2>()) );+ CALL_SUBTEST_9( triangular_rect(MatrixXcf(r, c)) );+ CALL_SUBTEST_5( triangular_rect(MatrixXcd(r, c)) );+ CALL_SUBTEST_6( triangular_rect(Matrix<float,Dynamic,Dynamic,RowMajor>(r, c)) );+ }+ + CALL_SUBTEST_1( bug_159() );+}
+ eigen3/test/umeyama.cpp view
@@ -0,0 +1,183 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Hauke Heibel <hauke.heibel@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++#include <Eigen/Core>+#include <Eigen/Geometry>++#include <Eigen/LU> // required for MatrixBase::determinant+#include <Eigen/SVD> // required for SVD++using namespace Eigen;++// Constructs a random matrix from the unitary group U(size).+template <typename T>+Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> randMatrixUnitary(int size)+{+ typedef T Scalar;+ typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> MatrixType;++ MatrixType Q;++ int max_tries = 40;+ double is_unitary = false;++ while (!is_unitary && max_tries > 0)+ {+ // initialize random matrix+ Q = MatrixType::Random(size, size);++ // orthogonalize columns using the Gram-Schmidt algorithm+ for (int col = 0; col < size; ++col)+ {+ typename MatrixType::ColXpr colVec = Q.col(col);+ for (int prevCol = 0; prevCol < col; ++prevCol)+ {+ typename MatrixType::ColXpr prevColVec = Q.col(prevCol);+ colVec -= colVec.dot(prevColVec)*prevColVec;+ }+ Q.col(col) = colVec.normalized();+ }++ // this additional orthogonalization is not necessary in theory but should enhance+ // the numerical orthogonality of the matrix+ for (int row = 0; row < size; ++row)+ {+ typename MatrixType::RowXpr rowVec = Q.row(row);+ for (int prevRow = 0; prevRow < row; ++prevRow)+ {+ typename MatrixType::RowXpr prevRowVec = Q.row(prevRow);+ rowVec -= rowVec.dot(prevRowVec)*prevRowVec;+ }+ Q.row(row) = rowVec.normalized();+ }++ // final check+ is_unitary = Q.isUnitary();+ --max_tries;+ }++ if (max_tries == 0)+ eigen_assert(false && "randMatrixUnitary: Could not construct unitary matrix!");++ return Q;+}++// Constructs a random matrix from the special unitary group SU(size).+template <typename T>+Eigen::Matrix<T, Eigen::Dynamic, Eigen::Dynamic> randMatrixSpecialUnitary(int size)+{+ typedef T Scalar;++ typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> MatrixType;++ // initialize unitary matrix+ MatrixType Q = randMatrixUnitary<Scalar>(size);++ // tweak the first column to make the determinant be 1+ Q.col(0) *= numext::conj(Q.determinant());++ return Q;+}++template <typename MatrixType>+void run_test(int dim, int num_elements)+{+ using std::abs;+ typedef typename internal::traits<MatrixType>::Scalar Scalar;+ typedef Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> MatrixX;+ typedef Matrix<Scalar, Eigen::Dynamic, 1> VectorX;++ // MUST be positive because in any other case det(cR_t) may become negative for+ // odd dimensions!+ const Scalar c = abs(internal::random<Scalar>());++ MatrixX R = randMatrixSpecialUnitary<Scalar>(dim);+ VectorX t = Scalar(50)*VectorX::Random(dim,1);++ MatrixX cR_t = MatrixX::Identity(dim+1,dim+1);+ cR_t.block(0,0,dim,dim) = c*R;+ cR_t.block(0,dim,dim,1) = t;++ MatrixX src = MatrixX::Random(dim+1, num_elements);+ src.row(dim) = Matrix<Scalar, 1, Dynamic>::Constant(num_elements, Scalar(1));++ MatrixX dst = cR_t*src;++ MatrixX cR_t_umeyama = umeyama(src.block(0,0,dim,num_elements), dst.block(0,0,dim,num_elements));++ const Scalar error = ( cR_t_umeyama*src - dst ).norm() / dst.norm();+ VERIFY(error < Scalar(40)*std::numeric_limits<Scalar>::epsilon());+}++template<typename Scalar, int Dimension>+void run_fixed_size_test(int num_elements)+{+ using std::abs;+ typedef Matrix<Scalar, Dimension+1, Dynamic> MatrixX;+ typedef Matrix<Scalar, Dimension+1, Dimension+1> HomMatrix;+ typedef Matrix<Scalar, Dimension, Dimension> FixedMatrix;+ typedef Matrix<Scalar, Dimension, 1> FixedVector;++ const int dim = Dimension;++ // MUST be positive because in any other case det(cR_t) may become negative for+ // odd dimensions!+ // Also if c is to small compared to t.norm(), problem is ill-posed (cf. Bug 744)+ const Scalar c = internal::random<Scalar>(0.5, 2.0);++ FixedMatrix R = randMatrixSpecialUnitary<Scalar>(dim);+ FixedVector t = Scalar(32)*FixedVector::Random(dim,1);++ HomMatrix cR_t = HomMatrix::Identity(dim+1,dim+1);+ cR_t.block(0,0,dim,dim) = c*R;+ cR_t.block(0,dim,dim,1) = t;++ MatrixX src = MatrixX::Random(dim+1, num_elements);+ src.row(dim) = Matrix<Scalar, 1, Dynamic>::Constant(num_elements, Scalar(1));++ MatrixX dst = cR_t*src;++ Block<MatrixX, Dimension, Dynamic> src_block(src,0,0,dim,num_elements);+ Block<MatrixX, Dimension, Dynamic> dst_block(dst,0,0,dim,num_elements);++ HomMatrix cR_t_umeyama = umeyama(src_block, dst_block);++ const Scalar error = ( cR_t_umeyama*src - dst ).squaredNorm();++ VERIFY(error < Scalar(16)*std::numeric_limits<Scalar>::epsilon());+}++void test_umeyama()+{+ for (int i=0; i<g_repeat; ++i)+ {+ const int num_elements = internal::random<int>(40,500);++ // works also for dimensions bigger than 3...+ for (int dim=2; dim<8; ++dim)+ {+ CALL_SUBTEST_1(run_test<MatrixXd>(dim, num_elements));+ CALL_SUBTEST_2(run_test<MatrixXf>(dim, num_elements));+ }++ CALL_SUBTEST_3((run_fixed_size_test<float, 2>(num_elements)));+ CALL_SUBTEST_4((run_fixed_size_test<float, 3>(num_elements)));+ CALL_SUBTEST_5((run_fixed_size_test<float, 4>(num_elements)));++ CALL_SUBTEST_6((run_fixed_size_test<double, 2>(num_elements)));+ CALL_SUBTEST_7((run_fixed_size_test<double, 3>(num_elements)));+ CALL_SUBTEST_8((run_fixed_size_test<double, 4>(num_elements)));+ }++ // Those two calls don't compile and result in meaningful error messages!+ // umeyama(MatrixXcf(),MatrixXcf());+ // umeyama(MatrixXcd(),MatrixXcd());+}
+ eigen3/test/umfpack_support.cpp view
@@ -0,0 +1,31 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "sparse_solver.h"++#include <Eigen/UmfPackSupport>++template<typename T> void test_umfpack_support_T()+{+ UmfPackLU<SparseMatrix<T, ColMajor> > umfpack_colmajor;+ UmfPackLU<SparseMatrix<T, RowMajor> > umfpack_rowmajor;+ + check_sparse_square_solving(umfpack_colmajor);+ check_sparse_square_solving(umfpack_rowmajor);+ + check_sparse_square_determinant(umfpack_colmajor);+ check_sparse_square_determinant(umfpack_rowmajor);+}++void test_umfpack_support()+{+ CALL_SUBTEST_1(test_umfpack_support_T<double>());+ CALL_SUBTEST_2(test_umfpack_support_T<std::complex<double> >());+}+
+ eigen3/test/unalignedassert.cpp view
@@ -0,0 +1,127 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++struct TestNew1+{+ MatrixXd m; // good: m will allocate its own array, taking care of alignment.+ TestNew1() : m(20,20) {}+};++struct TestNew2+{+ Matrix3d m; // good: m's size isn't a multiple of 16 bytes, so m doesn't have to be 16-byte aligned,+ // 8-byte alignment is good enough here, which we'll get automatically+};++struct TestNew3+{+ Vector2f m; // good: m's size isn't a multiple of 16 bytes, so m doesn't have to be 16-byte aligned+};++struct TestNew4+{+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW+ Vector2d m;+ float f; // make the struct have sizeof%16!=0 to make it a little more tricky when we allow an array of 2 such objects+};++struct TestNew5+{+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW+ float f; // try the f at first -- the EIGEN_ALIGN16 attribute of m should make that still work+ Matrix4f m;+};++struct TestNew6+{+ Matrix<float,2,2,DontAlign> m; // good: no alignment requested+ float f;+};++template<bool Align> struct Depends+{+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(Align)+ Vector2d m;+ float f;+};++template<typename T>+void check_unalignedassert_good()+{+ T *x, *y;+ x = new T;+ delete x;+ y = new T[2];+ delete[] y;+}++#if EIGEN_ALIGN_STATICALLY+template<typename T>+void construct_at_boundary(int boundary)+{+ char buf[sizeof(T)+256];+ size_t _buf = reinterpret_cast<size_t>(buf);+ _buf += (16 - (_buf % 16)); // make 16-byte aligned+ _buf += boundary; // make exact boundary-aligned+ T *x = ::new(reinterpret_cast<void*>(_buf)) T;+ x[0].setZero(); // just in order to silence warnings+ x->~T();+}+#endif++void unalignedassert()+{+ #if EIGEN_ALIGN_STATICALLY+ construct_at_boundary<Vector2f>(4);+ construct_at_boundary<Vector3f>(4);+ construct_at_boundary<Vector4f>(16);+ construct_at_boundary<Matrix2f>(16);+ construct_at_boundary<Matrix3f>(4);+ construct_at_boundary<Matrix4f>(16);++ construct_at_boundary<Vector2d>(16);+ construct_at_boundary<Vector3d>(4);+ construct_at_boundary<Vector4d>(16);+ construct_at_boundary<Matrix2d>(16);+ construct_at_boundary<Matrix3d>(4);+ construct_at_boundary<Matrix4d>(16);++ construct_at_boundary<Vector2cf>(16);+ construct_at_boundary<Vector3cf>(4);+ construct_at_boundary<Vector2cd>(16);+ construct_at_boundary<Vector3cd>(16);+ #endif++ check_unalignedassert_good<TestNew1>();+ check_unalignedassert_good<TestNew2>();+ check_unalignedassert_good<TestNew3>();++ check_unalignedassert_good<TestNew4>();+ check_unalignedassert_good<TestNew5>();+ check_unalignedassert_good<TestNew6>();+ check_unalignedassert_good<Depends<true> >();++#if EIGEN_ALIGN_STATICALLY+ VERIFY_RAISES_ASSERT(construct_at_boundary<Vector4f>(8));+ VERIFY_RAISES_ASSERT(construct_at_boundary<Matrix4f>(8));+ VERIFY_RAISES_ASSERT(construct_at_boundary<Vector2d>(8));+ VERIFY_RAISES_ASSERT(construct_at_boundary<Vector4d>(8));+ VERIFY_RAISES_ASSERT(construct_at_boundary<Matrix2d>(8));+ VERIFY_RAISES_ASSERT(construct_at_boundary<Matrix4d>(8));+ VERIFY_RAISES_ASSERT(construct_at_boundary<Vector2cf>(8));+ VERIFY_RAISES_ASSERT(construct_at_boundary<Vector2cd>(8));+#endif+}++void test_unalignedassert()+{+ CALL_SUBTEST(unalignedassert());+}
+ eigen3/test/unalignedcount.cpp view
@@ -0,0 +1,46 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++static int nb_load;+static int nb_loadu;+static int nb_store;+static int nb_storeu;++#define EIGEN_DEBUG_ALIGNED_LOAD { nb_load++; }+#define EIGEN_DEBUG_UNALIGNED_LOAD { nb_loadu++; }+#define EIGEN_DEBUG_ALIGNED_STORE { nb_store++; }+#define EIGEN_DEBUG_UNALIGNED_STORE { nb_storeu++; }++#define VERIFY_ALIGNED_UNALIGNED_COUNT(XPR,AL,UL,AS,US) {\+ nb_load = nb_loadu = nb_store = nb_storeu = 0; \+ XPR; \+ if(!(nb_load==AL && nb_loadu==UL && nb_store==AS && nb_storeu==US)) \+ std::cerr << " >> " << nb_load << ", " << nb_loadu << ", " << nb_store << ", " << nb_storeu << "\n"; \+ VERIFY( (#XPR) && nb_load==AL && nb_loadu==UL && nb_store==AS && nb_storeu==US ); \+ }+++#include "main.h"++void test_unalignedcount()+{+ #ifdef EIGEN_VECTORIZE_SSE+ VectorXf a(40), b(40);+ VERIFY_ALIGNED_UNALIGNED_COUNT(a += b, 20, 0, 10, 0);+ VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0,40) += b.segment(0,40), 10, 10, 10, 0);+ VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0,40) -= b.segment(0,40), 10, 10, 10, 0);+ VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0,40) *= 3.5, 10, 0, 10, 0);+ VERIFY_ALIGNED_UNALIGNED_COUNT(a.segment(0,40) /= 3.5, 10, 0, 10, 0);+ #else+ // The following line is to eliminate "variable not used" warnings+ nb_load = nb_loadu = nb_store = nb_storeu = 0;+ int a(0), b(0);+ VERIFY(a==b);+ #endif+}
+ eigen3/test/upperbidiagonalization.cpp view
@@ -0,0 +1,43 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/SVD>++template<typename MatrixType> void upperbidiag(const MatrixType& m)+{+ const typename MatrixType::Index rows = m.rows();+ const typename MatrixType::Index cols = m.cols();++ typedef Matrix<typename MatrixType::RealScalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime> RealMatrixType;+ typedef Matrix<typename MatrixType::Scalar, MatrixType::ColsAtCompileTime, MatrixType::RowsAtCompileTime> TransposeMatrixType;++ MatrixType a = MatrixType::Random(rows,cols);+ internal::UpperBidiagonalization<MatrixType> ubd(a);+ RealMatrixType b(rows, cols);+ b.setZero();+ b.block(0,0,cols,cols) = ubd.bidiagonal();+ MatrixType c = ubd.householderU() * b * ubd.householderV().adjoint();+ VERIFY_IS_APPROX(a,c);+ TransposeMatrixType d = ubd.householderV() * b.adjoint() * ubd.householderU().adjoint();+ VERIFY_IS_APPROX(a.adjoint(),d);+}++void test_upperbidiagonalization()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( upperbidiag(MatrixXf(3,3)) );+ CALL_SUBTEST_2( upperbidiag(MatrixXd(17,12)) );+ CALL_SUBTEST_3( upperbidiag(MatrixXcf(20,20)) );+ CALL_SUBTEST_4( upperbidiag(MatrixXcd(16,15)) );+ CALL_SUBTEST_5( upperbidiag(Matrix<float,6,4>()) );+ CALL_SUBTEST_6( upperbidiag(Matrix<float,5,5>()) );+ CALL_SUBTEST_7( upperbidiag(Matrix<double,4,3>()) );+ }+}
+ eigen3/test/vectorization_logic.cpp view
@@ -0,0 +1,235 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN_DEBUG_ASSIGN+#include "main.h"+#include <typeinfo>++std::string demangle_traversal(int t)+{+ if(t==DefaultTraversal) return "DefaultTraversal";+ if(t==LinearTraversal) return "LinearTraversal";+ if(t==InnerVectorizedTraversal) return "InnerVectorizedTraversal";+ if(t==LinearVectorizedTraversal) return "LinearVectorizedTraversal";+ if(t==SliceVectorizedTraversal) return "SliceVectorizedTraversal";+ return "?";+}+std::string demangle_unrolling(int t)+{+ if(t==NoUnrolling) return "NoUnrolling";+ if(t==InnerUnrolling) return "InnerUnrolling";+ if(t==CompleteUnrolling) return "CompleteUnrolling";+ return "?";+}++template<typename Dst, typename Src>+bool test_assign(const Dst&, const Src&, int traversal, int unrolling)+{+ internal::assign_traits<Dst,Src>::debug();+ bool res = internal::assign_traits<Dst,Src>::Traversal==traversal+ && internal::assign_traits<Dst,Src>::Unrolling==unrolling;+ if(!res)+ {+ std::cerr << " Expected Traversal == " << demangle_traversal(traversal)+ << " got " << demangle_traversal(internal::assign_traits<Dst,Src>::Traversal) << "\n";+ std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)+ << " got " << demangle_unrolling(internal::assign_traits<Dst,Src>::Unrolling) << "\n";+ }+ return res;+}++template<typename Dst, typename Src>+bool test_assign(int traversal, int unrolling)+{+ internal::assign_traits<Dst,Src>::debug();+ bool res = internal::assign_traits<Dst,Src>::Traversal==traversal+ && internal::assign_traits<Dst,Src>::Unrolling==unrolling;+ if(!res)+ {+ std::cerr << " Expected Traversal == " << demangle_traversal(traversal)+ << " got " << demangle_traversal(internal::assign_traits<Dst,Src>::Traversal) << "\n";+ std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)+ << " got " << demangle_unrolling(internal::assign_traits<Dst,Src>::Unrolling) << "\n";+ }+ return res;+}++template<typename Xpr>+bool test_redux(const Xpr&, int traversal, int unrolling)+{+ typedef internal::redux_traits<internal::scalar_sum_op<typename Xpr::Scalar>,Xpr> traits;+ bool res = traits::Traversal==traversal && traits::Unrolling==unrolling;+ if(!res)+ {+ std::cerr << " Expected Traversal == " << demangle_traversal(traversal)+ << " got " << demangle_traversal(traits::Traversal) << "\n";+ std::cerr << " Expected Unrolling == " << demangle_unrolling(unrolling)+ << " got " << demangle_unrolling(traits::Unrolling) << "\n";+ }+ return res;+}++template<typename Scalar, bool Enable = internal::packet_traits<Scalar>::Vectorizable> struct vectorization_logic+{+ enum {+ PacketSize = internal::packet_traits<Scalar>::size+ };+ static void run()+ {+ + typedef Matrix<Scalar,PacketSize,1> Vector1;+ typedef Matrix<Scalar,Dynamic,1> VectorX;+ typedef Matrix<Scalar,Dynamic,Dynamic> MatrixXX;+ typedef Matrix<Scalar,PacketSize,PacketSize> Matrix11;+ typedef Matrix<Scalar,2*PacketSize,2*PacketSize> Matrix22;+ typedef Matrix<Scalar,(Matrix11::Flags&RowMajorBit)?16:4*PacketSize,(Matrix11::Flags&RowMajorBit)?4*PacketSize:16> Matrix44;+ typedef Matrix<Scalar,(Matrix11::Flags&RowMajorBit)?16:4*PacketSize,(Matrix11::Flags&RowMajorBit)?4*PacketSize:16,DontAlign|EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION> Matrix44u;+ typedef Matrix<Scalar,4*PacketSize,16,ColMajor> Matrix44c;+ typedef Matrix<Scalar,4*PacketSize,16,RowMajor> Matrix44r;++ typedef Matrix<Scalar,+ (PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),+ (PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1)+ > Matrix1;++ typedef Matrix<Scalar,+ (PacketSize==8 ? 4 : PacketSize==4 ? 2 : PacketSize==2 ? 1 : /*PacketSize==1 ?*/ 1),+ (PacketSize==8 ? 2 : PacketSize==4 ? 2 : PacketSize==2 ? 2 : /*PacketSize==1 ?*/ 1),+ DontAlign|((Matrix1::Flags&RowMajorBit)?RowMajor:ColMajor)> Matrix1u;++ // this type is made such that it can only be vectorized when viewed as a linear 1D vector+ typedef Matrix<Scalar,+ (PacketSize==8 ? 4 : PacketSize==4 ? 6 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?2:3) : /*PacketSize==1 ?*/ 1),+ (PacketSize==8 ? 6 : PacketSize==4 ? 2 : PacketSize==2 ? ((Matrix11::Flags&RowMajorBit)?3:2) : /*PacketSize==1 ?*/ 3)+ > Matrix3;+ + #if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_STACK_ALIGNMENT+ VERIFY(test_assign(Vector1(),Vector1(),+ InnerVectorizedTraversal,CompleteUnrolling));+ VERIFY(test_assign(Vector1(),Vector1()+Vector1(),+ InnerVectorizedTraversal,CompleteUnrolling));+ VERIFY(test_assign(Vector1(),Vector1().cwiseProduct(Vector1()),+ InnerVectorizedTraversal,CompleteUnrolling));+ VERIFY(test_assign(Vector1(),Vector1().template cast<Scalar>(),+ InnerVectorizedTraversal,CompleteUnrolling));+++ VERIFY(test_assign(Vector1(),Vector1(),+ InnerVectorizedTraversal,CompleteUnrolling));+ VERIFY(test_assign(Vector1(),Vector1()+Vector1(),+ InnerVectorizedTraversal,CompleteUnrolling));+ VERIFY(test_assign(Vector1(),Vector1().cwiseProduct(Vector1()),+ InnerVectorizedTraversal,CompleteUnrolling));++ VERIFY(test_assign(Matrix44(),Matrix44()+Matrix44(),+ InnerVectorizedTraversal,InnerUnrolling));++ VERIFY(test_assign(Matrix44u(),Matrix44()+Matrix44(),+ LinearTraversal,NoUnrolling));++ VERIFY(test_assign(Matrix1u(),Matrix1()+Matrix1(),+ LinearTraversal,CompleteUnrolling));++ VERIFY(test_assign(Matrix44c().col(1),Matrix44c().col(2)+Matrix44c().col(3),+ InnerVectorizedTraversal,CompleteUnrolling));+ + VERIFY(test_assign(Matrix44r().row(2),Matrix44r().row(1)+Matrix44r().row(1),+ InnerVectorizedTraversal,CompleteUnrolling));+ + if(PacketSize>1)+ {+ typedef Matrix<Scalar,3,3,ColMajor> Matrix33c;+ VERIFY(test_assign(Matrix33c().row(2),Matrix33c().row(1)+Matrix33c().row(1),+ LinearTraversal,CompleteUnrolling));+ VERIFY(test_assign(Matrix33c().col(0),Matrix33c().col(1)+Matrix33c().col(1),+ LinearTraversal,CompleteUnrolling));+ + VERIFY(test_assign(Matrix3(),Matrix3().cwiseQuotient(Matrix3()),+ LinearVectorizedTraversal,CompleteUnrolling));++ VERIFY(test_assign(Matrix<Scalar,17,17>(),Matrix<Scalar,17,17>()+Matrix<Scalar,17,17>(),+ LinearTraversal,NoUnrolling));++ VERIFY(test_assign(Matrix11(),Matrix<Scalar,17,17>().template block<PacketSize,PacketSize>(2,3)+Matrix<Scalar,17,17>().template block<PacketSize,PacketSize>(10,4),+ DefaultTraversal,CompleteUnrolling));+ }+ + VERIFY(test_redux(Matrix3(),+ LinearVectorizedTraversal,CompleteUnrolling));++ VERIFY(test_redux(Matrix44(),+ LinearVectorizedTraversal,NoUnrolling));++ VERIFY(test_redux(Matrix44().template block<(Matrix1::Flags&RowMajorBit)?4:PacketSize,(Matrix1::Flags&RowMajorBit)?PacketSize:4>(1,2),+ DefaultTraversal,CompleteUnrolling));++ VERIFY(test_redux(Matrix44c().template block<2*PacketSize,1>(1,2),+ LinearVectorizedTraversal,CompleteUnrolling));++ VERIFY(test_redux(Matrix44r().template block<1,2*PacketSize>(2,1),+ LinearVectorizedTraversal,CompleteUnrolling));+ + VERIFY((test_assign<+ Map<Matrix22, Aligned, OuterStride<3*PacketSize> >,+ Matrix22+ >(InnerVectorizedTraversal,CompleteUnrolling)));++ VERIFY((test_assign<+ Map<Matrix22, Aligned, InnerStride<3*PacketSize> >,+ Matrix22+ >(DefaultTraversal,CompleteUnrolling)));++ VERIFY((test_assign(Matrix11(), Matrix11()*Matrix11(), InnerVectorizedTraversal, CompleteUnrolling)));+ #endif++ VERIFY(test_assign(MatrixXX(10,10),MatrixXX(20,20).block(10,10,2,3),+ SliceVectorizedTraversal,NoUnrolling));++ VERIFY(test_redux(VectorX(10),+ LinearVectorizedTraversal,NoUnrolling));++ + }+};++template<typename Scalar> struct vectorization_logic<Scalar,false>+{+ static void run() {}+};++void test_vectorization_logic()+{++#ifdef EIGEN_VECTORIZE++ CALL_SUBTEST( vectorization_logic<float>::run() );+ CALL_SUBTEST( vectorization_logic<double>::run() );+ CALL_SUBTEST( vectorization_logic<std::complex<float> >::run() );+ CALL_SUBTEST( vectorization_logic<std::complex<double> >::run() );+ + if(internal::packet_traits<float>::Vectorizable)+ {+ VERIFY(test_assign(Matrix<float,3,3>(),Matrix<float,3,3>()+Matrix<float,3,3>(),+ LinearTraversal,CompleteUnrolling));+ + VERIFY(test_redux(Matrix<float,5,2>(),+ DefaultTraversal,CompleteUnrolling));+ }+ + if(internal::packet_traits<double>::Vectorizable)+ {+ VERIFY(test_assign(Matrix<double,3,3>(),Matrix<double,3,3>()+Matrix<double,3,3>(),+ LinearTraversal,CompleteUnrolling));+ + VERIFY(test_redux(Matrix<double,7,3>(),+ DefaultTraversal,CompleteUnrolling));+ }+#endif // EIGEN_VECTORIZE++}
+ eigen3/test/vectorwiseop.cpp view
@@ -0,0 +1,205 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#define EIGEN_NO_STATIC_ASSERT++#include "main.h"++template<typename ArrayType> void vectorwiseop_array(const ArrayType& m)+{+ typedef typename ArrayType::Index Index;+ typedef typename ArrayType::Scalar Scalar;+ typedef Array<Scalar, ArrayType::RowsAtCompileTime, 1> ColVectorType;+ typedef Array<Scalar, 1, ArrayType::ColsAtCompileTime> RowVectorType;++ Index rows = m.rows();+ Index cols = m.cols();+ Index r = internal::random<Index>(0, rows-1),+ c = internal::random<Index>(0, cols-1);++ ArrayType m1 = ArrayType::Random(rows, cols),+ m2(rows, cols),+ m3(rows, cols);++ ColVectorType colvec = ColVectorType::Random(rows);+ RowVectorType rowvec = RowVectorType::Random(cols);++ // test addition++ m2 = m1;+ m2.colwise() += colvec;+ VERIFY_IS_APPROX(m2, m1.colwise() + colvec);+ VERIFY_IS_APPROX(m2.col(c), m1.col(c) + colvec);++ VERIFY_RAISES_ASSERT(m2.colwise() += colvec.transpose());+ VERIFY_RAISES_ASSERT(m1.colwise() + colvec.transpose());++ m2 = m1;+ m2.rowwise() += rowvec;+ VERIFY_IS_APPROX(m2, m1.rowwise() + rowvec);+ VERIFY_IS_APPROX(m2.row(r), m1.row(r) + rowvec);++ VERIFY_RAISES_ASSERT(m2.rowwise() += rowvec.transpose());+ VERIFY_RAISES_ASSERT(m1.rowwise() + rowvec.transpose());++ // test substraction++ m2 = m1;+ m2.colwise() -= colvec;+ VERIFY_IS_APPROX(m2, m1.colwise() - colvec);+ VERIFY_IS_APPROX(m2.col(c), m1.col(c) - colvec);++ VERIFY_RAISES_ASSERT(m2.colwise() -= colvec.transpose());+ VERIFY_RAISES_ASSERT(m1.colwise() - colvec.transpose());++ m2 = m1;+ m2.rowwise() -= rowvec;+ VERIFY_IS_APPROX(m2, m1.rowwise() - rowvec);+ VERIFY_IS_APPROX(m2.row(r), m1.row(r) - rowvec);++ VERIFY_RAISES_ASSERT(m2.rowwise() -= rowvec.transpose());+ VERIFY_RAISES_ASSERT(m1.rowwise() - rowvec.transpose());++ // test multiplication++ m2 = m1;+ m2.colwise() *= colvec;+ VERIFY_IS_APPROX(m2, m1.colwise() * colvec);+ VERIFY_IS_APPROX(m2.col(c), m1.col(c) * colvec);++ VERIFY_RAISES_ASSERT(m2.colwise() *= colvec.transpose());+ VERIFY_RAISES_ASSERT(m1.colwise() * colvec.transpose());++ m2 = m1;+ m2.rowwise() *= rowvec;+ VERIFY_IS_APPROX(m2, m1.rowwise() * rowvec);+ VERIFY_IS_APPROX(m2.row(r), m1.row(r) * rowvec);++ VERIFY_RAISES_ASSERT(m2.rowwise() *= rowvec.transpose());+ VERIFY_RAISES_ASSERT(m1.rowwise() * rowvec.transpose());++ // test quotient++ m2 = m1;+ m2.colwise() /= colvec;+ VERIFY_IS_APPROX(m2, m1.colwise() / colvec);+ VERIFY_IS_APPROX(m2.col(c), m1.col(c) / colvec);++ VERIFY_RAISES_ASSERT(m2.colwise() /= colvec.transpose());+ VERIFY_RAISES_ASSERT(m1.colwise() / colvec.transpose());++ m2 = m1;+ m2.rowwise() /= rowvec;+ VERIFY_IS_APPROX(m2, m1.rowwise() / rowvec);+ VERIFY_IS_APPROX(m2.row(r), m1.row(r) / rowvec);++ VERIFY_RAISES_ASSERT(m2.rowwise() /= rowvec.transpose());+ VERIFY_RAISES_ASSERT(m1.rowwise() / rowvec.transpose());+ + m2 = m1;+ // yes, there might be an aliasing issue there but ".rowwise() /="+ // is suppposed to evaluate " m2.colwise().sum()" into to temporary to avoid+ // evaluating the reducions multiple times+ if(ArrayType::RowsAtCompileTime>2 || ArrayType::RowsAtCompileTime==Dynamic)+ {+ m2.rowwise() /= m2.colwise().sum();+ VERIFY_IS_APPROX(m2, m1.rowwise() / m1.colwise().sum());+ }+}++template<typename MatrixType> void vectorwiseop_matrix(const MatrixType& m)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType;+ typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;+ typedef Matrix<RealScalar, MatrixType::RowsAtCompileTime, 1> RealColVectorType;+ typedef Matrix<RealScalar, 1, MatrixType::ColsAtCompileTime> RealRowVectorType;++ Index rows = m.rows();+ Index cols = m.cols();+ Index r = internal::random<Index>(0, rows-1),+ c = internal::random<Index>(0, cols-1);++ MatrixType m1 = MatrixType::Random(rows, cols),+ m2(rows, cols),+ m3(rows, cols);++ ColVectorType colvec = ColVectorType::Random(rows);+ RowVectorType rowvec = RowVectorType::Random(cols);+ RealColVectorType rcres;+ RealRowVectorType rrres;++ // test addition++ m2 = m1;+ m2.colwise() += colvec;+ VERIFY_IS_APPROX(m2, m1.colwise() + colvec);+ VERIFY_IS_APPROX(m2.col(c), m1.col(c) + colvec);++ VERIFY_RAISES_ASSERT(m2.colwise() += colvec.transpose());+ VERIFY_RAISES_ASSERT(m1.colwise() + colvec.transpose());++ m2 = m1;+ m2.rowwise() += rowvec;+ VERIFY_IS_APPROX(m2, m1.rowwise() + rowvec);+ VERIFY_IS_APPROX(m2.row(r), m1.row(r) + rowvec);++ VERIFY_RAISES_ASSERT(m2.rowwise() += rowvec.transpose());+ VERIFY_RAISES_ASSERT(m1.rowwise() + rowvec.transpose());++ // test substraction++ m2 = m1;+ m2.colwise() -= colvec;+ VERIFY_IS_APPROX(m2, m1.colwise() - colvec);+ VERIFY_IS_APPROX(m2.col(c), m1.col(c) - colvec);++ VERIFY_RAISES_ASSERT(m2.colwise() -= colvec.transpose());+ VERIFY_RAISES_ASSERT(m1.colwise() - colvec.transpose());++ m2 = m1;+ m2.rowwise() -= rowvec;+ VERIFY_IS_APPROX(m2, m1.rowwise() - rowvec);+ VERIFY_IS_APPROX(m2.row(r), m1.row(r) - rowvec);++ VERIFY_RAISES_ASSERT(m2.rowwise() -= rowvec.transpose());+ VERIFY_RAISES_ASSERT(m1.rowwise() - rowvec.transpose());+ + // test norm+ rrres = m1.colwise().norm();+ VERIFY_IS_APPROX(rrres(c), m1.col(c).norm());+ rcres = m1.rowwise().norm();+ VERIFY_IS_APPROX(rcres(r), m1.row(r).norm());+ + // test normalized+ m2 = m1.colwise().normalized();+ VERIFY_IS_APPROX(m2.col(c), m1.col(c).normalized());+ m2 = m1.rowwise().normalized();+ VERIFY_IS_APPROX(m2.row(r), m1.row(r).normalized());+ + // test normalize+ m2 = m1;+ m2.colwise().normalize();+ VERIFY_IS_APPROX(m2.col(c), m1.col(c).normalized());+ m2 = m1;+ m2.rowwise().normalize();+ VERIFY_IS_APPROX(m2.row(r), m1.row(r).normalized());+}++void test_vectorwiseop()+{+ CALL_SUBTEST_1(vectorwiseop_array(Array22cd()));+ CALL_SUBTEST_2(vectorwiseop_array(Array<double, 3, 2>()));+ CALL_SUBTEST_3(vectorwiseop_array(ArrayXXf(3, 4)));+ CALL_SUBTEST_4(vectorwiseop_matrix(Matrix4cf()));+ CALL_SUBTEST_5(vectorwiseop_matrix(Matrix<float,4,5>()));+ CALL_SUBTEST_6(vectorwiseop_matrix(MatrixXd(7,2)));+}
+ eigen3/test/visitor.cpp view
@@ -0,0 +1,130 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++template<typename MatrixType> void matrixVisitor(const MatrixType& p)+{+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::Index Index;++ Index rows = p.rows();+ Index cols = p.cols();++ // construct a random matrix where all coefficients are different+ MatrixType m;+ m = MatrixType::Random(rows, cols);+ for(Index i = 0; i < m.size(); i++)+ for(Index i2 = 0; i2 < i; i2++)+ while(m(i) == m(i2)) // yes, ==+ m(i) = internal::random<Scalar>();+ + Scalar minc = Scalar(1000), maxc = Scalar(-1000);+ Index minrow=0,mincol=0,maxrow=0,maxcol=0;+ for(Index j = 0; j < cols; j++)+ for(Index i = 0; i < rows; i++)+ {+ if(m(i,j) < minc)+ {+ minc = m(i,j);+ minrow = i;+ mincol = j;+ }+ if(m(i,j) > maxc)+ {+ maxc = m(i,j);+ maxrow = i;+ maxcol = j;+ }+ }+ Index eigen_minrow, eigen_mincol, eigen_maxrow, eigen_maxcol;+ Scalar eigen_minc, eigen_maxc;+ eigen_minc = m.minCoeff(&eigen_minrow,&eigen_mincol);+ eigen_maxc = m.maxCoeff(&eigen_maxrow,&eigen_maxcol);+ VERIFY(minrow == eigen_minrow);+ VERIFY(maxrow == eigen_maxrow);+ VERIFY(mincol == eigen_mincol);+ VERIFY(maxcol == eigen_maxcol);+ VERIFY_IS_APPROX(minc, eigen_minc);+ VERIFY_IS_APPROX(maxc, eigen_maxc);+ VERIFY_IS_APPROX(minc, m.minCoeff());+ VERIFY_IS_APPROX(maxc, m.maxCoeff());+}++template<typename VectorType> void vectorVisitor(const VectorType& w)+{+ typedef typename VectorType::Scalar Scalar;+ typedef typename VectorType::Index Index;++ Index size = w.size();++ // construct a random vector where all coefficients are different+ VectorType v;+ v = VectorType::Random(size);+ for(Index i = 0; i < size; i++)+ for(Index i2 = 0; i2 < i; i2++)+ while(v(i) == v(i2)) // yes, ==+ v(i) = internal::random<Scalar>();+ + Scalar minc = v(0), maxc = v(0);+ Index minidx=0, maxidx=0;+ for(Index i = 0; i < size; i++)+ {+ if(v(i) < minc)+ {+ minc = v(i);+ minidx = i;+ }+ if(v(i) > maxc)+ {+ maxc = v(i);+ maxidx = i;+ }+ }+ Index eigen_minidx, eigen_maxidx;+ Scalar eigen_minc, eigen_maxc;+ eigen_minc = v.minCoeff(&eigen_minidx);+ eigen_maxc = v.maxCoeff(&eigen_maxidx);+ VERIFY(minidx == eigen_minidx);+ VERIFY(maxidx == eigen_maxidx);+ VERIFY_IS_APPROX(minc, eigen_minc);+ VERIFY_IS_APPROX(maxc, eigen_maxc);+ VERIFY_IS_APPROX(minc, v.minCoeff());+ VERIFY_IS_APPROX(maxc, v.maxCoeff());+ + Index idx0 = internal::random<Index>(0,size-1);+ Index idx1 = eigen_minidx;+ Index idx2 = eigen_maxidx;+ VectorType v1(v), v2(v);+ v1(idx0) = v1(idx1);+ v2(idx0) = v2(idx2);+ v1.minCoeff(&eigen_minidx);+ v2.maxCoeff(&eigen_maxidx);+ VERIFY(eigen_minidx == (std::min)(idx0,idx1));+ VERIFY(eigen_maxidx == (std::min)(idx0,idx2));+}++void test_visitor()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( matrixVisitor(Matrix<float, 1, 1>()) );+ CALL_SUBTEST_2( matrixVisitor(Matrix2f()) );+ CALL_SUBTEST_3( matrixVisitor(Matrix4d()) );+ CALL_SUBTEST_4( matrixVisitor(MatrixXd(8, 12)) );+ CALL_SUBTEST_5( matrixVisitor(Matrix<double,Dynamic,Dynamic,RowMajor>(20, 20)) );+ CALL_SUBTEST_6( matrixVisitor(MatrixXi(8, 12)) );+ }+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_7( vectorVisitor(Vector4f()) );+ CALL_SUBTEST_7( vectorVisitor(Matrix<int,12,1>()) );+ CALL_SUBTEST_8( vectorVisitor(VectorXd(10)) );+ CALL_SUBTEST_9( vectorVisitor(RowVectorXd(10)) );+ CALL_SUBTEST_10( vectorVisitor(VectorXf(33)) );+ }+}
+ eigen3/test/zerosized.cpp view
@@ -0,0 +1,84 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+++template<typename MatrixType> void zeroReduction(const MatrixType& m) {+ // Reductions that must hold for zero sized objects+ VERIFY(m.all());+ VERIFY(!m.any());+ VERIFY(m.prod()==1);+ VERIFY(m.sum()==0);+ VERIFY(m.count()==0);+ VERIFY(m.allFinite());+ VERIFY(!m.hasNaN());+}+++template<typename MatrixType> void zeroSizedMatrix()+{+ MatrixType t1;++ if (MatrixType::SizeAtCompileTime == Dynamic || MatrixType::SizeAtCompileTime == 0)+ {+ zeroReduction(t1);+ if (MatrixType::RowsAtCompileTime == Dynamic)+ VERIFY(t1.rows() == 0);+ if (MatrixType::ColsAtCompileTime == Dynamic)+ VERIFY(t1.cols() == 0);++ if (MatrixType::RowsAtCompileTime == Dynamic && MatrixType::ColsAtCompileTime == Dynamic)+ {++ MatrixType t2(0, 0);+ VERIFY(t2.rows() == 0);+ VERIFY(t2.cols() == 0);++ zeroReduction(t2);+ VERIFY(t1==t2);+ }+ }+}++template<typename VectorType> void zeroSizedVector()+{+ VectorType t1;++ if (VectorType::SizeAtCompileTime == Dynamic || VectorType::SizeAtCompileTime==0)+ {+ zeroReduction(t1);+ VERIFY(t1.size() == 0);+ VectorType t2(DenseIndex(0)); // DenseIndex disambiguates with 0-the-null-pointer (error with gcc 4.4 and MSVC8)+ VERIFY(t2.size() == 0);+ zeroReduction(t2);++ VERIFY(t1==t2);+ }+}++void test_zerosized()+{+ zeroSizedMatrix<Matrix2d>();+ zeroSizedMatrix<Matrix3i>();+ zeroSizedMatrix<Matrix<float, 2, Dynamic> >();+ zeroSizedMatrix<MatrixXf>();+ zeroSizedMatrix<Matrix<float, 0, 0> >();+ zeroSizedMatrix<Matrix<float, Dynamic, 0, 0, 0, 0> >();+ zeroSizedMatrix<Matrix<float, 0, Dynamic, 0, 0, 0> >();+ zeroSizedMatrix<Matrix<float, Dynamic, Dynamic, 0, 0, 0> >();+ zeroSizedMatrix<Matrix<float, 0, 4> >();+ zeroSizedMatrix<Matrix<float, 4, 0> >();++ zeroSizedVector<Vector2d>();+ zeroSizedVector<Vector3i>();+ zeroSizedVector<VectorXf>();+ zeroSizedVector<Matrix<float, 0, 1> >();+ zeroSizedVector<Matrix<float, 1, 0> >();+}
+ eigen3/unsupported/CMakeLists.txt view
@@ -0,0 +1,7 @@+add_subdirectory(Eigen)+add_subdirectory(doc EXCLUDE_FROM_ALL)+if(EIGEN_LEAVE_TEST_IN_ALL_TARGET)+ add_subdirectory(test) # can't do EXCLUDE_FROM_ALL here, breaks CTest+else()+ add_subdirectory(test EXCLUDE_FROM_ALL)+endif()
+ eigen3/unsupported/Eigen/AdolcForward view
@@ -0,0 +1,156 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_ADLOC_FORWARD+#define EIGEN_ADLOC_FORWARD++//--------------------------------------------------------------------------------+//+// This file provides support for adolc's adouble type in forward mode.+// ADOL-C is a C++ automatic differentiation library,+// see https://projects.coin-or.org/ADOL-C for more information.+//+// Note that the maximal number of directions is controlled by+// the preprocessor token NUMBER_DIRECTIONS. The default is 2.+//+//--------------------------------------------------------------------------------++#define ADOLC_TAPELESS+#ifndef NUMBER_DIRECTIONS+# define NUMBER_DIRECTIONS 2+#endif+#include <adolc/adouble.h>++// adolc defines some very stupid macros:+#if defined(malloc)+# undef malloc+#endif++#if defined(calloc)+# undef calloc+#endif++#if defined(realloc)+# undef realloc+#endif++#include <Eigen/Core>++namespace Eigen {++/**+ * \defgroup AdolcForward_Module Adolc forward module+ * This module provides support for adolc's adouble type in forward mode.+ * ADOL-C is a C++ automatic differentiation library,+ * see https://projects.coin-or.org/ADOL-C for more information.+ * It mainly consists in:+ * - a struct Eigen::NumTraits<adtl::adouble> specialization+ * - overloads of internal::* math function for adtl::adouble type.+ *+ * Note that the maximal number of directions is controlled by+ * the preprocessor token NUMBER_DIRECTIONS. The default is 2.+ *+ * \code+ * #include <unsupported/Eigen/AdolcSupport>+ * \endcode+ */+ //@{++} // namespace Eigen++// Eigen's require a few additional functions which must be defined in the same namespace+// than the custom scalar type own namespace+namespace adtl {++inline const adouble& conj(const adouble& x) { return x; }+inline const adouble& real(const adouble& x) { return x; }+inline adouble imag(const adouble&) { return 0.; }+inline adouble abs(const adouble& x) { return fabs(x); }+inline adouble abs2(const adouble& x) { return x*x; }++}++namespace Eigen {++template<> struct NumTraits<adtl::adouble>+ : NumTraits<double>+{+ typedef adtl::adouble Real;+ typedef adtl::adouble NonInteger;+ typedef adtl::adouble Nested;+ enum {+ IsComplex = 0,+ IsInteger = 0,+ IsSigned = 1,+ RequireInitialization = 1,+ ReadCost = 1,+ AddCost = 1,+ MulCost = 1+ };+};++template<typename Functor> class AdolcForwardJacobian : public Functor+{+ typedef adtl::adouble ActiveScalar;+public:++ AdolcForwardJacobian() : Functor() {}+ AdolcForwardJacobian(const Functor& f) : Functor(f) {}++ // forward constructors+ template<typename T0>+ AdolcForwardJacobian(const T0& a0) : Functor(a0) {}+ template<typename T0, typename T1>+ AdolcForwardJacobian(const T0& a0, const T1& a1) : Functor(a0, a1) {}+ template<typename T0, typename T1, typename T2>+ AdolcForwardJacobian(const T0& a0, const T1& a1, const T1& a2) : Functor(a0, a1, a2) {}++ typedef typename Functor::InputType InputType;+ typedef typename Functor::ValueType ValueType;+ typedef typename Functor::JacobianType JacobianType;++ typedef Matrix<ActiveScalar, InputType::SizeAtCompileTime, 1> ActiveInput;+ typedef Matrix<ActiveScalar, ValueType::SizeAtCompileTime, 1> ActiveValue;++ void operator() (const InputType& x, ValueType* v, JacobianType* _jac) const+ {+ eigen_assert(v!=0);+ if (!_jac)+ {+ Functor::operator()(x, v);+ return;+ }++ JacobianType& jac = *_jac;++ ActiveInput ax = x.template cast<ActiveScalar>();+ ActiveValue av(jac.rows());++ for (int j=0; j<jac.cols(); j++)+ for (int i=0; i<jac.cols(); i++)+ ax[i].setADValue(j, i==j ? 1 : 0);++ Functor::operator()(ax, &av);++ for (int i=0; i<jac.rows(); i++)+ {+ (*v)[i] = av[i].getValue();+ for (int j=0; j<jac.cols(); j++)+ jac.coeffRef(i,j) = av[i].getADValue(j);+ }+ }+protected:++};++//@}++}++#endif // EIGEN_ADLOC_FORWARD
+ eigen3/unsupported/Eigen/AlignedVector3 view
@@ -0,0 +1,190 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_ALIGNED_VECTOR3+#define EIGEN_ALIGNED_VECTOR3++#include <Eigen/Geometry>++namespace Eigen {++/**+ * \defgroup AlignedVector3_Module Aligned vector3 module+ *+ * \code+ * #include <unsupported/Eigen/AlignedVector3>+ * \endcode+ */+ //@{+++/** \class AlignedVector3+ *+ * \brief A vectorization friendly 3D vector+ *+ * This class represents a 3D vector internally using a 4D vector+ * such that vectorization can be seamlessly enabled. Of course,+ * the same result can be achieved by directly using a 4D vector.+ * This class makes this process simpler.+ *+ */+// TODO specialize Cwise+template<typename _Scalar> class AlignedVector3;++namespace internal {+template<typename _Scalar> struct traits<AlignedVector3<_Scalar> >+ : traits<Matrix<_Scalar,3,1,0,4,1> >+{+};+}++template<typename _Scalar> class AlignedVector3+ : public MatrixBase<AlignedVector3<_Scalar> >+{+ typedef Matrix<_Scalar,4,1> CoeffType;+ CoeffType m_coeffs;+ public:++ typedef MatrixBase<AlignedVector3<_Scalar> > Base; + EIGEN_DENSE_PUBLIC_INTERFACE(AlignedVector3)+ using Base::operator*;++ inline Index rows() const { return 3; }+ inline Index cols() const { return 1; }++ inline const Scalar& coeff(Index row, Index col) const+ { return m_coeffs.coeff(row, col); }++ inline Scalar& coeffRef(Index row, Index col)+ { return m_coeffs.coeffRef(row, col); }++ inline const Scalar& coeff(Index index) const+ { return m_coeffs.coeff(index); }++ inline Scalar& coeffRef(Index index)+ { return m_coeffs.coeffRef(index);}+++ inline AlignedVector3(const Scalar& x, const Scalar& y, const Scalar& z)+ : m_coeffs(x, y, z, Scalar(0))+ {}++ inline AlignedVector3(const AlignedVector3& other)+ : Base(), m_coeffs(other.m_coeffs)+ {}++ template<typename XprType, int Size=XprType::SizeAtCompileTime>+ struct generic_assign_selector {};++ template<typename XprType> struct generic_assign_selector<XprType,4>+ {+ inline static void run(AlignedVector3& dest, const XprType& src)+ {+ dest.m_coeffs = src;+ }+ };++ template<typename XprType> struct generic_assign_selector<XprType,3>+ {+ inline static void run(AlignedVector3& dest, const XprType& src)+ {+ dest.m_coeffs.template head<3>() = src;+ dest.m_coeffs.w() = Scalar(0);+ }+ };++ template<typename Derived>+ inline explicit AlignedVector3(const MatrixBase<Derived>& other)+ {+ generic_assign_selector<Derived>::run(*this,other.derived());+ }++ inline AlignedVector3& operator=(const AlignedVector3& other)+ { m_coeffs = other.m_coeffs; return *this; }+++ inline AlignedVector3 operator+(const AlignedVector3& other) const+ { return AlignedVector3(m_coeffs + other.m_coeffs); }++ inline AlignedVector3& operator+=(const AlignedVector3& other)+ { m_coeffs += other.m_coeffs; return *this; }++ inline AlignedVector3 operator-(const AlignedVector3& other) const+ { return AlignedVector3(m_coeffs - other.m_coeffs); }++ inline AlignedVector3 operator-=(const AlignedVector3& other)+ { m_coeffs -= other.m_coeffs; return *this; }++ inline AlignedVector3 operator*(const Scalar& s) const+ { return AlignedVector3(m_coeffs * s); }++ inline friend AlignedVector3 operator*(const Scalar& s,const AlignedVector3& vec)+ { return AlignedVector3(s * vec.m_coeffs); }++ inline AlignedVector3& operator*=(const Scalar& s)+ { m_coeffs *= s; return *this; }++ inline AlignedVector3 operator/(const Scalar& s) const+ { return AlignedVector3(m_coeffs / s); }++ inline AlignedVector3& operator/=(const Scalar& s)+ { m_coeffs /= s; return *this; }++ inline Scalar dot(const AlignedVector3& other) const+ {+ eigen_assert(m_coeffs.w()==Scalar(0));+ eigen_assert(other.m_coeffs.w()==Scalar(0));+ return m_coeffs.dot(other.m_coeffs);+ }++ inline void normalize()+ {+ m_coeffs /= norm();+ }++ inline AlignedVector3 normalized()+ {+ return AlignedVector3(m_coeffs / norm());+ }++ inline Scalar sum() const+ {+ eigen_assert(m_coeffs.w()==Scalar(0));+ return m_coeffs.sum();+ }++ inline Scalar squaredNorm() const+ {+ eigen_assert(m_coeffs.w()==Scalar(0));+ return m_coeffs.squaredNorm();+ }++ inline Scalar norm() const+ {+ using std::sqrt;+ return sqrt(squaredNorm());+ }++ inline AlignedVector3 cross(const AlignedVector3& other) const+ {+ return AlignedVector3(m_coeffs.cross3(other.m_coeffs));+ }++ template<typename Derived>+ inline bool isApprox(const MatrixBase<Derived>& other, RealScalar eps=NumTraits<Scalar>::dummy_precision()) const+ {+ return m_coeffs.template head<3>().isApprox(other,eps);+ }+};++//@}++}++#endif // EIGEN_ALIGNED_VECTOR3
+ eigen3/unsupported/Eigen/ArpackSupport view
@@ -0,0 +1,31 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_ARPACKSUPPORT_MODULE_H+#define EIGEN_ARPACKSUPPORT_MODULE_H++#include <Eigen/Core>++#include <Eigen/src/Core/util/DisableStupidWarnings.h>++/** \defgroup ArpackSupport_Module Arpack support module+ *+ * This module provides a wrapper to Arpack, a library for sparse eigenvalue decomposition.+ *+ * \code+ * #include <Eigen/ArpackSupport>+ * \endcode+ */++#include <Eigen/SparseCholesky>+#include "src/Eigenvalues/ArpackSelfAdjointEigenSolver.h"++#include <Eigen/src/Core/util/ReenableStupidWarnings.h>++#endif // EIGEN_ARPACKSUPPORT_MODULE_H+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+ eigen3/unsupported/Eigen/AutoDiff view
@@ -0,0 +1,40 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_AUTODIFF_MODULE+#define EIGEN_AUTODIFF_MODULE++namespace Eigen {++/**+ * \defgroup AutoDiff_Module Auto Diff module+ *+ * This module features forward automatic differentation via a simple+ * templated scalar type wrapper AutoDiffScalar.+ *+ * Warning : this should NOT be confused with numerical differentiation, which+ * is a different method and has its own module in Eigen : \ref NumericalDiff_Module.+ *+ * \code+ * #include <unsupported/Eigen/AutoDiff>+ * \endcode+ */+//@{++}++#include "src/AutoDiff/AutoDiffScalar.h"+// #include "src/AutoDiff/AutoDiffVector.h"+#include "src/AutoDiff/AutoDiffJacobian.h"++namespace Eigen {+//@}+}++#endif // EIGEN_AUTODIFF_MODULE
+ eigen3/unsupported/Eigen/BVH view
@@ -0,0 +1,95 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Ilya Baran <ibaran@mit.edu>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_BVH_MODULE_H+#define EIGEN_BVH_MODULE_H++#include <Eigen/Core>+#include <Eigen/Geometry>+#include <Eigen/StdVector>+#include <algorithm>+#include <queue>++namespace Eigen {++/**+ * \defgroup BVH_Module BVH module+ * \brief This module provides generic bounding volume hierarchy algorithms+ * and reference tree implementations.+ *+ *+ * \code+ * #include <unsupported/Eigen/BVH>+ * \endcode+ *+ * A bounding volume hierarchy (BVH) can accelerate many geometric queries. This module provides a generic implementation+ * of the two basic algorithms over a BVH: intersection of a query object against all objects in the hierarchy and minimization+ * of a function over the objects in the hierarchy. It also provides intersection and minimization over a cartesian product of+ * two BVH's. A BVH accelerates intersection by using the fact that if a query object does not intersect a volume, then it cannot+ * intersect any object contained in that volume. Similarly, a BVH accelerates minimization because the minimum of a function+ * over a volume is no greater than the minimum of a function over any object contained in it.+ *+ * Some sample queries that can be written in terms of intersection are:+ * - Determine all points where a ray intersects a triangle mesh+ * - Given a set of points, determine which are contained in a query sphere+ * - Given a set of spheres, determine which contain the query point+ * - Given a set of disks, determine if any is completely contained in a query rectangle (represent each 2D disk as a point \f$(x,y,r)\f$+ * in 3D and represent the rectangle as a pyramid based on the original rectangle and shrinking in the \f$r\f$ direction)+ * - Given a set of points, count how many pairs are \f$d\pm\epsilon\f$ apart (done by looking at the cartesian product of the set+ * of points with itself)+ *+ * Some sample queries that can be written in terms of function minimization over a set of objects are:+ * - Find the intersection between a ray and a triangle mesh closest to the ray origin (function is infinite off the ray)+ * - Given a polyline and a query point, determine the closest point on the polyline to the query+ * - Find the diameter of a point cloud (done by looking at the cartesian product and using negative distance as the function)+ * - Determine how far two meshes are from colliding (this is also a cartesian product query)+ *+ * This implementation decouples the basic algorithms both from the type of hierarchy (and the types of the bounding volumes) and+ * from the particulars of the query. To enable abstraction from the BVH, the BVH is required to implement a generic mechanism+ * for traversal. To abstract from the query, the query is responsible for keeping track of results.+ *+ * To be used in the algorithms, a hierarchy must implement the following traversal mechanism (see KdBVH for a sample implementation): \code+ typedef Volume //the type of bounding volume+ typedef Object //the type of object in the hierarchy+ typedef Index //a reference to a node in the hierarchy--typically an int or a pointer+ typedef VolumeIterator //an iterator type over node children--returns Index+ typedef ObjectIterator //an iterator over object (leaf) children--returns const Object &+ Index getRootIndex() const //returns the index of the hierarchy root+ const Volume &getVolume(Index index) const //returns the bounding volume of the node at given index+ void getChildren(Index index, VolumeIterator &outVBegin, VolumeIterator &outVEnd,+ ObjectIterator &outOBegin, ObjectIterator &outOEnd) const+ //getChildren takes a node index and makes [outVBegin, outVEnd) range over its node children+ //and [outOBegin, outOEnd) range over its object children+ \endcode+ *+ * To use the hierarchy, call BVIntersect or BVMinimize, passing it a BVH (or two, for cartesian product) and a minimizer or intersector.+ * For an intersection query on a single BVH, the intersector encapsulates the query and must provide two functions:+ * \code+ bool intersectVolume(const Volume &volume) //returns true if the query intersects the volume+ bool intersectObject(const Object &object) //returns true if the intersection search should terminate immediately+ \endcode+ * The guarantee that BVIntersect provides is that intersectObject will be called on every object whose bounding volume+ * intersects the query (but possibly on other objects too) unless the search is terminated prematurely. It is the+ * responsibility of the intersectObject function to keep track of the results in whatever manner is appropriate.+ * The cartesian product intersection and the BVMinimize queries are similar--see their individual documentation.+ *+ * The following is a simple but complete example for how to use the BVH to accelerate the search for a closest red-blue point pair:+ * \include BVH_Example.cpp+ * Output: \verbinclude BVH_Example.out+ */+}++//@{++#include "src/BVH/BVAlgorithms.h"+#include "src/BVH/KdBVH.h"++//@}++#endif // EIGEN_BVH_MODULE_H
+ eigen3/unsupported/Eigen/CMakeLists.txt view
@@ -0,0 +1,11 @@+set(Eigen_HEADERS AdolcForward AlignedVector3 ArpackSupport AutoDiff BVH FFT IterativeSolvers KroneckerProduct LevenbergMarquardt+ MatrixFunctions MoreVectorization MPRealSupport NonLinearOptimization NumericalDiff OpenGLSupport Polynomials+ Skyline SparseExtra Splines+ )++install(FILES+ ${Eigen_HEADERS}+ DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen COMPONENT Devel+ )++add_subdirectory(src)
+ eigen3/unsupported/Eigen/FFT view
@@ -0,0 +1,418 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. +//+// Copyright (C) 2009 Mark Borgerding mark a borgerding net+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_FFT_H+#define EIGEN_FFT_H++#include <complex>+#include <vector>+#include <map>+#include <Eigen/Core>+++/**+ * \defgroup FFT_Module Fast Fourier Transform module+ *+ * \code+ * #include <unsupported/Eigen/FFT>+ * \endcode+ *+ * This module provides Fast Fourier transformation, with a configurable backend+ * implementation.+ *+ * The default implementation is based on kissfft. It is a small, free, and+ * reasonably efficient default.+ *+ * There are currently two implementation backend:+ *+ * - fftw (http://www.fftw.org) : faster, GPL -- incompatible with Eigen in LGPL form, bigger code size.+ * - MKL (http://en.wikipedia.org/wiki/Math_Kernel_Library) : fastest, commercial -- may be incompatible with Eigen in GPL form.+ *+ * \section FFTDesign Design+ *+ * The following design decisions were made concerning scaling and+ * half-spectrum for real FFT.+ *+ * The intent is to facilitate generic programming and ease migrating code+ * from Matlab/octave.+ * We think the default behavior of Eigen/FFT should favor correctness and+ * generality over speed. Of course, the caller should be able to "opt-out" from this+ * behavior and get the speed increase if they want it.+ *+ * 1) %Scaling:+ * Other libraries (FFTW,IMKL,KISSFFT) do not perform scaling, so there+ * is a constant gain incurred after the forward&inverse transforms , so + * IFFT(FFT(x)) = Kx; this is done to avoid a vector-by-value multiply. + * The downside is that algorithms that worked correctly in Matlab/octave + * don't behave the same way once implemented in C++.+ *+ * How Eigen/FFT differs: invertible scaling is performed so IFFT( FFT(x) ) = x. + *+ * 2) Real FFT half-spectrum+ * Other libraries use only half the frequency spectrum (plus one extra + * sample for the Nyquist bin) for a real FFT, the other half is the + * conjugate-symmetric of the first half. This saves them a copy and some + * memory. The downside is the caller needs to have special logic for the + * number of bins in complex vs real.+ *+ * How Eigen/FFT differs: The full spectrum is returned from the forward + * transform. This facilitates generic template programming by obviating + * separate specializations for real vs complex. On the inverse+ * transform, only half the spectrum is actually used if the output type is real.+ */+ ++#ifdef EIGEN_FFTW_DEFAULT+// FFTW: faster, GPL -- incompatible with Eigen in LGPL form, bigger code size+# include <fftw3.h>+# include "src/FFT/ei_fftw_impl.h"+ namespace Eigen {+ //template <typename T> typedef struct internal::fftw_impl default_fft_impl; this does not work+ template <typename T> struct default_fft_impl : public internal::fftw_impl<T> {};+ }+#elif defined EIGEN_MKL_DEFAULT+// TODO +// intel Math Kernel Library: fastest, commercial -- may be incompatible with Eigen in GPL form+# include "src/FFT/ei_imklfft_impl.h"+ namespace Eigen {+ template <typename T> struct default_fft_impl : public internal::imklfft_impl {};+ }+#else+// internal::kissfft_impl: small, free, reasonably efficient default, derived from kissfft+//+# include "src/FFT/ei_kissfft_impl.h"+ namespace Eigen {+ template <typename T> + struct default_fft_impl : public internal::kissfft_impl<T> {};+ }+#endif++namespace Eigen {++ +// +template<typename T_SrcMat,typename T_FftIfc> struct fft_fwd_proxy;+template<typename T_SrcMat,typename T_FftIfc> struct fft_inv_proxy;++namespace internal {+template<typename T_SrcMat,typename T_FftIfc>+struct traits< fft_fwd_proxy<T_SrcMat,T_FftIfc> >+{+ typedef typename T_SrcMat::PlainObject ReturnType;+};+template<typename T_SrcMat,typename T_FftIfc>+struct traits< fft_inv_proxy<T_SrcMat,T_FftIfc> >+{+ typedef typename T_SrcMat::PlainObject ReturnType;+};+}++template<typename T_SrcMat,typename T_FftIfc> +struct fft_fwd_proxy+ : public ReturnByValue<fft_fwd_proxy<T_SrcMat,T_FftIfc> >+{+ typedef DenseIndex Index;++ fft_fwd_proxy(const T_SrcMat& src,T_FftIfc & fft, Index nfft) : m_src(src),m_ifc(fft), m_nfft(nfft) {}++ template<typename T_DestMat> void evalTo(T_DestMat& dst) const;++ Index rows() const { return m_src.rows(); }+ Index cols() const { return m_src.cols(); }+protected:+ const T_SrcMat & m_src;+ T_FftIfc & m_ifc;+ Index m_nfft;+private:+ fft_fwd_proxy& operator=(const fft_fwd_proxy&);+};++template<typename T_SrcMat,typename T_FftIfc> +struct fft_inv_proxy+ : public ReturnByValue<fft_inv_proxy<T_SrcMat,T_FftIfc> >+{+ typedef DenseIndex Index;++ fft_inv_proxy(const T_SrcMat& src,T_FftIfc & fft, Index nfft) : m_src(src),m_ifc(fft), m_nfft(nfft) {}++ template<typename T_DestMat> void evalTo(T_DestMat& dst) const;++ Index rows() const { return m_src.rows(); }+ Index cols() const { return m_src.cols(); }+protected:+ const T_SrcMat & m_src;+ T_FftIfc & m_ifc;+ Index m_nfft;+private:+ fft_inv_proxy& operator=(const fft_inv_proxy&);+};+++template <typename T_Scalar,+ typename T_Impl=default_fft_impl<T_Scalar> >+class FFT+{+ public:+ typedef T_Impl impl_type;+ typedef DenseIndex Index;+ typedef typename impl_type::Scalar Scalar;+ typedef typename impl_type::Complex Complex;++ enum Flag {+ Default=0, // goof proof+ Unscaled=1,+ HalfSpectrum=2,+ // SomeOtherSpeedOptimization=4+ Speedy=32767+ };++ FFT( const impl_type & impl=impl_type() , Flag flags=Default ) :m_impl(impl),m_flag(flags) { }++ inline+ bool HasFlag(Flag f) const { return (m_flag & (int)f) == f;}++ inline+ void SetFlag(Flag f) { m_flag |= (int)f;}++ inline+ void ClearFlag(Flag f) { m_flag &= (~(int)f);}++ inline+ void fwd( Complex * dst, const Scalar * src, Index nfft)+ {+ m_impl.fwd(dst,src,static_cast<int>(nfft));+ if ( HasFlag(HalfSpectrum) == false)+ ReflectSpectrum(dst,nfft);+ }++ inline+ void fwd( Complex * dst, const Complex * src, Index nfft)+ {+ m_impl.fwd(dst,src,static_cast<int>(nfft));+ }++ /*+ inline + void fwd2(Complex * dst, const Complex * src, int n0,int n1)+ {+ m_impl.fwd2(dst,src,n0,n1);+ }+ */++ template <typename _Input>+ inline+ void fwd( std::vector<Complex> & dst, const std::vector<_Input> & src) + {+ if ( NumTraits<_Input>::IsComplex == 0 && HasFlag(HalfSpectrum) )+ dst.resize( (src.size()>>1)+1); // half the bins + Nyquist bin+ else+ dst.resize(src.size());+ fwd(&dst[0],&src[0],src.size());+ }++ template<typename InputDerived, typename ComplexDerived>+ inline+ void fwd( MatrixBase<ComplexDerived> & dst, const MatrixBase<InputDerived> & src, Index nfft=-1)+ {+ typedef typename ComplexDerived::Scalar dst_type;+ typedef typename InputDerived::Scalar src_type;+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(InputDerived)+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(ComplexDerived)+ EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(ComplexDerived,InputDerived) // size at compile-time+ EIGEN_STATIC_ASSERT((internal::is_same<dst_type, Complex>::value),+ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)+ EIGEN_STATIC_ASSERT(int(InputDerived::Flags)&int(ComplexDerived::Flags)&DirectAccessBit,+ THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES)++ if (nfft<1)+ nfft = src.size();++ if ( NumTraits< src_type >::IsComplex == 0 && HasFlag(HalfSpectrum) )+ dst.derived().resize( (nfft>>1)+1);+ else+ dst.derived().resize(nfft);++ if ( src.innerStride() != 1 || src.size() < nfft ) {+ Matrix<src_type,1,Dynamic> tmp;+ if (src.size()<nfft) {+ tmp.setZero(nfft);+ tmp.block(0,0,src.size(),1 ) = src;+ }else{+ tmp = src;+ }+ fwd( &dst[0],&tmp[0],nfft );+ }else{+ fwd( &dst[0],&src[0],nfft );+ }+ }+ + template<typename InputDerived>+ inline+ fft_fwd_proxy< MatrixBase<InputDerived>, FFT<T_Scalar,T_Impl> >+ fwd( const MatrixBase<InputDerived> & src, Index nfft=-1)+ {+ return fft_fwd_proxy< MatrixBase<InputDerived> ,FFT<T_Scalar,T_Impl> >( src, *this,nfft );+ }++ template<typename InputDerived>+ inline+ fft_inv_proxy< MatrixBase<InputDerived>, FFT<T_Scalar,T_Impl> >+ inv( const MatrixBase<InputDerived> & src, Index nfft=-1)+ {+ return fft_inv_proxy< MatrixBase<InputDerived> ,FFT<T_Scalar,T_Impl> >( src, *this,nfft );+ }++ inline+ void inv( Complex * dst, const Complex * src, Index nfft)+ {+ m_impl.inv( dst,src,static_cast<int>(nfft) );+ if ( HasFlag( Unscaled ) == false)+ scale(dst,Scalar(1./nfft),nfft); // scale the time series+ }++ inline+ void inv( Scalar * dst, const Complex * src, Index nfft)+ {+ m_impl.inv( dst,src,static_cast<int>(nfft) );+ if ( HasFlag( Unscaled ) == false)+ scale(dst,Scalar(1./nfft),nfft); // scale the time series+ }++ template<typename OutputDerived, typename ComplexDerived>+ inline+ void inv( MatrixBase<OutputDerived> & dst, const MatrixBase<ComplexDerived> & src, Index nfft=-1)+ {+ typedef typename ComplexDerived::Scalar src_type;+ typedef typename OutputDerived::Scalar dst_type;+ const bool realfft= (NumTraits<dst_type>::IsComplex == 0);+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(OutputDerived)+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(ComplexDerived)+ EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(ComplexDerived,OutputDerived) // size at compile-time+ EIGEN_STATIC_ASSERT((internal::is_same<src_type, Complex>::value),+ YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)+ EIGEN_STATIC_ASSERT(int(OutputDerived::Flags)&int(ComplexDerived::Flags)&DirectAccessBit,+ THIS_METHOD_IS_ONLY_FOR_EXPRESSIONS_WITH_DIRECT_MEMORY_ACCESS_SUCH_AS_MAP_OR_PLAIN_MATRICES)++ if (nfft<1) { //automatic FFT size determination+ if ( realfft && HasFlag(HalfSpectrum) ) + nfft = 2*(src.size()-1); //assume even fft size+ else+ nfft = src.size();+ }+ dst.derived().resize( nfft );++ // check for nfft that does not fit the input data size+ Index resize_input= ( realfft && HasFlag(HalfSpectrum) )+ ? ( (nfft/2+1) - src.size() )+ : ( nfft - src.size() );++ if ( src.innerStride() != 1 || resize_input ) {+ // if the vector is strided, then we need to copy it to a packed temporary+ Matrix<src_type,1,Dynamic> tmp;+ if ( resize_input ) {+ size_t ncopy = (std::min)(src.size(),src.size() + resize_input);+ tmp.setZero(src.size() + resize_input);+ if ( realfft && HasFlag(HalfSpectrum) ) {+ // pad at the Nyquist bin+ tmp.head(ncopy) = src.head(ncopy);+ tmp(ncopy-1) = real(tmp(ncopy-1)); // enforce real-only Nyquist bin+ }else{+ size_t nhead,ntail;+ nhead = 1+ncopy/2-1; // range [0:pi)+ ntail = ncopy/2-1; // range (-pi:0)+ tmp.head(nhead) = src.head(nhead);+ tmp.tail(ntail) = src.tail(ntail);+ if (resize_input<0) { //shrinking -- create the Nyquist bin as the average of the two bins that fold into it+ tmp(nhead) = ( src(nfft/2) + src( src.size() - nfft/2 ) )*src_type(.5);+ }else{ // expanding -- split the old Nyquist bin into two halves+ tmp(nhead) = src(nhead) * src_type(.5);+ tmp(tmp.size()-nhead) = tmp(nhead);+ }+ }+ }else{+ tmp = src;+ }+ inv( &dst[0],&tmp[0], nfft);+ }else{+ inv( &dst[0],&src[0], nfft);+ }+ }++ template <typename _Output>+ inline+ void inv( std::vector<_Output> & dst, const std::vector<Complex> & src,Index nfft=-1)+ {+ if (nfft<1)+ nfft = ( NumTraits<_Output>::IsComplex == 0 && HasFlag(HalfSpectrum) ) ? 2*(src.size()-1) : src.size();+ dst.resize( nfft );+ inv( &dst[0],&src[0],nfft);+ }+++ /*+ // TODO: multi-dimensional FFTs+ inline + void inv2(Complex * dst, const Complex * src, int n0,int n1)+ {+ m_impl.inv2(dst,src,n0,n1);+ if ( HasFlag( Unscaled ) == false)+ scale(dst,1./(n0*n1),n0*n1);+ }+ */++ inline+ impl_type & impl() {return m_impl;}+ private:++ template <typename T_Data>+ inline+ void scale(T_Data * x,Scalar s,Index nx)+ {+#if 1+ for (int k=0;k<nx;++k)+ *x++ *= s;+#else+ if ( ((ptrdiff_t)x) & 15 )+ Matrix<T_Data, Dynamic, 1>::Map(x,nx) *= s;+ else+ Matrix<T_Data, Dynamic, 1>::MapAligned(x,nx) *= s;+ //Matrix<T_Data, Dynamic, Dynamic>::Map(x,nx) * s;+#endif + }++ inline+ void ReflectSpectrum(Complex * freq, Index nfft)+ {+ // create the implicit right-half spectrum (conjugate-mirror of the left-half)+ Index nhbins=(nfft>>1)+1;+ for (Index k=nhbins;k < nfft; ++k )+ freq[k] = conj(freq[nfft-k]);+ }++ impl_type m_impl;+ int m_flag;+};++template<typename T_SrcMat,typename T_FftIfc> +template<typename T_DestMat> inline +void fft_fwd_proxy<T_SrcMat,T_FftIfc>::evalTo(T_DestMat& dst) const+{+ m_ifc.fwd( dst, m_src, m_nfft);+}++template<typename T_SrcMat,typename T_FftIfc> +template<typename T_DestMat> inline +void fft_inv_proxy<T_SrcMat,T_FftIfc>::evalTo(T_DestMat& dst) const+{+ m_ifc.inv( dst, m_src, m_nfft);+}++}+#endif+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+ eigen3/unsupported/Eigen/IterativeSolvers view
@@ -0,0 +1,45 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_ITERATIVE_SOLVERS_MODULE_H+#define EIGEN_ITERATIVE_SOLVERS_MODULE_H++#include <Eigen/Sparse>++/**+ * \defgroup IterativeSolvers_Module Iterative solvers module+ * This module aims to provide various iterative linear and non linear solver algorithms.+ * It currently provides:+ * - a constrained conjugate gradient+ * - a Householder GMRES implementation+ * \code+ * #include <unsupported/Eigen/IterativeSolvers>+ * \endcode+ */+//@{++#include "../../Eigen/src/misc/Solve.h"+#include "../../Eigen/src/misc/SparseSolve.h"++#ifndef EIGEN_MPL2_ONLY+#include "src/IterativeSolvers/IterationController.h"+#include "src/IterativeSolvers/ConstrainedConjGrad.h"+#endif++#include "src/IterativeSolvers/IncompleteLU.h"+#include "../../Eigen/Jacobi"+#include "../../Eigen/Householder"+#include "src/IterativeSolvers/GMRES.h"+#include "src/IterativeSolvers/IncompleteCholesky.h"+//#include "src/IterativeSolvers/SSORPreconditioner.h"+#include "src/IterativeSolvers/MINRES.h"++//@}++#endif // EIGEN_ITERATIVE_SOLVERS_MODULE_H
+ eigen3/unsupported/Eigen/KroneckerProduct view
@@ -0,0 +1,34 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_KRONECKER_PRODUCT_MODULE_H+#define EIGEN_KRONECKER_PRODUCT_MODULE_H++#include "../../Eigen/Core"++#include "../../Eigen/src/Core/util/DisableStupidWarnings.h"++namespace Eigen {++/**+ * \defgroup KroneckerProduct_Module KroneckerProduct module+ *+ * This module contains an experimental Kronecker product implementation.+ *+ * \code+ * #include <Eigen/KroneckerProduct>+ * \endcode+ */++} // namespace Eigen++#include "src/KroneckerProduct/KroneckerTensorProduct.h"++#include "../../Eigen/src/Core/util/ReenableStupidWarnings.h"++#endif // EIGEN_KRONECKER_PRODUCT_MODULE_H
+ eigen3/unsupported/Eigen/LevenbergMarquardt view
@@ -0,0 +1,45 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_LEVENBERGMARQUARDT_MODULE+#define EIGEN_LEVENBERGMARQUARDT_MODULE++// #include <vector>++#include <Eigen/Core>+#include <Eigen/Jacobi>+#include <Eigen/QR>+#include <unsupported/Eigen/NumericalDiff> ++#include <Eigen/SparseQR>++/**+ * \defgroup LevenbergMarquardt_Module Levenberg-Marquardt module+ *+ * \code+ * #include </Eigen/LevenbergMarquardt>+ * \endcode+ *+ * + */++#include "Eigen/SparseCore"+#ifndef EIGEN_PARSED_BY_DOXYGEN++#include "src/LevenbergMarquardt/LMqrsolv.h"+#include "src/LevenbergMarquardt/LMcovar.h"+#include "src/LevenbergMarquardt/LMpar.h"++#endif++#include "src/LevenbergMarquardt/LevenbergMarquardt.h"+#include "src/LevenbergMarquardt/LMonestep.h"+++#endif // EIGEN_LEVENBERGMARQUARDT_MODULE
+ eigen3/unsupported/Eigen/MPRealSupport view
@@ -0,0 +1,203 @@+// This file is part of a joint effort between Eigen, a lightweight C++ template library+// for linear algebra, and MPFR C++, a C++ interface to MPFR library (http://www.holoborodko.com/pavel/)+//+// Copyright (C) 2010-2012 Pavel Holoborodko <pavel@holoborodko.com>+// Copyright (C) 2010 Konstantin Holoborodko <konstantin@holoborodko.com>+// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_MPREALSUPPORT_MODULE_H+#define EIGEN_MPREALSUPPORT_MODULE_H++#include <Eigen/Core>+#include <mpreal.h>++namespace Eigen {+ +/**+ * \defgroup MPRealSupport_Module MPFRC++ Support module+ * \code+ * #include <Eigen/MPRealSupport>+ * \endcode+ *+ * This module provides support for multi precision floating point numbers+ * via the <a href="http://www.holoborodko.com/pavel/mpfr">MPFR C++</a>+ * library which itself is built upon <a href="http://www.mpfr.org/">MPFR</a>/<a href="http://gmplib.org/">GMP</a>.+ *+ * You can find a copy of MPFR C++ that is known to be compatible in the unsupported/test/mpreal folder.+ *+ * Here is an example:+ *+\code+#include <iostream>+#include <Eigen/MPRealSupport>+#include <Eigen/LU>+using namespace mpfr;+using namespace Eigen;+int main()+{+ // set precision to 256 bits (double has only 53 bits)+ mpreal::set_default_prec(256);+ // Declare matrix and vector types with multi-precision scalar type+ typedef Matrix<mpreal,Dynamic,Dynamic> MatrixXmp;+ typedef Matrix<mpreal,Dynamic,1> VectorXmp;++ MatrixXmp A = MatrixXmp::Random(100,100);+ VectorXmp b = VectorXmp::Random(100);++ // Solve Ax=b using LU+ VectorXmp x = A.lu().solve(b);+ std::cout << "relative error: " << (A*x - b).norm() / b.norm() << std::endl;+ return 0;+}+\endcode+ *+ */+ + template<> struct NumTraits<mpfr::mpreal>+ : GenericNumTraits<mpfr::mpreal>+ {+ enum {+ IsInteger = 0,+ IsSigned = 1,+ IsComplex = 0,+ RequireInitialization = 1,+ ReadCost = 10,+ AddCost = 10,+ MulCost = 40+ };++ typedef mpfr::mpreal Real;+ typedef mpfr::mpreal NonInteger;+ + inline static Real highest (long Precision = mpfr::mpreal::get_default_prec()) { return mpfr::maxval(Precision); }+ inline static Real lowest (long Precision = mpfr::mpreal::get_default_prec()) { return -mpfr::maxval(Precision); }++ // Constants+ inline static Real Pi (long Precision = mpfr::mpreal::get_default_prec()) { return mpfr::const_pi(Precision); }+ inline static Real Euler (long Precision = mpfr::mpreal::get_default_prec()) { return mpfr::const_euler(Precision); }+ inline static Real Log2 (long Precision = mpfr::mpreal::get_default_prec()) { return mpfr::const_log2(Precision); }+ inline static Real Catalan (long Precision = mpfr::mpreal::get_default_prec()) { return mpfr::const_catalan(Precision); }++ inline static Real epsilon (long Precision = mpfr::mpreal::get_default_prec()) { return mpfr::machine_epsilon(Precision); }+ inline static Real epsilon (const Real& x) { return mpfr::machine_epsilon(x); }++ inline static Real dummy_precision() + { + unsigned int weak_prec = ((mpfr::mpreal::get_default_prec()-1) * 90) / 100;+ return mpfr::machine_epsilon(weak_prec);+ }+ };++ namespace internal {++ template<> inline mpfr::mpreal random<mpfr::mpreal>()+ {+ return mpfr::random();+ }++ template<> inline mpfr::mpreal random<mpfr::mpreal>(const mpfr::mpreal& a, const mpfr::mpreal& b)+ {+ return a + (b-a) * random<mpfr::mpreal>();+ }++ inline bool isMuchSmallerThan(const mpfr::mpreal& a, const mpfr::mpreal& b, const mpfr::mpreal& eps)+ {+ return mpfr::abs(a) <= mpfr::abs(b) * eps;+ }++ inline bool isApprox(const mpfr::mpreal& a, const mpfr::mpreal& b, const mpfr::mpreal& eps)+ {+ return mpfr::isEqualFuzzy(a,b,eps);+ }++ inline bool isApproxOrLessThan(const mpfr::mpreal& a, const mpfr::mpreal& b, const mpfr::mpreal& eps)+ {+ return a <= b || mpfr::isEqualFuzzy(a,b,eps);+ }++ template<> inline long double cast<mpfr::mpreal,long double>(const mpfr::mpreal& x)+ { return x.toLDouble(); }++ template<> inline double cast<mpfr::mpreal,double>(const mpfr::mpreal& x)+ { return x.toDouble(); }++ template<> inline long cast<mpfr::mpreal,long>(const mpfr::mpreal& x)+ { return x.toLong(); }++ template<> inline int cast<mpfr::mpreal,int>(const mpfr::mpreal& x)+ { return int(x.toLong()); }++ // Specialize GEBP kernel and traits for mpreal (no need for peeling, nor complicated stuff)+ // This also permits to directly call mpfr's routines and avoid many temporaries produced by mpreal+ template<>+ class gebp_traits<mpfr::mpreal, mpfr::mpreal, false, false>+ {+ public:+ typedef mpfr::mpreal ResScalar;+ enum {+ nr = 2, // must be 2 for proper packing...+ mr = 1,+ WorkSpaceFactor = nr,+ LhsProgress = 1,+ RhsProgress = 1+ };+ };++ template<typename Index, int mr, int nr, bool ConjugateLhs, bool ConjugateRhs>+ struct gebp_kernel<mpfr::mpreal,mpfr::mpreal,Index,mr,nr,ConjugateLhs,ConjugateRhs>+ {+ typedef mpfr::mpreal mpreal;++ EIGEN_DONT_INLINE+ void operator()(mpreal* res, Index resStride, const mpreal* blockA, const mpreal* blockB, Index rows, Index depth, Index cols, mpreal alpha,+ Index strideA=-1, Index strideB=-1, Index offsetA=0, Index offsetB=0, mpreal* /*unpackedB*/ = 0)+ {+ mpreal acc1, acc2, tmp;+ + if(strideA==-1) strideA = depth;+ if(strideB==-1) strideB = depth;++ for(Index j=0; j<cols; j+=nr)+ {+ Index actual_nr = (std::min<Index>)(nr,cols-j);+ mpreal *C1 = res + j*resStride;+ mpreal *C2 = res + (j+1)*resStride;+ for(Index i=0; i<rows; i++)+ {+ mpreal *B = const_cast<mpreal*>(blockB) + j*strideB + offsetB*actual_nr;+ mpreal *A = const_cast<mpreal*>(blockA) + i*strideA + offsetA;+ acc1 = 0;+ acc2 = 0;+ for(Index k=0; k<depth; k++)+ {+ mpfr_mul(tmp.mpfr_ptr(), A[k].mpfr_ptr(), B[0].mpfr_ptr(), mpreal::get_default_rnd());+ mpfr_add(acc1.mpfr_ptr(), acc1.mpfr_ptr(), tmp.mpfr_ptr(), mpreal::get_default_rnd());+ + if(actual_nr==2) {+ mpfr_mul(tmp.mpfr_ptr(), A[k].mpfr_ptr(), B[1].mpfr_ptr(), mpreal::get_default_rnd());+ mpfr_add(acc2.mpfr_ptr(), acc2.mpfr_ptr(), tmp.mpfr_ptr(), mpreal::get_default_rnd());+ }+ + B+=actual_nr;+ }+ + mpfr_mul(acc1.mpfr_ptr(), acc1.mpfr_ptr(), alpha.mpfr_ptr(), mpreal::get_default_rnd());+ mpfr_add(C1[i].mpfr_ptr(), C1[i].mpfr_ptr(), acc1.mpfr_ptr(), mpreal::get_default_rnd());+ + if(actual_nr==2) {+ mpfr_mul(acc2.mpfr_ptr(), acc2.mpfr_ptr(), alpha.mpfr_ptr(), mpreal::get_default_rnd());+ mpfr_add(C2[i].mpfr_ptr(), C2[i].mpfr_ptr(), acc2.mpfr_ptr(), mpreal::get_default_rnd());+ }+ }+ }+ }+ };++ } // end namespace internal+}++#endif // EIGEN_MPREALSUPPORT_MODULE_H
+ eigen3/unsupported/Eigen/MatrixFunctions view
@@ -0,0 +1,447 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Jitse Niesen <jitse@maths.leeds.ac.uk>+// Copyright (C) 2012 Chen-Pang He <jdh8@ms63.hinet.net>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_MATRIX_FUNCTIONS+#define EIGEN_MATRIX_FUNCTIONS++#include <cfloat>+#include <list>+#include <functional>+#include <iterator>++#include <Eigen/Core>+#include <Eigen/LU>+#include <Eigen/Eigenvalues>++/**+ * \defgroup MatrixFunctions_Module Matrix functions module+ * \brief This module aims to provide various methods for the computation of+ * matrix functions. + *+ * To use this module, add + * \code+ * #include <unsupported/Eigen/MatrixFunctions>+ * \endcode+ * at the start of your source file.+ *+ * This module defines the following MatrixBase methods.+ * - \ref matrixbase_cos "MatrixBase::cos()", for computing the matrix cosine+ * - \ref matrixbase_cosh "MatrixBase::cosh()", for computing the matrix hyperbolic cosine+ * - \ref matrixbase_exp "MatrixBase::exp()", for computing the matrix exponential+ * - \ref matrixbase_log "MatrixBase::log()", for computing the matrix logarithm+ * - \ref matrixbase_pow "MatrixBase::pow()", for computing the matrix power+ * - \ref matrixbase_matrixfunction "MatrixBase::matrixFunction()", for computing general matrix functions+ * - \ref matrixbase_sin "MatrixBase::sin()", for computing the matrix sine+ * - \ref matrixbase_sinh "MatrixBase::sinh()", for computing the matrix hyperbolic sine+ * - \ref matrixbase_sqrt "MatrixBase::sqrt()", for computing the matrix square root+ *+ * These methods are the main entry points to this module. + *+ * %Matrix functions are defined as follows. Suppose that \f$ f \f$+ * is an entire function (that is, a function on the complex plane+ * that is everywhere complex differentiable). Then its Taylor+ * series+ * \f[ f(0) + f'(0) x + \frac{f''(0)}{2} x^2 + \frac{f'''(0)}{3!} x^3 + \cdots \f]+ * converges to \f$ f(x) \f$. In this case, we can define the matrix+ * function by the same series:+ * \f[ f(M) = f(0) + f'(0) M + \frac{f''(0)}{2} M^2 + \frac{f'''(0)}{3!} M^3 + \cdots \f]+ *+ */++#include "src/MatrixFunctions/MatrixExponential.h"+#include "src/MatrixFunctions/MatrixFunction.h"+#include "src/MatrixFunctions/MatrixSquareRoot.h"+#include "src/MatrixFunctions/MatrixLogarithm.h"+#include "src/MatrixFunctions/MatrixPower.h"+++/** +\page matrixbaseextra_page+\ingroup MatrixFunctions_Module++\section matrixbaseextra MatrixBase methods defined in the MatrixFunctions module++The remainder of the page documents the following MatrixBase methods+which are defined in the MatrixFunctions module.++++\subsection matrixbase_cos MatrixBase::cos()++Compute the matrix cosine.++\code+const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::cos() const+\endcode++\param[in] M a square matrix.+\returns expression representing \f$ \cos(M) \f$.++This function calls \ref matrixbase_matrixfunction "matrixFunction()" with StdStemFunctions::cos().++\sa \ref matrixbase_sin "sin()" for an example.++++\subsection matrixbase_cosh MatrixBase::cosh()++Compute the matrix hyberbolic cosine.++\code+const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::cosh() const+\endcode++\param[in] M a square matrix.+\returns expression representing \f$ \cosh(M) \f$++This function calls \ref matrixbase_matrixfunction "matrixFunction()" with StdStemFunctions::cosh().++\sa \ref matrixbase_sinh "sinh()" for an example.++++\subsection matrixbase_exp MatrixBase::exp()++Compute the matrix exponential.++\code+const MatrixExponentialReturnValue<Derived> MatrixBase<Derived>::exp() const+\endcode++\param[in] M matrix whose exponential is to be computed.+\returns expression representing the matrix exponential of \p M.++The matrix exponential of \f$ M \f$ is defined by+\f[ \exp(M) = \sum_{k=0}^\infty \frac{M^k}{k!}. \f]+The matrix exponential can be used to solve linear ordinary+differential equations: the solution of \f$ y' = My \f$ with the+initial condition \f$ y(0) = y_0 \f$ is given by+\f$ y(t) = \exp(M) y_0 \f$.++The cost of the computation is approximately \f$ 20 n^3 \f$ for+matrices of size \f$ n \f$. The number 20 depends weakly on the+norm of the matrix.++The matrix exponential is computed using the scaling-and-squaring+method combined with Padé approximation. The matrix is first+rescaled, then the exponential of the reduced matrix is computed+approximant, and then the rescaling is undone by repeated+squaring. The degree of the Padé approximant is chosen such+that the approximation error is less than the round-off+error. However, errors may accumulate during the squaring phase.++Details of the algorithm can be found in: Nicholas J. Higham, "The+scaling and squaring method for the matrix exponential revisited,"+<em>SIAM J. %Matrix Anal. Applic.</em>, <b>26</b>:1179–1193,+2005.++Example: The following program checks that+\f[ \exp \left[ \begin{array}{ccc}+ 0 & \frac14\pi & 0 \\+ -\frac14\pi & 0 & 0 \\+ 0 & 0 & 0+ \end{array} \right] = \left[ \begin{array}{ccc}+ \frac12\sqrt2 & -\frac12\sqrt2 & 0 \\+ \frac12\sqrt2 & \frac12\sqrt2 & 0 \\+ 0 & 0 & 1+ \end{array} \right]. \f]+This corresponds to a rotation of \f$ \frac14\pi \f$ radians around+the z-axis.++\include MatrixExponential.cpp+Output: \verbinclude MatrixExponential.out++\note \p M has to be a matrix of \c float, \c double, \c long double+\c complex<float>, \c complex<double>, or \c complex<long double> .+++\subsection matrixbase_log MatrixBase::log()++Compute the matrix logarithm.++\code+const MatrixLogarithmReturnValue<Derived> MatrixBase<Derived>::log() const+\endcode++\param[in] M invertible matrix whose logarithm is to be computed.+\returns expression representing the matrix logarithm root of \p M.++The matrix logarithm of \f$ M \f$ is a matrix \f$ X \f$ such that +\f$ \exp(X) = M \f$ where exp denotes the matrix exponential. As for+the scalar logarithm, the equation \f$ \exp(X) = M \f$ may have+multiple solutions; this function returns a matrix whose eigenvalues+have imaginary part in the interval \f$ (-\pi,\pi] \f$.++In the real case, the matrix \f$ M \f$ should be invertible and+it should have no eigenvalues which are real and negative (pairs of+complex conjugate eigenvalues are allowed). In the complex case, it+only needs to be invertible.++This function computes the matrix logarithm using the Schur-Parlett+algorithm as implemented by MatrixBase::matrixFunction(). The+logarithm of an atomic block is computed by MatrixLogarithmAtomic,+which uses direct computation for 1-by-1 and 2-by-2 blocks and an+inverse scaling-and-squaring algorithm for bigger blocks, with the+square roots computed by MatrixBase::sqrt().++Details of the algorithm can be found in Section 11.6.2 of:+Nicholas J. Higham,+<em>Functions of Matrices: Theory and Computation</em>,+SIAM 2008. ISBN 978-0-898716-46-7.++Example: The following program checks that+\f[ \log \left[ \begin{array}{ccc} + \frac12\sqrt2 & -\frac12\sqrt2 & 0 \\+ \frac12\sqrt2 & \frac12\sqrt2 & 0 \\+ 0 & 0 & 1+ \end{array} \right] = \left[ \begin{array}{ccc}+ 0 & \frac14\pi & 0 \\ + -\frac14\pi & 0 & 0 \\+ 0 & 0 & 0 + \end{array} \right]. \f]+This corresponds to a rotation of \f$ \frac14\pi \f$ radians around+the z-axis. This is the inverse of the example used in the+documentation of \ref matrixbase_exp "exp()".++\include MatrixLogarithm.cpp+Output: \verbinclude MatrixLogarithm.out++\note \p M has to be a matrix of \c float, \c double, <tt>long+double</tt>, \c complex<float>, \c complex<double>, or \c complex<long+double> .++\sa MatrixBase::exp(), MatrixBase::matrixFunction(), + class MatrixLogarithmAtomic, MatrixBase::sqrt().+++\subsection matrixbase_pow MatrixBase::pow()++Compute the matrix raised to arbitrary real power.++\code+const MatrixPowerReturnValue<Derived> MatrixBase<Derived>::pow(RealScalar p) const+\endcode++\param[in] M base of the matrix power, should be a square matrix.+\param[in] p exponent of the matrix power, should be real.++The matrix power \f$ M^p \f$ is defined as \f$ \exp(p \log(M)) \f$,+where exp denotes the matrix exponential, and log denotes the matrix+logarithm.++The matrix \f$ M \f$ should meet the conditions to be an argument of+matrix logarithm. If \p p is not of the real scalar type of \p M, it+is casted into the real scalar type of \p M.++This function computes the matrix power using the Schur-Padé+algorithm as implemented by class MatrixPower. The exponent is split+into integral part and fractional part, where the fractional part is+in the interval \f$ (-1, 1) \f$. The main diagonal and the first+super-diagonal is directly computed.++Details of the algorithm can be found in: Nicholas J. Higham and+Lijing Lin, "A Schur-Padé algorithm for fractional powers of a+matrix," <em>SIAM J. %Matrix Anal. Applic.</em>,+<b>32(3)</b>:1056–1078, 2011.++Example: The following program checks that+\f[ \left[ \begin{array}{ccc}+ \cos1 & -\sin1 & 0 \\+ \sin1 & \cos1 & 0 \\+ 0 & 0 & 1+ \end{array} \right]^{\frac14\pi} = \left[ \begin{array}{ccc}+ \frac12\sqrt2 & -\frac12\sqrt2 & 0 \\+ \frac12\sqrt2 & \frac12\sqrt2 & 0 \\+ 0 & 0 & 1+ \end{array} \right]. \f]+This corresponds to \f$ \frac14\pi \f$ rotations of 1 radian around+the z-axis.++\include MatrixPower.cpp+Output: \verbinclude MatrixPower.out++MatrixBase::pow() is user-friendly. However, there are some+circumstances under which you should use class MatrixPower directly.+MatrixPower can save the result of Schur decomposition, so it's+better for computing various powers for the same matrix.++Example:+\include MatrixPower_optimal.cpp+Output: \verbinclude MatrixPower_optimal.out++\note \p M has to be a matrix of \c float, \c double, <tt>long+double</tt>, \c complex<float>, \c complex<double>, or \c complex<long+double> .++\sa MatrixBase::exp(), MatrixBase::log(), class MatrixPower.+++\subsection matrixbase_matrixfunction MatrixBase::matrixFunction()++Compute a matrix function.++\code+const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::matrixFunction(typename internal::stem_function<typename internal::traits<Derived>::Scalar>::type f) const+\endcode++\param[in] M argument of matrix function, should be a square matrix.+\param[in] f an entire function; \c f(x,n) should compute the n-th+derivative of f at x.+\returns expression representing \p f applied to \p M.++Suppose that \p M is a matrix whose entries have type \c Scalar. +Then, the second argument, \p f, should be a function with prototype+\code +ComplexScalar f(ComplexScalar, int) +\endcode+where \c ComplexScalar = \c std::complex<Scalar> if \c Scalar is+real (e.g., \c float or \c double) and \c ComplexScalar =+\c Scalar if \c Scalar is complex. The return value of \c f(x,n)+should be \f$ f^{(n)}(x) \f$, the n-th derivative of f at x.++This routine uses the algorithm described in:+Philip Davies and Nicholas J. Higham, +"A Schur-Parlett algorithm for computing matrix functions", +<em>SIAM J. %Matrix Anal. Applic.</em>, <b>25</b>:464–485, 2003.++The actual work is done by the MatrixFunction class.++Example: The following program checks that+\f[ \exp \left[ \begin{array}{ccc} + 0 & \frac14\pi & 0 \\ + -\frac14\pi & 0 & 0 \\+ 0 & 0 & 0 + \end{array} \right] = \left[ \begin{array}{ccc}+ \frac12\sqrt2 & -\frac12\sqrt2 & 0 \\+ \frac12\sqrt2 & \frac12\sqrt2 & 0 \\+ 0 & 0 & 1+ \end{array} \right]. \f]+This corresponds to a rotation of \f$ \frac14\pi \f$ radians around+the z-axis. This is the same example as used in the documentation+of \ref matrixbase_exp "exp()".++\include MatrixFunction.cpp+Output: \verbinclude MatrixFunction.out++Note that the function \c expfn is defined for complex numbers +\c x, even though the matrix \c A is over the reals. Instead of+\c expfn, we could also have used StdStemFunctions::exp:+\code+A.matrixFunction(StdStemFunctions<std::complex<double> >::exp, &B);+\endcode++++\subsection matrixbase_sin MatrixBase::sin()++Compute the matrix sine.++\code+const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::sin() const+\endcode++\param[in] M a square matrix.+\returns expression representing \f$ \sin(M) \f$.++This function calls \ref matrixbase_matrixfunction "matrixFunction()" with StdStemFunctions::sin().++Example: \include MatrixSine.cpp+Output: \verbinclude MatrixSine.out++++\subsection matrixbase_sinh MatrixBase::sinh()++Compute the matrix hyperbolic sine.++\code+MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::sinh() const+\endcode++\param[in] M a square matrix.+\returns expression representing \f$ \sinh(M) \f$++This function calls \ref matrixbase_matrixfunction "matrixFunction()" with StdStemFunctions::sinh().++Example: \include MatrixSinh.cpp+Output: \verbinclude MatrixSinh.out+++\subsection matrixbase_sqrt MatrixBase::sqrt()++Compute the matrix square root.++\code+const MatrixSquareRootReturnValue<Derived> MatrixBase<Derived>::sqrt() const+\endcode++\param[in] M invertible matrix whose square root is to be computed.+\returns expression representing the matrix square root of \p M.++The matrix square root of \f$ M \f$ is the matrix \f$ M^{1/2} \f$+whose square is the original matrix; so if \f$ S = M^{1/2} \f$ then+\f$ S^2 = M \f$. ++In the <b>real case</b>, the matrix \f$ M \f$ should be invertible and+it should have no eigenvalues which are real and negative (pairs of+complex conjugate eigenvalues are allowed). In that case, the matrix+has a square root which is also real, and this is the square root+computed by this function. ++The matrix square root is computed by first reducing the matrix to+quasi-triangular form with the real Schur decomposition. The square+root of the quasi-triangular matrix can then be computed directly. The+cost is approximately \f$ 25 n^3 \f$ real flops for the real Schur+decomposition and \f$ 3\frac13 n^3 \f$ real flops for the remainder+(though the computation time in practice is likely more than this+indicates).++Details of the algorithm can be found in: Nicholas J. Highan,+"Computing real square roots of a real matrix", <em>Linear Algebra+Appl.</em>, 88/89:405–430, 1987.++If the matrix is <b>positive-definite symmetric</b>, then the square+root is also positive-definite symmetric. In this case, it is best to+use SelfAdjointEigenSolver::operatorSqrt() to compute it.++In the <b>complex case</b>, the matrix \f$ M \f$ should be invertible;+this is a restriction of the algorithm. The square root computed by+this algorithm is the one whose eigenvalues have an argument in the+interval \f$ (-\frac12\pi, \frac12\pi] \f$. This is the usual branch+cut.++The computation is the same as in the real case, except that the+complex Schur decomposition is used to reduce the matrix to a+triangular matrix. The theoretical cost is the same. Details are in:+Åke Björck and Sven Hammarling, "A Schur method for the+square root of a matrix", <em>Linear Algebra Appl.</em>,+52/53:127–140, 1983.++Example: The following program checks that the square root of+\f[ \left[ \begin{array}{cc} + \cos(\frac13\pi) & -\sin(\frac13\pi) \\+ \sin(\frac13\pi) & \cos(\frac13\pi)+ \end{array} \right], \f]+corresponding to a rotation over 60 degrees, is a rotation over 30 degrees:+\f[ \left[ \begin{array}{cc} + \cos(\frac16\pi) & -\sin(\frac16\pi) \\+ \sin(\frac16\pi) & \cos(\frac16\pi)+ \end{array} \right]. \f]++\include MatrixSquareRoot.cpp+Output: \verbinclude MatrixSquareRoot.out++\sa class RealSchur, class ComplexSchur, class MatrixSquareRoot,+ SelfAdjointEigenSolver::operatorSqrt().++*/++#endif // EIGEN_MATRIX_FUNCTIONS+
+ eigen3/unsupported/Eigen/MoreVectorization view
@@ -0,0 +1,24 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_MOREVECTORIZATION_MODULE_H+#define EIGEN_MOREVECTORIZATION_MODULE_H++#include <Eigen/Core>++namespace Eigen {++/**+ * \defgroup MoreVectorization More vectorization module+ */++}++#include "src/MoreVectorization/MathFunctions.h"++#endif // EIGEN_MOREVECTORIZATION_MODULE_H
+ eigen3/unsupported/Eigen/NonLinearOptimization view
@@ -0,0 +1,134 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_NONLINEAROPTIMIZATION_MODULE+#define EIGEN_NONLINEAROPTIMIZATION_MODULE++#include <vector>++#include <Eigen/Core>+#include <Eigen/Jacobi>+#include <Eigen/QR>+#include <unsupported/Eigen/NumericalDiff>++/**+ * \defgroup NonLinearOptimization_Module Non linear optimization module+ *+ * \code+ * #include <unsupported/Eigen/NonLinearOptimization>+ * \endcode+ *+ * This module provides implementation of two important algorithms in non linear+ * optimization. In both cases, we consider a system of non linear functions. Of+ * course, this should work, and even work very well if those functions are+ * actually linear. But if this is so, you should probably better use other+ * methods more fitted to this special case.+ *+ * One algorithm allows to find an extremum of such a system (Levenberg+ * Marquardt algorithm) and the second one is used to find + * a zero for the system (Powell hybrid "dogleg" method).+ *+ * This code is a port of minpack (http://en.wikipedia.org/wiki/MINPACK).+ * Minpack is a very famous, old, robust and well-reknown package, written in + * fortran. Those implementations have been carefully tuned, tested, and used+ * for several decades.+ *+ * The original fortran code was automatically translated using f2c (http://en.wikipedia.org/wiki/F2c) in C,+ * then c++, and then cleaned by several different authors.+ * The last one of those cleanings being our starting point : + * http://devernay.free.fr/hacks/cminpack.html+ * + * Finally, we ported this code to Eigen, creating classes and API+ * coherent with Eigen. When possible, we switched to Eigen+ * implementation, such as most linear algebra (vectors, matrices, stable norms).+ *+ * Doing so, we were very careful to check the tests we setup at the very+ * beginning, which ensure that the same results are found.+ *+ * \section Tests Tests+ * + * The tests are placed in the file unsupported/test/NonLinear.cpp.+ * + * There are two kinds of tests : those that come from examples bundled with cminpack.+ * They guaranty we get the same results as the original algorithms (value for 'x',+ * for the number of evaluations of the function, and for the number of evaluations+ * of the jacobian if ever).+ * + * Other tests were added by myself at the very beginning of the + * process and check the results for levenberg-marquardt using the reference data + * on http://www.itl.nist.gov/div898/strd/nls/nls_main.shtml. Since then i've + * carefully checked that the same results were obtained when modifiying the + * code. Please note that we do not always get the exact same decimals as they do,+ * but this is ok : they use 128bits float, and we do the tests using the C type 'double',+ * which is 64 bits on most platforms (x86 and amd64, at least).+ * I've performed those tests on several other implementations of levenberg-marquardt, and+ * (c)minpack performs VERY well compared to those, both in accuracy and speed.+ * + * The documentation for running the tests is on the wiki+ * http://eigen.tuxfamily.org/index.php?title=Tests+ * + * \section API API : overview of methods+ * + * Both algorithms can use either the jacobian (provided by the user) or compute + * an approximation by themselves (actually using Eigen \ref NumericalDiff_Module).+ * The part of API referring to the latter use 'NumericalDiff' in the method names+ * (exemple: LevenbergMarquardt.minimizeNumericalDiff() ) + * + * The methods LevenbergMarquardt.lmder1()/lmdif1()/lmstr1() and + * HybridNonLinearSolver.hybrj1()/hybrd1() are specific methods from the original + * minpack package that you probably should NOT use until you are porting a code that+ * was previously using minpack. They just define a 'simple' API with default values + * for some parameters.+ * + * All algorithms are provided using Two APIs :+ * - one where the user inits the algorithm, and uses '*OneStep()' as much as he wants : + * this way the caller have control over the steps+ * - one where the user just calls a method (optimize() or solve()) which will + * handle the loop: init + loop until a stop condition is met. Those are provided for+ * convenience.+ * + * As an example, the method LevenbergMarquardt::minimize() is + * implemented as follow : + * \code+ * Status LevenbergMarquardt<FunctorType,Scalar>::minimize(FVectorType &x, const int mode)+ * {+ * Status status = minimizeInit(x, mode);+ * do {+ * status = minimizeOneStep(x, mode);+ * } while (status==Running);+ * return status;+ * }+ * \endcode+ * + * \section examples Examples+ * + * The easiest way to understand how to use this module is by looking at the many examples in the file+ * unsupported/test/NonLinearOptimization.cpp.+ */++#ifndef EIGEN_PARSED_BY_DOXYGEN++#include "src/NonLinearOptimization/qrsolv.h"+#include "src/NonLinearOptimization/r1updt.h"+#include "src/NonLinearOptimization/r1mpyq.h"+#include "src/NonLinearOptimization/rwupdt.h"+#include "src/NonLinearOptimization/fdjac1.h"+#include "src/NonLinearOptimization/lmpar.h"+#include "src/NonLinearOptimization/dogleg.h"+#include "src/NonLinearOptimization/covar.h"++#include "src/NonLinearOptimization/chkder.h"++#endif++#include "src/NonLinearOptimization/HybridNonLinearSolver.h"+#include "src/NonLinearOptimization/LevenbergMarquardt.h"+++#endif // EIGEN_NONLINEAROPTIMIZATION_MODULE
+ eigen3/unsupported/Eigen/NumericalDiff view
@@ -0,0 +1,56 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_NUMERICALDIFF_MODULE+#define EIGEN_NUMERICALDIFF_MODULE++#include <Eigen/Core>++namespace Eigen {++/**+ * \defgroup NumericalDiff_Module Numerical differentiation module+ *+ * \code+ * #include <unsupported/Eigen/NumericalDiff>+ * \endcode+ *+ * See http://en.wikipedia.org/wiki/Numerical_differentiation+ *+ * Warning : this should NOT be confused with automatic differentiation, which+ * is a different method and has its own module in Eigen : \ref+ * AutoDiff_Module.+ *+ * Currently only "Forward" and "Central" schemes are implemented. Those+ * are basic methods, and there exist some more elaborated way of+ * computing such approximates. They are implemented using both+ * proprietary and free software, and usually requires linking to an+ * external library. It is very easy for you to write a functor+ * using such software, and the purpose is quite orthogonal to what we+ * want to achieve with Eigen.+ *+ * This is why we will not provide wrappers for every great numerical+ * differentiation software that exist, but should rather stick with those+ * basic ones, that still are useful for testing.+ *+ * Also, the \ref NonLinearOptimization_Module needs this in order to+ * provide full features compatibility with the original (c)minpack+ * package.+ *+ */+}++//@{++#include "src/NumericalDiff/NumericalDiff.h"++//@}+++#endif // EIGEN_NUMERICALDIFF_MODULE
+ eigen3/unsupported/Eigen/OpenGLSupport view
@@ -0,0 +1,322 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_OPENGL_MODULE+#define EIGEN_OPENGL_MODULE++#include <Eigen/Geometry>++#if defined(__APPLE_CC__)+ #include <OpenGL/gl.h>+#else+ #include <GL/gl.h>+#endif++namespace Eigen {++/**+ * \defgroup OpenGLSUpport_Module OpenGL Support module+ *+ * This module provides wrapper functions for a couple of OpenGL functions+ * which simplify the way to pass Eigen's object to openGL.+ * Here is an exmaple:+ * + * \code+ * // You need to add path_to_eigen/unsupported to your include path.+ * #include <Eigen/OpenGLSupport>+ * // ...+ * Vector3f x, y;+ * Matrix3f rot;+ * + * glVertex(y + x * rot);+ * + * Quaternion q;+ * glRotate(q);+ * + * // ...+ * \endcode+ *+ */+//@{++#define EIGEN_GL_FUNC_DECLARATION(FUNC) \+namespace internal { \+ template< typename XprType, \+ typename Scalar = typename XprType::Scalar, \+ int Rows = XprType::RowsAtCompileTime, \+ int Cols = XprType::ColsAtCompileTime, \+ bool IsGLCompatible = bool(XprType::Flags&LinearAccessBit) \+ && bool(XprType::Flags&DirectAccessBit) \+ && (XprType::IsVectorAtCompileTime || (XprType::Flags&RowMajorBit)==0)> \+ struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl); \+ \+ template<typename XprType, typename Scalar, int Rows, int Cols> \+ struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType,Scalar,Rows,Cols,false> { \+ inline static void run(const XprType& p) { \+ EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<typename plain_matrix_type_column_major<XprType>::type>::run(p); } \+ }; \+} \+ \+template<typename Derived> inline void FUNC(const Eigen::DenseBase<Derived>& p) { \+ EIGEN_CAT(EIGEN_CAT(internal::gl_,FUNC),_impl)<Derived>::run(p.derived()); \+}+++#define EIGEN_GL_FUNC_SPECIALIZATION_MAT(FUNC,SCALAR,ROWS,COLS,SUFFIX) \+namespace internal { \+ template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, ROWS, COLS, true> { \+ inline static void run(const XprType& p) { FUNC##SUFFIX(p.data()); } \+ }; \+}++ +#define EIGEN_GL_FUNC_SPECIALIZATION_VEC(FUNC,SCALAR,SIZE,SUFFIX) \+namespace internal { \+ template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, SIZE, 1, true> { \+ inline static void run(const XprType& p) { FUNC##SUFFIX(p.data()); } \+ }; \+ template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, 1, SIZE, true> { \+ inline static void run(const XprType& p) { FUNC##SUFFIX(p.data()); } \+ }; \+}++ +EIGEN_GL_FUNC_DECLARATION (glVertex)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,int, 2,2iv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,short, 2,2sv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,float, 2,2fv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,double, 2,2dv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,int, 3,3iv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,short, 3,3sv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,float, 3,3fv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,double, 3,3dv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,int, 4,4iv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,short, 4,4sv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,float, 4,4fv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glVertex,double, 4,4dv)++EIGEN_GL_FUNC_DECLARATION (glTexCoord)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,int, 2,2iv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,short, 2,2sv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,float, 2,2fv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,double, 2,2dv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,int, 3,3iv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,short, 3,3sv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,float, 3,3fv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,double, 3,3dv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,int, 4,4iv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,short, 4,4sv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,float, 4,4fv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTexCoord,double, 4,4dv)++EIGEN_GL_FUNC_DECLARATION (glColor)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,int, 2,2iv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,short, 2,2sv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,float, 2,2fv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,double, 2,2dv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,int, 3,3iv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,short, 3,3sv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,float, 3,3fv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,double, 3,3dv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,int, 4,4iv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,short, 4,4sv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,float, 4,4fv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glColor,double, 4,4dv)++EIGEN_GL_FUNC_DECLARATION (glNormal)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,int, 3,3iv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,short, 3,3sv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,float, 3,3fv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glNormal,double, 3,3dv)++inline void glScale2fv(const float* v) { glScalef(v[0], v[1], 1.f); }+inline void glScale2dv(const double* v) { glScaled(v[0], v[1], 1.0); }+inline void glScale3fv(const float* v) { glScalef(v[0], v[1], v[2]); }+inline void glScale3dv(const double* v) { glScaled(v[0], v[1], v[2]); }++EIGEN_GL_FUNC_DECLARATION (glScale)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,float, 2,2fv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,double, 2,2dv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,float, 3,3fv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glScale,double, 3,3dv)++template<typename Scalar> void glScale(const UniformScaling<Scalar>& s) { glScale(Matrix<Scalar,3,1>::Constant(s.factor())); }++inline void glTranslate2fv(const float* v) { glTranslatef(v[0], v[1], 0.f); }+inline void glTranslate2dv(const double* v) { glTranslated(v[0], v[1], 0.0); }+inline void glTranslate3fv(const float* v) { glTranslatef(v[0], v[1], v[2]); }+inline void glTranslate3dv(const double* v) { glTranslated(v[0], v[1], v[2]); }++EIGEN_GL_FUNC_DECLARATION (glTranslate)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,float, 2,2fv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,double, 2,2dv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,float, 3,3fv)+EIGEN_GL_FUNC_SPECIALIZATION_VEC(glTranslate,double, 3,3dv)++template<typename Scalar> void glTranslate(const Translation<Scalar,2>& t) { glTranslate(t.vector()); }+template<typename Scalar> void glTranslate(const Translation<Scalar,3>& t) { glTranslate(t.vector()); }++EIGEN_GL_FUNC_DECLARATION (glMultMatrix)+EIGEN_GL_FUNC_SPECIALIZATION_MAT(glMultMatrix,float, 4,4,f)+EIGEN_GL_FUNC_SPECIALIZATION_MAT(glMultMatrix,double, 4,4,d)++template<typename Scalar> void glMultMatrix(const Transform<Scalar,3,Affine>& t) { glMultMatrix(t.matrix()); }+template<typename Scalar> void glMultMatrix(const Transform<Scalar,3,Projective>& t) { glMultMatrix(t.matrix()); }+template<typename Scalar> void glMultMatrix(const Transform<Scalar,3,AffineCompact>& t) { glMultMatrix(Transform<Scalar,3,Affine>(t).matrix()); }++EIGEN_GL_FUNC_DECLARATION (glLoadMatrix)+EIGEN_GL_FUNC_SPECIALIZATION_MAT(glLoadMatrix,float, 4,4,f)+EIGEN_GL_FUNC_SPECIALIZATION_MAT(glLoadMatrix,double, 4,4,d)++template<typename Scalar> void glLoadMatrix(const Transform<Scalar,3,Affine>& t) { glLoadMatrix(t.matrix()); }+template<typename Scalar> void glLoadMatrix(const Transform<Scalar,3,Projective>& t) { glLoadMatrix(t.matrix()); }+template<typename Scalar> void glLoadMatrix(const Transform<Scalar,3,AffineCompact>& t) { glLoadMatrix(Transform<Scalar,3,Affine>(t).matrix()); }++inline void glRotate(const Rotation2D<float>& rot)+{+ glRotatef(rot.angle()*180.f/float(M_PI), 0.f, 0.f, 1.f);+}+inline void glRotate(const Rotation2D<double>& rot)+{+ glRotated(rot.angle()*180.0/M_PI, 0.0, 0.0, 1.0);+}++template<typename Derived> void glRotate(const RotationBase<Derived,3>& rot)+{ + Transform<typename Derived::Scalar,3,Projective> tr(rot);+ glMultMatrix(tr.matrix());+}++#define EIGEN_GL_MAKE_CONST_const const+#define EIGEN_GL_MAKE_CONST__ +#define EIGEN_GL_EVAL(X) X++#define EIGEN_GL_FUNC1_DECLARATION(FUNC,ARG1,CONST) \+namespace internal { \+ template< typename XprType, \+ typename Scalar = typename XprType::Scalar, \+ int Rows = XprType::RowsAtCompileTime, \+ int Cols = XprType::ColsAtCompileTime, \+ bool IsGLCompatible = bool(XprType::Flags&LinearAccessBit) \+ && bool(XprType::Flags&DirectAccessBit) \+ && (XprType::IsVectorAtCompileTime || (XprType::Flags&RowMajorBit)==0)> \+ struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl); \+ \+ template<typename XprType, typename Scalar, int Rows, int Cols> \+ struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType,Scalar,Rows,Cols,false> { \+ inline static void run(ARG1 a,EIGEN_GL_EVAL(EIGEN_GL_MAKE_CONST_##CONST) XprType& p) { \+ EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<typename plain_matrix_type_column_major<XprType>::type>::run(a,p); } \+ }; \+} \+ \+template<typename Derived> inline void FUNC(ARG1 a,EIGEN_GL_EVAL(EIGEN_GL_MAKE_CONST_##CONST) Eigen::DenseBase<Derived>& p) { \+ EIGEN_CAT(EIGEN_CAT(internal::gl_,FUNC),_impl)<Derived>::run(a,p.derived()); \+}+++#define EIGEN_GL_FUNC1_SPECIALIZATION_MAT(FUNC,ARG1,CONST,SCALAR,ROWS,COLS,SUFFIX) \+namespace internal { \+ template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, ROWS, COLS, true> { \+ inline static void run(ARG1 a, EIGEN_GL_EVAL(EIGEN_GL_MAKE_CONST_##CONST) XprType& p) { FUNC##SUFFIX(a,p.data()); } \+ }; \+}++ +#define EIGEN_GL_FUNC1_SPECIALIZATION_VEC(FUNC,ARG1,CONST,SCALAR,SIZE,SUFFIX) \+namespace internal { \+ template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, SIZE, 1, true> { \+ inline static void run(ARG1 a, EIGEN_GL_EVAL(EIGEN_GL_MAKE_CONST_##CONST) XprType& p) { FUNC##SUFFIX(a,p.data()); } \+ }; \+ template< typename XprType> struct EIGEN_CAT(EIGEN_CAT(gl_,FUNC),_impl)<XprType, SCALAR, 1, SIZE, true> { \+ inline static void run(ARG1 a, EIGEN_GL_EVAL(EIGEN_GL_MAKE_CONST_##CONST) XprType& p) { FUNC##SUFFIX(a,p.data()); } \+ }; \+}++EIGEN_GL_FUNC1_DECLARATION (glGet,GLenum,_)+EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glGet,GLenum,_,float, 4,4,Floatv)+EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glGet,GLenum,_,double, 4,4,Doublev)++// glUniform API++#ifdef GL_VERSION_2_0++inline void glUniform2fv_ei (GLint loc, const float* v) { glUniform2fv(loc,1,v); }+inline void glUniform2iv_ei (GLint loc, const int* v) { glUniform2iv(loc,1,v); }++inline void glUniform3fv_ei (GLint loc, const float* v) { glUniform3fv(loc,1,v); }+inline void glUniform3iv_ei (GLint loc, const int* v) { glUniform3iv(loc,1,v); }++inline void glUniform4fv_ei (GLint loc, const float* v) { glUniform4fv(loc,1,v); }+inline void glUniform4iv_ei (GLint loc, const int* v) { glUniform4iv(loc,1,v); }++inline void glUniformMatrix2fv_ei (GLint loc, const float* v) { glUniformMatrix2fv(loc,1,false,v); }+inline void glUniformMatrix3fv_ei (GLint loc, const float* v) { glUniformMatrix3fv(loc,1,false,v); }+inline void glUniformMatrix4fv_ei (GLint loc, const float* v) { glUniformMatrix4fv(loc,1,false,v); }+++EIGEN_GL_FUNC1_DECLARATION (glUniform,GLint,const)+EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,float, 2,2fv_ei)+EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,int, 2,2iv_ei)+EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,float, 3,3fv_ei)+EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,int, 3,3iv_ei)+EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,float, 4,4fv_ei)+EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,int, 4,4iv_ei)++EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 2,2,Matrix2fv_ei)+EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 3,3,Matrix3fv_ei)+EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 4,4,Matrix4fv_ei)++#endif++#ifdef GL_VERSION_2_1++static void glUniformMatrix2x3fv_ei(GLint loc, const float* v) { glUniformMatrix2x3fv(loc,1,false,v); }+static void glUniformMatrix3x2fv_ei(GLint loc, const float* v) { glUniformMatrix3x2fv(loc,1,false,v); }+static void glUniformMatrix2x4fv_ei(GLint loc, const float* v) { glUniformMatrix2x4fv(loc,1,false,v); }+static void glUniformMatrix4x2fv_ei(GLint loc, const float* v) { glUniformMatrix4x2fv(loc,1,false,v); }+static void glUniformMatrix3x4fv_ei(GLint loc, const float* v) { glUniformMatrix3x4fv(loc,1,false,v); }+static void glUniformMatrix4x3fv_ei(GLint loc, const float* v) { glUniformMatrix4x3fv(loc,1,false,v); }++EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 2,3,Matrix2x3fv_ei)+EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 3,2,Matrix3x2fv_ei)+EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 2,4,Matrix2x4fv_ei)+EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 4,2,Matrix4x2fv_ei)+EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 3,4,Matrix3x4fv_ei)+EIGEN_GL_FUNC1_SPECIALIZATION_MAT(glUniform,GLint,const,float, 4,3,Matrix4x3fv_ei)++#endif++#ifdef GL_VERSION_3_0++inline void glUniform2uiv_ei (GLint loc, const unsigned int* v) { glUniform2uiv(loc,1,v); }+inline void glUniform3uiv_ei (GLint loc, const unsigned int* v) { glUniform3uiv(loc,1,v); }+inline void glUniform4uiv_ei (GLint loc, const unsigned int* v) { glUniform4uiv(loc,1,v); }++EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,unsigned int, 2,2uiv_ei)+EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,unsigned int, 3,3uiv_ei)+EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,unsigned int, 4,4uiv_ei)++#endif++#ifdef GL_ARB_gpu_shader_fp64+inline void glUniform2dv_ei (GLint loc, const double* v) { glUniform2dv(loc,1,v); }+inline void glUniform3dv_ei (GLint loc, const double* v) { glUniform3dv(loc,1,v); }+inline void glUniform4dv_ei (GLint loc, const double* v) { glUniform4dv(loc,1,v); }++EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,double, 2,2dv_ei)+EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,double, 3,3dv_ei)+EIGEN_GL_FUNC1_SPECIALIZATION_VEC(glUniform,GLint,const,double, 4,4dv_ei)+#endif+++//@}++}++#endif // EIGEN_OPENGL_MODULE
+ eigen3/unsupported/Eigen/Polynomials view
@@ -0,0 +1,138 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_POLYNOMIALS_MODULE_H+#define EIGEN_POLYNOMIALS_MODULE_H++#include <Eigen/Core>++#include <Eigen/src/Core/util/DisableStupidWarnings.h>++#include <Eigen/Eigenvalues>++// Note that EIGEN_HIDE_HEAVY_CODE has to be defined per module+#if (defined EIGEN_EXTERN_INSTANTIATIONS) && (EIGEN_EXTERN_INSTANTIATIONS>=2)+ #ifndef EIGEN_HIDE_HEAVY_CODE+ #define EIGEN_HIDE_HEAVY_CODE+ #endif+#elif defined EIGEN_HIDE_HEAVY_CODE+ #undef EIGEN_HIDE_HEAVY_CODE+#endif++/**+ * \defgroup Polynomials_Module Polynomials module+ * \brief This module provides a QR based polynomial solver.+ *+ * To use this module, add+ * \code+ * #include <unsupported/Eigen/Polynomials>+ * \endcode+ * at the start of your source file.+ */++#include "src/Polynomials/PolynomialUtils.h"+#include "src/Polynomials/Companion.h"+#include "src/Polynomials/PolynomialSolver.h"++/**+ \page polynomials Polynomials defines functions for dealing with polynomials+ and a QR based polynomial solver.+ \ingroup Polynomials_Module++ The remainder of the page documents first the functions for evaluating, computing+ polynomials, computing estimates about polynomials and next the QR based polynomial+ solver.++ \section polynomialUtils convenient functions to deal with polynomials+ \subsection roots_to_monicPolynomial+ The function+ \code+ void roots_to_monicPolynomial( const RootVector& rv, Polynomial& poly )+ \endcode+ computes the coefficients \f$ a_i \f$ of++ \f$ p(x) = a_0 + a_{1}x + ... + a_{n-1}x^{n-1} + x^n \f$++ where \f$ p \f$ is known through its roots i.e. \f$ p(x) = (x-r_1)(x-r_2)...(x-r_n) \f$.++ \subsection poly_eval+ The function+ \code+ T poly_eval( const Polynomials& poly, const T& x )+ \endcode+ evaluates a polynomial at a given point using stabilized Hörner method.++ The following code: first computes the coefficients in the monomial basis of the monic polynomial that has the provided roots;+ then, it evaluates the computed polynomial, using a stabilized Hörner method.++ \include PolynomialUtils1.cpp+ Output: \verbinclude PolynomialUtils1.out++ \subsection Cauchy bounds+ The function+ \code+ Real cauchy_max_bound( const Polynomial& poly )+ \endcode+ provides a maximum bound (the Cauchy one: \f$C(p)\f$) for the absolute value of a root of the given polynomial i.e.+ \f$ \forall r_i \f$ root of \f$ p(x) = \sum_{k=0}^d a_k x^k \f$,+ \f$ |r_i| \le C(p) = \sum_{k=0}^{d} \left | \frac{a_k}{a_d} \right | \f$+ The leading coefficient \f$ p \f$: should be non zero \f$a_d \neq 0\f$.+++ The function+ \code+ Real cauchy_min_bound( const Polynomial& poly )+ \endcode+ provides a minimum bound (the Cauchy one: \f$c(p)\f$) for the absolute value of a non zero root of the given polynomial i.e.+ \f$ \forall r_i \neq 0 \f$ root of \f$ p(x) = \sum_{k=0}^d a_k x^k \f$,+ \f$ |r_i| \ge c(p) = \left( \sum_{k=0}^{d} \left | \frac{a_k}{a_0} \right | \right)^{-1} \f$+++++ \section QR polynomial solver class+ Computes the complex roots of a polynomial by computing the eigenvalues of the associated companion matrix with the QR algorithm.+ + The roots of \f$ p(x) = a_0 + a_1 x + a_2 x^2 + a_{3} x^3 + x^4 \f$ are the eigenvalues of+ \f$+ \left [+ \begin{array}{cccc}+ 0 & 0 & 0 & a_0 \\+ 1 & 0 & 0 & a_1 \\+ 0 & 1 & 0 & a_2 \\+ 0 & 0 & 1 & a_3+ \end{array} \right ]+ \f$++ However, the QR algorithm is not guaranteed to converge when there are several eigenvalues with same modulus.++ Therefore the current polynomial solver is guaranteed to provide a correct result only when the complex roots \f$r_1,r_2,...,r_d\f$ have distinct moduli i.e.+ + \f$ \forall i,j \in [1;d],~ \| r_i \| \neq \| r_j \| \f$.++ With 32bit (float) floating types this problem shows up frequently.+ However, almost always, correct accuracy is reached even in these cases for 64bit+ (double) floating types and small polynomial degree (<20).++ \include PolynomialSolver1.cpp+ + In the above example:+ + -# a simple use of the polynomial solver is shown;+ -# the accuracy problem with the QR algorithm is presented: a polynomial with almost conjugate roots is provided to the solver.+ Those roots have almost same module therefore the QR algorithm failed to converge: the accuracy+ of the last root is bad;+ -# a simple way to circumvent the problem is shown: use doubles instead of floats.++ Output: \verbinclude PolynomialSolver1.out+*/++#include <Eigen/src/Core/util/ReenableStupidWarnings.h>++#endif // EIGEN_POLYNOMIALS_MODULE_H+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+ eigen3/unsupported/Eigen/SVD view
@@ -0,0 +1,39 @@+#ifndef EIGEN_SVD_MODULE_H+#define EIGEN_SVD_MODULE_H++#include <Eigen/QR>+#include <Eigen/Householder>+#include <Eigen/Jacobi>++#include "../../Eigen/src/Core/util/DisableStupidWarnings.h"++/** \defgroup SVD_Module SVD module+ *+ *+ *+ * This module provides SVD decomposition for matrices (both real and complex).+ * This decomposition is accessible via the following MatrixBase method:+ * - MatrixBase::jacobiSvd()+ *+ * \code+ * #include <Eigen/SVD>+ * \endcode+ */++#include "../../Eigen/src/misc/Solve.h"+#include "../../Eigen/src/SVD/UpperBidiagonalization.h"+#include "src/SVD/SVDBase.h"+#include "src/SVD/JacobiSVD.h"+#include "src/SVD/BDCSVD.h"+#if defined(EIGEN_USE_LAPACKE) && !defined(EIGEN_USE_LAPACKE_STRICT)+#include "../../Eigen/src/SVD/JacobiSVD_MKL.h"+#endif++#ifdef EIGEN2_SUPPORT+#include "../../Eigen/src/Eigen2Support/SVD.h"+#endif++#include "../../Eigen/src/Core/util/ReenableStupidWarnings.h"++#endif // EIGEN_SVD_MODULE_H+/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+ eigen3/unsupported/Eigen/Skyline view
@@ -0,0 +1,39 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_SKYLINE_MODULE_H+#define EIGEN_SKYLINE_MODULE_H+++#include "Eigen/Core"++#include "Eigen/src/Core/util/DisableStupidWarnings.h"++#include <map>+#include <cstdlib>+#include <cstring>+#include <algorithm>++/**+ * \defgroup Skyline_Module Skyline module+ *+ *+ *+ *+ */++#include "src/Skyline/SkylineUtil.h"+#include "src/Skyline/SkylineMatrixBase.h"+#include "src/Skyline/SkylineStorage.h"+#include "src/Skyline/SkylineMatrix.h"+#include "src/Skyline/SkylineInplaceLU.h"+#include "src/Skyline/SkylineProduct.h"++#include "Eigen/src/Core/util/ReenableStupidWarnings.h"++#endif // EIGEN_SKYLINE_MODULE_H
+ eigen3/unsupported/Eigen/SparseExtra view
@@ -0,0 +1,56 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_SPARSE_EXTRA_MODULE_H+#define EIGEN_SPARSE_EXTRA_MODULE_H++#include "../../Eigen/Sparse"++#include "../../Eigen/src/Core/util/DisableStupidWarnings.h"++#include <vector>+#include <map>+#include <cstdlib>+#include <cstring>+#include <algorithm>+#include <fstream>+#include <sstream>++#ifdef EIGEN_GOOGLEHASH_SUPPORT+ #include <google/dense_hash_map>+#endif++/**+ * \defgroup SparseExtra_Module SparseExtra module+ *+ * This module contains some experimental features extending the sparse module.+ *+ * \code+ * #include <Eigen/SparseExtra>+ * \endcode+ */+++#include "../../Eigen/src/misc/Solve.h"+#include "../../Eigen/src/misc/SparseSolve.h"++#include "src/SparseExtra/DynamicSparseMatrix.h"+#include "src/SparseExtra/BlockOfDynamicSparseMatrix.h"+#include "src/SparseExtra/RandomSetter.h"++#include "src/SparseExtra/MarketIO.h"++#if !defined(_WIN32)+#include <dirent.h>+#include "src/SparseExtra/MatrixMarketIterator.h"+#endif++#include "../../Eigen/src/Core/util/ReenableStupidWarnings.h"++#endif // EIGEN_SPARSE_EXTRA_MODULE_H
+ eigen3/unsupported/Eigen/Splines view
@@ -0,0 +1,31 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 20010-2011 Hauke Heibel <hauke.heibel@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_SPLINES_MODULE_H+#define EIGEN_SPLINES_MODULE_H++namespace Eigen +{+/**+ * \defgroup Splines_Module Spline and spline fitting module+ *+ * This module provides a simple multi-dimensional spline class while+ * offering most basic functionality to fit a spline to point sets.+ *+ * \code+ * #include <unsupported/Eigen/Splines>+ * \endcode+ */+}++#include "src/Splines/SplineFwd.h"+#include "src/Splines/Spline.h"+#include "src/Splines/SplineFitting.h"++#endif // EIGEN_SPLINES_MODULE_H
+ eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h view
@@ -0,0 +1,83 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_AUTODIFF_JACOBIAN_H+#define EIGEN_AUTODIFF_JACOBIAN_H++namespace Eigen+{++template<typename Functor> class AutoDiffJacobian : public Functor+{+public:+ AutoDiffJacobian() : Functor() {}+ AutoDiffJacobian(const Functor& f) : Functor(f) {}++ // forward constructors+ template<typename T0>+ AutoDiffJacobian(const T0& a0) : Functor(a0) {}+ template<typename T0, typename T1>+ AutoDiffJacobian(const T0& a0, const T1& a1) : Functor(a0, a1) {}+ template<typename T0, typename T1, typename T2>+ AutoDiffJacobian(const T0& a0, const T1& a1, const T2& a2) : Functor(a0, a1, a2) {}++ enum {+ InputsAtCompileTime = Functor::InputsAtCompileTime,+ ValuesAtCompileTime = Functor::ValuesAtCompileTime+ };++ typedef typename Functor::InputType InputType;+ typedef typename Functor::ValueType ValueType;+ typedef typename Functor::JacobianType JacobianType;+ typedef typename JacobianType::Scalar Scalar;+ typedef typename JacobianType::Index Index;++ typedef Matrix<Scalar,InputsAtCompileTime,1> DerivativeType;+ typedef AutoDiffScalar<DerivativeType> ActiveScalar;+++ typedef Matrix<ActiveScalar, InputsAtCompileTime, 1> ActiveInput;+ typedef Matrix<ActiveScalar, ValuesAtCompileTime, 1> ActiveValue;++ void operator() (const InputType& x, ValueType* v, JacobianType* _jac=0) const+ {+ eigen_assert(v!=0);+ if (!_jac)+ {+ Functor::operator()(x, v);+ return;+ }++ JacobianType& jac = *_jac;++ ActiveInput ax = x.template cast<ActiveScalar>();+ ActiveValue av(jac.rows());++ if(InputsAtCompileTime==Dynamic)+ for (Index j=0; j<jac.rows(); j++)+ av[j].derivatives().resize(this->inputs());++ for (Index i=0; i<jac.cols(); i++)+ ax[i].derivatives() = DerivativeType::Unit(this->inputs(),i);++ Functor::operator()(ax, &av);++ for (Index i=0; i<jac.rows(); i++)+ {+ (*v)[i] = av[i].value();+ jac.row(i) = av[i].derivatives();+ }+ }+protected:++};++}++#endif // EIGEN_AUTODIFF_JACOBIAN_H
+ eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h view
@@ -0,0 +1,642 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_AUTODIFF_SCALAR_H+#define EIGEN_AUTODIFF_SCALAR_H++namespace Eigen {++namespace internal {++template<typename A, typename B>+struct make_coherent_impl {+ static void run(A&, B&) {}+};++// resize a to match b is a.size()==0, and conversely.+template<typename A, typename B>+void make_coherent(const A& a, const B&b)+{+ make_coherent_impl<A,B>::run(a.const_cast_derived(), b.const_cast_derived());+}++template<typename _DerType, bool Enable> struct auto_diff_special_op;++} // end namespace internal++/** \class AutoDiffScalar+ * \brief A scalar type replacement with automatic differentation capability+ *+ * \param _DerType the vector type used to store/represent the derivatives. The base scalar type+ * as well as the number of derivatives to compute are determined from this type.+ * Typical choices include, e.g., \c Vector4f for 4 derivatives, or \c VectorXf+ * if the number of derivatives is not known at compile time, and/or, the number+ * of derivatives is large.+ * Note that _DerType can also be a reference (e.g., \c VectorXf&) to wrap a+ * existing vector into an AutoDiffScalar.+ * Finally, _DerType can also be any Eigen compatible expression.+ *+ * This class represents a scalar value while tracking its respective derivatives using Eigen's expression+ * template mechanism.+ *+ * It supports the following list of global math function:+ * - std::abs, std::sqrt, std::pow, std::exp, std::log, std::sin, std::cos,+ * - internal::abs, internal::sqrt, numext::pow, internal::exp, internal::log, internal::sin, internal::cos,+ * - internal::conj, internal::real, internal::imag, numext::abs2.+ *+ * AutoDiffScalar can be used as the scalar type of an Eigen::Matrix object. However,+ * in that case, the expression template mechanism only occurs at the top Matrix level,+ * while derivatives are computed right away.+ *+ */++template<typename _DerType>+class AutoDiffScalar+ : public internal::auto_diff_special_op+ <_DerType, !internal::is_same<typename internal::traits<typename internal::remove_all<_DerType>::type>::Scalar,+ typename NumTraits<typename internal::traits<typename internal::remove_all<_DerType>::type>::Scalar>::Real>::value>+{+ public:+ typedef internal::auto_diff_special_op+ <_DerType, !internal::is_same<typename internal::traits<typename internal::remove_all<_DerType>::type>::Scalar,+ typename NumTraits<typename internal::traits<typename internal::remove_all<_DerType>::type>::Scalar>::Real>::value> Base;+ typedef typename internal::remove_all<_DerType>::type DerType;+ typedef typename internal::traits<DerType>::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real Real;++ using Base::operator+;+ using Base::operator*;++ /** Default constructor without any initialization. */+ AutoDiffScalar() {}++ /** Constructs an active scalar from its \a value,+ and initializes the \a nbDer derivatives such that it corresponds to the \a derNumber -th variable */+ AutoDiffScalar(const Scalar& value, int nbDer, int derNumber)+ : m_value(value), m_derivatives(DerType::Zero(nbDer))+ {+ m_derivatives.coeffRef(derNumber) = Scalar(1);+ }++ /** Conversion from a scalar constant to an active scalar.+ * The derivatives are set to zero. */+ /*explicit*/ AutoDiffScalar(const Real& value)+ : m_value(value)+ {+ if(m_derivatives.size()>0)+ m_derivatives.setZero();+ }++ /** Constructs an active scalar from its \a value and derivatives \a der */+ AutoDiffScalar(const Scalar& value, const DerType& der)+ : m_value(value), m_derivatives(der)+ {}++ template<typename OtherDerType>+ AutoDiffScalar(const AutoDiffScalar<OtherDerType>& other)+ : m_value(other.value()), m_derivatives(other.derivatives())+ {}++ friend std::ostream & operator << (std::ostream & s, const AutoDiffScalar& a)+ {+ return s << a.value();+ }++ AutoDiffScalar(const AutoDiffScalar& other)+ : m_value(other.value()), m_derivatives(other.derivatives())+ {}++ template<typename OtherDerType>+ inline AutoDiffScalar& operator=(const AutoDiffScalar<OtherDerType>& other)+ {+ m_value = other.value();+ m_derivatives = other.derivatives();+ return *this;+ }++ inline AutoDiffScalar& operator=(const AutoDiffScalar& other)+ {+ m_value = other.value();+ m_derivatives = other.derivatives();+ return *this;+ }++// inline operator const Scalar& () const { return m_value; }+// inline operator Scalar& () { return m_value; }++ inline const Scalar& value() const { return m_value; }+ inline Scalar& value() { return m_value; }++ inline const DerType& derivatives() const { return m_derivatives; }+ inline DerType& derivatives() { return m_derivatives; }++ inline bool operator< (const Scalar& other) const { return m_value < other; }+ inline bool operator<=(const Scalar& other) const { return m_value <= other; }+ inline bool operator> (const Scalar& other) const { return m_value > other; }+ inline bool operator>=(const Scalar& other) const { return m_value >= other; }+ inline bool operator==(const Scalar& other) const { return m_value == other; }+ inline bool operator!=(const Scalar& other) const { return m_value != other; }++ friend inline bool operator< (const Scalar& a, const AutoDiffScalar& b) { return a < b.value(); }+ friend inline bool operator<=(const Scalar& a, const AutoDiffScalar& b) { return a <= b.value(); }+ friend inline bool operator> (const Scalar& a, const AutoDiffScalar& b) { return a > b.value(); }+ friend inline bool operator>=(const Scalar& a, const AutoDiffScalar& b) { return a >= b.value(); }+ friend inline bool operator==(const Scalar& a, const AutoDiffScalar& b) { return a == b.value(); }+ friend inline bool operator!=(const Scalar& a, const AutoDiffScalar& b) { return a != b.value(); }++ template<typename OtherDerType> inline bool operator< (const AutoDiffScalar<OtherDerType>& b) const { return m_value < b.value(); }+ template<typename OtherDerType> inline bool operator<=(const AutoDiffScalar<OtherDerType>& b) const { return m_value <= b.value(); }+ template<typename OtherDerType> inline bool operator> (const AutoDiffScalar<OtherDerType>& b) const { return m_value > b.value(); }+ template<typename OtherDerType> inline bool operator>=(const AutoDiffScalar<OtherDerType>& b) const { return m_value >= b.value(); }+ template<typename OtherDerType> inline bool operator==(const AutoDiffScalar<OtherDerType>& b) const { return m_value == b.value(); }+ template<typename OtherDerType> inline bool operator!=(const AutoDiffScalar<OtherDerType>& b) const { return m_value != b.value(); }++ inline const AutoDiffScalar<DerType&> operator+(const Scalar& other) const+ {+ return AutoDiffScalar<DerType&>(m_value + other, m_derivatives);+ }++ friend inline const AutoDiffScalar<DerType&> operator+(const Scalar& a, const AutoDiffScalar& b)+ {+ return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());+ }++// inline const AutoDiffScalar<DerType&> operator+(const Real& other) const+// {+// return AutoDiffScalar<DerType&>(m_value + other, m_derivatives);+// }++// friend inline const AutoDiffScalar<DerType&> operator+(const Real& a, const AutoDiffScalar& b)+// {+// return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());+// }++ inline AutoDiffScalar& operator+=(const Scalar& other)+ {+ value() += other;+ return *this;+ }++ template<typename OtherDerType>+ inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,const DerType,const typename internal::remove_all<OtherDerType>::type> >+ operator+(const AutoDiffScalar<OtherDerType>& other) const+ {+ internal::make_coherent(m_derivatives, other.derivatives());+ return AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,const DerType,const typename internal::remove_all<OtherDerType>::type> >(+ m_value + other.value(),+ m_derivatives + other.derivatives());+ }++ template<typename OtherDerType>+ inline AutoDiffScalar&+ operator+=(const AutoDiffScalar<OtherDerType>& other)+ {+ (*this) = (*this) + other;+ return *this;+ }++ inline const AutoDiffScalar<DerType&> operator-(const Scalar& b) const+ {+ return AutoDiffScalar<DerType&>(m_value - b, m_derivatives);+ }++ friend inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >+ operator-(const Scalar& a, const AutoDiffScalar& b)+ {+ return AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >+ (a - b.value(), -b.derivatives());+ }++ inline AutoDiffScalar& operator-=(const Scalar& other)+ {+ value() -= other;+ return *this;+ }++ template<typename OtherDerType>+ inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_difference_op<Scalar>, const DerType,const typename internal::remove_all<OtherDerType>::type> >+ operator-(const AutoDiffScalar<OtherDerType>& other) const+ {+ internal::make_coherent(m_derivatives, other.derivatives());+ return AutoDiffScalar<CwiseBinaryOp<internal::scalar_difference_op<Scalar>, const DerType,const typename internal::remove_all<OtherDerType>::type> >(+ m_value - other.value(),+ m_derivatives - other.derivatives());+ }++ template<typename OtherDerType>+ inline AutoDiffScalar&+ operator-=(const AutoDiffScalar<OtherDerType>& other)+ {+ *this = *this - other;+ return *this;+ }++ inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >+ operator-() const+ {+ return AutoDiffScalar<CwiseUnaryOp<internal::scalar_opposite_op<Scalar>, const DerType> >(+ -m_value,+ -m_derivatives);+ }++ inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >+ operator*(const Scalar& other) const+ {+ return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >(+ m_value * other,+ (m_derivatives * other));+ }++ friend inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >+ operator*(const Scalar& other, const AutoDiffScalar& a)+ {+ return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >(+ a.value() * other,+ a.derivatives() * other);+ }++// inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >+// operator*(const Real& other) const+// {+// return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(+// m_value * other,+// (m_derivatives * other));+// }+//+// friend inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >+// operator*(const Real& other, const AutoDiffScalar& a)+// {+// return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(+// a.value() * other,+// a.derivatives() * other);+// }++ inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >+ operator/(const Scalar& other) const+ {+ return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >(+ m_value / other,+ (m_derivatives * (Scalar(1)/other)));+ }++ friend inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >+ operator/(const Scalar& other, const AutoDiffScalar& a)+ {+ return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType> >(+ other / a.value(),+ a.derivatives() * (Scalar(-other) / (a.value()*a.value())));+ }++// inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >+// operator/(const Real& other) const+// {+// return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(+// m_value / other,+// (m_derivatives * (Real(1)/other)));+// }+//+// friend inline const AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >+// operator/(const Real& other, const AutoDiffScalar& a)+// {+// return AutoDiffScalar<typename CwiseUnaryOp<internal::scalar_multiple_op<Real>, DerType>::Type >(+// other / a.value(),+// a.derivatives() * (-Real(1)/other));+// }++ template<typename OtherDerType>+ inline const AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,+ const CwiseBinaryOp<internal::scalar_difference_op<Scalar>,+ const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType>,+ const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const typename internal::remove_all<OtherDerType>::type > > > >+ operator/(const AutoDiffScalar<OtherDerType>& other) const+ {+ internal::make_coherent(m_derivatives, other.derivatives());+ return AutoDiffScalar<CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,+ const CwiseBinaryOp<internal::scalar_difference_op<Scalar>,+ const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType>,+ const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const typename internal::remove_all<OtherDerType>::type > > > >(+ m_value / other.value(),+ ((m_derivatives * other.value()) - (m_value * other.derivatives()))+ * (Scalar(1)/(other.value()*other.value())));+ }++ template<typename OtherDerType>+ inline const AutoDiffScalar<CwiseBinaryOp<internal::scalar_sum_op<Scalar>,+ const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType>,+ const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const typename internal::remove_all<OtherDerType>::type> > >+ operator*(const AutoDiffScalar<OtherDerType>& other) const+ {+ internal::make_coherent(m_derivatives, other.derivatives());+ return AutoDiffScalar<const CwiseBinaryOp<internal::scalar_sum_op<Scalar>,+ const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DerType>,+ const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const typename internal::remove_all<OtherDerType>::type > > >(+ m_value * other.value(),+ (m_derivatives * other.value()) + (m_value * other.derivatives()));+ }++ inline AutoDiffScalar& operator*=(const Scalar& other)+ {+ *this = *this * other;+ return *this;+ }++ template<typename OtherDerType>+ inline AutoDiffScalar& operator*=(const AutoDiffScalar<OtherDerType>& other)+ {+ *this = *this * other;+ return *this;+ }++ inline AutoDiffScalar& operator/=(const Scalar& other)+ {+ *this = *this / other;+ return *this;+ }++ template<typename OtherDerType>+ inline AutoDiffScalar& operator/=(const AutoDiffScalar<OtherDerType>& other)+ {+ *this = *this / other;+ return *this;+ }++ protected:+ Scalar m_value;+ DerType m_derivatives;++};++namespace internal {++template<typename _DerType>+struct auto_diff_special_op<_DerType, true>+// : auto_diff_scalar_op<_DerType, typename NumTraits<Scalar>::Real,+// is_same<Scalar,typename NumTraits<Scalar>::Real>::value>+{+ typedef typename remove_all<_DerType>::type DerType;+ typedef typename traits<DerType>::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real Real;++// typedef auto_diff_scalar_op<_DerType, typename NumTraits<Scalar>::Real,+// is_same<Scalar,typename NumTraits<Scalar>::Real>::value> Base;++// using Base::operator+;+// using Base::operator+=;+// using Base::operator-;+// using Base::operator-=;+// using Base::operator*;+// using Base::operator*=;++ const AutoDiffScalar<_DerType>& derived() const { return *static_cast<const AutoDiffScalar<_DerType>*>(this); }+ AutoDiffScalar<_DerType>& derived() { return *static_cast<AutoDiffScalar<_DerType>*>(this); }+++ inline const AutoDiffScalar<DerType&> operator+(const Real& other) const+ {+ return AutoDiffScalar<DerType&>(derived().value() + other, derived().derivatives());+ }++ friend inline const AutoDiffScalar<DerType&> operator+(const Real& a, const AutoDiffScalar<_DerType>& b)+ {+ return AutoDiffScalar<DerType&>(a + b.value(), b.derivatives());+ }++ inline AutoDiffScalar<_DerType>& operator+=(const Real& other)+ {+ derived().value() += other;+ return derived();+ }+++ inline const AutoDiffScalar<typename CwiseUnaryOp<scalar_multiple2_op<Scalar,Real>, DerType>::Type >+ operator*(const Real& other) const+ {+ return AutoDiffScalar<typename CwiseUnaryOp<scalar_multiple2_op<Scalar,Real>, DerType>::Type >(+ derived().value() * other,+ derived().derivatives() * other);+ }++ friend inline const AutoDiffScalar<typename CwiseUnaryOp<scalar_multiple2_op<Scalar,Real>, DerType>::Type >+ operator*(const Real& other, const AutoDiffScalar<_DerType>& a)+ {+ return AutoDiffScalar<typename CwiseUnaryOp<scalar_multiple2_op<Scalar,Real>, DerType>::Type >(+ a.value() * other,+ a.derivatives() * other);+ }++ inline AutoDiffScalar<_DerType>& operator*=(const Scalar& other)+ {+ *this = *this * other;+ return derived();+ }+};++template<typename _DerType>+struct auto_diff_special_op<_DerType, false>+{+ void operator*() const;+ void operator-() const;+ void operator+() const;+};++template<typename A_Scalar, int A_Rows, int A_Cols, int A_Options, int A_MaxRows, int A_MaxCols, typename B>+struct make_coherent_impl<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>, B> {+ typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> A;+ static void run(A& a, B& b) {+ if((A_Rows==Dynamic || A_Cols==Dynamic) && (a.size()==0))+ {+ a.resize(b.size());+ a.setZero();+ }+ }+};++template<typename A, typename B_Scalar, int B_Rows, int B_Cols, int B_Options, int B_MaxRows, int B_MaxCols>+struct make_coherent_impl<A, Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> > {+ typedef Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> B;+ static void run(A& a, B& b) {+ if((B_Rows==Dynamic || B_Cols==Dynamic) && (b.size()==0))+ {+ b.resize(a.size());+ b.setZero();+ }+ }+};++template<typename A_Scalar, int A_Rows, int A_Cols, int A_Options, int A_MaxRows, int A_MaxCols,+ typename B_Scalar, int B_Rows, int B_Cols, int B_Options, int B_MaxRows, int B_MaxCols>+struct make_coherent_impl<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>,+ Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> > {+ typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> A;+ typedef Matrix<B_Scalar, B_Rows, B_Cols, B_Options, B_MaxRows, B_MaxCols> B;+ static void run(A& a, B& b) {+ if((A_Rows==Dynamic || A_Cols==Dynamic) && (a.size()==0))+ {+ a.resize(b.size());+ a.setZero();+ }+ else if((B_Rows==Dynamic || B_Cols==Dynamic) && (b.size()==0))+ {+ b.resize(a.size());+ b.setZero();+ }+ }+};++template<typename A_Scalar, int A_Rows, int A_Cols, int A_Options, int A_MaxRows, int A_MaxCols>+struct scalar_product_traits<Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols>,A_Scalar>+{+ enum { Defined = 1 };+ typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> ReturnType;+};++template<typename A_Scalar, int A_Rows, int A_Cols, int A_Options, int A_MaxRows, int A_MaxCols>+struct scalar_product_traits<A_Scalar, Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> >+{+ enum { Defined = 1 };+ typedef Matrix<A_Scalar, A_Rows, A_Cols, A_Options, A_MaxRows, A_MaxCols> ReturnType;+};++template<typename DerType>+struct scalar_product_traits<AutoDiffScalar<DerType>,typename DerType::Scalar>+{+ enum { Defined = 1 };+ typedef AutoDiffScalar<DerType> ReturnType;+};++template<typename DerType>+struct scalar_product_traits<typename DerType::Scalar,AutoDiffScalar<DerType> >+{+ enum { Defined = 1 };+ typedef AutoDiffScalar<DerType> ReturnType;+};++} // end namespace internal++#define EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(FUNC,CODE) \+ template<typename DerType> \+ inline const Eigen::AutoDiffScalar<Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<typename Eigen::internal::traits<typename Eigen::internal::remove_all<DerType>::type>::Scalar>, const typename Eigen::internal::remove_all<DerType>::type> > \+ FUNC(const Eigen::AutoDiffScalar<DerType>& x) { \+ using namespace Eigen; \+ typedef typename Eigen::internal::traits<typename Eigen::internal::remove_all<DerType>::type>::Scalar Scalar; \+ typedef AutoDiffScalar<CwiseUnaryOp<Eigen::internal::scalar_multiple_op<Scalar>, const typename Eigen::internal::remove_all<DerType>::type> > ReturnType; \+ CODE; \+ }++template<typename DerType>+inline const AutoDiffScalar<DerType>& conj(const AutoDiffScalar<DerType>& x) { return x; }+template<typename DerType>+inline const AutoDiffScalar<DerType>& real(const AutoDiffScalar<DerType>& x) { return x; }+template<typename DerType>+inline typename DerType::Scalar imag(const AutoDiffScalar<DerType>&) { return 0.; }+template<typename DerType, typename T>+inline AutoDiffScalar<DerType> (min)(const AutoDiffScalar<DerType>& x, const T& y) { return (x <= y ? x : y); }+template<typename DerType, typename T>+inline AutoDiffScalar<DerType> (max)(const AutoDiffScalar<DerType>& x, const T& y) { return (x >= y ? x : y); }+template<typename DerType, typename T>+inline AutoDiffScalar<DerType> (min)(const T& x, const AutoDiffScalar<DerType>& y) { return (x < y ? x : y); }+template<typename DerType, typename T>+inline AutoDiffScalar<DerType> (max)(const T& x, const AutoDiffScalar<DerType>& y) { return (x > y ? x : y); }++EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs,+ using std::abs;+ return ReturnType(abs(x.value()), x.derivatives() * (x.value()<0 ? -1 : 1) );)++EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(abs2,+ using numext::abs2;+ return ReturnType(abs2(x.value()), x.derivatives() * (Scalar(2)*x.value()));)++EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sqrt,+ using std::sqrt;+ Scalar sqrtx = sqrt(x.value());+ return ReturnType(sqrtx,x.derivatives() * (Scalar(0.5) / sqrtx));)++EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(cos,+ using std::cos;+ using std::sin;+ return ReturnType(cos(x.value()), x.derivatives() * (-sin(x.value())));)++EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(sin,+ using std::sin;+ using std::cos;+ return ReturnType(sin(x.value()),x.derivatives() * cos(x.value()));)++EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(exp,+ using std::exp;+ Scalar expx = exp(x.value());+ return ReturnType(expx,x.derivatives() * expx);)++EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(log,+ using std::log;+ return ReturnType(log(x.value()),x.derivatives() * (Scalar(1)/x.value()));)++template<typename DerType>+inline const Eigen::AutoDiffScalar<Eigen::CwiseUnaryOp<Eigen::internal::scalar_multiple_op<typename Eigen::internal::traits<DerType>::Scalar>, const DerType> >+pow(const Eigen::AutoDiffScalar<DerType>& x, typename Eigen::internal::traits<DerType>::Scalar y)+{+ using namespace Eigen;+ typedef typename Eigen::internal::traits<DerType>::Scalar Scalar;+ return AutoDiffScalar<CwiseUnaryOp<Eigen::internal::scalar_multiple_op<Scalar>, const DerType> >(+ std::pow(x.value(),y),+ x.derivatives() * (y * std::pow(x.value(),y-1)));+}+++template<typename DerTypeA,typename DerTypeB>+inline const AutoDiffScalar<Matrix<typename internal::traits<DerTypeA>::Scalar,Dynamic,1> >+atan2(const AutoDiffScalar<DerTypeA>& a, const AutoDiffScalar<DerTypeB>& b)+{+ using std::atan2;+ using std::max;+ typedef typename internal::traits<DerTypeA>::Scalar Scalar;+ typedef AutoDiffScalar<Matrix<Scalar,Dynamic,1> > PlainADS;+ PlainADS ret;+ ret.value() = atan2(a.value(), b.value());+ + Scalar tmp2 = a.value() * a.value();+ Scalar tmp3 = b.value() * b.value();+ Scalar tmp4 = tmp3/(tmp2+tmp3);+ + if (tmp4!=0)+ ret.derivatives() = (a.derivatives() * b.value() - a.value() * b.derivatives()) * (tmp2+tmp3);++ return ret;+}++EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(tan,+ using std::tan;+ using std::cos;+ return ReturnType(tan(x.value()),x.derivatives() * (Scalar(1)/numext::abs2(cos(x.value()))));)++EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(asin,+ using std::sqrt;+ using std::asin;+ return ReturnType(asin(x.value()),x.derivatives() * (Scalar(1)/sqrt(1-numext::abs2(x.value()))));)+ +EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY(acos,+ using std::sqrt;+ using std::acos;+ return ReturnType(acos(x.value()),x.derivatives() * (Scalar(-1)/sqrt(1-numext::abs2(x.value()))));)++#undef EIGEN_AUTODIFF_DECLARE_GLOBAL_UNARY++template<typename DerType> struct NumTraits<AutoDiffScalar<DerType> >+ : NumTraits< typename NumTraits<typename DerType::Scalar>::Real >+{+ typedef AutoDiffScalar<Matrix<typename NumTraits<typename DerType::Scalar>::Real,DerType::RowsAtCompileTime,DerType::ColsAtCompileTime> > Real;+ typedef AutoDiffScalar<DerType> NonInteger;+ typedef AutoDiffScalar<DerType>& Nested;+ enum{+ RequireInitialization = 1+ };+};++}++#endif // EIGEN_AUTODIFF_SCALAR_H
+ eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h view
@@ -0,0 +1,220 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_AUTODIFF_VECTOR_H+#define EIGEN_AUTODIFF_VECTOR_H++namespace Eigen {++/* \class AutoDiffScalar+ * \brief A scalar type replacement with automatic differentation capability+ *+ * \param DerType the vector type used to store/represent the derivatives (e.g. Vector3f)+ *+ * This class represents a scalar value while tracking its respective derivatives.+ *+ * It supports the following list of global math function:+ * - std::abs, std::sqrt, std::pow, std::exp, std::log, std::sin, std::cos,+ * - internal::abs, internal::sqrt, numext::pow, internal::exp, internal::log, internal::sin, internal::cos,+ * - internal::conj, internal::real, internal::imag, numext::abs2.+ *+ * AutoDiffScalar can be used as the scalar type of an Eigen::Matrix object. However,+ * in that case, the expression template mechanism only occurs at the top Matrix level,+ * while derivatives are computed right away.+ *+ */+template<typename ValueType, typename JacobianType>+class AutoDiffVector+{+ public:+ //typedef typename internal::traits<ValueType>::Scalar Scalar;+ typedef typename internal::traits<ValueType>::Scalar BaseScalar;+ typedef AutoDiffScalar<Matrix<BaseScalar,JacobianType::RowsAtCompileTime,1> > ActiveScalar;+ typedef ActiveScalar Scalar;+ typedef AutoDiffScalar<typename JacobianType::ColXpr> CoeffType;+ typedef typename JacobianType::Index Index;++ inline AutoDiffVector() {}++ inline AutoDiffVector(const ValueType& values)+ : m_values(values)+ {+ m_jacobian.setZero();+ }+++ CoeffType operator[] (Index i) { return CoeffType(m_values[i], m_jacobian.col(i)); }+ const CoeffType operator[] (Index i) const { return CoeffType(m_values[i], m_jacobian.col(i)); }++ CoeffType operator() (Index i) { return CoeffType(m_values[i], m_jacobian.col(i)); }+ const CoeffType operator() (Index i) const { return CoeffType(m_values[i], m_jacobian.col(i)); }++ CoeffType coeffRef(Index i) { return CoeffType(m_values[i], m_jacobian.col(i)); }+ const CoeffType coeffRef(Index i) const { return CoeffType(m_values[i], m_jacobian.col(i)); }++ Index size() const { return m_values.size(); }++ // FIXME here we could return an expression of the sum+ Scalar sum() const { /*std::cerr << "sum \n\n";*/ /*std::cerr << m_jacobian.rowwise().sum() << "\n\n";*/ return Scalar(m_values.sum(), m_jacobian.rowwise().sum()); }+++ inline AutoDiffVector(const ValueType& values, const JacobianType& jac)+ : m_values(values), m_jacobian(jac)+ {}++ template<typename OtherValueType, typename OtherJacobianType>+ inline AutoDiffVector(const AutoDiffVector<OtherValueType, OtherJacobianType>& other)+ : m_values(other.values()), m_jacobian(other.jacobian())+ {}++ inline AutoDiffVector(const AutoDiffVector& other)+ : m_values(other.values()), m_jacobian(other.jacobian())+ {}++ template<typename OtherValueType, typename OtherJacobianType>+ inline AutoDiffVector& operator=(const AutoDiffVector<OtherValueType, OtherJacobianType>& other)+ {+ m_values = other.values();+ m_jacobian = other.jacobian();+ return *this;+ }++ inline AutoDiffVector& operator=(const AutoDiffVector& other)+ {+ m_values = other.values();+ m_jacobian = other.jacobian();+ return *this;+ }++ inline const ValueType& values() const { return m_values; }+ inline ValueType& values() { return m_values; }++ inline const JacobianType& jacobian() const { return m_jacobian; }+ inline JacobianType& jacobian() { return m_jacobian; }++ template<typename OtherValueType,typename OtherJacobianType>+ inline const AutoDiffVector<+ typename MakeCwiseBinaryOp<internal::scalar_sum_op<BaseScalar>,ValueType,OtherValueType>::Type,+ typename MakeCwiseBinaryOp<internal::scalar_sum_op<BaseScalar>,JacobianType,OtherJacobianType>::Type >+ operator+(const AutoDiffVector<OtherValueType,OtherJacobianType>& other) const+ {+ return AutoDiffVector<+ typename MakeCwiseBinaryOp<internal::scalar_sum_op<BaseScalar>,ValueType,OtherValueType>::Type,+ typename MakeCwiseBinaryOp<internal::scalar_sum_op<BaseScalar>,JacobianType,OtherJacobianType>::Type >(+ m_values + other.values(),+ m_jacobian + other.jacobian());+ }++ template<typename OtherValueType, typename OtherJacobianType>+ inline AutoDiffVector&+ operator+=(const AutoDiffVector<OtherValueType,OtherJacobianType>& other)+ {+ m_values += other.values();+ m_jacobian += other.jacobian();+ return *this;+ }++ template<typename OtherValueType,typename OtherJacobianType>+ inline const AutoDiffVector<+ typename MakeCwiseBinaryOp<internal::scalar_difference_op<Scalar>,ValueType,OtherValueType>::Type,+ typename MakeCwiseBinaryOp<internal::scalar_difference_op<Scalar>,JacobianType,OtherJacobianType>::Type >+ operator-(const AutoDiffVector<OtherValueType,OtherJacobianType>& other) const+ {+ return AutoDiffVector<+ typename MakeCwiseBinaryOp<internal::scalar_difference_op<Scalar>,ValueType,OtherValueType>::Type,+ typename MakeCwiseBinaryOp<internal::scalar_difference_op<Scalar>,JacobianType,OtherJacobianType>::Type >(+ m_values - other.values(),+ m_jacobian - other.jacobian());+ }++ template<typename OtherValueType, typename OtherJacobianType>+ inline AutoDiffVector&+ operator-=(const AutoDiffVector<OtherValueType,OtherJacobianType>& other)+ {+ m_values -= other.values();+ m_jacobian -= other.jacobian();+ return *this;+ }++ inline const AutoDiffVector<+ typename MakeCwiseUnaryOp<internal::scalar_opposite_op<Scalar>, ValueType>::Type,+ typename MakeCwiseUnaryOp<internal::scalar_opposite_op<Scalar>, JacobianType>::Type >+ operator-() const+ {+ return AutoDiffVector<+ typename MakeCwiseUnaryOp<internal::scalar_opposite_op<Scalar>, ValueType>::Type,+ typename MakeCwiseUnaryOp<internal::scalar_opposite_op<Scalar>, JacobianType>::Type >(+ -m_values,+ -m_jacobian);+ }++ inline const AutoDiffVector<+ typename MakeCwiseUnaryOp<internal::scalar_multiple_op<Scalar>, ValueType>::Type,+ typename MakeCwiseUnaryOp<internal::scalar_multiple_op<Scalar>, JacobianType>::Type>+ operator*(const BaseScalar& other) const+ {+ return AutoDiffVector<+ typename MakeCwiseUnaryOp<internal::scalar_multiple_op<Scalar>, ValueType>::Type,+ typename MakeCwiseUnaryOp<internal::scalar_multiple_op<Scalar>, JacobianType>::Type >(+ m_values * other,+ m_jacobian * other);+ }++ friend inline const AutoDiffVector<+ typename MakeCwiseUnaryOp<internal::scalar_multiple_op<Scalar>, ValueType>::Type,+ typename MakeCwiseUnaryOp<internal::scalar_multiple_op<Scalar>, JacobianType>::Type >+ operator*(const Scalar& other, const AutoDiffVector& v)+ {+ return AutoDiffVector<+ typename MakeCwiseUnaryOp<internal::scalar_multiple_op<Scalar>, ValueType>::Type,+ typename MakeCwiseUnaryOp<internal::scalar_multiple_op<Scalar>, JacobianType>::Type >(+ v.values() * other,+ v.jacobian() * other);+ }++// template<typename OtherValueType,typename OtherJacobianType>+// inline const AutoDiffVector<+// CwiseBinaryOp<internal::scalar_multiple_op<Scalar>, ValueType, OtherValueType>+// CwiseBinaryOp<internal::scalar_sum_op<Scalar>,+// CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, JacobianType>,+// CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, OtherJacobianType> > >+// operator*(const AutoDiffVector<OtherValueType,OtherJacobianType>& other) const+// {+// return AutoDiffVector<+// CwiseBinaryOp<internal::scalar_multiple_op<Scalar>, ValueType, OtherValueType>+// CwiseBinaryOp<internal::scalar_sum_op<Scalar>,+// CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, JacobianType>,+// CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, OtherJacobianType> > >(+// m_values.cwise() * other.values(),+// (m_jacobian * other.values()) + (m_values * other.jacobian()));+// }++ inline AutoDiffVector& operator*=(const Scalar& other)+ {+ m_values *= other;+ m_jacobian *= other;+ return *this;+ }++ template<typename OtherValueType,typename OtherJacobianType>+ inline AutoDiffVector& operator*=(const AutoDiffVector<OtherValueType,OtherJacobianType>& other)+ {+ *this = *this * other;+ return *this;+ }++ protected:+ ValueType m_values;+ JacobianType m_jacobian;++};++}++#endif // EIGEN_AUTODIFF_VECTOR_H
+ eigen3/unsupported/Eigen/src/AutoDiff/CMakeLists.txt view
@@ -0,0 +1,6 @@+FILE(GLOB Eigen_AutoDiff_SRCS "*.h")++INSTALL(FILES+ ${Eigen_AutoDiff_SRCS}+ DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/AutoDiff COMPONENT Devel+ )
+ eigen3/unsupported/Eigen/src/BVH/BVAlgorithms.h view
@@ -0,0 +1,293 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Ilya Baran <ibaran@mit.edu>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_BVALGORITHMS_H+#define EIGEN_BVALGORITHMS_H++namespace Eigen { ++namespace internal {++#ifndef EIGEN_PARSED_BY_DOXYGEN+template<typename BVH, typename Intersector>+bool intersect_helper(const BVH &tree, Intersector &intersector, typename BVH::Index root)+{+ typedef typename BVH::Index Index;+ typedef typename BVH::VolumeIterator VolIter;+ typedef typename BVH::ObjectIterator ObjIter;++ VolIter vBegin = VolIter(), vEnd = VolIter();+ ObjIter oBegin = ObjIter(), oEnd = ObjIter();++ std::vector<Index> todo(1, root);++ while(!todo.empty()) {+ tree.getChildren(todo.back(), vBegin, vEnd, oBegin, oEnd);+ todo.pop_back();++ for(; vBegin != vEnd; ++vBegin) //go through child volumes+ if(intersector.intersectVolume(tree.getVolume(*vBegin)))+ todo.push_back(*vBegin);++ for(; oBegin != oEnd; ++oBegin) //go through child objects+ if(intersector.intersectObject(*oBegin))+ return true; //intersector said to stop query+ }+ return false;+}+#endif //not EIGEN_PARSED_BY_DOXYGEN++template<typename Volume1, typename Object1, typename Object2, typename Intersector>+struct intersector_helper1+{+ intersector_helper1(const Object2 &inStored, Intersector &in) : stored(inStored), intersector(in) {}+ bool intersectVolume(const Volume1 &vol) { return intersector.intersectVolumeObject(vol, stored); }+ bool intersectObject(const Object1 &obj) { return intersector.intersectObjectObject(obj, stored); }+ Object2 stored;+ Intersector &intersector;+private:+ intersector_helper1& operator=(const intersector_helper1&);+};++template<typename Volume2, typename Object2, typename Object1, typename Intersector>+struct intersector_helper2+{+ intersector_helper2(const Object1 &inStored, Intersector &in) : stored(inStored), intersector(in) {}+ bool intersectVolume(const Volume2 &vol) { return intersector.intersectObjectVolume(stored, vol); }+ bool intersectObject(const Object2 &obj) { return intersector.intersectObjectObject(stored, obj); }+ Object1 stored;+ Intersector &intersector;+private:+ intersector_helper2& operator=(const intersector_helper2&);+};++} // end namespace internal++/** Given a BVH, runs the query encapsulated by \a intersector.+ * The Intersector type must provide the following members: \code+ bool intersectVolume(const BVH::Volume &volume) //returns true if volume intersects the query+ bool intersectObject(const BVH::Object &object) //returns true if the search should terminate immediately+ \endcode+ */+template<typename BVH, typename Intersector>+void BVIntersect(const BVH &tree, Intersector &intersector)+{+ internal::intersect_helper(tree, intersector, tree.getRootIndex());+}++/** Given two BVH's, runs the query on their Cartesian product encapsulated by \a intersector.+ * The Intersector type must provide the following members: \code+ bool intersectVolumeVolume(const BVH1::Volume &v1, const BVH2::Volume &v2) //returns true if product of volumes intersects the query+ bool intersectVolumeObject(const BVH1::Volume &v1, const BVH2::Object &o2) //returns true if the volume-object product intersects the query+ bool intersectObjectVolume(const BVH1::Object &o1, const BVH2::Volume &v2) //returns true if the volume-object product intersects the query+ bool intersectObjectObject(const BVH1::Object &o1, const BVH2::Object &o2) //returns true if the search should terminate immediately+ \endcode+ */+template<typename BVH1, typename BVH2, typename Intersector>+void BVIntersect(const BVH1 &tree1, const BVH2 &tree2, Intersector &intersector) //TODO: tandem descent when it makes sense+{+ typedef typename BVH1::Index Index1;+ typedef typename BVH2::Index Index2;+ typedef internal::intersector_helper1<typename BVH1::Volume, typename BVH1::Object, typename BVH2::Object, Intersector> Helper1;+ typedef internal::intersector_helper2<typename BVH2::Volume, typename BVH2::Object, typename BVH1::Object, Intersector> Helper2;+ typedef typename BVH1::VolumeIterator VolIter1;+ typedef typename BVH1::ObjectIterator ObjIter1;+ typedef typename BVH2::VolumeIterator VolIter2;+ typedef typename BVH2::ObjectIterator ObjIter2;++ VolIter1 vBegin1 = VolIter1(), vEnd1 = VolIter1();+ ObjIter1 oBegin1 = ObjIter1(), oEnd1 = ObjIter1();+ VolIter2 vBegin2 = VolIter2(), vEnd2 = VolIter2(), vCur2 = VolIter2();+ ObjIter2 oBegin2 = ObjIter2(), oEnd2 = ObjIter2(), oCur2 = ObjIter2();++ std::vector<std::pair<Index1, Index2> > todo(1, std::make_pair(tree1.getRootIndex(), tree2.getRootIndex()));++ while(!todo.empty()) {+ tree1.getChildren(todo.back().first, vBegin1, vEnd1, oBegin1, oEnd1);+ tree2.getChildren(todo.back().second, vBegin2, vEnd2, oBegin2, oEnd2);+ todo.pop_back();++ for(; vBegin1 != vEnd1; ++vBegin1) { //go through child volumes of first tree+ const typename BVH1::Volume &vol1 = tree1.getVolume(*vBegin1);+ for(vCur2 = vBegin2; vCur2 != vEnd2; ++vCur2) { //go through child volumes of second tree+ if(intersector.intersectVolumeVolume(vol1, tree2.getVolume(*vCur2)))+ todo.push_back(std::make_pair(*vBegin1, *vCur2));+ }++ for(oCur2 = oBegin2; oCur2 != oEnd2; ++oCur2) {//go through child objects of second tree+ Helper1 helper(*oCur2, intersector);+ if(internal::intersect_helper(tree1, helper, *vBegin1))+ return; //intersector said to stop query+ }+ }++ for(; oBegin1 != oEnd1; ++oBegin1) { //go through child objects of first tree+ for(vCur2 = vBegin2; vCur2 != vEnd2; ++vCur2) { //go through child volumes of second tree+ Helper2 helper(*oBegin1, intersector);+ if(internal::intersect_helper(tree2, helper, *vCur2))+ return; //intersector said to stop query+ }++ for(oCur2 = oBegin2; oCur2 != oEnd2; ++oCur2) {//go through child objects of second tree+ if(intersector.intersectObjectObject(*oBegin1, *oCur2))+ return; //intersector said to stop query+ }+ }+ }+}++namespace internal {++#ifndef EIGEN_PARSED_BY_DOXYGEN+template<typename BVH, typename Minimizer>+typename Minimizer::Scalar minimize_helper(const BVH &tree, Minimizer &minimizer, typename BVH::Index root, typename Minimizer::Scalar minimum)+{+ typedef typename Minimizer::Scalar Scalar;+ typedef typename BVH::Index Index;+ typedef std::pair<Scalar, Index> QueueElement; //first element is priority+ typedef typename BVH::VolumeIterator VolIter;+ typedef typename BVH::ObjectIterator ObjIter;++ VolIter vBegin = VolIter(), vEnd = VolIter();+ ObjIter oBegin = ObjIter(), oEnd = ObjIter();+ std::priority_queue<QueueElement, std::vector<QueueElement>, std::greater<QueueElement> > todo; //smallest is at the top++ todo.push(std::make_pair(Scalar(), root));++ while(!todo.empty()) {+ tree.getChildren(todo.top().second, vBegin, vEnd, oBegin, oEnd);+ todo.pop();++ for(; oBegin != oEnd; ++oBegin) //go through child objects+ minimum = (std::min)(minimum, minimizer.minimumOnObject(*oBegin));++ for(; vBegin != vEnd; ++vBegin) { //go through child volumes+ Scalar val = minimizer.minimumOnVolume(tree.getVolume(*vBegin));+ if(val < minimum)+ todo.push(std::make_pair(val, *vBegin));+ }+ }++ return minimum;+}+#endif //not EIGEN_PARSED_BY_DOXYGEN+++template<typename Volume1, typename Object1, typename Object2, typename Minimizer>+struct minimizer_helper1+{+ typedef typename Minimizer::Scalar Scalar;+ minimizer_helper1(const Object2 &inStored, Minimizer &m) : stored(inStored), minimizer(m) {}+ Scalar minimumOnVolume(const Volume1 &vol) { return minimizer.minimumOnVolumeObject(vol, stored); }+ Scalar minimumOnObject(const Object1 &obj) { return minimizer.minimumOnObjectObject(obj, stored); }+ Object2 stored;+ Minimizer &minimizer;+private:+ minimizer_helper1& operator=(const minimizer_helper1&);+};++template<typename Volume2, typename Object2, typename Object1, typename Minimizer>+struct minimizer_helper2+{+ typedef typename Minimizer::Scalar Scalar;+ minimizer_helper2(const Object1 &inStored, Minimizer &m) : stored(inStored), minimizer(m) {}+ Scalar minimumOnVolume(const Volume2 &vol) { return minimizer.minimumOnObjectVolume(stored, vol); }+ Scalar minimumOnObject(const Object2 &obj) { return minimizer.minimumOnObjectObject(stored, obj); }+ Object1 stored;+ Minimizer &minimizer;+private:+ minimizer_helper2& operator=(const minimizer_helper2&);+};++} // end namespace internal++/** Given a BVH, runs the query encapsulated by \a minimizer.+ * \returns the minimum value.+ * The Minimizer type must provide the following members: \code+ typedef Scalar //the numeric type of what is being minimized--not necessarily the Scalar type of the BVH (if it has one)+ Scalar minimumOnVolume(const BVH::Volume &volume)+ Scalar minimumOnObject(const BVH::Object &object)+ \endcode+ */+template<typename BVH, typename Minimizer>+typename Minimizer::Scalar BVMinimize(const BVH &tree, Minimizer &minimizer)+{+ return internal::minimize_helper(tree, minimizer, tree.getRootIndex(), (std::numeric_limits<typename Minimizer::Scalar>::max)());+}++/** Given two BVH's, runs the query on their cartesian product encapsulated by \a minimizer.+ * \returns the minimum value.+ * The Minimizer type must provide the following members: \code+ typedef Scalar //the numeric type of what is being minimized--not necessarily the Scalar type of the BVH (if it has one)+ Scalar minimumOnVolumeVolume(const BVH1::Volume &v1, const BVH2::Volume &v2)+ Scalar minimumOnVolumeObject(const BVH1::Volume &v1, const BVH2::Object &o2)+ Scalar minimumOnObjectVolume(const BVH1::Object &o1, const BVH2::Volume &v2)+ Scalar minimumOnObjectObject(const BVH1::Object &o1, const BVH2::Object &o2)+ \endcode+ */+template<typename BVH1, typename BVH2, typename Minimizer>+typename Minimizer::Scalar BVMinimize(const BVH1 &tree1, const BVH2 &tree2, Minimizer &minimizer)+{+ typedef typename Minimizer::Scalar Scalar;+ typedef typename BVH1::Index Index1;+ typedef typename BVH2::Index Index2;+ typedef internal::minimizer_helper1<typename BVH1::Volume, typename BVH1::Object, typename BVH2::Object, Minimizer> Helper1;+ typedef internal::minimizer_helper2<typename BVH2::Volume, typename BVH2::Object, typename BVH1::Object, Minimizer> Helper2;+ typedef std::pair<Scalar, std::pair<Index1, Index2> > QueueElement; //first element is priority+ typedef typename BVH1::VolumeIterator VolIter1;+ typedef typename BVH1::ObjectIterator ObjIter1;+ typedef typename BVH2::VolumeIterator VolIter2;+ typedef typename BVH2::ObjectIterator ObjIter2;++ VolIter1 vBegin1 = VolIter1(), vEnd1 = VolIter1();+ ObjIter1 oBegin1 = ObjIter1(), oEnd1 = ObjIter1();+ VolIter2 vBegin2 = VolIter2(), vEnd2 = VolIter2(), vCur2 = VolIter2();+ ObjIter2 oBegin2 = ObjIter2(), oEnd2 = ObjIter2(), oCur2 = ObjIter2();+ std::priority_queue<QueueElement, std::vector<QueueElement>, std::greater<QueueElement> > todo; //smallest is at the top++ Scalar minimum = (std::numeric_limits<Scalar>::max)();+ todo.push(std::make_pair(Scalar(), std::make_pair(tree1.getRootIndex(), tree2.getRootIndex())));++ while(!todo.empty()) {+ tree1.getChildren(todo.top().second.first, vBegin1, vEnd1, oBegin1, oEnd1);+ tree2.getChildren(todo.top().second.second, vBegin2, vEnd2, oBegin2, oEnd2);+ todo.pop();++ for(; oBegin1 != oEnd1; ++oBegin1) { //go through child objects of first tree+ for(oCur2 = oBegin2; oCur2 != oEnd2; ++oCur2) {//go through child objects of second tree+ minimum = (std::min)(minimum, minimizer.minimumOnObjectObject(*oBegin1, *oCur2));+ }++ for(vCur2 = vBegin2; vCur2 != vEnd2; ++vCur2) { //go through child volumes of second tree+ Helper2 helper(*oBegin1, minimizer);+ minimum = (std::min)(minimum, internal::minimize_helper(tree2, helper, *vCur2, minimum));+ }+ }++ for(; vBegin1 != vEnd1; ++vBegin1) { //go through child volumes of first tree+ const typename BVH1::Volume &vol1 = tree1.getVolume(*vBegin1);++ for(oCur2 = oBegin2; oCur2 != oEnd2; ++oCur2) {//go through child objects of second tree+ Helper1 helper(*oCur2, minimizer);+ minimum = (std::min)(minimum, internal::minimize_helper(tree1, helper, *vBegin1, minimum));+ }++ for(vCur2 = vBegin2; vCur2 != vEnd2; ++vCur2) { //go through child volumes of second tree+ Scalar val = minimizer.minimumOnVolumeVolume(vol1, tree2.getVolume(*vCur2));+ if(val < minimum)+ todo.push(std::make_pair(val, std::make_pair(*vBegin1, *vCur2)));+ }+ }+ }+ return minimum;+}++} // end namespace Eigen++#endif // EIGEN_BVALGORITHMS_H
+ eigen3/unsupported/Eigen/src/BVH/CMakeLists.txt view
@@ -0,0 +1,6 @@+FILE(GLOB Eigen_BVH_SRCS "*.h")++INSTALL(FILES+ ${Eigen_BVH_SRCS}+ DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/BVH COMPONENT Devel+ )
+ eigen3/unsupported/Eigen/src/BVH/KdBVH.h view
@@ -0,0 +1,222 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Ilya Baran <ibaran@mit.edu>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef KDBVH_H_INCLUDED+#define KDBVH_H_INCLUDED++namespace Eigen { ++namespace internal {++//internal pair class for the BVH--used instead of std::pair because of alignment+template<typename Scalar, int Dim>+struct vector_int_pair+{+EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar, Dim)+ typedef Matrix<Scalar, Dim, 1> VectorType;++ vector_int_pair(const VectorType &v, int i) : first(v), second(i) {}++ VectorType first;+ int second;+};++//these templates help the tree initializer get the bounding boxes either from a provided+//iterator range or using bounding_box in a unified way+template<typename ObjectList, typename VolumeList, typename BoxIter>+struct get_boxes_helper {+ void operator()(const ObjectList &objects, BoxIter boxBegin, BoxIter boxEnd, VolumeList &outBoxes)+ {+ outBoxes.insert(outBoxes.end(), boxBegin, boxEnd);+ eigen_assert(outBoxes.size() == objects.size());+ }+};++template<typename ObjectList, typename VolumeList>+struct get_boxes_helper<ObjectList, VolumeList, int> {+ void operator()(const ObjectList &objects, int, int, VolumeList &outBoxes)+ {+ outBoxes.reserve(objects.size());+ for(int i = 0; i < (int)objects.size(); ++i)+ outBoxes.push_back(bounding_box(objects[i]));+ }+};++} // end namespace internal+++/** \class KdBVH+ * \brief A simple bounding volume hierarchy based on AlignedBox+ *+ * \param _Scalar The underlying scalar type of the bounding boxes+ * \param _Dim The dimension of the space in which the hierarchy lives+ * \param _Object The object type that lives in the hierarchy. It must have value semantics. Either bounding_box(_Object) must+ * be defined and return an AlignedBox<_Scalar, _Dim> or bounding boxes must be provided to the tree initializer.+ *+ * This class provides a simple (as opposed to optimized) implementation of a bounding volume hierarchy analogous to a Kd-tree.+ * Given a sequence of objects, it computes their bounding boxes, constructs a Kd-tree of their centers+ * and builds a BVH with the structure of that Kd-tree. When the elements of the tree are too expensive to be copied around,+ * it is useful for _Object to be a pointer.+ */+template<typename _Scalar, int _Dim, typename _Object> class KdBVH+{+public:+ enum { Dim = _Dim };+ typedef _Object Object;+ typedef std::vector<Object, aligned_allocator<Object> > ObjectList;+ typedef _Scalar Scalar;+ typedef AlignedBox<Scalar, Dim> Volume;+ typedef std::vector<Volume, aligned_allocator<Volume> > VolumeList;+ typedef int Index;+ typedef const int *VolumeIterator; //the iterators are just pointers into the tree's vectors+ typedef const Object *ObjectIterator;++ KdBVH() {}++ /** Given an iterator range over \a Object references, constructs the BVH. Requires that bounding_box(Object) return a Volume. */+ template<typename Iter> KdBVH(Iter begin, Iter end) { init(begin, end, 0, 0); } //int is recognized by init as not being an iterator type++ /** Given an iterator range over \a Object references and an iterator range over their bounding boxes, constructs the BVH */+ template<typename OIter, typename BIter> KdBVH(OIter begin, OIter end, BIter boxBegin, BIter boxEnd) { init(begin, end, boxBegin, boxEnd); }++ /** Given an iterator range over \a Object references, constructs the BVH, overwriting whatever is in there currently.+ * Requires that bounding_box(Object) return a Volume. */+ template<typename Iter> void init(Iter begin, Iter end) { init(begin, end, 0, 0); }++ /** Given an iterator range over \a Object references and an iterator range over their bounding boxes,+ * constructs the BVH, overwriting whatever is in there currently. */+ template<typename OIter, typename BIter> void init(OIter begin, OIter end, BIter boxBegin, BIter boxEnd)+ {+ objects.clear();+ boxes.clear();+ children.clear();++ objects.insert(objects.end(), begin, end);+ int n = static_cast<int>(objects.size());++ if(n < 2)+ return; //if we have at most one object, we don't need any internal nodes++ VolumeList objBoxes;+ VIPairList objCenters;++ //compute the bounding boxes depending on BIter type+ internal::get_boxes_helper<ObjectList, VolumeList, BIter>()(objects, boxBegin, boxEnd, objBoxes);++ objCenters.reserve(n);+ boxes.reserve(n - 1);+ children.reserve(2 * n - 2);++ for(int i = 0; i < n; ++i)+ objCenters.push_back(VIPair(objBoxes[i].center(), i));++ build(objCenters, 0, n, objBoxes, 0); //the recursive part of the algorithm++ ObjectList tmp(n);+ tmp.swap(objects);+ for(int i = 0; i < n; ++i)+ objects[i] = tmp[objCenters[i].second];+ }++ /** \returns the index of the root of the hierarchy */+ inline Index getRootIndex() const { return (int)boxes.size() - 1; }++ /** Given an \a index of a node, on exit, \a outVBegin and \a outVEnd range over the indices of the volume children of the node+ * and \a outOBegin and \a outOEnd range over the object children of the node */+ EIGEN_STRONG_INLINE void getChildren(Index index, VolumeIterator &outVBegin, VolumeIterator &outVEnd,+ ObjectIterator &outOBegin, ObjectIterator &outOEnd) const+ { //inlining this function should open lots of optimization opportunities to the compiler+ if(index < 0) {+ outVBegin = outVEnd;+ if(!objects.empty())+ outOBegin = &(objects[0]);+ outOEnd = outOBegin + objects.size(); //output all objects--necessary when the tree has only one object+ return;+ }++ int numBoxes = static_cast<int>(boxes.size());++ int idx = index * 2;+ if(children[idx + 1] < numBoxes) { //second index is always bigger+ outVBegin = &(children[idx]);+ outVEnd = outVBegin + 2;+ outOBegin = outOEnd;+ }+ else if(children[idx] >= numBoxes) { //if both children are objects+ outVBegin = outVEnd;+ outOBegin = &(objects[children[idx] - numBoxes]);+ outOEnd = outOBegin + 2;+ } else { //if the first child is a volume and the second is an object+ outVBegin = &(children[idx]);+ outVEnd = outVBegin + 1;+ outOBegin = &(objects[children[idx + 1] - numBoxes]);+ outOEnd = outOBegin + 1;+ }+ }++ /** \returns the bounding box of the node at \a index */+ inline const Volume &getVolume(Index index) const+ {+ return boxes[index];+ }++private:+ typedef internal::vector_int_pair<Scalar, Dim> VIPair;+ typedef std::vector<VIPair, aligned_allocator<VIPair> > VIPairList;+ typedef Matrix<Scalar, Dim, 1> VectorType;+ struct VectorComparator //compares vectors, or, more specificall, VIPairs along a particular dimension+ {+ VectorComparator(int inDim) : dim(inDim) {}+ inline bool operator()(const VIPair &v1, const VIPair &v2) const { return v1.first[dim] < v2.first[dim]; }+ int dim;+ };++ //Build the part of the tree between objects[from] and objects[to] (not including objects[to]).+ //This routine partitions the objCenters in [from, to) along the dimension dim, recursively constructs+ //the two halves, and adds their parent node. TODO: a cache-friendlier layout+ void build(VIPairList &objCenters, int from, int to, const VolumeList &objBoxes, int dim)+ {+ eigen_assert(to - from > 1);+ if(to - from == 2) {+ boxes.push_back(objBoxes[objCenters[from].second].merged(objBoxes[objCenters[from + 1].second]));+ children.push_back(from + (int)objects.size() - 1); //there are objects.size() - 1 tree nodes+ children.push_back(from + (int)objects.size());+ }+ else if(to - from == 3) {+ int mid = from + 2;+ std::nth_element(objCenters.begin() + from, objCenters.begin() + mid,+ objCenters.begin() + to, VectorComparator(dim)); //partition+ build(objCenters, from, mid, objBoxes, (dim + 1) % Dim);+ int idx1 = (int)boxes.size() - 1;+ boxes.push_back(boxes[idx1].merged(objBoxes[objCenters[mid].second]));+ children.push_back(idx1);+ children.push_back(mid + (int)objects.size() - 1);+ }+ else {+ int mid = from + (to - from) / 2;+ nth_element(objCenters.begin() + from, objCenters.begin() + mid,+ objCenters.begin() + to, VectorComparator(dim)); //partition+ build(objCenters, from, mid, objBoxes, (dim + 1) % Dim);+ int idx1 = (int)boxes.size() - 1;+ build(objCenters, mid, to, objBoxes, (dim + 1) % Dim);+ int idx2 = (int)boxes.size() - 1;+ boxes.push_back(boxes[idx1].merged(boxes[idx2]));+ children.push_back(idx1);+ children.push_back(idx2);+ }+ }++ std::vector<int> children; //children of x are children[2x] and children[2x+1], indices bigger than boxes.size() index into objects.+ VolumeList boxes;+ ObjectList objects;+};++} // end namespace Eigen++#endif //KDBVH_H_INCLUDED
+ eigen3/unsupported/Eigen/src/CMakeLists.txt view
@@ -0,0 +1,14 @@+ADD_SUBDIRECTORY(AutoDiff)+ADD_SUBDIRECTORY(BVH)+ADD_SUBDIRECTORY(FFT)+ADD_SUBDIRECTORY(IterativeSolvers)+ADD_SUBDIRECTORY(KroneckerProduct)+ADD_SUBDIRECTORY(LevenbergMarquardt)+ADD_SUBDIRECTORY(MatrixFunctions)+ADD_SUBDIRECTORY(MoreVectorization)+ADD_SUBDIRECTORY(NonLinearOptimization)+ADD_SUBDIRECTORY(NumericalDiff)+ADD_SUBDIRECTORY(Polynomials)+ADD_SUBDIRECTORY(Skyline)+ADD_SUBDIRECTORY(SparseExtra)+ADD_SUBDIRECTORY(Splines)
+ eigen3/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h view
@@ -0,0 +1,805 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 David Harmon <dharmon@gmail.com>+//+// Eigen is free software; you can redistribute it and/or+// modify it under the terms of the GNU Lesser General Public+// License as published by the Free Software Foundation; either+// version 3 of the License, or (at your option) any later version.+//+// Alternatively, you can redistribute it and/or+// modify it under the terms of the GNU General Public License as+// published by the Free Software Foundation; either version 2 of+// the License, or (at your option) any later version.+//+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the+// GNU General Public License for more details.+//+// You should have received a copy of the GNU Lesser General Public+// License and a copy of the GNU General Public License along with+// Eigen. If not, see <http://www.gnu.org/licenses/>.++#ifndef EIGEN_ARPACKGENERALIZEDSELFADJOINTEIGENSOLVER_H+#define EIGEN_ARPACKGENERALIZEDSELFADJOINTEIGENSOLVER_H++#include <Eigen/Dense>++namespace Eigen { ++namespace internal {+ template<typename Scalar, typename RealScalar> struct arpack_wrapper;+ template<typename MatrixSolver, typename MatrixType, typename Scalar, bool BisSPD> struct OP;+}++++template<typename MatrixType, typename MatrixSolver=SimplicialLLT<MatrixType>, bool BisSPD=false>+class ArpackGeneralizedSelfAdjointEigenSolver+{+public:+ //typedef typename MatrixSolver::MatrixType MatrixType;++ /** \brief Scalar type for matrices of type \p MatrixType. */+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::Index Index;++ /** \brief Real scalar type for \p MatrixType.+ *+ * This is just \c Scalar if #Scalar is real (e.g., \c float or+ * \c Scalar), and the type of the real part of \c Scalar if #Scalar is+ * complex.+ */+ typedef typename NumTraits<Scalar>::Real RealScalar;++ /** \brief Type for vector of eigenvalues as returned by eigenvalues().+ *+ * This is a column vector with entries of type #RealScalar.+ * The length of the vector is the size of \p nbrEigenvalues.+ */+ typedef typename internal::plain_col_type<MatrixType, RealScalar>::type RealVectorType;++ /** \brief Default constructor.+ *+ * The default constructor is for cases in which the user intends to+ * perform decompositions via compute().+ *+ */+ ArpackGeneralizedSelfAdjointEigenSolver()+ : m_eivec(),+ m_eivalues(),+ m_isInitialized(false),+ m_eigenvectorsOk(false),+ m_nbrConverged(0),+ m_nbrIterations(0)+ { }++ /** \brief Constructor; computes generalized eigenvalues of given matrix with respect to another matrix.+ *+ * \param[in] A Self-adjoint matrix whose eigenvalues / eigenvectors will+ * computed. By default, the upper triangular part is used, but can be changed+ * through the template parameter.+ * \param[in] B Self-adjoint matrix for the generalized eigenvalue problem.+ * \param[in] nbrEigenvalues The number of eigenvalues / eigenvectors to compute.+ * Must be less than the size of the input matrix, or an error is returned.+ * \param[in] eigs_sigma String containing either "LM", "SM", "LA", or "SA", with+ * respective meanings to find the largest magnitude , smallest magnitude,+ * largest algebraic, or smallest algebraic eigenvalues. Alternatively, this+ * value can contain floating point value in string form, in which case the+ * eigenvalues closest to this value will be found.+ * \param[in] options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly.+ * \param[in] tol What tolerance to find the eigenvalues to. Default is 0, which+ * means machine precision.+ *+ * This constructor calls compute(const MatrixType&, const MatrixType&, Index, string, int, RealScalar)+ * to compute the eigenvalues of the matrix \p A with respect to \p B. The eigenvectors are computed if+ * \p options equals #ComputeEigenvectors.+ *+ */+ ArpackGeneralizedSelfAdjointEigenSolver(const MatrixType& A, const MatrixType& B,+ Index nbrEigenvalues, std::string eigs_sigma="LM",+ int options=ComputeEigenvectors, RealScalar tol=0.0)+ : m_eivec(),+ m_eivalues(),+ m_isInitialized(false),+ m_eigenvectorsOk(false),+ m_nbrConverged(0),+ m_nbrIterations(0)+ {+ compute(A, B, nbrEigenvalues, eigs_sigma, options, tol);+ }++ /** \brief Constructor; computes eigenvalues of given matrix.+ *+ * \param[in] A Self-adjoint matrix whose eigenvalues / eigenvectors will+ * computed. By default, the upper triangular part is used, but can be changed+ * through the template parameter.+ * \param[in] nbrEigenvalues The number of eigenvalues / eigenvectors to compute.+ * Must be less than the size of the input matrix, or an error is returned.+ * \param[in] eigs_sigma String containing either "LM", "SM", "LA", or "SA", with+ * respective meanings to find the largest magnitude , smallest magnitude,+ * largest algebraic, or smallest algebraic eigenvalues. Alternatively, this+ * value can contain floating point value in string form, in which case the+ * eigenvalues closest to this value will be found.+ * \param[in] options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly.+ * \param[in] tol What tolerance to find the eigenvalues to. Default is 0, which+ * means machine precision.+ *+ * This constructor calls compute(const MatrixType&, Index, string, int, RealScalar)+ * to compute the eigenvalues of the matrix \p A. The eigenvectors are computed if+ * \p options equals #ComputeEigenvectors.+ *+ */++ ArpackGeneralizedSelfAdjointEigenSolver(const MatrixType& A,+ Index nbrEigenvalues, std::string eigs_sigma="LM",+ int options=ComputeEigenvectors, RealScalar tol=0.0)+ : m_eivec(),+ m_eivalues(),+ m_isInitialized(false),+ m_eigenvectorsOk(false),+ m_nbrConverged(0),+ m_nbrIterations(0)+ {+ compute(A, nbrEigenvalues, eigs_sigma, options, tol);+ }+++ /** \brief Computes generalized eigenvalues / eigenvectors of given matrix using the external ARPACK library.+ *+ * \param[in] A Selfadjoint matrix whose eigendecomposition is to be computed.+ * \param[in] B Selfadjoint matrix for generalized eigenvalues.+ * \param[in] nbrEigenvalues The number of eigenvalues / eigenvectors to compute.+ * Must be less than the size of the input matrix, or an error is returned.+ * \param[in] eigs_sigma String containing either "LM", "SM", "LA", or "SA", with+ * respective meanings to find the largest magnitude , smallest magnitude,+ * largest algebraic, or smallest algebraic eigenvalues. Alternatively, this+ * value can contain floating point value in string form, in which case the+ * eigenvalues closest to this value will be found.+ * \param[in] options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly.+ * \param[in] tol What tolerance to find the eigenvalues to. Default is 0, which+ * means machine precision.+ *+ * \returns Reference to \c *this+ *+ * This function computes the generalized eigenvalues of \p A with respect to \p B using ARPACK. The eigenvalues()+ * function can be used to retrieve them. If \p options equals #ComputeEigenvectors,+ * then the eigenvectors are also computed and can be retrieved by+ * calling eigenvectors().+ *+ */+ ArpackGeneralizedSelfAdjointEigenSolver& compute(const MatrixType& A, const MatrixType& B,+ Index nbrEigenvalues, std::string eigs_sigma="LM",+ int options=ComputeEigenvectors, RealScalar tol=0.0);+ + /** \brief Computes eigenvalues / eigenvectors of given matrix using the external ARPACK library.+ *+ * \param[in] A Selfadjoint matrix whose eigendecomposition is to be computed.+ * \param[in] nbrEigenvalues The number of eigenvalues / eigenvectors to compute.+ * Must be less than the size of the input matrix, or an error is returned.+ * \param[in] eigs_sigma String containing either "LM", "SM", "LA", or "SA", with+ * respective meanings to find the largest magnitude , smallest magnitude,+ * largest algebraic, or smallest algebraic eigenvalues. Alternatively, this+ * value can contain floating point value in string form, in which case the+ * eigenvalues closest to this value will be found.+ * \param[in] options Can be #ComputeEigenvectors (default) or #EigenvaluesOnly.+ * \param[in] tol What tolerance to find the eigenvalues to. Default is 0, which+ * means machine precision.+ *+ * \returns Reference to \c *this+ *+ * This function computes the eigenvalues of \p A using ARPACK. The eigenvalues()+ * function can be used to retrieve them. If \p options equals #ComputeEigenvectors,+ * then the eigenvectors are also computed and can be retrieved by+ * calling eigenvectors().+ *+ */+ ArpackGeneralizedSelfAdjointEigenSolver& compute(const MatrixType& A,+ Index nbrEigenvalues, std::string eigs_sigma="LM",+ int options=ComputeEigenvectors, RealScalar tol=0.0);+++ /** \brief Returns the eigenvectors of given matrix.+ *+ * \returns A const reference to the matrix whose columns are the eigenvectors.+ *+ * \pre The eigenvectors have been computed before.+ *+ * Column \f$ k \f$ of the returned matrix is an eigenvector corresponding+ * to eigenvalue number \f$ k \f$ as returned by eigenvalues(). The+ * eigenvectors are normalized to have (Euclidean) norm equal to one. If+ * this object was used to solve the eigenproblem for the selfadjoint+ * matrix \f$ A \f$, then the matrix returned by this function is the+ * matrix \f$ V \f$ in the eigendecomposition \f$ A V = D V \f$.+ * For the generalized eigenproblem, the matrix returned is the solution \f$ A V = D B V \f$+ *+ * Example: \include SelfAdjointEigenSolver_eigenvectors.cpp+ * Output: \verbinclude SelfAdjointEigenSolver_eigenvectors.out+ *+ * \sa eigenvalues()+ */+ const Matrix<Scalar, Dynamic, Dynamic>& eigenvectors() const+ {+ eigen_assert(m_isInitialized && "ArpackGeneralizedSelfAdjointEigenSolver is not initialized.");+ eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");+ return m_eivec;+ }++ /** \brief Returns the eigenvalues of given matrix.+ *+ * \returns A const reference to the column vector containing the eigenvalues.+ *+ * \pre The eigenvalues have been computed before.+ *+ * The eigenvalues are repeated according to their algebraic multiplicity,+ * so there are as many eigenvalues as rows in the matrix. The eigenvalues+ * are sorted in increasing order.+ *+ * Example: \include SelfAdjointEigenSolver_eigenvalues.cpp+ * Output: \verbinclude SelfAdjointEigenSolver_eigenvalues.out+ *+ * \sa eigenvectors(), MatrixBase::eigenvalues()+ */+ const Matrix<Scalar, Dynamic, 1>& eigenvalues() const+ {+ eigen_assert(m_isInitialized && "ArpackGeneralizedSelfAdjointEigenSolver is not initialized.");+ return m_eivalues;+ }++ /** \brief Computes the positive-definite square root of the matrix.+ *+ * \returns the positive-definite square root of the matrix+ *+ * \pre The eigenvalues and eigenvectors of a positive-definite matrix+ * have been computed before.+ *+ * The square root of a positive-definite matrix \f$ A \f$ is the+ * positive-definite matrix whose square equals \f$ A \f$. This function+ * uses the eigendecomposition \f$ A = V D V^{-1} \f$ to compute the+ * square root as \f$ A^{1/2} = V D^{1/2} V^{-1} \f$.+ *+ * Example: \include SelfAdjointEigenSolver_operatorSqrt.cpp+ * Output: \verbinclude SelfAdjointEigenSolver_operatorSqrt.out+ *+ * \sa operatorInverseSqrt(),+ * \ref MatrixFunctions_Module "MatrixFunctions Module"+ */+ Matrix<Scalar, Dynamic, Dynamic> operatorSqrt() const+ {+ eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");+ eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");+ return m_eivec * m_eivalues.cwiseSqrt().asDiagonal() * m_eivec.adjoint();+ }++ /** \brief Computes the inverse square root of the matrix.+ *+ * \returns the inverse positive-definite square root of the matrix+ *+ * \pre The eigenvalues and eigenvectors of a positive-definite matrix+ * have been computed before.+ *+ * This function uses the eigendecomposition \f$ A = V D V^{-1} \f$ to+ * compute the inverse square root as \f$ V D^{-1/2} V^{-1} \f$. This is+ * cheaper than first computing the square root with operatorSqrt() and+ * then its inverse with MatrixBase::inverse().+ *+ * Example: \include SelfAdjointEigenSolver_operatorInverseSqrt.cpp+ * Output: \verbinclude SelfAdjointEigenSolver_operatorInverseSqrt.out+ *+ * \sa operatorSqrt(), MatrixBase::inverse(),+ * \ref MatrixFunctions_Module "MatrixFunctions Module"+ */+ Matrix<Scalar, Dynamic, Dynamic> operatorInverseSqrt() const+ {+ eigen_assert(m_isInitialized && "SelfAdjointEigenSolver is not initialized.");+ eigen_assert(m_eigenvectorsOk && "The eigenvectors have not been computed together with the eigenvalues.");+ return m_eivec * m_eivalues.cwiseInverse().cwiseSqrt().asDiagonal() * m_eivec.adjoint();+ }++ /** \brief Reports whether previous computation was successful.+ *+ * \returns \c Success if computation was succesful, \c NoConvergence otherwise.+ */+ ComputationInfo info() const+ {+ eigen_assert(m_isInitialized && "ArpackGeneralizedSelfAdjointEigenSolver is not initialized.");+ return m_info;+ }++ size_t getNbrConvergedEigenValues() const+ { return m_nbrConverged; }++ size_t getNbrIterations() const+ { return m_nbrIterations; }++protected:+ Matrix<Scalar, Dynamic, Dynamic> m_eivec;+ Matrix<Scalar, Dynamic, 1> m_eivalues;+ ComputationInfo m_info;+ bool m_isInitialized;+ bool m_eigenvectorsOk;++ size_t m_nbrConverged;+ size_t m_nbrIterations;+};++++++template<typename MatrixType, typename MatrixSolver, bool BisSPD>+ArpackGeneralizedSelfAdjointEigenSolver<MatrixType, MatrixSolver, BisSPD>&+ ArpackGeneralizedSelfAdjointEigenSolver<MatrixType, MatrixSolver, BisSPD>+::compute(const MatrixType& A, Index nbrEigenvalues,+ std::string eigs_sigma, int options, RealScalar tol)+{+ MatrixType B(0,0);+ compute(A, B, nbrEigenvalues, eigs_sigma, options, tol);+ + return *this;+}+++template<typename MatrixType, typename MatrixSolver, bool BisSPD>+ArpackGeneralizedSelfAdjointEigenSolver<MatrixType, MatrixSolver, BisSPD>&+ ArpackGeneralizedSelfAdjointEigenSolver<MatrixType, MatrixSolver, BisSPD>+::compute(const MatrixType& A, const MatrixType& B, Index nbrEigenvalues,+ std::string eigs_sigma, int options, RealScalar tol)+{+ eigen_assert(A.cols() == A.rows());+ eigen_assert(B.cols() == B.rows());+ eigen_assert(B.rows() == 0 || A.cols() == B.rows());+ eigen_assert((options &~ (EigVecMask | GenEigMask)) == 0+ && (options & EigVecMask) != EigVecMask+ && "invalid option parameter");++ bool isBempty = (B.rows() == 0) || (B.cols() == 0);++ // For clarity, all parameters match their ARPACK name+ //+ // Always 0 on the first call+ //+ int ido = 0;++ int n = (int)A.cols();++ // User options: "LA", "SA", "SM", "LM", "BE"+ //+ char whch[3] = "LM";+ + // Specifies the shift if iparam[6] = { 3, 4, 5 }, not used if iparam[6] = { 1, 2 }+ //+ RealScalar sigma = 0.0;++ if (eigs_sigma.length() >= 2 && isalpha(eigs_sigma[0]) && isalpha(eigs_sigma[1]))+ {+ eigs_sigma[0] = toupper(eigs_sigma[0]);+ eigs_sigma[1] = toupper(eigs_sigma[1]);++ // In the following special case we're going to invert the problem, since solving+ // for larger magnitude is much much faster+ // i.e., if 'SM' is specified, we're going to really use 'LM', the default+ //+ if (eigs_sigma.substr(0,2) != "SM")+ {+ whch[0] = eigs_sigma[0];+ whch[1] = eigs_sigma[1];+ }+ }+ else+ {+ eigen_assert(false && "Specifying clustered eigenvalues is not yet supported!");++ // If it's not scalar values, then the user may be explicitly+ // specifying the sigma value to cluster the evs around+ //+ sigma = atof(eigs_sigma.c_str());++ // If atof fails, it returns 0.0, which is a fine default+ //+ }++ // "I" means normal eigenvalue problem, "G" means generalized+ //+ char bmat[2] = "I";+ if (eigs_sigma.substr(0,2) == "SM" || !(isalpha(eigs_sigma[0]) && isalpha(eigs_sigma[1])) || (!isBempty && !BisSPD))+ bmat[0] = 'G';++ // Now we determine the mode to use+ //+ int mode = (bmat[0] == 'G') + 1;+ if (eigs_sigma.substr(0,2) == "SM" || !(isalpha(eigs_sigma[0]) && isalpha(eigs_sigma[1])))+ {+ // We're going to use shift-and-invert mode, and basically find+ // the largest eigenvalues of the inverse operator+ //+ mode = 3;+ }++ // The user-specified number of eigenvalues/vectors to compute+ //+ int nev = (int)nbrEigenvalues;++ // Allocate space for ARPACK to store the residual+ //+ Scalar *resid = new Scalar[n];++ // Number of Lanczos vectors, must satisfy nev < ncv <= n+ // Note that this indicates that nev != n, and we cannot compute+ // all eigenvalues of a mtrix+ //+ int ncv = std::min(std::max(2*nev, 20), n);++ // The working n x ncv matrix, also store the final eigenvectors (if computed)+ //+ Scalar *v = new Scalar[n*ncv];+ int ldv = n;++ // Working space+ //+ Scalar *workd = new Scalar[3*n];+ int lworkl = ncv*ncv+8*ncv; // Must be at least this length+ Scalar *workl = new Scalar[lworkl];++ int *iparam= new int[11];+ iparam[0] = 1; // 1 means we let ARPACK perform the shifts, 0 means we'd have to do it+ iparam[2] = std::max(300, (int)std::ceil(2*n/std::max(ncv,1)));+ iparam[6] = mode; // The mode, 1 is standard ev problem, 2 for generalized ev, 3 for shift-and-invert++ // Used during reverse communicate to notify where arrays start+ //+ int *ipntr = new int[11]; ++ // Error codes are returned in here, initial value of 0 indicates a random initial+ // residual vector is used, any other values means resid contains the initial residual+ // vector, possibly from a previous run+ //+ int info = 0;++ Scalar scale = 1.0;+ //if (!isBempty)+ //{+ //Scalar scale = B.norm() / std::sqrt(n);+ //scale = std::pow(2, std::floor(std::log(scale+1)));+ ////M /= scale;+ //for (size_t i=0; i<(size_t)B.outerSize(); i++)+ // for (typename MatrixType::InnerIterator it(B, i); it; ++it)+ // it.valueRef() /= scale;+ //}++ MatrixSolver OP;+ if (mode == 1 || mode == 2)+ {+ if (!isBempty)+ OP.compute(B);+ }+ else if (mode == 3)+ {+ if (sigma == 0.0)+ {+ OP.compute(A);+ }+ else+ {+ // Note: We will never enter here because sigma must be 0.0+ //+ if (isBempty)+ {+ MatrixType AminusSigmaB(A);+ for (Index i=0; i<A.rows(); ++i)+ AminusSigmaB.coeffRef(i,i) -= sigma;+ + OP.compute(AminusSigmaB);+ }+ else+ {+ MatrixType AminusSigmaB = A - sigma * B;+ OP.compute(AminusSigmaB);+ }+ }+ }+ + if (!(mode == 1 && isBempty) && !(mode == 2 && isBempty) && OP.info() != Success)+ std::cout << "Error factoring matrix" << std::endl;++ do+ {+ internal::arpack_wrapper<Scalar, RealScalar>::saupd(&ido, bmat, &n, whch, &nev, &tol, resid, + &ncv, v, &ldv, iparam, ipntr, workd, workl,+ &lworkl, &info);++ if (ido == -1 || ido == 1)+ {+ Scalar *in = workd + ipntr[0] - 1;+ Scalar *out = workd + ipntr[1] - 1;++ if (ido == 1 && mode != 2)+ {+ Scalar *out2 = workd + ipntr[2] - 1;+ if (isBempty || mode == 1)+ Matrix<Scalar, Dynamic, 1>::Map(out2, n) = Matrix<Scalar, Dynamic, 1>::Map(in, n);+ else+ Matrix<Scalar, Dynamic, 1>::Map(out2, n) = B * Matrix<Scalar, Dynamic, 1>::Map(in, n);+ + in = workd + ipntr[2] - 1;+ }++ if (mode == 1)+ {+ if (isBempty)+ {+ // OP = A+ //+ Matrix<Scalar, Dynamic, 1>::Map(out, n) = A * Matrix<Scalar, Dynamic, 1>::Map(in, n);+ }+ else+ {+ // OP = L^{-1}AL^{-T}+ //+ internal::OP<MatrixSolver, MatrixType, Scalar, BisSPD>::applyOP(OP, A, n, in, out);+ }+ }+ else if (mode == 2)+ {+ if (ido == 1)+ Matrix<Scalar, Dynamic, 1>::Map(in, n) = A * Matrix<Scalar, Dynamic, 1>::Map(in, n);+ + // OP = B^{-1} A+ //+ Matrix<Scalar, Dynamic, 1>::Map(out, n) = OP.solve(Matrix<Scalar, Dynamic, 1>::Map(in, n));+ }+ else if (mode == 3)+ {+ // OP = (A-\sigmaB)B (\sigma could be 0, and B could be I)+ // The B * in is already computed and stored at in if ido == 1+ //+ if (ido == 1 || isBempty)+ Matrix<Scalar, Dynamic, 1>::Map(out, n) = OP.solve(Matrix<Scalar, Dynamic, 1>::Map(in, n));+ else+ Matrix<Scalar, Dynamic, 1>::Map(out, n) = OP.solve(B * Matrix<Scalar, Dynamic, 1>::Map(in, n));+ }+ }+ else if (ido == 2)+ {+ Scalar *in = workd + ipntr[0] - 1;+ Scalar *out = workd + ipntr[1] - 1;++ if (isBempty || mode == 1)+ Matrix<Scalar, Dynamic, 1>::Map(out, n) = Matrix<Scalar, Dynamic, 1>::Map(in, n);+ else+ Matrix<Scalar, Dynamic, 1>::Map(out, n) = B * Matrix<Scalar, Dynamic, 1>::Map(in, n);+ }+ } while (ido != 99);++ if (info == 1)+ m_info = NoConvergence;+ else if (info == 3)+ m_info = NumericalIssue;+ else if (info < 0)+ m_info = InvalidInput;+ else if (info != 0)+ eigen_assert(false && "Unknown ARPACK return value!");+ else+ {+ // Do we compute eigenvectors or not?+ //+ int rvec = (options & ComputeEigenvectors) == ComputeEigenvectors;++ // "A" means "All", use "S" to choose specific eigenvalues (not yet supported in ARPACK))+ //+ char howmny[2] = "A"; ++ // if howmny == "S", specifies the eigenvalues to compute (not implemented in ARPACK)+ //+ int *select = new int[ncv];++ // Final eigenvalues+ //+ m_eivalues.resize(nev, 1);++ internal::arpack_wrapper<Scalar, RealScalar>::seupd(&rvec, howmny, select, m_eivalues.data(), v, &ldv,+ &sigma, bmat, &n, whch, &nev, &tol, resid, &ncv,+ v, &ldv, iparam, ipntr, workd, workl, &lworkl, &info);++ if (info == -14)+ m_info = NoConvergence;+ else if (info != 0)+ m_info = InvalidInput;+ else+ {+ if (rvec)+ {+ m_eivec.resize(A.rows(), nev);+ for (int i=0; i<nev; i++)+ for (int j=0; j<n; j++)+ m_eivec(j,i) = v[i*n+j] / scale;+ + if (mode == 1 && !isBempty && BisSPD)+ internal::OP<MatrixSolver, MatrixType, Scalar, BisSPD>::project(OP, n, nev, m_eivec.data());++ m_eigenvectorsOk = true;+ }++ m_nbrIterations = iparam[2];+ m_nbrConverged = iparam[4];++ m_info = Success;+ }++ delete select;+ }++ delete v;+ delete iparam;+ delete ipntr;+ delete workd;+ delete workl;+ delete resid;++ m_isInitialized = true;++ return *this;+}+++// Single precision+//+extern "C" void ssaupd_(int *ido, char *bmat, int *n, char *which,+ int *nev, float *tol, float *resid, int *ncv,+ float *v, int *ldv, int *iparam, int *ipntr,+ float *workd, float *workl, int *lworkl,+ int *info);++extern "C" void sseupd_(int *rvec, char *All, int *select, float *d,+ float *z, int *ldz, float *sigma, + char *bmat, int *n, char *which, int *nev,+ float *tol, float *resid, int *ncv, float *v,+ int *ldv, int *iparam, int *ipntr, float *workd,+ float *workl, int *lworkl, int *ierr);++// Double precision+//+extern "C" void dsaupd_(int *ido, char *bmat, int *n, char *which,+ int *nev, double *tol, double *resid, int *ncv,+ double *v, int *ldv, int *iparam, int *ipntr,+ double *workd, double *workl, int *lworkl,+ int *info);++extern "C" void dseupd_(int *rvec, char *All, int *select, double *d,+ double *z, int *ldz, double *sigma, + char *bmat, int *n, char *which, int *nev,+ double *tol, double *resid, int *ncv, double *v,+ int *ldv, int *iparam, int *ipntr, double *workd,+ double *workl, int *lworkl, int *ierr);+++namespace internal {++template<typename Scalar, typename RealScalar> struct arpack_wrapper+{+ static inline void saupd(int *ido, char *bmat, int *n, char *which,+ int *nev, RealScalar *tol, Scalar *resid, int *ncv,+ Scalar *v, int *ldv, int *iparam, int *ipntr,+ Scalar *workd, Scalar *workl, int *lworkl, int *info)+ { + EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsComplex, NUMERIC_TYPE_MUST_BE_REAL)+ }++ static inline void seupd(int *rvec, char *All, int *select, Scalar *d,+ Scalar *z, int *ldz, RealScalar *sigma,+ char *bmat, int *n, char *which, int *nev,+ RealScalar *tol, Scalar *resid, int *ncv, Scalar *v,+ int *ldv, int *iparam, int *ipntr, Scalar *workd,+ Scalar *workl, int *lworkl, int *ierr)+ {+ EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::IsComplex, NUMERIC_TYPE_MUST_BE_REAL)+ }+};++template <> struct arpack_wrapper<float, float>+{+ static inline void saupd(int *ido, char *bmat, int *n, char *which,+ int *nev, float *tol, float *resid, int *ncv,+ float *v, int *ldv, int *iparam, int *ipntr,+ float *workd, float *workl, int *lworkl, int *info)+ {+ ssaupd_(ido, bmat, n, which, nev, tol, resid, ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, info);+ }++ static inline void seupd(int *rvec, char *All, int *select, float *d,+ float *z, int *ldz, float *sigma,+ char *bmat, int *n, char *which, int *nev,+ float *tol, float *resid, int *ncv, float *v,+ int *ldv, int *iparam, int *ipntr, float *workd,+ float *workl, int *lworkl, int *ierr)+ {+ sseupd_(rvec, All, select, d, z, ldz, sigma, bmat, n, which, nev, tol, resid, ncv, v, ldv, iparam, ipntr,+ workd, workl, lworkl, ierr);+ }+};++template <> struct arpack_wrapper<double, double>+{+ static inline void saupd(int *ido, char *bmat, int *n, char *which,+ int *nev, double *tol, double *resid, int *ncv,+ double *v, int *ldv, int *iparam, int *ipntr,+ double *workd, double *workl, int *lworkl, int *info)+ {+ dsaupd_(ido, bmat, n, which, nev, tol, resid, ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, info);+ }++ static inline void seupd(int *rvec, char *All, int *select, double *d,+ double *z, int *ldz, double *sigma,+ char *bmat, int *n, char *which, int *nev,+ double *tol, double *resid, int *ncv, double *v,+ int *ldv, int *iparam, int *ipntr, double *workd,+ double *workl, int *lworkl, int *ierr)+ {+ dseupd_(rvec, All, select, d, v, ldv, sigma, bmat, n, which, nev, tol, resid, ncv, v, ldv, iparam, ipntr,+ workd, workl, lworkl, ierr);+ }+};+++template<typename MatrixSolver, typename MatrixType, typename Scalar, bool BisSPD>+struct OP+{+ static inline void applyOP(MatrixSolver &OP, const MatrixType &A, int n, Scalar *in, Scalar *out);+ static inline void project(MatrixSolver &OP, int n, int k, Scalar *vecs);+};++template<typename MatrixSolver, typename MatrixType, typename Scalar>+struct OP<MatrixSolver, MatrixType, Scalar, true>+{+ static inline void applyOP(MatrixSolver &OP, const MatrixType &A, int n, Scalar *in, Scalar *out)+{+ // OP = L^{-1} A L^{-T} (B = LL^T)+ //+ // First solve L^T out = in+ //+ Matrix<Scalar, Dynamic, 1>::Map(out, n) = OP.matrixU().solve(Matrix<Scalar, Dynamic, 1>::Map(in, n));+ Matrix<Scalar, Dynamic, 1>::Map(out, n) = OP.permutationPinv() * Matrix<Scalar, Dynamic, 1>::Map(out, n);++ // Then compute out = A out+ //+ Matrix<Scalar, Dynamic, 1>::Map(out, n) = A * Matrix<Scalar, Dynamic, 1>::Map(out, n);++ // Then solve L out = out+ //+ Matrix<Scalar, Dynamic, 1>::Map(out, n) = OP.permutationP() * Matrix<Scalar, Dynamic, 1>::Map(out, n);+ Matrix<Scalar, Dynamic, 1>::Map(out, n) = OP.matrixL().solve(Matrix<Scalar, Dynamic, 1>::Map(out, n));+}++ static inline void project(MatrixSolver &OP, int n, int k, Scalar *vecs)+{+ // Solve L^T out = in+ //+ Matrix<Scalar, Dynamic, Dynamic>::Map(vecs, n, k) = OP.matrixU().solve(Matrix<Scalar, Dynamic, Dynamic>::Map(vecs, n, k));+ Matrix<Scalar, Dynamic, Dynamic>::Map(vecs, n, k) = OP.permutationPinv() * Matrix<Scalar, Dynamic, Dynamic>::Map(vecs, n, k);+}++};++template<typename MatrixSolver, typename MatrixType, typename Scalar>+struct OP<MatrixSolver, MatrixType, Scalar, false>+{+ static inline void applyOP(MatrixSolver &OP, const MatrixType &A, int n, Scalar *in, Scalar *out)+{+ eigen_assert(false && "Should never be in here...");+}++ static inline void project(MatrixSolver &OP, int n, int k, Scalar *vecs)+{+ eigen_assert(false && "Should never be in here...");+}++};++} // end namespace internal++} // end namespace Eigen++#endif // EIGEN_ARPACKSELFADJOINTEIGENSOLVER_H+
+ eigen3/unsupported/Eigen/src/FFT/CMakeLists.txt view
@@ -0,0 +1,6 @@+FILE(GLOB Eigen_FFT_SRCS "*.h")++INSTALL(FILES+ ${Eigen_FFT_SRCS}+ DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/FFT COMPONENT Devel+ )
+ eigen3/unsupported/Eigen/src/FFT/ei_fftw_impl.h view
@@ -0,0 +1,261 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra. +//+// Copyright (C) 2009 Mark Borgerding mark a borgerding net+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++namespace Eigen { ++namespace internal {++ // FFTW uses non-const arguments+ // so we must use ugly const_cast calls for all the args it uses+ //+ // This should be safe as long as + // 1. we use FFTW_ESTIMATE for all our planning+ // see the FFTW docs section 4.3.2 "Planner Flags"+ // 2. fftw_complex is compatible with std::complex+ // This assumes std::complex<T> layout is array of size 2 with real,imag+ template <typename T> + inline + T * fftw_cast(const T* p)+ { + return const_cast<T*>( p); + }++ inline + fftw_complex * fftw_cast( const std::complex<double> * p)+ {+ return const_cast<fftw_complex*>( reinterpret_cast<const fftw_complex*>(p) ); + }++ inline + fftwf_complex * fftw_cast( const std::complex<float> * p)+ { + return const_cast<fftwf_complex*>( reinterpret_cast<const fftwf_complex*>(p) ); + }++ inline + fftwl_complex * fftw_cast( const std::complex<long double> * p)+ { + return const_cast<fftwl_complex*>( reinterpret_cast<const fftwl_complex*>(p) ); + }++ template <typename T> + struct fftw_plan {};++ template <> + struct fftw_plan<float>+ {+ typedef float scalar_type;+ typedef fftwf_complex complex_type;+ fftwf_plan m_plan;+ fftw_plan() :m_plan(NULL) {}+ ~fftw_plan() {if (m_plan) fftwf_destroy_plan(m_plan);}++ inline+ void fwd(complex_type * dst,complex_type * src,int nfft) {+ if (m_plan==NULL) m_plan = fftwf_plan_dft_1d(nfft,src,dst, FFTW_FORWARD, FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftwf_execute_dft( m_plan, src,dst);+ }+ inline+ void inv(complex_type * dst,complex_type * src,int nfft) {+ if (m_plan==NULL) m_plan = fftwf_plan_dft_1d(nfft,src,dst, FFTW_BACKWARD , FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftwf_execute_dft( m_plan, src,dst);+ }+ inline+ void fwd(complex_type * dst,scalar_type * src,int nfft) {+ if (m_plan==NULL) m_plan = fftwf_plan_dft_r2c_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftwf_execute_dft_r2c( m_plan,src,dst);+ }+ inline+ void inv(scalar_type * dst,complex_type * src,int nfft) {+ if (m_plan==NULL)+ m_plan = fftwf_plan_dft_c2r_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftwf_execute_dft_c2r( m_plan, src,dst);+ }++ inline + void fwd2( complex_type * dst,complex_type * src,int n0,int n1) {+ if (m_plan==NULL) m_plan = fftwf_plan_dft_2d(n0,n1,src,dst,FFTW_FORWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftwf_execute_dft( m_plan, src,dst);+ }+ inline + void inv2( complex_type * dst,complex_type * src,int n0,int n1) {+ if (m_plan==NULL) m_plan = fftwf_plan_dft_2d(n0,n1,src,dst,FFTW_BACKWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftwf_execute_dft( m_plan, src,dst);+ }++ };+ template <> + struct fftw_plan<double>+ {+ typedef double scalar_type;+ typedef fftw_complex complex_type;+ ::fftw_plan m_plan;+ fftw_plan() :m_plan(NULL) {}+ ~fftw_plan() {if (m_plan) fftw_destroy_plan(m_plan);}++ inline+ void fwd(complex_type * dst,complex_type * src,int nfft) {+ if (m_plan==NULL) m_plan = fftw_plan_dft_1d(nfft,src,dst, FFTW_FORWARD, FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftw_execute_dft( m_plan, src,dst);+ }+ inline+ void inv(complex_type * dst,complex_type * src,int nfft) {+ if (m_plan==NULL) m_plan = fftw_plan_dft_1d(nfft,src,dst, FFTW_BACKWARD , FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftw_execute_dft( m_plan, src,dst);+ }+ inline+ void fwd(complex_type * dst,scalar_type * src,int nfft) {+ if (m_plan==NULL) m_plan = fftw_plan_dft_r2c_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftw_execute_dft_r2c( m_plan,src,dst);+ }+ inline+ void inv(scalar_type * dst,complex_type * src,int nfft) {+ if (m_plan==NULL)+ m_plan = fftw_plan_dft_c2r_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftw_execute_dft_c2r( m_plan, src,dst);+ }+ inline + void fwd2( complex_type * dst,complex_type * src,int n0,int n1) {+ if (m_plan==NULL) m_plan = fftw_plan_dft_2d(n0,n1,src,dst,FFTW_FORWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftw_execute_dft( m_plan, src,dst);+ }+ inline + void inv2( complex_type * dst,complex_type * src,int n0,int n1) {+ if (m_plan==NULL) m_plan = fftw_plan_dft_2d(n0,n1,src,dst,FFTW_BACKWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftw_execute_dft( m_plan, src,dst);+ }+ };+ template <> + struct fftw_plan<long double>+ {+ typedef long double scalar_type;+ typedef fftwl_complex complex_type;+ fftwl_plan m_plan;+ fftw_plan() :m_plan(NULL) {}+ ~fftw_plan() {if (m_plan) fftwl_destroy_plan(m_plan);}++ inline+ void fwd(complex_type * dst,complex_type * src,int nfft) {+ if (m_plan==NULL) m_plan = fftwl_plan_dft_1d(nfft,src,dst, FFTW_FORWARD, FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftwl_execute_dft( m_plan, src,dst);+ }+ inline+ void inv(complex_type * dst,complex_type * src,int nfft) {+ if (m_plan==NULL) m_plan = fftwl_plan_dft_1d(nfft,src,dst, FFTW_BACKWARD , FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftwl_execute_dft( m_plan, src,dst);+ }+ inline+ void fwd(complex_type * dst,scalar_type * src,int nfft) {+ if (m_plan==NULL) m_plan = fftwl_plan_dft_r2c_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftwl_execute_dft_r2c( m_plan,src,dst);+ }+ inline+ void inv(scalar_type * dst,complex_type * src,int nfft) {+ if (m_plan==NULL)+ m_plan = fftwl_plan_dft_c2r_1d(nfft,src,dst,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftwl_execute_dft_c2r( m_plan, src,dst);+ }+ inline + void fwd2( complex_type * dst,complex_type * src,int n0,int n1) {+ if (m_plan==NULL) m_plan = fftwl_plan_dft_2d(n0,n1,src,dst,FFTW_FORWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftwl_execute_dft( m_plan, src,dst);+ }+ inline + void inv2( complex_type * dst,complex_type * src,int n0,int n1) {+ if (m_plan==NULL) m_plan = fftwl_plan_dft_2d(n0,n1,src,dst,FFTW_BACKWARD,FFTW_ESTIMATE|FFTW_PRESERVE_INPUT);+ fftwl_execute_dft( m_plan, src,dst);+ }+ };++ template <typename _Scalar>+ struct fftw_impl+ {+ typedef _Scalar Scalar;+ typedef std::complex<Scalar> Complex;++ inline+ void clear() + {+ m_plans.clear();+ }++ // complex-to-complex forward FFT+ inline+ void fwd( Complex * dst,const Complex *src,int nfft)+ {+ get_plan(nfft,false,dst,src).fwd(fftw_cast(dst), fftw_cast(src),nfft );+ }++ // real-to-complex forward FFT+ inline+ void fwd( Complex * dst,const Scalar * src,int nfft) + {+ get_plan(nfft,false,dst,src).fwd(fftw_cast(dst), fftw_cast(src) ,nfft);+ }++ // 2-d complex-to-complex+ inline+ void fwd2(Complex * dst, const Complex * src, int n0,int n1)+ {+ get_plan(n0,n1,false,dst,src).fwd2(fftw_cast(dst), fftw_cast(src) ,n0,n1);+ }++ // inverse complex-to-complex+ inline+ void inv(Complex * dst,const Complex *src,int nfft)+ {+ get_plan(nfft,true,dst,src).inv(fftw_cast(dst), fftw_cast(src),nfft );+ }++ // half-complex to scalar+ inline+ void inv( Scalar * dst,const Complex * src,int nfft) + {+ get_plan(nfft,true,dst,src).inv(fftw_cast(dst), fftw_cast(src),nfft );+ }++ // 2-d complex-to-complex+ inline+ void inv2(Complex * dst, const Complex * src, int n0,int n1)+ {+ get_plan(n0,n1,true,dst,src).inv2(fftw_cast(dst), fftw_cast(src) ,n0,n1);+ }+++ protected:+ typedef fftw_plan<Scalar> PlanData;++ typedef std::map<int64_t,PlanData> PlanMap;++ PlanMap m_plans;++ inline+ PlanData & get_plan(int nfft,bool inverse,void * dst,const void * src)+ {+ bool inplace = (dst==src);+ bool aligned = ( (reinterpret_cast<size_t>(src)&15) | (reinterpret_cast<size_t>(dst)&15) ) == 0;+ int64_t key = ( (nfft<<3 ) | (inverse<<2) | (inplace<<1) | aligned ) << 1;+ return m_plans[key];+ }++ inline+ PlanData & get_plan(int n0,int n1,bool inverse,void * dst,const void * src)+ {+ bool inplace = (dst==src);+ bool aligned = ( (reinterpret_cast<size_t>(src)&15) | (reinterpret_cast<size_t>(dst)&15) ) == 0;+ int64_t key = ( ( (((int64_t)n0) << 30)|(n1<<3 ) | (inverse<<2) | (inplace<<1) | aligned ) << 1 ) + 1;+ return m_plans[key];+ }+ };++} // end namespace internal++} // end namespace Eigen++/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+ eigen3/unsupported/Eigen/src/FFT/ei_kissfft_impl.h view
@@ -0,0 +1,420 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Mark Borgerding mark a borgerding net+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++namespace Eigen { ++namespace internal {++ // This FFT implementation was derived from kissfft http:sourceforge.net/projects/kissfft+ // Copyright 2003-2009 Mark Borgerding++template <typename _Scalar>+struct kiss_cpx_fft+{+ typedef _Scalar Scalar;+ typedef std::complex<Scalar> Complex;+ std::vector<Complex> m_twiddles;+ std::vector<int> m_stageRadix;+ std::vector<int> m_stageRemainder;+ std::vector<Complex> m_scratchBuf;+ bool m_inverse;++ inline+ void make_twiddles(int nfft,bool inverse)+ {+ using std::acos;+ m_inverse = inverse;+ m_twiddles.resize(nfft);+ Scalar phinc = (inverse?2:-2)* acos( (Scalar) -1) / nfft;+ for (int i=0;i<nfft;++i)+ m_twiddles[i] = exp( Complex(0,i*phinc) );+ }++ void factorize(int nfft)+ {+ //start factoring out 4's, then 2's, then 3,5,7,9,...+ int n= nfft;+ int p=4;+ do {+ while (n % p) {+ switch (p) {+ case 4: p = 2; break;+ case 2: p = 3; break;+ default: p += 2; break;+ }+ if (p*p>n)+ p=n;// impossible to have a factor > sqrt(n)+ }+ n /= p;+ m_stageRadix.push_back(p);+ m_stageRemainder.push_back(n);+ if ( p > 5 )+ m_scratchBuf.resize(p); // scratchbuf will be needed in bfly_generic+ }while(n>1);+ }++ template <typename _Src>+ inline+ void work( int stage,Complex * xout, const _Src * xin, size_t fstride,size_t in_stride)+ {+ int p = m_stageRadix[stage];+ int m = m_stageRemainder[stage];+ Complex * Fout_beg = xout;+ Complex * Fout_end = xout + p*m;++ if (m>1) {+ do{+ // recursive call:+ // DFT of size m*p performed by doing+ // p instances of smaller DFTs of size m, + // each one takes a decimated version of the input+ work(stage+1, xout , xin, fstride*p,in_stride);+ xin += fstride*in_stride;+ }while( (xout += m) != Fout_end );+ }else{+ do{+ *xout = *xin;+ xin += fstride*in_stride;+ }while(++xout != Fout_end );+ }+ xout=Fout_beg;++ // recombine the p smaller DFTs + switch (p) {+ case 2: bfly2(xout,fstride,m); break;+ case 3: bfly3(xout,fstride,m); break;+ case 4: bfly4(xout,fstride,m); break;+ case 5: bfly5(xout,fstride,m); break;+ default: bfly_generic(xout,fstride,m,p); break;+ }+ }++ inline+ void bfly2( Complex * Fout, const size_t fstride, int m)+ {+ for (int k=0;k<m;++k) {+ Complex t = Fout[m+k] * m_twiddles[k*fstride];+ Fout[m+k] = Fout[k] - t;+ Fout[k] += t;+ }+ }++ inline+ void bfly4( Complex * Fout, const size_t fstride, const size_t m)+ {+ Complex scratch[6];+ int negative_if_inverse = m_inverse * -2 +1;+ for (size_t k=0;k<m;++k) {+ scratch[0] = Fout[k+m] * m_twiddles[k*fstride];+ scratch[1] = Fout[k+2*m] * m_twiddles[k*fstride*2];+ scratch[2] = Fout[k+3*m] * m_twiddles[k*fstride*3];+ scratch[5] = Fout[k] - scratch[1];++ Fout[k] += scratch[1];+ scratch[3] = scratch[0] + scratch[2];+ scratch[4] = scratch[0] - scratch[2];+ scratch[4] = Complex( scratch[4].imag()*negative_if_inverse , -scratch[4].real()* negative_if_inverse );++ Fout[k+2*m] = Fout[k] - scratch[3];+ Fout[k] += scratch[3];+ Fout[k+m] = scratch[5] + scratch[4];+ Fout[k+3*m] = scratch[5] - scratch[4];+ }+ }++ inline+ void bfly3( Complex * Fout, const size_t fstride, const size_t m)+ {+ size_t k=m;+ const size_t m2 = 2*m;+ Complex *tw1,*tw2;+ Complex scratch[5];+ Complex epi3;+ epi3 = m_twiddles[fstride*m];++ tw1=tw2=&m_twiddles[0];++ do{+ scratch[1]=Fout[m] * *tw1;+ scratch[2]=Fout[m2] * *tw2;++ scratch[3]=scratch[1]+scratch[2];+ scratch[0]=scratch[1]-scratch[2];+ tw1 += fstride;+ tw2 += fstride*2;+ Fout[m] = Complex( Fout->real() - Scalar(.5)*scratch[3].real() , Fout->imag() - Scalar(.5)*scratch[3].imag() );+ scratch[0] *= epi3.imag();+ *Fout += scratch[3];+ Fout[m2] = Complex( Fout[m].real() + scratch[0].imag() , Fout[m].imag() - scratch[0].real() );+ Fout[m] += Complex( -scratch[0].imag(),scratch[0].real() );+ ++Fout;+ }while(--k);+ }++ inline+ void bfly5( Complex * Fout, const size_t fstride, const size_t m)+ {+ Complex *Fout0,*Fout1,*Fout2,*Fout3,*Fout4;+ size_t u;+ Complex scratch[13];+ Complex * twiddles = &m_twiddles[0];+ Complex *tw;+ Complex ya,yb;+ ya = twiddles[fstride*m];+ yb = twiddles[fstride*2*m];++ Fout0=Fout;+ Fout1=Fout0+m;+ Fout2=Fout0+2*m;+ Fout3=Fout0+3*m;+ Fout4=Fout0+4*m;++ tw=twiddles;+ for ( u=0; u<m; ++u ) {+ scratch[0] = *Fout0;++ scratch[1] = *Fout1 * tw[u*fstride];+ scratch[2] = *Fout2 * tw[2*u*fstride];+ scratch[3] = *Fout3 * tw[3*u*fstride];+ scratch[4] = *Fout4 * tw[4*u*fstride];++ scratch[7] = scratch[1] + scratch[4];+ scratch[10] = scratch[1] - scratch[4];+ scratch[8] = scratch[2] + scratch[3];+ scratch[9] = scratch[2] - scratch[3];++ *Fout0 += scratch[7];+ *Fout0 += scratch[8];++ scratch[5] = scratch[0] + Complex(+ (scratch[7].real()*ya.real() ) + (scratch[8].real() *yb.real() ),+ (scratch[7].imag()*ya.real()) + (scratch[8].imag()*yb.real())+ );++ scratch[6] = Complex(+ (scratch[10].imag()*ya.imag()) + (scratch[9].imag()*yb.imag()),+ -(scratch[10].real()*ya.imag()) - (scratch[9].real()*yb.imag())+ );++ *Fout1 = scratch[5] - scratch[6];+ *Fout4 = scratch[5] + scratch[6];++ scratch[11] = scratch[0] ++ Complex(+ (scratch[7].real()*yb.real()) + (scratch[8].real()*ya.real()),+ (scratch[7].imag()*yb.real()) + (scratch[8].imag()*ya.real())+ );++ scratch[12] = Complex(+ -(scratch[10].imag()*yb.imag()) + (scratch[9].imag()*ya.imag()),+ (scratch[10].real()*yb.imag()) - (scratch[9].real()*ya.imag())+ );++ *Fout2=scratch[11]+scratch[12];+ *Fout3=scratch[11]-scratch[12];++ ++Fout0;++Fout1;++Fout2;++Fout3;++Fout4;+ }+ }++ /* perform the butterfly for one stage of a mixed radix FFT */+ inline+ void bfly_generic(+ Complex * Fout,+ const size_t fstride,+ int m,+ int p+ )+ {+ int u,k,q1,q;+ Complex * twiddles = &m_twiddles[0];+ Complex t;+ int Norig = static_cast<int>(m_twiddles.size());+ Complex * scratchbuf = &m_scratchBuf[0];++ for ( u=0; u<m; ++u ) {+ k=u;+ for ( q1=0 ; q1<p ; ++q1 ) {+ scratchbuf[q1] = Fout[ k ];+ k += m;+ }++ k=u;+ for ( q1=0 ; q1<p ; ++q1 ) {+ int twidx=0;+ Fout[ k ] = scratchbuf[0];+ for (q=1;q<p;++q ) {+ twidx += static_cast<int>(fstride) * k;+ if (twidx>=Norig) twidx-=Norig;+ t=scratchbuf[q] * twiddles[twidx];+ Fout[ k ] += t;+ }+ k += m;+ }+ }+ }+};++template <typename _Scalar>+struct kissfft_impl+{+ typedef _Scalar Scalar;+ typedef std::complex<Scalar> Complex;++ void clear() + {+ m_plans.clear();+ m_realTwiddles.clear();+ }++ inline+ void fwd( Complex * dst,const Complex *src,int nfft)+ {+ get_plan(nfft,false).work(0, dst, src, 1,1);+ }++ inline+ void fwd2( Complex * dst,const Complex *src,int n0,int n1)+ {+ EIGEN_UNUSED_VARIABLE(dst);+ EIGEN_UNUSED_VARIABLE(src);+ EIGEN_UNUSED_VARIABLE(n0);+ EIGEN_UNUSED_VARIABLE(n1);+ }++ inline+ void inv2( Complex * dst,const Complex *src,int n0,int n1)+ {+ EIGEN_UNUSED_VARIABLE(dst);+ EIGEN_UNUSED_VARIABLE(src);+ EIGEN_UNUSED_VARIABLE(n0);+ EIGEN_UNUSED_VARIABLE(n1);+ }++ // real-to-complex forward FFT+ // perform two FFTs of src even and src odd+ // then twiddle to recombine them into the half-spectrum format+ // then fill in the conjugate symmetric half+ inline+ void fwd( Complex * dst,const Scalar * src,int nfft) + {+ if ( nfft&3 ) {+ // use generic mode for odd+ m_tmpBuf1.resize(nfft);+ get_plan(nfft,false).work(0, &m_tmpBuf1[0], src, 1,1);+ std::copy(m_tmpBuf1.begin(),m_tmpBuf1.begin()+(nfft>>1)+1,dst );+ }else{+ int ncfft = nfft>>1;+ int ncfft2 = nfft>>2;+ Complex * rtw = real_twiddles(ncfft2);++ // use optimized mode for even real+ fwd( dst, reinterpret_cast<const Complex*> (src), ncfft);+ Complex dc = dst[0].real() + dst[0].imag();+ Complex nyquist = dst[0].real() - dst[0].imag();+ int k;+ for ( k=1;k <= ncfft2 ; ++k ) {+ Complex fpk = dst[k];+ Complex fpnk = conj(dst[ncfft-k]);+ Complex f1k = fpk + fpnk;+ Complex f2k = fpk - fpnk;+ Complex tw= f2k * rtw[k-1];+ dst[k] = (f1k + tw) * Scalar(.5);+ dst[ncfft-k] = conj(f1k -tw)*Scalar(.5);+ }+ dst[0] = dc;+ dst[ncfft] = nyquist;+ }+ }++ // inverse complex-to-complex+ inline+ void inv(Complex * dst,const Complex *src,int nfft)+ {+ get_plan(nfft,true).work(0, dst, src, 1,1);+ }++ // half-complex to scalar+ inline+ void inv( Scalar * dst,const Complex * src,int nfft) + {+ if (nfft&3) {+ m_tmpBuf1.resize(nfft);+ m_tmpBuf2.resize(nfft);+ std::copy(src,src+(nfft>>1)+1,m_tmpBuf1.begin() );+ for (int k=1;k<(nfft>>1)+1;++k)+ m_tmpBuf1[nfft-k] = conj(m_tmpBuf1[k]);+ inv(&m_tmpBuf2[0],&m_tmpBuf1[0],nfft);+ for (int k=0;k<nfft;++k)+ dst[k] = m_tmpBuf2[k].real();+ }else{+ // optimized version for multiple of 4+ int ncfft = nfft>>1;+ int ncfft2 = nfft>>2;+ Complex * rtw = real_twiddles(ncfft2);+ m_tmpBuf1.resize(ncfft);+ m_tmpBuf1[0] = Complex( src[0].real() + src[ncfft].real(), src[0].real() - src[ncfft].real() );+ for (int k = 1; k <= ncfft / 2; ++k) {+ Complex fk = src[k];+ Complex fnkc = conj(src[ncfft-k]);+ Complex fek = fk + fnkc;+ Complex tmp = fk - fnkc;+ Complex fok = tmp * conj(rtw[k-1]);+ m_tmpBuf1[k] = fek + fok;+ m_tmpBuf1[ncfft-k] = conj(fek - fok);+ }+ get_plan(ncfft,true).work(0, reinterpret_cast<Complex*>(dst), &m_tmpBuf1[0], 1,1);+ }+ }++ protected:+ typedef kiss_cpx_fft<Scalar> PlanData;+ typedef std::map<int,PlanData> PlanMap;++ PlanMap m_plans;+ std::map<int, std::vector<Complex> > m_realTwiddles;+ std::vector<Complex> m_tmpBuf1;+ std::vector<Complex> m_tmpBuf2;++ inline+ int PlanKey(int nfft, bool isinverse) const { return (nfft<<1) | int(isinverse); }++ inline+ PlanData & get_plan(int nfft, bool inverse)+ {+ // TODO look for PlanKey(nfft, ! inverse) and conjugate the twiddles+ PlanData & pd = m_plans[ PlanKey(nfft,inverse) ];+ if ( pd.m_twiddles.size() == 0 ) {+ pd.make_twiddles(nfft,inverse);+ pd.factorize(nfft);+ }+ return pd;+ }++ inline+ Complex * real_twiddles(int ncfft2)+ {+ using std::acos;+ std::vector<Complex> & twidref = m_realTwiddles[ncfft2];// creates new if not there+ if ( (int)twidref.size() != ncfft2 ) {+ twidref.resize(ncfft2);+ int ncfft= ncfft2<<1;+ Scalar pi = acos( Scalar(-1) );+ for (int k=1;k<=ncfft2;++k) + twidref[k-1] = exp( Complex(0,-pi * (Scalar(k) / ncfft + Scalar(.5)) ) );+ }+ return &twidref[0];+ }+};++} // end namespace internal++} // end namespace Eigen++/* vim: set filetype=cpp et sw=2 ts=2 ai: */
+ eigen3/unsupported/Eigen/src/IterativeSolvers/CMakeLists.txt view
@@ -0,0 +1,6 @@+FILE(GLOB Eigen_IterativeSolvers_SRCS "*.h")++INSTALL(FILES+ ${Eigen_IterativeSolvers_SRCS}+ DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/IterativeSolvers COMPONENT Devel+ )
+ eigen3/unsupported/Eigen/src/IterativeSolvers/ConstrainedConjGrad.h view
@@ -0,0 +1,189 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>++/* NOTE The functions of this file have been adapted from the GMM++ library */++//========================================================================+//+// Copyright (C) 2002-2007 Yves Renard+//+// This file is a part of GETFEM+++//+// Getfem++ is free software; you can redistribute it and/or modify+// it under the terms of the GNU Lesser General Public License as+// published by the Free Software Foundation; version 2.1 of the License.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU Lesser General Public License for more details.+// You should have received a copy of the GNU Lesser General Public+// License along with this program; if not, write to the Free Software+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,+// USA.+//+//========================================================================++#include "../../../../Eigen/src/Core/util/NonMPL2.h"++#ifndef EIGEN_CONSTRAINEDCG_H+#define EIGEN_CONSTRAINEDCG_H++#include <Eigen/Core>++namespace Eigen { ++namespace internal {++/** \ingroup IterativeSolvers_Module+ * Compute the pseudo inverse of the non-square matrix C such that+ * \f$ CINV = (C * C^T)^{-1} * C \f$ based on a conjugate gradient method.+ *+ * This function is internally used by constrained_cg.+ */+template <typename CMatrix, typename CINVMatrix>+void pseudo_inverse(const CMatrix &C, CINVMatrix &CINV)+{+ // optimisable : copie de la ligne, precalcul de C * trans(C).+ typedef typename CMatrix::Scalar Scalar;+ typedef typename CMatrix::Index Index;+ // FIXME use sparse vectors ?+ typedef Matrix<Scalar,Dynamic,1> TmpVec;++ Index rows = C.rows(), cols = C.cols();++ TmpVec d(rows), e(rows), l(cols), p(rows), q(rows), r(rows);+ Scalar rho, rho_1, alpha;+ d.setZero();++ typedef Triplet<double> T;+ std::vector<T> tripletList;+ + for (Index i = 0; i < rows; ++i)+ {+ d[i] = 1.0;+ rho = 1.0;+ e.setZero();+ r = d;+ p = d;++ while (rho >= 1e-38)+ { /* conjugate gradient to compute e */+ /* which is the i-th row of inv(C * trans(C)) */+ l = C.transpose() * p;+ q = C * l;+ alpha = rho / p.dot(q);+ e += alpha * p;+ r += -alpha * q;+ rho_1 = rho;+ rho = r.dot(r);+ p = (rho/rho_1) * p + r;+ }++ l = C.transpose() * e; // l is the i-th row of CINV+ // FIXME add a generic "prune/filter" expression for both dense and sparse object to sparse+ for (Index j=0; j<l.size(); ++j)+ if (l[j]<1e-15)+ tripletList.push_back(T(i,j,l(j)));++ + d[i] = 0.0;+ }+ CINV.setFromTriplets(tripletList.begin(), tripletList.end());+}++++/** \ingroup IterativeSolvers_Module+ * Constrained conjugate gradient+ *+ * Computes the minimum of \f$ 1/2((Ax).x) - bx \f$ under the contraint \f$ Cx \le f \f$+ */+template<typename TMatrix, typename CMatrix,+ typename VectorX, typename VectorB, typename VectorF>+void constrained_cg(const TMatrix& A, const CMatrix& C, VectorX& x,+ const VectorB& b, const VectorF& f, IterationController &iter)+{+ using std::sqrt;+ typedef typename TMatrix::Scalar Scalar;+ typedef typename TMatrix::Index Index;+ typedef Matrix<Scalar,Dynamic,1> TmpVec;++ Scalar rho = 1.0, rho_1, lambda, gamma;+ Index xSize = x.size();+ TmpVec p(xSize), q(xSize), q2(xSize),+ r(xSize), old_z(xSize), z(xSize),+ memox(xSize);+ std::vector<bool> satured(C.rows());+ p.setZero();+ iter.setRhsNorm(sqrt(b.dot(b))); // gael vect_sp(PS, b, b)+ if (iter.rhsNorm() == 0.0) iter.setRhsNorm(1.0);++ SparseMatrix<Scalar,RowMajor> CINV(C.rows(), C.cols());+ pseudo_inverse(C, CINV);++ while(true)+ {+ // computation of residual+ old_z = z;+ memox = x;+ r = b;+ r += A * -x;+ z = r;+ bool transition = false;+ for (Index i = 0; i < C.rows(); ++i)+ {+ Scalar al = C.row(i).dot(x) - f.coeff(i);+ if (al >= -1.0E-15)+ {+ if (!satured[i])+ {+ satured[i] = true;+ transition = true;+ }+ Scalar bb = CINV.row(i).dot(z);+ if (bb > 0.0)+ // FIXME: we should allow that: z += -bb * C.row(i);+ for (typename CMatrix::InnerIterator it(C,i); it; ++it)+ z.coeffRef(it.index()) -= bb*it.value();+ }+ else+ satured[i] = false;+ }++ // descent direction+ rho_1 = rho;+ rho = r.dot(z);++ if (iter.finished(rho)) break;++ if (iter.noiseLevel() > 0 && transition) std::cerr << "CCG: transition\n";+ if (transition || iter.first()) gamma = 0.0;+ else gamma = (std::max)(0.0, (rho - old_z.dot(z)) / rho_1);+ p = z + gamma*p;++ ++iter;+ // one dimensionnal optimization+ q = A * p;+ lambda = rho / q.dot(p);+ for (Index i = 0; i < C.rows(); ++i)+ {+ if (!satured[i])+ {+ Scalar bb = C.row(i).dot(p) - f[i];+ if (bb > 0.0)+ lambda = (std::min)(lambda, (f.coeff(i)-C.row(i).dot(x)) / bb);+ }+ }+ x += lambda * p;+ memox -= x;+ }+}++} // end namespace internal++} // end namespace Eigen++#endif // EIGEN_CONSTRAINEDCG_H
+ eigen3/unsupported/Eigen/src/IterativeSolvers/DGMRES.h view
@@ -0,0 +1,542 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_DGMRES_H+#define EIGEN_DGMRES_H++#include <Eigen/Eigenvalues>++namespace Eigen { + +template< typename _MatrixType,+ typename _Preconditioner = DiagonalPreconditioner<typename _MatrixType::Scalar> >+class DGMRES;++namespace internal {++template< typename _MatrixType, typename _Preconditioner>+struct traits<DGMRES<_MatrixType,_Preconditioner> >+{+ typedef _MatrixType MatrixType;+ typedef _Preconditioner Preconditioner;+};++/** \brief Computes a permutation vector to have a sorted sequence+ * \param vec The vector to reorder.+ * \param perm gives the sorted sequence on output. Must be initialized with 0..n-1+ * \param ncut Put the ncut smallest elements at the end of the vector+ * WARNING This is an expensive sort, so should be used only + * for small size vectors+ * TODO Use modified QuickSplit or std::nth_element to get the smallest values + */+template <typename VectorType, typename IndexType>+void sortWithPermutation (VectorType& vec, IndexType& perm, typename IndexType::Scalar& ncut)+{+ eigen_assert(vec.size() == perm.size());+ typedef typename IndexType::Scalar Index; + typedef typename VectorType::Scalar Scalar; + bool flag; + for (Index k = 0; k < ncut; k++)+ {+ flag = false;+ for (Index j = 0; j < vec.size()-1; j++)+ {+ if ( vec(perm(j)) < vec(perm(j+1)) )+ {+ std::swap(perm(j),perm(j+1)); + flag = true;+ }+ if (!flag) break; // The vector is in sorted order+ }+ }+}++}+/**+ * \ingroup IterativeLInearSolvers_Module+ * \brief A Restarted GMRES with deflation.+ * This class implements a modification of the GMRES solver for+ * sparse linear systems. The basis is built with modified + * Gram-Schmidt. At each restart, a few approximated eigenvectors+ * corresponding to the smallest eigenvalues are used to build a+ * preconditioner for the next cycle. This preconditioner + * for deflation can be combined with any other preconditioner, + * the IncompleteLUT for instance. The preconditioner is applied + * at right of the matrix and the combination is multiplicative.+ * + * \tparam _MatrixType the type of the sparse matrix A, can be a dense or a sparse matrix.+ * \tparam _Preconditioner the type of the preconditioner. Default is DiagonalPreconditioner+ * Typical usage :+ * \code+ * SparseMatrix<double> A;+ * VectorXd x, b; + * //Fill A and b ...+ * DGMRES<SparseMatrix<double> > solver;+ * solver.set_restart(30); // Set restarting value+ * solver.setEigenv(1); // Set the number of eigenvalues to deflate+ * solver.compute(A);+ * x = solver.solve(b);+ * \endcode+ * + * References :+ * [1] D. NUENTSA WAKAM and F. PACULL, Memory Efficient Hybrid+ * Algebraic Solvers for Linear Systems Arising from Compressible+ * Flows, Computers and Fluids, In Press,+ * http://dx.doi.org/10.1016/j.compfluid.2012.03.023 + * [2] K. Burrage and J. Erhel, On the performance of various + * adaptive preconditioned GMRES strategies, 5(1998), 101-121.+ * [3] J. Erhel, K. Burrage and B. Pohl, Restarted GMRES + * preconditioned by deflation,J. Computational and Applied+ * Mathematics, 69(1996), 303-318. ++ * + */+template< typename _MatrixType, typename _Preconditioner>+class DGMRES : public IterativeSolverBase<DGMRES<_MatrixType,_Preconditioner> >+{+ typedef IterativeSolverBase<DGMRES> Base;+ using Base::mp_matrix;+ using Base::m_error;+ using Base::m_iterations;+ using Base::m_info;+ using Base::m_isInitialized;+ using Base::m_tolerance; + public:+ typedef _MatrixType MatrixType;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::RealScalar RealScalar;+ typedef _Preconditioner Preconditioner;+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix; + typedef Matrix<RealScalar,Dynamic,Dynamic> DenseRealMatrix; + typedef Matrix<Scalar,Dynamic,1> DenseVector;+ typedef Matrix<RealScalar,Dynamic,1> DenseRealVector; + typedef Matrix<std::complex<RealScalar>, Dynamic, 1> ComplexVector;+ + + /** Default constructor. */+ DGMRES() : Base(),m_restart(30),m_neig(0),m_r(0),m_maxNeig(5),m_isDeflAllocated(false),m_isDeflInitialized(false) {}++ /** Initialize the solver with matrix \a A for further \c Ax=b solving.+ * + * This constructor is a shortcut for the default constructor followed+ * by a call to compute().+ * + * \warning this class stores a reference to the matrix A as well as some+ * precomputed values that depend on it. Therefore, if \a A is changed+ * this class becomes invalid. Call compute() to update it with the new+ * matrix A, or modify a copy of A.+ */+ DGMRES(const MatrixType& A) : Base(A),m_restart(30),m_neig(0),m_r(0),m_maxNeig(5),m_isDeflAllocated(false),m_isDeflInitialized(false)+ {}++ ~DGMRES() {}+ + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A+ * \a x0 as an initial solution.+ *+ * \sa compute()+ */+ template<typename Rhs,typename Guess>+ inline const internal::solve_retval_with_guess<DGMRES, Rhs, Guess>+ solveWithGuess(const MatrixBase<Rhs>& b, const Guess& x0) const+ {+ eigen_assert(m_isInitialized && "DGMRES is not initialized.");+ eigen_assert(Base::rows()==b.rows()+ && "DGMRES::solve(): invalid number of rows of the right hand side matrix b");+ return internal::solve_retval_with_guess+ <DGMRES, Rhs, Guess>(*this, b.derived(), x0);+ }+ + /** \internal */+ template<typename Rhs,typename Dest>+ void _solveWithGuess(const Rhs& b, Dest& x) const+ { + bool failed = false;+ for(int j=0; j<b.cols(); ++j)+ {+ m_iterations = Base::maxIterations();+ m_error = Base::m_tolerance;+ + typename Dest::ColXpr xj(x,j);+ dgmres(*mp_matrix, b.col(j), xj, Base::m_preconditioner);+ }+ m_info = failed ? NumericalIssue+ : m_error <= Base::m_tolerance ? Success+ : NoConvergence;+ m_isInitialized = true;+ }++ /** \internal */+ template<typename Rhs,typename Dest>+ void _solve(const Rhs& b, Dest& x) const+ {+ x = b;+ _solveWithGuess(b,x);+ }+ /** + * Get the restart value+ */+ int restart() { return m_restart; }+ + /** + * Set the restart value (default is 30) + */+ void set_restart(const int restart) { m_restart=restart; }+ + /** + * Set the number of eigenvalues to deflate at each restart + */+ void setEigenv(const int neig) + {+ m_neig = neig;+ if (neig+1 > m_maxNeig) m_maxNeig = neig+1; // To allow for complex conjugates+ }+ + /** + * Get the size of the deflation subspace size+ */ + int deflSize() {return m_r; }+ + /**+ * Set the maximum size of the deflation subspace+ */+ void setMaxEigenv(const int maxNeig) { m_maxNeig = maxNeig; }+ + protected:+ // DGMRES algorithm + template<typename Rhs, typename Dest>+ void dgmres(const MatrixType& mat,const Rhs& rhs, Dest& x, const Preconditioner& precond) const;+ // Perform one cycle of GMRES+ template<typename Dest>+ int dgmresCycle(const MatrixType& mat, const Preconditioner& precond, Dest& x, DenseVector& r0, RealScalar& beta, const RealScalar& normRhs, int& nbIts) const; + // Compute data to use for deflation + int dgmresComputeDeflationData(const MatrixType& mat, const Preconditioner& precond, const Index& it, Index& neig) const;+ // Apply deflation to a vector+ template<typename RhsType, typename DestType>+ int dgmresApplyDeflation(const RhsType& In, DestType& Out) const; + ComplexVector schurValues(const ComplexSchur<DenseMatrix>& schurofH) const;+ ComplexVector schurValues(const RealSchur<DenseMatrix>& schurofH) const;+ // Init data for deflation+ void dgmresInitDeflation(Index& rows) const; + mutable DenseMatrix m_V; // Krylov basis vectors+ mutable DenseMatrix m_H; // Hessenberg matrix + mutable DenseMatrix m_Hes; // Initial hessenberg matrix wihout Givens rotations applied+ mutable Index m_restart; // Maximum size of the Krylov subspace+ mutable DenseMatrix m_U; // Vectors that form the basis of the invariant subspace + mutable DenseMatrix m_MU; // matrix operator applied to m_U (for next cycles)+ mutable DenseMatrix m_T; /* T=U^T*M^{-1}*A*U */+ mutable PartialPivLU<DenseMatrix> m_luT; // LU factorization of m_T+ mutable int m_neig; //Number of eigenvalues to extract at each restart+ mutable int m_r; // Current number of deflated eigenvalues, size of m_U+ mutable int m_maxNeig; // Maximum number of eigenvalues to deflate+ mutable RealScalar m_lambdaN; //Modulus of the largest eigenvalue of A+ mutable bool m_isDeflAllocated;+ mutable bool m_isDeflInitialized;+ + //Adaptive strategy + mutable RealScalar m_smv; // Smaller multiple of the remaining number of steps allowed+ mutable bool m_force; // Force the use of deflation at each restart+ +}; +/** + * \brief Perform several cycles of restarted GMRES with modified Gram Schmidt, + * + * A right preconditioner is used combined with deflation.+ * + */+template< typename _MatrixType, typename _Preconditioner>+template<typename Rhs, typename Dest>+void DGMRES<_MatrixType, _Preconditioner>::dgmres(const MatrixType& mat,const Rhs& rhs, Dest& x,+ const Preconditioner& precond) const+{+ //Initialization+ int n = mat.rows(); + DenseVector r0(n); + int nbIts = 0; + m_H.resize(m_restart+1, m_restart);+ m_Hes.resize(m_restart, m_restart);+ m_V.resize(n,m_restart+1);+ //Initial residual vector and intial norm+ x = precond.solve(x);+ r0 = rhs - mat * x; + RealScalar beta = r0.norm(); + RealScalar normRhs = rhs.norm();+ m_error = beta/normRhs; + if(m_error < m_tolerance)+ m_info = Success; + else+ m_info = NoConvergence;+ + // Iterative process+ while (nbIts < m_iterations && m_info == NoConvergence)+ {+ dgmresCycle(mat, precond, x, r0, beta, normRhs, nbIts); + + // Compute the new residual vector for the restart + if (nbIts < m_iterations && m_info == NoConvergence)+ r0 = rhs - mat * x; + }+} ++/**+ * \brief Perform one restart cycle of DGMRES+ * \param mat The coefficient matrix+ * \param precond The preconditioner+ * \param x the new approximated solution+ * \param r0 The initial residual vector+ * \param beta The norm of the residual computed so far+ * \param normRhs The norm of the right hand side vector+ * \param nbIts The number of iterations+ */+template< typename _MatrixType, typename _Preconditioner>+template<typename Dest>+int DGMRES<_MatrixType, _Preconditioner>::dgmresCycle(const MatrixType& mat, const Preconditioner& precond, Dest& x, DenseVector& r0, RealScalar& beta, const RealScalar& normRhs, int& nbIts) const+{+ //Initialization + DenseVector g(m_restart+1); // Right hand side of the least square problem+ g.setZero(); + g(0) = Scalar(beta); + m_V.col(0) = r0/beta; + m_info = NoConvergence; + std::vector<JacobiRotation<Scalar> >gr(m_restart); // Givens rotations+ int it = 0; // Number of inner iterations + int n = mat.rows();+ DenseVector tv1(n), tv2(n); //Temporary vectors+ while (m_info == NoConvergence && it < m_restart && nbIts < m_iterations)+ { + // Apply preconditioner(s) at right+ if (m_isDeflInitialized )+ {+ dgmresApplyDeflation(m_V.col(it), tv1); // Deflation+ tv2 = precond.solve(tv1); + }+ else+ {+ tv2 = precond.solve(m_V.col(it)); // User's selected preconditioner+ }+ tv1 = mat * tv2; + + // Orthogonalize it with the previous basis in the basis using modified Gram-Schmidt+ Scalar coef; + for (int i = 0; i <= it; ++i)+ { + coef = tv1.dot(m_V.col(i));+ tv1 = tv1 - coef * m_V.col(i); + m_H(i,it) = coef; + m_Hes(i,it) = coef; + }+ // Normalize the vector + coef = tv1.norm(); + m_V.col(it+1) = tv1/coef;+ m_H(it+1, it) = coef;+// m_Hes(it+1,it) = coef; + + // FIXME Check for happy breakdown + + // Update Hessenberg matrix with Givens rotations+ for (int i = 1; i <= it; ++i) + {+ m_H.col(it).applyOnTheLeft(i-1,i,gr[i-1].adjoint());+ }+ // Compute the new plane rotation + gr[it].makeGivens(m_H(it, it), m_H(it+1,it)); + // Apply the new rotation+ m_H.col(it).applyOnTheLeft(it,it+1,gr[it].adjoint());+ g.applyOnTheLeft(it,it+1, gr[it].adjoint()); + + beta = std::abs(g(it+1));+ m_error = beta/normRhs; + std::cerr << nbIts << " Relative Residual Norm " << m_error << std::endl;+ it++; nbIts++; + + if (m_error < m_tolerance)+ {+ // The method has converged+ m_info = Success;+ break;+ }+ }+ + // Compute the new coefficients by solving the least square problem+// it++;+ //FIXME Check first if the matrix is singular ... zero diagonal+ DenseVector nrs(m_restart); + nrs = m_H.topLeftCorner(it,it).template triangularView<Upper>().solve(g.head(it)); + + // Form the new solution+ if (m_isDeflInitialized)+ {+ tv1 = m_V.leftCols(it) * nrs; + dgmresApplyDeflation(tv1, tv2); + x = x + precond.solve(tv2);+ }+ else+ x = x + precond.solve(m_V.leftCols(it) * nrs); + + // Go for a new cycle and compute data for deflation+ if(nbIts < m_iterations && m_info == NoConvergence && m_neig > 0 && (m_r+m_neig) < m_maxNeig)+ dgmresComputeDeflationData(mat, precond, it, m_neig); + return 0; + +}+++template< typename _MatrixType, typename _Preconditioner>+void DGMRES<_MatrixType, _Preconditioner>::dgmresInitDeflation(Index& rows) const+{+ m_U.resize(rows, m_maxNeig);+ m_MU.resize(rows, m_maxNeig); + m_T.resize(m_maxNeig, m_maxNeig);+ m_lambdaN = 0.0; + m_isDeflAllocated = true; +}++template< typename _MatrixType, typename _Preconditioner>+inline typename DGMRES<_MatrixType, _Preconditioner>::ComplexVector DGMRES<_MatrixType, _Preconditioner>::schurValues(const ComplexSchur<DenseMatrix>& schurofH) const+{+ return schurofH.matrixT().diagonal();+}++template< typename _MatrixType, typename _Preconditioner>+inline typename DGMRES<_MatrixType, _Preconditioner>::ComplexVector DGMRES<_MatrixType, _Preconditioner>::schurValues(const RealSchur<DenseMatrix>& schurofH) const+{+ typedef typename MatrixType::Index Index;+ const DenseMatrix& T = schurofH.matrixT();+ Index it = T.rows();+ ComplexVector eig(it);+ Index j = 0;+ while (j < it-1)+ {+ if (T(j+1,j) ==Scalar(0))+ {+ eig(j) = std::complex<RealScalar>(T(j,j),RealScalar(0)); + j++; + }+ else+ {+ eig(j) = std::complex<RealScalar>(T(j,j),T(j+1,j)); + eig(j+1) = std::complex<RealScalar>(T(j,j+1),T(j+1,j+1));+ j++;+ }+ }+ if (j < it-1) eig(j) = std::complex<RealScalar>(T(j,j),RealScalar(0));+ return eig;+}++template< typename _MatrixType, typename _Preconditioner>+int DGMRES<_MatrixType, _Preconditioner>::dgmresComputeDeflationData(const MatrixType& mat, const Preconditioner& precond, const Index& it, Index& neig) const+{+ // First, find the Schur form of the Hessenberg matrix H+ typename internal::conditional<NumTraits<Scalar>::IsComplex, ComplexSchur<DenseMatrix>, RealSchur<DenseMatrix> >::type schurofH; + bool computeU = true;+ DenseMatrix matrixQ(it,it); + matrixQ.setIdentity();+ schurofH.computeFromHessenberg(m_Hes.topLeftCorner(it,it), matrixQ, computeU); + + ComplexVector eig(it);+ Matrix<Index,Dynamic,1>perm(it); + eig = this->schurValues(schurofH);+ + // Reorder the absolute values of Schur values+ DenseRealVector modulEig(it); + for (int j=0; j<it; ++j) modulEig(j) = std::abs(eig(j)); + perm.setLinSpaced(it,0,it-1);+ internal::sortWithPermutation(modulEig, perm, neig);+ + if (!m_lambdaN)+ {+ m_lambdaN = (std::max)(modulEig.maxCoeff(), m_lambdaN);+ }+ //Count the real number of extracted eigenvalues (with complex conjugates)+ int nbrEig = 0; + while (nbrEig < neig)+ {+ if(eig(perm(it-nbrEig-1)).imag() == RealScalar(0)) nbrEig++; + else nbrEig += 2; + }+ // Extract the Schur vectors corresponding to the smallest Ritz values+ DenseMatrix Sr(it, nbrEig); + Sr.setZero();+ for (int j = 0; j < nbrEig; j++)+ {+ Sr.col(j) = schurofH.matrixU().col(perm(it-j-1));+ }+ + // Form the Schur vectors of the initial matrix using the Krylov basis+ DenseMatrix X; + X = m_V.leftCols(it) * Sr;+ if (m_r)+ {+ // Orthogonalize X against m_U using modified Gram-Schmidt+ for (int j = 0; j < nbrEig; j++)+ for (int k =0; k < m_r; k++)+ X.col(j) = X.col(j) - (m_U.col(k).dot(X.col(j)))*m_U.col(k); + }+ + // Compute m_MX = A * M^-1 * X+ Index m = m_V.rows();+ if (!m_isDeflAllocated) + dgmresInitDeflation(m); + DenseMatrix MX(m, nbrEig);+ DenseVector tv1(m);+ for (int j = 0; j < nbrEig; j++)+ {+ tv1 = mat * X.col(j);+ MX.col(j) = precond.solve(tv1);+ }+ + //Update m_T = [U'MU U'MX; X'MU X'MX]+ m_T.block(m_r, m_r, nbrEig, nbrEig) = X.transpose() * MX; + if(m_r)+ {+ m_T.block(0, m_r, m_r, nbrEig) = m_U.leftCols(m_r).transpose() * MX; + m_T.block(m_r, 0, nbrEig, m_r) = X.transpose() * m_MU.leftCols(m_r);+ }+ + // Save X into m_U and m_MX in m_MU+ for (int j = 0; j < nbrEig; j++) m_U.col(m_r+j) = X.col(j);+ for (int j = 0; j < nbrEig; j++) m_MU.col(m_r+j) = MX.col(j);+ // Increase the size of the invariant subspace+ m_r += nbrEig; + + // Factorize m_T into m_luT+ m_luT.compute(m_T.topLeftCorner(m_r, m_r));+ + //FIXME CHeck if the factorization was correctly done (nonsingular matrix)+ m_isDeflInitialized = true;+ return 0; +}+template<typename _MatrixType, typename _Preconditioner>+template<typename RhsType, typename DestType>+int DGMRES<_MatrixType, _Preconditioner>::dgmresApplyDeflation(const RhsType &x, DestType &y) const+{+ DenseVector x1 = m_U.leftCols(m_r).transpose() * x; + y = x + m_U.leftCols(m_r) * ( m_lambdaN * m_luT.solve(x1) - x1);+ return 0; +}++namespace internal {++ template<typename _MatrixType, typename _Preconditioner, typename Rhs>+struct solve_retval<DGMRES<_MatrixType, _Preconditioner>, Rhs>+ : solve_retval_base<DGMRES<_MatrixType, _Preconditioner>, Rhs>+{+ typedef DGMRES<_MatrixType, _Preconditioner> Dec;+ EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)++ template<typename Dest> void evalTo(Dest& dst) const+ {+ dec()._solve(rhs(),dst);+ }+};+} // end namespace internal++} // end namespace Eigen+#endif
+ eigen3/unsupported/Eigen/src/IterativeSolvers/GMRES.h view
@@ -0,0 +1,370 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2012, 2014 Kolja Brix <brix@igpm.rwth-aaachen.de>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_GMRES_H+#define EIGEN_GMRES_H++namespace Eigen { ++namespace internal {++/**+ * Generalized Minimal Residual Algorithm based on the+ * Arnoldi algorithm implemented with Householder reflections.+ *+ * Parameters:+ * \param mat matrix of linear system of equations+ * \param Rhs right hand side vector of linear system of equations+ * \param x on input: initial guess, on output: solution+ * \param precond preconditioner used+ * \param iters on input: maximum number of iterations to perform+ * on output: number of iterations performed+ * \param restart number of iterations for a restart+ * \param tol_error on input: residual tolerance+ * on output: residuum achieved+ *+ * \sa IterativeMethods::bicgstab() + * + *+ * For references, please see:+ *+ * Saad, Y. and Schultz, M. H.+ * GMRES: A Generalized Minimal Residual Algorithm for Solving Nonsymmetric Linear Systems.+ * SIAM J.Sci.Stat.Comp. 7, 1986, pp. 856 - 869.+ *+ * Saad, Y.+ * Iterative Methods for Sparse Linear Systems.+ * Society for Industrial and Applied Mathematics, Philadelphia, 2003.+ *+ * Walker, H. F.+ * Implementations of the GMRES method.+ * Comput.Phys.Comm. 53, 1989, pp. 311 - 320.+ *+ * Walker, H. F.+ * Implementation of the GMRES Method using Householder Transformations.+ * SIAM J.Sci.Stat.Comp. 9, 1988, pp. 152 - 163.+ *+ */+template<typename MatrixType, typename Rhs, typename Dest, typename Preconditioner>+bool gmres(const MatrixType & mat, const Rhs & rhs, Dest & x, const Preconditioner & precond,+ int &iters, const int &restart, typename Dest::RealScalar & tol_error) {++ using std::sqrt;+ using std::abs;++ typedef typename Dest::RealScalar RealScalar;+ typedef typename Dest::Scalar Scalar;+ typedef Matrix < Scalar, Dynamic, 1 > VectorType;+ typedef Matrix < Scalar, Dynamic, Dynamic > FMatrixType;++ RealScalar tol = tol_error;+ const int maxIters = iters;+ iters = 0;++ const int m = mat.rows();++ VectorType p0 = rhs - mat*x;+ VectorType r0 = precond.solve(p0);+ + // is initial guess already good enough?+ if(abs(r0.norm()) < tol) {+ return true; + }++ VectorType w = VectorType::Zero(restart + 1);++ FMatrixType H = FMatrixType::Zero(m, restart + 1); // Hessenberg matrix+ VectorType tau = VectorType::Zero(restart + 1);+ std::vector < JacobiRotation < Scalar > > G(restart);++ // generate first Householder vector+ VectorType e(m-1);+ RealScalar beta;+ r0.makeHouseholder(e, tau.coeffRef(0), beta);+ w(0)=(Scalar) beta;+ H.bottomLeftCorner(m - 1, 1) = e;++ for (int k = 1; k <= restart; ++k) {++ ++iters;++ VectorType v = VectorType::Unit(m, k - 1), workspace(m);++ // apply Householder reflections H_{1} ... H_{k-1} to v+ for (int i = k - 1; i >= 0; --i) {+ v.tail(m - i).applyHouseholderOnTheLeft(H.col(i).tail(m - i - 1), tau.coeffRef(i), workspace.data());+ }++ // apply matrix M to v: v = mat * v;+ VectorType t=mat*v;+ v=precond.solve(t);++ // apply Householder reflections H_{k-1} ... H_{1} to v+ for (int i = 0; i < k; ++i) {+ v.tail(m - i).applyHouseholderOnTheLeft(H.col(i).tail(m - i - 1), tau.coeffRef(i), workspace.data());+ }++ if (v.tail(m - k).norm() != 0.0) {++ if (k <= restart) {++ // generate new Householder vector+ VectorType e(m - k - 1);+ RealScalar beta;+ v.tail(m - k).makeHouseholder(e, tau.coeffRef(k), beta);+ H.col(k).tail(m - k - 1) = e;++ // apply Householder reflection H_{k} to v+ v.tail(m - k).applyHouseholderOnTheLeft(H.col(k).tail(m - k - 1), tau.coeffRef(k), workspace.data());++ }+ }++ if (k > 1) {+ for (int i = 0; i < k - 1; ++i) {+ // apply old Givens rotations to v+ v.applyOnTheLeft(i, i + 1, G[i].adjoint());+ }+ }++ if (k<m && v(k) != (Scalar) 0) {+ // determine next Givens rotation+ G[k - 1].makeGivens(v(k - 1), v(k));++ // apply Givens rotation to v and w+ v.applyOnTheLeft(k - 1, k, G[k - 1].adjoint());+ w.applyOnTheLeft(k - 1, k, G[k - 1].adjoint());++ }++ // insert coefficients into upper matrix triangle+ H.col(k - 1).head(k) = v.head(k);++ bool stop=(k==m || abs(w(k)) < tol || iters == maxIters);++ if (stop || k == restart) {++ // solve upper triangular system+ VectorType y = w.head(k);+ H.topLeftCorner(k, k).template triangularView < Eigen::Upper > ().solveInPlace(y);++ // use Horner-like scheme to calculate solution vector+ VectorType x_new = y(k - 1) * VectorType::Unit(m, k - 1);++ // apply Householder reflection H_{k} to x_new+ x_new.tail(m - k + 1).applyHouseholderOnTheLeft(H.col(k - 1).tail(m - k), tau.coeffRef(k - 1), workspace.data());++ for (int i = k - 2; i >= 0; --i) {+ x_new += y(i) * VectorType::Unit(m, i);+ // apply Householder reflection H_{i} to x_new+ x_new.tail(m - i).applyHouseholderOnTheLeft(H.col(i).tail(m - i - 1), tau.coeffRef(i), workspace.data());+ }++ x += x_new;++ if (stop) {+ return true;+ } else {+ k=0;++ // reset data for a restart r0 = rhs - mat * x;+ VectorType p0=mat*x;+ VectorType p1=precond.solve(p0);+ r0 = rhs - p1;+// r0_sqnorm = r0.squaredNorm();+ w = VectorType::Zero(restart + 1);+ H = FMatrixType::Zero(m, restart + 1);+ tau = VectorType::Zero(restart + 1);++ // generate first Householder vector+ RealScalar beta;+ r0.makeHouseholder(e, tau.coeffRef(0), beta);+ w(0)=(Scalar) beta;+ H.bottomLeftCorner(m - 1, 1) = e;++ }++ }++++ }+ + return false;++}++}++template< typename _MatrixType,+ typename _Preconditioner = DiagonalPreconditioner<typename _MatrixType::Scalar> >+class GMRES;++namespace internal {++template< typename _MatrixType, typename _Preconditioner>+struct traits<GMRES<_MatrixType,_Preconditioner> >+{+ typedef _MatrixType MatrixType;+ typedef _Preconditioner Preconditioner;+};++}++/** \ingroup IterativeLinearSolvers_Module+ * \brief A GMRES solver for sparse square problems+ *+ * This class allows to solve for A.x = b sparse linear problems using a generalized minimal+ * residual method. The vectors x and b can be either dense or sparse.+ *+ * \tparam _MatrixType the type of the sparse matrix A, can be a dense or a sparse matrix.+ * \tparam _Preconditioner the type of the preconditioner. Default is DiagonalPreconditioner+ *+ * The maximal number of iterations and tolerance value can be controlled via the setMaxIterations()+ * and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations+ * and NumTraits<Scalar>::epsilon() for the tolerance.+ * + * This class can be used as the direct solver classes. Here is a typical usage example:+ * \code+ * int n = 10000;+ * VectorXd x(n), b(n);+ * SparseMatrix<double> A(n,n);+ * // fill A and b+ * GMRES<SparseMatrix<double> > solver(A);+ * x = solver.solve(b);+ * std::cout << "#iterations: " << solver.iterations() << std::endl;+ * std::cout << "estimated error: " << solver.error() << std::endl;+ * // update b, and solve again+ * x = solver.solve(b);+ * \endcode+ * + * By default the iterations start with x=0 as an initial guess of the solution.+ * One can control the start using the solveWithGuess() method.+ * + * \sa class SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner+ */+template< typename _MatrixType, typename _Preconditioner>+class GMRES : public IterativeSolverBase<GMRES<_MatrixType,_Preconditioner> >+{+ typedef IterativeSolverBase<GMRES> Base;+ using Base::mp_matrix;+ using Base::m_error;+ using Base::m_iterations;+ using Base::m_info;+ using Base::m_isInitialized;+ +private:+ int m_restart;+ +public:+ typedef _MatrixType MatrixType;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::RealScalar RealScalar;+ typedef _Preconditioner Preconditioner;++public:++ /** Default constructor. */+ GMRES() : Base(), m_restart(30) {}++ /** Initialize the solver with matrix \a A for further \c Ax=b solving.+ * + * This constructor is a shortcut for the default constructor followed+ * by a call to compute().+ * + * \warning this class stores a reference to the matrix A as well as some+ * precomputed values that depend on it. Therefore, if \a A is changed+ * this class becomes invalid. Call compute() to update it with the new+ * matrix A, or modify a copy of A.+ */+ GMRES(const MatrixType& A) : Base(A), m_restart(30) {}++ ~GMRES() {}+ + /** Get the number of iterations after that a restart is performed.+ */+ int get_restart() { return m_restart; }+ + /** Set the number of iterations after that a restart is performed.+ * \param restart number of iterations for a restarti, default is 30.+ */+ void set_restart(const int restart) { m_restart=restart; }+ + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A+ * \a x0 as an initial solution.+ *+ * \sa compute()+ */+ template<typename Rhs,typename Guess>+ inline const internal::solve_retval_with_guess<GMRES, Rhs, Guess>+ solveWithGuess(const MatrixBase<Rhs>& b, const Guess& x0) const+ {+ eigen_assert(m_isInitialized && "GMRES is not initialized.");+ eigen_assert(Base::rows()==b.rows()+ && "GMRES::solve(): invalid number of rows of the right hand side matrix b");+ return internal::solve_retval_with_guess+ <GMRES, Rhs, Guess>(*this, b.derived(), x0);+ }+ + /** \internal */+ template<typename Rhs,typename Dest>+ void _solveWithGuess(const Rhs& b, Dest& x) const+ { + bool failed = false;+ for(int j=0; j<b.cols(); ++j)+ {+ m_iterations = Base::maxIterations();+ m_error = Base::m_tolerance;+ + typename Dest::ColXpr xj(x,j);+ if(!internal::gmres(*mp_matrix, b.col(j), xj, Base::m_preconditioner, m_iterations, m_restart, m_error))+ failed = true;+ }+ m_info = failed ? NumericalIssue+ : m_error <= Base::m_tolerance ? Success+ : NoConvergence;+ m_isInitialized = true;+ }++ /** \internal */+ template<typename Rhs,typename Dest>+ void _solve(const Rhs& b, Dest& x) const+ {+ x = b;+ if(x.squaredNorm() == 0) return; // Check Zero right hand side+ _solveWithGuess(b,x);+ }++protected:++};+++namespace internal {++ template<typename _MatrixType, typename _Preconditioner, typename Rhs>+struct solve_retval<GMRES<_MatrixType, _Preconditioner>, Rhs>+ : solve_retval_base<GMRES<_MatrixType, _Preconditioner>, Rhs>+{+ typedef GMRES<_MatrixType, _Preconditioner> Dec;+ EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)++ template<typename Dest> void evalTo(Dest& dst) const+ {+ dec()._solve(rhs(),dst);+ }+};++} // end namespace internal++} // end namespace Eigen++#endif // EIGEN_GMRES_H
+ eigen3/unsupported/Eigen/src/IterativeSolvers/IncompleteCholesky.h view
@@ -0,0 +1,278 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Désiré Nuentsa-Wakam <desire.nuentsa_wakam@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_INCOMPLETE_CHOlESKY_H+#define EIGEN_INCOMPLETE_CHOlESKY_H+#include "Eigen/src/IterativeLinearSolvers/IncompleteLUT.h" +#include <Eigen/OrderingMethods>+#include <list>++namespace Eigen { +/** + * \brief Modified Incomplete Cholesky with dual threshold+ * + * References : C-J. Lin and J. J. Moré, Incomplete Cholesky Factorizations with+ * Limited memory, SIAM J. Sci. Comput. 21(1), pp. 24-45, 1999+ * + * \tparam _MatrixType The type of the sparse matrix. It should be a symmetric + * matrix. It is advised to give a row-oriented sparse matrix + * \tparam _UpLo The triangular part of the matrix to reference. + * \tparam _OrderingType + */++template <typename Scalar, int _UpLo = Lower, typename _OrderingType = NaturalOrdering<int> >+class IncompleteCholesky : internal::noncopyable+{+ public:+ typedef SparseMatrix<Scalar,ColMajor> MatrixType;+ typedef _OrderingType OrderingType;+ typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + typedef PermutationMatrix<Dynamic, Dynamic, Index> PermutationType;+ typedef Matrix<Scalar,Dynamic,1> ScalarType; + typedef Matrix<Index,Dynamic, 1> IndexType;+ typedef std::vector<std::list<Index> > VectorList; + enum { UpLo = _UpLo };+ public:+ IncompleteCholesky() : m_shift(1),m_factorizationIsOk(false) {}+ IncompleteCholesky(const MatrixType& matrix) : m_shift(1),m_factorizationIsOk(false)+ {+ compute(matrix);+ }+ + Index rows() const { return m_L.rows(); }+ + Index cols() const { return m_L.cols(); }+ ++ /** \brief Reports whether previous computation was successful.+ *+ * \returns \c Success if computation was succesful,+ * \c NumericalIssue if the matrix appears to be negative.+ */+ ComputationInfo info() const+ {+ eigen_assert(m_isInitialized && "IncompleteLLT is not initialized.");+ return m_info;+ }+ + /** + * \brief Set the initial shift parameter+ */+ void setShift( Scalar shift) { m_shift = shift; }+ + /**+ * \brief Computes the fill reducing permutation vector. + */+ template<typename MatrixType>+ void analyzePattern(const MatrixType& mat)+ {+ OrderingType ord; + ord(mat.template selfadjointView<UpLo>(), m_perm); + m_analysisIsOk = true; + }+ + template<typename MatrixType>+ void factorize(const MatrixType& amat);+ + template<typename MatrixType>+ void compute (const MatrixType& matrix)+ {+ analyzePattern(matrix); + factorize(matrix);+ }+ + template<typename Rhs, typename Dest>+ void _solve(const Rhs& b, Dest& x) const+ {+ eigen_assert(m_factorizationIsOk && "factorize() should be called first");+ if (m_perm.rows() == b.rows())+ x = m_perm.inverse() * b; + else + x = b; + x = m_scal.asDiagonal() * x;+ x = m_L.template triangularView<UnitLower>().solve(x); + x = m_L.adjoint().template triangularView<Upper>().solve(x); + if (m_perm.rows() == b.rows())+ x = m_perm * x;+ x = m_scal.asDiagonal() * x;+ }+ template<typename Rhs> inline const internal::solve_retval<IncompleteCholesky, Rhs>+ solve(const MatrixBase<Rhs>& b) const+ {+ eigen_assert(m_factorizationIsOk && "IncompleteLLT did not succeed");+ eigen_assert(m_isInitialized && "IncompleteLLT is not initialized.");+ eigen_assert(cols()==b.rows()+ && "IncompleteLLT::solve(): invalid number of rows of the right hand side matrix b");+ return internal::solve_retval<IncompleteCholesky, Rhs>(*this, b.derived());+ }+ protected:+ SparseMatrix<Scalar,ColMajor> m_L; // The lower part stored in CSC+ ScalarType m_scal; // The vector for scaling the matrix + Scalar m_shift; //The initial shift parameter+ bool m_analysisIsOk; + bool m_factorizationIsOk; + bool m_isInitialized;+ ComputationInfo m_info;+ PermutationType m_perm; + + private:+ template <typename IdxType, typename SclType>+ inline void updateList(const IdxType& colPtr, IdxType& rowIdx, SclType& vals, const Index& col, const Index& jk, IndexType& firstElt, VectorList& listCol); +}; ++template<typename Scalar, int _UpLo, typename OrderingType>+template<typename _MatrixType>+void IncompleteCholesky<Scalar,_UpLo, OrderingType>::factorize(const _MatrixType& mat)+{+ using std::sqrt;+ using std::min;+ eigen_assert(m_analysisIsOk && "analyzePattern() should be called first"); + + // Dropping strategies : Keep only the p largest elements per column, where p is the number of elements in the column of the original matrix. Other strategies will be added+ + // Apply the fill-reducing permutation computed in analyzePattern()+ if (m_perm.rows() == mat.rows() ) // To detect the null permutation+ m_L.template selfadjointView<Lower>() = mat.template selfadjointView<_UpLo>().twistedBy(m_perm);+ else+ m_L.template selfadjointView<Lower>() = mat.template selfadjointView<_UpLo>();+ + Index n = m_L.cols(); + Index nnz = m_L.nonZeros();+ Map<ScalarType> vals(m_L.valuePtr(), nnz); //values+ Map<IndexType> rowIdx(m_L.innerIndexPtr(), nnz); //Row indices+ Map<IndexType> colPtr( m_L.outerIndexPtr(), n+1); // Pointer to the beginning of each row+ IndexType firstElt(n-1); // for each j, points to the next entry in vals that will be used in the factorization+ VectorList listCol(n); // listCol(j) is a linked list of columns to update column j+ ScalarType curCol(n); // Store a nonzero values in each column+ IndexType irow(n); // Row indices of nonzero elements in each column+ + + // Computes the scaling factors + m_scal.resize(n);+ for (int j = 0; j < n; j++)+ {+ m_scal(j) = m_L.col(j).norm();+ m_scal(j) = sqrt(m_scal(j));+ }+ // Scale and compute the shift for the matrix + Scalar mindiag = vals[0];+ for (int j = 0; j < n; j++){+ for (int k = colPtr[j]; k < colPtr[j+1]; k++)+ vals[k] /= (m_scal(j) * m_scal(rowIdx[k]));+ mindiag = (min)(vals[colPtr[j]], mindiag);+ }+ + if(mindiag < Scalar(0.)) m_shift = m_shift - mindiag;+ // Apply the shift to the diagonal elements of the matrix+ for (int j = 0; j < n; j++)+ vals[colPtr[j]] += m_shift;+ // jki version of the Cholesky factorization + for (int j=0; j < n; ++j)+ { + //Left-looking factorize the column j + // First, load the jth column into curCol + Scalar diag = vals[colPtr[j]]; // It is assumed that only the lower part is stored+ curCol.setZero();+ irow.setLinSpaced(n,0,n-1); + for (int i = colPtr[j] + 1; i < colPtr[j+1]; i++)+ {+ curCol(rowIdx[i]) = vals[i]; + irow(rowIdx[i]) = rowIdx[i]; + }+ std::list<int>::iterator k; + // Browse all previous columns that will update column j+ for(k = listCol[j].begin(); k != listCol[j].end(); k++) + {+ int jk = firstElt(*k); // First element to use in the column + jk += 1; + for (int i = jk; i < colPtr[*k+1]; i++)+ {+ curCol(rowIdx[i]) -= vals[i] * vals[jk] ;+ }+ updateList(colPtr,rowIdx,vals, *k, jk, firstElt, listCol);+ }+ + // Scale the current column+ if(RealScalar(diag) <= 0) + {+ std::cerr << "\nNegative diagonal during Incomplete factorization... "<< j << "\n";+ m_info = NumericalIssue; + return; + }+ RealScalar rdiag = sqrt(RealScalar(diag));+ vals[colPtr[j]] = rdiag;+ for (int i = j+1; i < n; i++)+ {+ //Scale + curCol(i) /= rdiag;+ //Update the remaining diagonals with curCol+ vals[colPtr[i]] -= curCol(i) * curCol(i);+ }+ // Select the largest p elements+ // p is the original number of elements in the column (without the diagonal)+ int p = colPtr[j+1] - colPtr[j] - 1 ; + internal::QuickSplit(curCol, irow, p); + // Insert the largest p elements in the matrix+ int cpt = 0; + for (int i = colPtr[j]+1; i < colPtr[j+1]; i++)+ {+ vals[i] = curCol(cpt); + rowIdx[i] = irow(cpt); + cpt ++; + }+ // Get the first smallest row index and put it after the diagonal element+ Index jk = colPtr(j)+1;+ updateList(colPtr,rowIdx,vals,j,jk,firstElt,listCol); + }+ m_factorizationIsOk = true; + m_isInitialized = true;+ m_info = Success; +}++template<typename Scalar, int _UpLo, typename OrderingType>+template <typename IdxType, typename SclType>+inline void IncompleteCholesky<Scalar,_UpLo, OrderingType>::updateList(const IdxType& colPtr, IdxType& rowIdx, SclType& vals, const Index& col, const Index& jk, IndexType& firstElt, VectorList& listCol)+{+ if (jk < colPtr(col+1) )+ {+ Index p = colPtr(col+1) - jk;+ Index minpos; + rowIdx.segment(jk,p).minCoeff(&minpos);+ minpos += jk;+ if (rowIdx(minpos) != rowIdx(jk))+ {+ //Swap+ std::swap(rowIdx(jk),rowIdx(minpos));+ std::swap(vals(jk),vals(minpos));+ }+ firstElt(col) = jk;+ listCol[rowIdx(jk)].push_back(col);+ }+}+namespace internal {++template<typename _Scalar, int _UpLo, typename OrderingType, typename Rhs>+struct solve_retval<IncompleteCholesky<_Scalar, _UpLo, OrderingType>, Rhs>+ : solve_retval_base<IncompleteCholesky<_Scalar, _UpLo, OrderingType>, Rhs>+{+ typedef IncompleteCholesky<_Scalar, _UpLo, OrderingType> Dec;+ EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)++ template<typename Dest> void evalTo(Dest& dst) const+ {+ dec()._solve(rhs(),dst);+ }+};++} // end namespace internal++} // end namespace Eigen ++#endif
+ eigen3/unsupported/Eigen/src/IterativeSolvers/IncompleteLU.h view
@@ -0,0 +1,113 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_INCOMPLETE_LU_H+#define EIGEN_INCOMPLETE_LU_H++namespace Eigen { ++template <typename _Scalar>+class IncompleteLU+{+ typedef _Scalar Scalar;+ typedef Matrix<Scalar,Dynamic,1> Vector;+ typedef typename Vector::Index Index;+ typedef SparseMatrix<Scalar,RowMajor> FactorType;++ public:+ typedef Matrix<Scalar,Dynamic,Dynamic> MatrixType;++ IncompleteLU() : m_isInitialized(false) {}++ template<typename MatrixType>+ IncompleteLU(const MatrixType& mat) : m_isInitialized(false)+ {+ compute(mat);+ }++ Index rows() const { return m_lu.rows(); }+ Index cols() const { return m_lu.cols(); }++ template<typename MatrixType>+ IncompleteLU& compute(const MatrixType& mat)+ {+ m_lu = mat;+ int size = mat.cols();+ Vector diag(size);+ for(int i=0; i<size; ++i)+ {+ typename FactorType::InnerIterator k_it(m_lu,i);+ for(; k_it && k_it.index()<i; ++k_it)+ {+ int k = k_it.index();+ k_it.valueRef() /= diag(k);++ typename FactorType::InnerIterator j_it(k_it);+ typename FactorType::InnerIterator kj_it(m_lu, k);+ while(kj_it && kj_it.index()<=k) ++kj_it;+ for(++j_it; j_it; )+ {+ if(kj_it.index()==j_it.index())+ {+ j_it.valueRef() -= k_it.value() * kj_it.value();+ ++j_it;+ ++kj_it;+ }+ else if(kj_it.index()<j_it.index()) ++kj_it;+ else ++j_it;+ }+ }+ if(k_it && k_it.index()==i) diag(i) = k_it.value();+ else diag(i) = 1;+ }+ m_isInitialized = true;+ return *this;+ }++ template<typename Rhs, typename Dest>+ void _solve(const Rhs& b, Dest& x) const+ {+ x = m_lu.template triangularView<UnitLower>().solve(b);+ x = m_lu.template triangularView<Upper>().solve(x);+ }++ template<typename Rhs> inline const internal::solve_retval<IncompleteLU, Rhs>+ solve(const MatrixBase<Rhs>& b) const+ {+ eigen_assert(m_isInitialized && "IncompleteLU is not initialized.");+ eigen_assert(cols()==b.rows()+ && "IncompleteLU::solve(): invalid number of rows of the right hand side matrix b");+ return internal::solve_retval<IncompleteLU, Rhs>(*this, b.derived());+ }++ protected:+ FactorType m_lu;+ bool m_isInitialized;+};++namespace internal {++template<typename _MatrixType, typename Rhs>+struct solve_retval<IncompleteLU<_MatrixType>, Rhs>+ : solve_retval_base<IncompleteLU<_MatrixType>, Rhs>+{+ typedef IncompleteLU<_MatrixType> Dec;+ EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)++ template<typename Dest> void evalTo(Dest& dst) const+ {+ dec()._solve(rhs(),dst);+ }+};++} // end namespace internal++} // end namespace Eigen++#endif // EIGEN_INCOMPLETE_LU_H
+ eigen3/unsupported/Eigen/src/IterativeSolvers/IterationController.h view
@@ -0,0 +1,154 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>++/* NOTE The class IterationController has been adapted from the iteration+ * class of the GMM++ and ITL libraries.+ */++//=======================================================================+// Copyright (C) 1997-2001+// Authors: Andrew Lumsdaine <lums@osl.iu.edu> +// Lie-Quan Lee <llee@osl.iu.edu>+//+// This file is part of the Iterative Template Library+//+// You should have received a copy of the License Agreement for the+// Iterative Template Library along with the software; see the+// file LICENSE. +//+// Permission to modify the code and to distribute modified code is+// granted, provided the text of this NOTICE is retained, a notice that+// the code was modified is included with the above COPYRIGHT NOTICE and+// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE+// file is distributed with the modified code.+//+// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.+// By way of example, but not limitation, Licensor MAKES NO+// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY+// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS+// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS+// OR OTHER RIGHTS.+//=======================================================================++//========================================================================+//+// Copyright (C) 2002-2007 Yves Renard+//+// This file is a part of GETFEM+++//+// Getfem++ is free software; you can redistribute it and/or modify+// it under the terms of the GNU Lesser General Public License as+// published by the Free Software Foundation; version 2.1 of the License.+//+// This program is distributed in the hope that it will be useful,+// but WITHOUT ANY WARRANTY; without even the implied warranty of+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the+// GNU Lesser General Public License for more details.+// You should have received a copy of the GNU Lesser General Public+// License along with this program; if not, write to the Free Software+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,+// USA.+//+//========================================================================++#include "../../../../Eigen/src/Core/util/NonMPL2.h"++#ifndef EIGEN_ITERATION_CONTROLLER_H+#define EIGEN_ITERATION_CONTROLLER_H++namespace Eigen { ++/** \ingroup IterativeSolvers_Module+ * \class IterationController+ *+ * \brief Controls the iterations of the iterative solvers+ *+ * This class has been adapted from the iteration class of GMM++ and ITL libraries.+ *+ */+class IterationController+{+ protected :+ double m_rhsn; ///< Right hand side norm+ size_t m_maxiter; ///< Max. number of iterations+ int m_noise; ///< if noise > 0 iterations are printed+ double m_resmax; ///< maximum residual+ double m_resminreach, m_resadd;+ size_t m_nit; ///< iteration number+ double m_res; ///< last computed residual+ bool m_written;+ void (*m_callback)(const IterationController&);+ public :++ void init()+ {+ m_nit = 0; m_res = 0.0; m_written = false;+ m_resminreach = 1E50; m_resadd = 0.0;+ m_callback = 0;+ }++ IterationController(double r = 1.0E-8, int noi = 0, size_t mit = size_t(-1))+ : m_rhsn(1.0), m_maxiter(mit), m_noise(noi), m_resmax(r) { init(); }++ void operator ++(int) { m_nit++; m_written = false; m_resadd += m_res; }+ void operator ++() { (*this)++; }++ bool first() { return m_nit == 0; }++ /* get/set the "noisyness" (verbosity) of the solvers */+ int noiseLevel() const { return m_noise; }+ void setNoiseLevel(int n) { m_noise = n; }+ void reduceNoiseLevel() { if (m_noise > 0) m_noise--; }++ double maxResidual() const { return m_resmax; }+ void setMaxResidual(double r) { m_resmax = r; }++ double residual() const { return m_res; }++ /* change the user-definable callback, called after each iteration */+ void setCallback(void (*t)(const IterationController&))+ {+ m_callback = t;+ }++ size_t iteration() const { return m_nit; }+ void setIteration(size_t i) { m_nit = i; }++ size_t maxIterarions() const { return m_maxiter; }+ void setMaxIterations(size_t i) { m_maxiter = i; }++ double rhsNorm() const { return m_rhsn; }+ void setRhsNorm(double r) { m_rhsn = r; }++ bool converged() const { return m_res <= m_rhsn * m_resmax; }+ bool converged(double nr)+ {+ using std::abs;+ m_res = abs(nr); + m_resminreach = (std::min)(m_resminreach, m_res);+ return converged();+ }+ template<typename VectorType> bool converged(const VectorType &v)+ { return converged(v.squaredNorm()); }++ bool finished(double nr)+ {+ if (m_callback) m_callback(*this);+ if (m_noise > 0 && !m_written)+ {+ converged(nr);+ m_written = true;+ }+ return (m_nit >= m_maxiter || converged(nr));+ }+ template <typename VectorType>+ bool finished(const MatrixBase<VectorType> &v)+ { return finished(double(v.squaredNorm())); }++};++} // end namespace Eigen++#endif // EIGEN_ITERATION_CONTROLLER_H
+ eigen3/unsupported/Eigen/src/IterativeSolvers/MINRES.h view
@@ -0,0 +1,310 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Giacomo Po <gpo@ucla.edu>+// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.+++#ifndef EIGEN_MINRES_H_+#define EIGEN_MINRES_H_+++namespace Eigen {+ + namespace internal {+ + /** \internal Low-level MINRES algorithm+ * \param mat The matrix A+ * \param rhs The right hand side vector b+ * \param x On input and initial solution, on output the computed solution.+ * \param precond A right preconditioner being able to efficiently solve for an+ * approximation of Ax=b (regardless of b)+ * \param iters On input the max number of iteration, on output the number of performed iterations.+ * \param tol_error On input the tolerance error, on output an estimation of the relative error.+ */+ template<typename MatrixType, typename Rhs, typename Dest, typename Preconditioner>+ EIGEN_DONT_INLINE+ void minres(const MatrixType& mat, const Rhs& rhs, Dest& x,+ const Preconditioner& precond, int& iters,+ typename Dest::RealScalar& tol_error)+ {+ using std::sqrt;+ typedef typename Dest::RealScalar RealScalar;+ typedef typename Dest::Scalar Scalar;+ typedef Matrix<Scalar,Dynamic,1> VectorType;++ // Check for zero rhs+ const RealScalar rhsNorm2(rhs.squaredNorm());+ if(rhsNorm2 == 0)+ {+ x.setZero();+ iters = 0;+ tol_error = 0;+ return;+ }+ + // initialize+ const int maxIters(iters); // initialize maxIters to iters+ const int N(mat.cols()); // the size of the matrix+ const RealScalar threshold2(tol_error*tol_error*rhsNorm2); // convergence threshold (compared to residualNorm2)+ + // Initialize preconditioned Lanczos+ VectorType v_old(N); // will be initialized inside loop+ VectorType v( VectorType::Zero(N) ); //initialize v+ VectorType v_new(rhs-mat*x); //initialize v_new+ RealScalar residualNorm2(v_new.squaredNorm());+ VectorType w(N); // will be initialized inside loop+ VectorType w_new(precond.solve(v_new)); // initialize w_new+// RealScalar beta; // will be initialized inside loop+ RealScalar beta_new2(v_new.dot(w_new));+ eigen_assert(beta_new2 >= 0.0 && "PRECONDITIONER IS NOT POSITIVE DEFINITE");+ RealScalar beta_new(sqrt(beta_new2));+ const RealScalar beta_one(beta_new);+ v_new /= beta_new;+ w_new /= beta_new;+ // Initialize other variables+ RealScalar c(1.0); // the cosine of the Givens rotation+ RealScalar c_old(1.0);+ RealScalar s(0.0); // the sine of the Givens rotation+ RealScalar s_old(0.0); // the sine of the Givens rotation+ VectorType p_oold(N); // will be initialized in loop+ VectorType p_old(VectorType::Zero(N)); // initialize p_old=0+ VectorType p(p_old); // initialize p=0+ RealScalar eta(1.0);+ + iters = 0; // reset iters+ while ( iters < maxIters )+ {+ // Preconditioned Lanczos+ /* Note that there are 4 variants on the Lanczos algorithm. These are+ * described in Paige, C. C. (1972). Computational variants of+ * the Lanczos method for the eigenproblem. IMA Journal of Applied+ * Mathematics, 10(3), 373–381. The current implementation corresponds + * to the case A(2,7) in the paper. It also corresponds to + * algorithm 6.14 in Y. Saad, Iterative Methods for Sparse Linear+ * Systems, 2003 p.173. For the preconditioned version see + * A. Greenbaum, Iterative Methods for Solving Linear Systems, SIAM (1987).+ */+ const RealScalar beta(beta_new);+ v_old = v; // update: at first time step, this makes v_old = 0 so value of beta doesn't matter+// const VectorType v_old(v); // NOT SURE IF CREATING v_old EVERY ITERATION IS EFFICIENT+ v = v_new; // update+ w = w_new; // update+// const VectorType w(w_new); // NOT SURE IF CREATING w EVERY ITERATION IS EFFICIENT+ v_new.noalias() = mat*w - beta*v_old; // compute v_new+ const RealScalar alpha = v_new.dot(w);+ v_new -= alpha*v; // overwrite v_new+ w_new = precond.solve(v_new); // overwrite w_new+ beta_new2 = v_new.dot(w_new); // compute beta_new+ eigen_assert(beta_new2 >= 0.0 && "PRECONDITIONER IS NOT POSITIVE DEFINITE");+ beta_new = sqrt(beta_new2); // compute beta_new+ v_new /= beta_new; // overwrite v_new for next iteration+ w_new /= beta_new; // overwrite w_new for next iteration+ + // Givens rotation+ const RealScalar r2 =s*alpha+c*c_old*beta; // s, s_old, c and c_old are still from previous iteration+ const RealScalar r3 =s_old*beta; // s, s_old, c and c_old are still from previous iteration+ const RealScalar r1_hat=c*alpha-c_old*s*beta;+ const RealScalar r1 =sqrt( std::pow(r1_hat,2) + std::pow(beta_new,2) );+ c_old = c; // store for next iteration+ s_old = s; // store for next iteration+ c=r1_hat/r1; // new cosine+ s=beta_new/r1; // new sine+ + // Update solution+ p_oold = p_old;+// const VectorType p_oold(p_old); // NOT SURE IF CREATING p_oold EVERY ITERATION IS EFFICIENT+ p_old = p;+ p.noalias()=(w-r2*p_old-r3*p_oold) /r1; // IS NOALIAS REQUIRED?+ x += beta_one*c*eta*p;+ + /* Update the squared residual. Note that this is the estimated residual.+ The real residual |Ax-b|^2 may be slightly larger */+ residualNorm2 *= s*s;+ + if ( residualNorm2 < threshold2)+ {+ break;+ }+ + eta=-s*eta; // update eta+ iters++; // increment iteration number (for output purposes)+ }+ + /* Compute error. Note that this is the estimated error. The real + error |Ax-b|/|b| may be slightly larger */+ tol_error = std::sqrt(residualNorm2 / rhsNorm2);+ }+ + }+ + template< typename _MatrixType, int _UpLo=Lower,+ typename _Preconditioner = IdentityPreconditioner>+// typename _Preconditioner = IdentityPreconditioner<typename _MatrixType::Scalar> > // preconditioner must be positive definite+ class MINRES;+ + namespace internal {+ + template< typename _MatrixType, int _UpLo, typename _Preconditioner>+ struct traits<MINRES<_MatrixType,_UpLo,_Preconditioner> >+ {+ typedef _MatrixType MatrixType;+ typedef _Preconditioner Preconditioner;+ };+ + }+ + /** \ingroup IterativeLinearSolvers_Module+ * \brief A minimal residual solver for sparse symmetric problems+ *+ * This class allows to solve for A.x = b sparse linear problems using the MINRES algorithm+ * of Paige and Saunders (1975). The sparse matrix A must be symmetric (possibly indefinite).+ * The vectors x and b can be either dense or sparse.+ *+ * \tparam _MatrixType the type of the sparse matrix A, can be a dense or a sparse matrix.+ * \tparam _UpLo the triangular part that will be used for the computations. It can be Lower+ * or Upper. Default is Lower.+ * \tparam _Preconditioner the type of the preconditioner. Default is DiagonalPreconditioner+ *+ * The maximal number of iterations and tolerance value can be controlled via the setMaxIterations()+ * and setTolerance() methods. The defaults are the size of the problem for the maximal number of iterations+ * and NumTraits<Scalar>::epsilon() for the tolerance.+ *+ * This class can be used as the direct solver classes. Here is a typical usage example:+ * \code+ * int n = 10000;+ * VectorXd x(n), b(n);+ * SparseMatrix<double> A(n,n);+ * // fill A and b+ * MINRES<SparseMatrix<double> > mr;+ * mr.compute(A);+ * x = mr.solve(b);+ * std::cout << "#iterations: " << mr.iterations() << std::endl;+ * std::cout << "estimated error: " << mr.error() << std::endl;+ * // update b, and solve again+ * x = mr.solve(b);+ * \endcode+ *+ * By default the iterations start with x=0 as an initial guess of the solution.+ * One can control the start using the solveWithGuess() method.+ *+ * \sa class ConjugateGradient, BiCGSTAB, SimplicialCholesky, DiagonalPreconditioner, IdentityPreconditioner+ */+ template< typename _MatrixType, int _UpLo, typename _Preconditioner>+ class MINRES : public IterativeSolverBase<MINRES<_MatrixType,_UpLo,_Preconditioner> >+ {+ + typedef IterativeSolverBase<MINRES> Base;+ using Base::mp_matrix;+ using Base::m_error;+ using Base::m_iterations;+ using Base::m_info;+ using Base::m_isInitialized;+ public:+ typedef _MatrixType MatrixType;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::RealScalar RealScalar;+ typedef _Preconditioner Preconditioner;+ + enum {UpLo = _UpLo};+ + public:+ + /** Default constructor. */+ MINRES() : Base() {}+ + /** Initialize the solver with matrix \a A for further \c Ax=b solving.+ *+ * This constructor is a shortcut for the default constructor followed+ * by a call to compute().+ *+ * \warning this class stores a reference to the matrix A as well as some+ * precomputed values that depend on it. Therefore, if \a A is changed+ * this class becomes invalid. Call compute() to update it with the new+ * matrix A, or modify a copy of A.+ */+ MINRES(const MatrixType& A) : Base(A) {}+ + /** Destructor. */+ ~MINRES(){}+ + /** \returns the solution x of \f$ A x = b \f$ using the current decomposition of A+ * \a x0 as an initial solution.+ *+ * \sa compute()+ */+ template<typename Rhs,typename Guess>+ inline const internal::solve_retval_with_guess<MINRES, Rhs, Guess>+ solveWithGuess(const MatrixBase<Rhs>& b, const Guess& x0) const+ {+ eigen_assert(m_isInitialized && "MINRES is not initialized.");+ eigen_assert(Base::rows()==b.rows()+ && "MINRES::solve(): invalid number of rows of the right hand side matrix b");+ return internal::solve_retval_with_guess+ <MINRES, Rhs, Guess>(*this, b.derived(), x0);+ }+ + /** \internal */+ template<typename Rhs,typename Dest>+ void _solveWithGuess(const Rhs& b, Dest& x) const+ {+ typedef typename internal::conditional<UpLo==(Lower|Upper),+ const MatrixType&,+ SparseSelfAdjointView<const MatrixType, UpLo>+ >::type MatrixWrapperType;+ + m_iterations = Base::maxIterations();+ m_error = Base::m_tolerance;+ + for(int j=0; j<b.cols(); ++j)+ {+ m_iterations = Base::maxIterations();+ m_error = Base::m_tolerance;+ + typename Dest::ColXpr xj(x,j);+ internal::minres(MatrixWrapperType(*mp_matrix), b.col(j), xj,+ Base::m_preconditioner, m_iterations, m_error);+ }+ + m_isInitialized = true;+ m_info = m_error <= Base::m_tolerance ? Success : NoConvergence;+ }+ + /** \internal */+ template<typename Rhs,typename Dest>+ void _solve(const Rhs& b, Dest& x) const+ {+ x.setZero();+ _solveWithGuess(b,x);+ }+ + protected:+ + };+ + namespace internal {+ + template<typename _MatrixType, int _UpLo, typename _Preconditioner, typename Rhs>+ struct solve_retval<MINRES<_MatrixType,_UpLo,_Preconditioner>, Rhs>+ : solve_retval_base<MINRES<_MatrixType,_UpLo,_Preconditioner>, Rhs>+ {+ typedef MINRES<_MatrixType,_UpLo,_Preconditioner> Dec;+ EIGEN_MAKE_SOLVE_HELPERS(Dec,Rhs)+ + template<typename Dest> void evalTo(Dest& dst) const+ {+ dec()._solve(rhs(),dst);+ }+ };+ + } // end namespace internal+ +} // end namespace Eigen++#endif // EIGEN_MINRES_H+
+ eigen3/unsupported/Eigen/src/IterativeSolvers/Scaling.h view
@@ -0,0 +1,185 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Desire NUENTSA WAKAM <desire.nuentsa_wakam@inria.fr+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_ITERSCALING_H+#define EIGEN_ITERSCALING_H+/**+ * \ingroup IterativeSolvers_Module+ * \brief iterative scaling algorithm to equilibrate rows and column norms in matrices+ * + * This class can be used as a preprocessing tool to accelerate the convergence of iterative methods + * + * This feature is useful to limit the pivoting amount during LU/ILU factorization+ * The scaling strategy as presented here preserves the symmetry of the problem+ * NOTE It is assumed that the matrix does not have empty row or column, + * + * Example with key steps + * \code+ * VectorXd x(n), b(n);+ * SparseMatrix<double> A;+ * // fill A and b;+ * IterScaling<SparseMatrix<double> > scal; + * // Compute the left and right scaling vectors. The matrix is equilibrated at output+ * scal.computeRef(A); + * // Scale the right hand side+ * b = scal.LeftScaling().cwiseProduct(b); + * // Now, solve the equilibrated linear system with any available solver+ * + * // Scale back the computed solution+ * x = scal.RightScaling().cwiseProduct(x); + * \endcode+ * + * \tparam _MatrixType the type of the matrix. It should be a real square sparsematrix+ * + * References : D. Ruiz and B. Ucar, A Symmetry Preserving Algorithm for Matrix Scaling, INRIA Research report RR-7552+ * + * \sa \ref IncompleteLUT + */+namespace Eigen {+using std::abs; +template<typename _MatrixType>+class IterScaling+{+ public:+ typedef _MatrixType MatrixType; + typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::Index Index;+ + public:+ IterScaling() { init(); }+ + IterScaling(const MatrixType& matrix)+ {+ init();+ compute(matrix);+ }+ + ~IterScaling() { }+ + /** + * Compute the left and right diagonal matrices to scale the input matrix @p mat+ * + * FIXME This algorithm will be modified such that the diagonal elements are permuted on the diagonal. + * + * \sa LeftScaling() RightScaling()+ */+ void compute (const MatrixType& mat)+ {+ int m = mat.rows(); + int n = mat.cols();+ eigen_assert((m>0 && m == n) && "Please give a non - empty matrix");+ m_left.resize(m); + m_right.resize(n);+ m_left.setOnes();+ m_right.setOnes();+ m_matrix = mat;+ VectorXd Dr, Dc, DrRes, DcRes; // Temporary Left and right scaling vectors+ Dr.resize(m); Dc.resize(n);+ DrRes.resize(m); DcRes.resize(n);+ double EpsRow = 1.0, EpsCol = 1.0;+ int its = 0; + do+ { // Iterate until the infinite norm of each row and column is approximately 1+ // Get the maximum value in each row and column+ Dr.setZero(); Dc.setZero();+ for (int k=0; k<m_matrix.outerSize(); ++k)+ {+ for (typename MatrixType::InnerIterator it(m_matrix, k); it; ++it)+ {+ if ( Dr(it.row()) < abs(it.value()) )+ Dr(it.row()) = abs(it.value());+ + if ( Dc(it.col()) < abs(it.value()) )+ Dc(it.col()) = abs(it.value());+ }+ }+ for (int i = 0; i < m; ++i) + {+ Dr(i) = std::sqrt(Dr(i));+ Dc(i) = std::sqrt(Dc(i));+ }+ // Save the scaling factors + for (int i = 0; i < m; ++i) + {+ m_left(i) /= Dr(i);+ m_right(i) /= Dc(i);+ }+ // Scale the rows and the columns of the matrix+ DrRes.setZero(); DcRes.setZero(); + for (int k=0; k<m_matrix.outerSize(); ++k)+ {+ for (typename MatrixType::InnerIterator it(m_matrix, k); it; ++it)+ {+ it.valueRef() = it.value()/( Dr(it.row()) * Dc(it.col()) );+ // Accumulate the norms of the row and column vectors + if ( DrRes(it.row()) < abs(it.value()) )+ DrRes(it.row()) = abs(it.value());+ + if ( DcRes(it.col()) < abs(it.value()) )+ DcRes(it.col()) = abs(it.value());+ }+ } + DrRes.array() = (1-DrRes.array()).abs();+ EpsRow = DrRes.maxCoeff();+ DcRes.array() = (1-DcRes.array()).abs();+ EpsCol = DcRes.maxCoeff();+ its++;+ }while ( (EpsRow >m_tol || EpsCol > m_tol) && (its < m_maxits) );+ m_isInitialized = true;+ }+ /** Compute the left and right vectors to scale the vectors+ * the input matrix is scaled with the computed vectors at output+ * + * \sa compute()+ */+ void computeRef (MatrixType& mat)+ {+ compute (mat);+ mat = m_matrix;+ }+ /** Get the vector to scale the rows of the matrix + */+ VectorXd& LeftScaling()+ {+ return m_left;+ }+ + /** Get the vector to scale the columns of the matrix + */+ VectorXd& RightScaling()+ {+ return m_right;+ }+ + /** Set the tolerance for the convergence of the iterative scaling algorithm+ */+ void setTolerance(double tol)+ {+ m_tol = tol; + }+ + protected:+ + void init()+ {+ m_tol = 1e-10;+ m_maxits = 5;+ m_isInitialized = false;+ }+ + MatrixType m_matrix;+ mutable ComputationInfo m_info; + bool m_isInitialized; + VectorXd m_left; // Left scaling vector+ VectorXd m_right; // m_right scaling vector+ double m_tol; + int m_maxits; // Maximum number of iterations allowed+};+}+#endif
+ eigen3/unsupported/Eigen/src/KroneckerProduct/CMakeLists.txt view
@@ -0,0 +1,6 @@+FILE(GLOB Eigen_KroneckerProduct_SRCS "*.h")++INSTALL(FILES+ ${Eigen_KroneckerProduct_SRCS}+ DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/KroneckerProduct COMPONENT Devel+ )
+ eigen3/unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h view
@@ -0,0 +1,244 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Kolja Brix <brix@igpm.rwth-aachen.de>+// Copyright (C) 2011 Andreas Platen <andiplaten@gmx.de>+// Copyright (C) 2012 Chen-Pang He <jdh8@ms63.hinet.net>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef KRONECKER_TENSOR_PRODUCT_H+#define KRONECKER_TENSOR_PRODUCT_H++namespace Eigen { ++template<typename Scalar, int Options, typename Index> class SparseMatrix;++/*!+ * \brief Kronecker tensor product helper class for dense matrices+ *+ * This class is the return value of kroneckerProduct(MatrixBase,+ * MatrixBase). Use the function rather than construct this class+ * directly to avoid specifying template prarameters.+ *+ * \tparam Lhs Type of the left-hand side, a matrix expression.+ * \tparam Rhs Type of the rignt-hand side, a matrix expression.+ */+template<typename Lhs, typename Rhs>+class KroneckerProduct : public ReturnByValue<KroneckerProduct<Lhs,Rhs> >+{+ private:+ typedef ReturnByValue<KroneckerProduct> Base;+ typedef typename Base::Scalar Scalar;+ typedef typename Base::Index Index;++ public:+ /*! \brief Constructor. */+ KroneckerProduct(const Lhs& A, const Rhs& B)+ : m_A(A), m_B(B)+ {}++ /*! \brief Evaluate the Kronecker tensor product. */+ template<typename Dest> void evalTo(Dest& dst) const;+ + inline Index rows() const { return m_A.rows() * m_B.rows(); }+ inline Index cols() const { return m_A.cols() * m_B.cols(); }++ Scalar coeff(Index row, Index col) const+ {+ return m_A.coeff(row / m_B.rows(), col / m_B.cols()) *+ m_B.coeff(row % m_B.rows(), col % m_B.cols());+ }++ Scalar coeff(Index i) const+ {+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(KroneckerProduct);+ return m_A.coeff(i / m_A.size()) * m_B.coeff(i % m_A.size());+ }++ private:+ typename Lhs::Nested m_A;+ typename Rhs::Nested m_B;+};++/*!+ * \brief Kronecker tensor product helper class for sparse matrices+ *+ * If at least one of the operands is a sparse matrix expression,+ * then this class is returned and evaluates into a sparse matrix.+ *+ * This class is the return value of kroneckerProduct(EigenBase,+ * EigenBase). Use the function rather than construct this class+ * directly to avoid specifying template prarameters.+ *+ * \tparam Lhs Type of the left-hand side, a matrix expression.+ * \tparam Rhs Type of the rignt-hand side, a matrix expression.+ */+template<typename Lhs, typename Rhs>+class KroneckerProductSparse : public EigenBase<KroneckerProductSparse<Lhs,Rhs> >+{+ private:+ typedef typename internal::traits<KroneckerProductSparse>::Index Index;++ public:+ /*! \brief Constructor. */+ KroneckerProductSparse(const Lhs& A, const Rhs& B)+ : m_A(A), m_B(B)+ {}++ /*! \brief Evaluate the Kronecker tensor product. */+ template<typename Dest> void evalTo(Dest& dst) const;+ + inline Index rows() const { return m_A.rows() * m_B.rows(); }+ inline Index cols() const { return m_A.cols() * m_B.cols(); }++ template<typename Scalar, int Options, typename Index>+ operator SparseMatrix<Scalar, Options, Index>()+ {+ SparseMatrix<Scalar, Options, Index> result;+ evalTo(result.derived());+ return result;+ }++ private:+ typename Lhs::Nested m_A;+ typename Rhs::Nested m_B;+};++template<typename Lhs, typename Rhs>+template<typename Dest>+void KroneckerProduct<Lhs,Rhs>::evalTo(Dest& dst) const+{+ const int BlockRows = Rhs::RowsAtCompileTime,+ BlockCols = Rhs::ColsAtCompileTime;+ const Index Br = m_B.rows(),+ Bc = m_B.cols();+ for (Index i=0; i < m_A.rows(); ++i)+ for (Index j=0; j < m_A.cols(); ++j)+ Block<Dest,BlockRows,BlockCols>(dst,i*Br,j*Bc,Br,Bc) = m_A.coeff(i,j) * m_B;+}++template<typename Lhs, typename Rhs>+template<typename Dest>+void KroneckerProductSparse<Lhs,Rhs>::evalTo(Dest& dst) const+{+ const Index Br = m_B.rows(),+ Bc = m_B.cols();+ dst.resize(rows(),cols());+ dst.resizeNonZeros(0);+ dst.reserve(m_A.nonZeros() * m_B.nonZeros());++ for (Index kA=0; kA < m_A.outerSize(); ++kA)+ {+ for (Index kB=0; kB < m_B.outerSize(); ++kB)+ {+ for (typename Lhs::InnerIterator itA(m_A,kA); itA; ++itA)+ {+ for (typename Rhs::InnerIterator itB(m_B,kB); itB; ++itB)+ {+ const Index i = itA.row() * Br + itB.row(),+ j = itA.col() * Bc + itB.col();+ dst.insert(i,j) = itA.value() * itB.value();+ }+ }+ }+ }+}++namespace internal {++template<typename _Lhs, typename _Rhs>+struct traits<KroneckerProduct<_Lhs,_Rhs> >+{+ typedef typename remove_all<_Lhs>::type Lhs;+ typedef typename remove_all<_Rhs>::type Rhs;+ typedef typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType Scalar;++ enum {+ Rows = size_at_compile_time<traits<Lhs>::RowsAtCompileTime, traits<Rhs>::RowsAtCompileTime>::ret,+ Cols = size_at_compile_time<traits<Lhs>::ColsAtCompileTime, traits<Rhs>::ColsAtCompileTime>::ret,+ MaxRows = size_at_compile_time<traits<Lhs>::MaxRowsAtCompileTime, traits<Rhs>::MaxRowsAtCompileTime>::ret,+ MaxCols = size_at_compile_time<traits<Lhs>::MaxColsAtCompileTime, traits<Rhs>::MaxColsAtCompileTime>::ret,+ CoeffReadCost = Lhs::CoeffReadCost + Rhs::CoeffReadCost + NumTraits<Scalar>::MulCost+ };++ typedef Matrix<Scalar,Rows,Cols> ReturnType;+};++template<typename _Lhs, typename _Rhs>+struct traits<KroneckerProductSparse<_Lhs,_Rhs> >+{+ typedef MatrixXpr XprKind;+ typedef typename remove_all<_Lhs>::type Lhs;+ typedef typename remove_all<_Rhs>::type Rhs;+ typedef typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType Scalar;+ typedef typename promote_storage_type<typename traits<Lhs>::StorageKind, typename traits<Rhs>::StorageKind>::ret StorageKind;+ typedef typename promote_index_type<typename Lhs::Index, typename Rhs::Index>::type Index;++ enum {+ LhsFlags = Lhs::Flags,+ RhsFlags = Rhs::Flags,++ RowsAtCompileTime = size_at_compile_time<traits<Lhs>::RowsAtCompileTime, traits<Rhs>::RowsAtCompileTime>::ret,+ ColsAtCompileTime = size_at_compile_time<traits<Lhs>::ColsAtCompileTime, traits<Rhs>::ColsAtCompileTime>::ret,+ MaxRowsAtCompileTime = size_at_compile_time<traits<Lhs>::MaxRowsAtCompileTime, traits<Rhs>::MaxRowsAtCompileTime>::ret,+ MaxColsAtCompileTime = size_at_compile_time<traits<Lhs>::MaxColsAtCompileTime, traits<Rhs>::MaxColsAtCompileTime>::ret,++ EvalToRowMajor = (LhsFlags & RhsFlags & RowMajorBit),+ RemovedBits = ~(EvalToRowMajor ? 0 : RowMajorBit),++ Flags = ((LhsFlags | RhsFlags) & HereditaryBits & RemovedBits)+ | EvalBeforeNestingBit | EvalBeforeAssigningBit,+ CoeffReadCost = Dynamic+ };+};++} // end namespace internal++/*!+ * \ingroup KroneckerProduct_Module+ *+ * Computes Kronecker tensor product of two dense matrices+ *+ * \warning If you want to replace a matrix by its Kronecker product+ * with some matrix, do \b NOT do this:+ * \code+ * A = kroneckerProduct(A,B); // bug!!! caused by aliasing effect+ * \endcode+ * instead, use eval() to work around this:+ * \code+ * A = kroneckerProduct(A,B).eval();+ * \endcode+ *+ * \param a Dense matrix a+ * \param b Dense matrix b+ * \return Kronecker tensor product of a and b+ */+template<typename A, typename B>+KroneckerProduct<A,B> kroneckerProduct(const MatrixBase<A>& a, const MatrixBase<B>& b)+{+ return KroneckerProduct<A, B>(a.derived(), b.derived());+}++/*!+ * \ingroup KroneckerProduct_Module+ *+ * Computes Kronecker tensor product of two matrices, at least one of+ * which is sparse+ *+ * \param a Dense/sparse matrix a+ * \param b Dense/sparse matrix b+ * \return Kronecker tensor product of a and b, stored in a sparse+ * matrix+ */+template<typename A, typename B>+KroneckerProductSparse<A,B> kroneckerProduct(const EigenBase<A>& a, const EigenBase<B>& b)+{+ return KroneckerProductSparse<A,B>(a.derived(), b.derived());+}++} // end namespace Eigen++#endif // KRONECKER_TENSOR_PRODUCT_H
+ eigen3/unsupported/Eigen/src/LevenbergMarquardt/CMakeLists.txt view
@@ -0,0 +1,6 @@+FILE(GLOB Eigen_LevenbergMarquardt_SRCS "*.h")++INSTALL(FILES+ ${Eigen_LevenbergMarquardt_SRCS}+ DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/LevenbergMarquardt COMPONENT Devel+ )
+ eigen3/unsupported/Eigen/src/LevenbergMarquardt/CopyrightMINPACK.txt view
@@ -0,0 +1,52 @@+Minpack Copyright Notice (1999) University of Chicago. All rights reserved++Redistribution and use in source and binary forms, with or+without modification, are permitted provided that the+following conditions are met:++1. Redistributions of source code must retain the above+copyright notice, this list of conditions and the following+disclaimer.++2. Redistributions in binary form must reproduce the above+copyright notice, this list of conditions and the following+disclaimer in the documentation and/or other materials+provided with the distribution.++3. The end-user documentation included with the+redistribution, if any, must include the following+acknowledgment:++ "This product includes software developed by the+ University of Chicago, as Operator of Argonne National+ Laboratory.++Alternately, this acknowledgment may appear in the software+itself, if and wherever such third-party acknowledgments+normally appear.++4. WARRANTY DISCLAIMER. THE SOFTWARE IS SUPPLIED "AS IS"+WITHOUT WARRANTY OF ANY KIND. THE COPYRIGHT HOLDER, THE+UNITED STATES, THE UNITED STATES DEPARTMENT OF ENERGY, AND+THEIR EMPLOYEES: (1) DISCLAIM ANY WARRANTIES, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO ANY IMPLIED WARRANTIES+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE+OR NON-INFRINGEMENT, (2) DO NOT ASSUME ANY LEGAL LIABILITY+OR RESPONSIBILITY FOR THE ACCURACY, COMPLETENESS, OR+USEFULNESS OF THE SOFTWARE, (3) DO NOT REPRESENT THAT USE OF+THE SOFTWARE WOULD NOT INFRINGE PRIVATELY OWNED RIGHTS, (4)+DO NOT WARRANT THAT THE SOFTWARE WILL FUNCTION+UNINTERRUPTED, THAT IT IS ERROR-FREE OR THAT ANY ERRORS WILL+BE CORRECTED.++5. LIMITATION OF LIABILITY. IN NO EVENT WILL THE COPYRIGHT+HOLDER, THE UNITED STATES, THE UNITED STATES DEPARTMENT OF+ENERGY, OR THEIR EMPLOYEES: BE LIABLE FOR ANY INDIRECT,+INCIDENTAL, CONSEQUENTIAL, SPECIAL OR PUNITIVE DAMAGES OF+ANY KIND OR NATURE, INCLUDING BUT NOT LIMITED TO LOSS OF+PROFITS OR LOSS OF DATA, FOR ANY REASON WHATSOEVER, WHETHER+SUCH LIABILITY IS ASSERTED ON THE BASIS OF CONTRACT, TORT+(INCLUDING NEGLIGENCE OR STRICT LIABILITY), OR OTHERWISE,+EVEN IF ANY OF SAID PARTIES HAS BEEN WARNED OF THE+POSSIBILITY OF SUCH LOSS OR DAMAGES.+
+ eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMcovar.h view
@@ -0,0 +1,85 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// This code initially comes from MINPACK whose original authors are:+// Copyright Jorge More - Argonne National Laboratory+// Copyright Burt Garbow - Argonne National Laboratory+// Copyright Ken Hillstrom - Argonne National Laboratory+//+// This Source Code Form is subject to the terms of the Minpack license+// (a BSD-like license) described in the campaigned CopyrightMINPACK.txt file.++#ifndef EIGEN_LMCOVAR_H+#define EIGEN_LMCOVAR_H++namespace Eigen { ++namespace internal {++template <typename Scalar>+void covar(+ Matrix< Scalar, Dynamic, Dynamic > &r,+ const VectorXi& ipvt,+ Scalar tol = std::sqrt(NumTraits<Scalar>::epsilon()) )+{+ using std::abs;+ typedef DenseIndex Index;+ /* Local variables */+ Index i, j, k, l, ii, jj;+ bool sing;+ Scalar temp;++ /* Function Body */+ const Index n = r.cols();+ const Scalar tolr = tol * abs(r(0,0));+ Matrix< Scalar, Dynamic, 1 > wa(n);+ eigen_assert(ipvt.size()==n);++ /* form the inverse of r in the full upper triangle of r. */+ l = -1;+ for (k = 0; k < n; ++k)+ if (abs(r(k,k)) > tolr) {+ r(k,k) = 1. / r(k,k);+ for (j = 0; j <= k-1; ++j) {+ temp = r(k,k) * r(j,k);+ r(j,k) = 0.;+ r.col(k).head(j+1) -= r.col(j).head(j+1) * temp;+ }+ l = k;+ }++ /* form the full upper triangle of the inverse of (r transpose)*r */+ /* in the full upper triangle of r. */+ for (k = 0; k <= l; ++k) {+ for (j = 0; j <= k-1; ++j)+ r.col(j).head(j+1) += r.col(k).head(j+1) * r(j,k);+ r.col(k).head(k+1) *= r(k,k);+ }++ /* form the full lower triangle of the covariance matrix */+ /* in the strict lower triangle of r and in wa. */+ for (j = 0; j < n; ++j) {+ jj = ipvt[j];+ sing = j > l;+ for (i = 0; i <= j; ++i) {+ if (sing)+ r(i,j) = 0.;+ ii = ipvt[i];+ if (ii > jj)+ r(ii,jj) = r(i,j);+ if (ii < jj)+ r(jj,ii) = r(i,j);+ }+ wa[jj] = r(j,j);+ }++ /* symmetrize the covariance matrix in r. */+ r.topLeftCorner(n,n).template triangularView<StrictlyUpper>() = r.topLeftCorner(n,n).transpose();+ r.diagonal() = wa;+}++} // end namespace internal++} // end namespace Eigen++#endif // EIGEN_LMCOVAR_H
+ eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h view
@@ -0,0 +1,202 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>+//+// This code initially comes from MINPACK whose original authors are:+// Copyright Jorge More - Argonne National Laboratory+// Copyright Burt Garbow - Argonne National Laboratory+// Copyright Ken Hillstrom - Argonne National Laboratory+//+// This Source Code Form is subject to the terms of the Minpack license+// (a BSD-like license) described in the campaigned CopyrightMINPACK.txt file.++#ifndef EIGEN_LMONESTEP_H+#define EIGEN_LMONESTEP_H++namespace Eigen {++template<typename FunctorType>+LevenbergMarquardtSpace::Status+LevenbergMarquardt<FunctorType>::minimizeOneStep(FVectorType &x)+{+ using std::abs;+ using std::sqrt;+ RealScalar temp, temp1,temp2; + RealScalar ratio; + RealScalar pnorm, xnorm, fnorm1, actred, dirder, prered;+ eigen_assert(x.size()==n); // check the caller is not cheating us++ temp = 0.0; xnorm = 0.0;+ /* calculate the jacobian matrix. */+ Index df_ret = m_functor.df(x, m_fjac);+ if (df_ret<0)+ return LevenbergMarquardtSpace::UserAsked;+ if (df_ret>0)+ // numerical diff, we evaluated the function df_ret times+ m_nfev += df_ret;+ else m_njev++;++ /* compute the qr factorization of the jacobian. */+ for (int j = 0; j < x.size(); ++j)+ m_wa2(j) = m_fjac.col(j).blueNorm();+ QRSolver qrfac(m_fjac);+ if(qrfac.info() != Success) {+ m_info = NumericalIssue;+ return LevenbergMarquardtSpace::ImproperInputParameters;+ }+ // Make a copy of the first factor with the associated permutation+ m_rfactor = qrfac.matrixR();+ m_permutation = (qrfac.colsPermutation());++ /* on the first iteration and if external scaling is not used, scale according */+ /* to the norms of the columns of the initial jacobian. */+ if (m_iter == 1) {+ if (!m_useExternalScaling)+ for (Index j = 0; j < n; ++j)+ m_diag[j] = (m_wa2[j]==0.)? 1. : m_wa2[j];++ /* on the first iteration, calculate the norm of the scaled x */+ /* and initialize the step bound m_delta. */+ xnorm = m_diag.cwiseProduct(x).stableNorm();+ m_delta = m_factor * xnorm;+ if (m_delta == 0.)+ m_delta = m_factor;+ }++ /* form (q transpose)*m_fvec and store the first n components in */+ /* m_qtf. */+ m_wa4 = m_fvec;+ m_wa4 = qrfac.matrixQ().adjoint() * m_fvec; + m_qtf = m_wa4.head(n);++ /* compute the norm of the scaled gradient. */+ m_gnorm = 0.;+ if (m_fnorm != 0.)+ for (Index j = 0; j < n; ++j)+ if (m_wa2[m_permutation.indices()[j]] != 0.)+ m_gnorm = (std::max)(m_gnorm, abs( m_rfactor.col(j).head(j+1).dot(m_qtf.head(j+1)/m_fnorm) / m_wa2[m_permutation.indices()[j]]));++ /* test for convergence of the gradient norm. */+ if (m_gnorm <= m_gtol) {+ m_info = Success;+ return LevenbergMarquardtSpace::CosinusTooSmall;+ }++ /* rescale if necessary. */+ if (!m_useExternalScaling)+ m_diag = m_diag.cwiseMax(m_wa2);++ do {+ /* determine the levenberg-marquardt parameter. */+ internal::lmpar2(qrfac, m_diag, m_qtf, m_delta, m_par, m_wa1);++ /* store the direction p and x + p. calculate the norm of p. */+ m_wa1 = -m_wa1;+ m_wa2 = x + m_wa1;+ pnorm = m_diag.cwiseProduct(m_wa1).stableNorm();++ /* on the first iteration, adjust the initial step bound. */+ if (m_iter == 1)+ m_delta = (std::min)(m_delta,pnorm);++ /* evaluate the function at x + p and calculate its norm. */+ if ( m_functor(m_wa2, m_wa4) < 0)+ return LevenbergMarquardtSpace::UserAsked;+ ++m_nfev;+ fnorm1 = m_wa4.stableNorm();++ /* compute the scaled actual reduction. */+ actred = -1.;+ if (Scalar(.1) * fnorm1 < m_fnorm)+ actred = 1. - numext::abs2(fnorm1 / m_fnorm);++ /* compute the scaled predicted reduction and */+ /* the scaled directional derivative. */+ m_wa3 = m_rfactor.template triangularView<Upper>() * (m_permutation.inverse() *m_wa1);+ temp1 = numext::abs2(m_wa3.stableNorm() / m_fnorm);+ temp2 = numext::abs2(sqrt(m_par) * pnorm / m_fnorm);+ prered = temp1 + temp2 / Scalar(.5);+ dirder = -(temp1 + temp2);++ /* compute the ratio of the actual to the predicted */+ /* reduction. */+ ratio = 0.;+ if (prered != 0.)+ ratio = actred / prered;++ /* update the step bound. */+ if (ratio <= Scalar(.25)) {+ if (actred >= 0.)+ temp = RealScalar(.5);+ if (actred < 0.)+ temp = RealScalar(.5) * dirder / (dirder + RealScalar(.5) * actred);+ if (RealScalar(.1) * fnorm1 >= m_fnorm || temp < RealScalar(.1))+ temp = Scalar(.1);+ /* Computing MIN */+ m_delta = temp * (std::min)(m_delta, pnorm / RealScalar(.1));+ m_par /= temp;+ } else if (!(m_par != 0. && ratio < RealScalar(.75))) {+ m_delta = pnorm / RealScalar(.5);+ m_par = RealScalar(.5) * m_par;+ }++ /* test for successful iteration. */+ if (ratio >= RealScalar(1e-4)) {+ /* successful iteration. update x, m_fvec, and their norms. */+ x = m_wa2;+ m_wa2 = m_diag.cwiseProduct(x);+ m_fvec = m_wa4;+ xnorm = m_wa2.stableNorm();+ m_fnorm = fnorm1;+ ++m_iter;+ }++ /* tests for convergence. */+ if (abs(actred) <= m_ftol && prered <= m_ftol && Scalar(.5) * ratio <= 1. && m_delta <= m_xtol * xnorm)+ {+ m_info = Success;+ return LevenbergMarquardtSpace::RelativeErrorAndReductionTooSmall;+ }+ if (abs(actred) <= m_ftol && prered <= m_ftol && Scalar(.5) * ratio <= 1.) + {+ m_info = Success;+ return LevenbergMarquardtSpace::RelativeReductionTooSmall;+ }+ if (m_delta <= m_xtol * xnorm)+ {+ m_info = Success;+ return LevenbergMarquardtSpace::RelativeErrorTooSmall;+ }++ /* tests for termination and stringent tolerances. */+ if (m_nfev >= m_maxfev) + {+ m_info = NoConvergence;+ return LevenbergMarquardtSpace::TooManyFunctionEvaluation;+ }+ if (abs(actred) <= NumTraits<Scalar>::epsilon() && prered <= NumTraits<Scalar>::epsilon() && Scalar(.5) * ratio <= 1.)+ {+ m_info = Success;+ return LevenbergMarquardtSpace::FtolTooSmall;+ }+ if (m_delta <= NumTraits<Scalar>::epsilon() * xnorm) + {+ m_info = Success;+ return LevenbergMarquardtSpace::XtolTooSmall;+ }+ if (m_gnorm <= NumTraits<Scalar>::epsilon())+ {+ m_info = Success;+ return LevenbergMarquardtSpace::GtolTooSmall;+ }++ } while (ratio < Scalar(1e-4));++ return LevenbergMarquardtSpace::Running;+}++ +} // end namespace Eigen++#endif // EIGEN_LMONESTEP_H
+ eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMpar.h view
@@ -0,0 +1,160 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// This code initially comes from MINPACK whose original authors are:+// Copyright Jorge More - Argonne National Laboratory+// Copyright Burt Garbow - Argonne National Laboratory+// Copyright Ken Hillstrom - Argonne National Laboratory+//+// This Source Code Form is subject to the terms of the Minpack license+// (a BSD-like license) described in the campaigned CopyrightMINPACK.txt file.++#ifndef EIGEN_LMPAR_H+#define EIGEN_LMPAR_H++namespace Eigen {++namespace internal {+ + template <typename QRSolver, typename VectorType>+ void lmpar2(+ const QRSolver &qr,+ const VectorType &diag,+ const VectorType &qtb,+ typename VectorType::Scalar m_delta,+ typename VectorType::Scalar &par,+ VectorType &x)++ {+ using std::sqrt;+ using std::abs;+ typedef typename QRSolver::MatrixType MatrixType;+ typedef typename QRSolver::Scalar Scalar;+ typedef typename QRSolver::Index Index;++ /* Local variables */+ Index j;+ Scalar fp;+ Scalar parc, parl;+ Index iter;+ Scalar temp, paru;+ Scalar gnorm;+ Scalar dxnorm;+ + // Make a copy of the triangular factor. + // This copy is modified during call the qrsolv+ MatrixType s;+ s = qr.matrixR();++ /* Function Body */+ const Scalar dwarf = (std::numeric_limits<Scalar>::min)();+ const Index n = qr.matrixR().cols();+ eigen_assert(n==diag.size());+ eigen_assert(n==qtb.size());++ VectorType wa1, wa2;++ /* compute and store in x the gauss-newton direction. if the */+ /* jacobian is rank-deficient, obtain a least squares solution. */++ // const Index rank = qr.nonzeroPivots(); // exactly double(0.)+ const Index rank = qr.rank(); // use a threshold+ wa1 = qtb;+ wa1.tail(n-rank).setZero();+ //FIXME There is no solve in place for sparse triangularView+ wa1.head(rank) = s.topLeftCorner(rank,rank).template triangularView<Upper>().solve(qtb.head(rank));++ x = qr.colsPermutation()*wa1;++ /* initialize the iteration counter. */+ /* evaluate the function at the origin, and test */+ /* for acceptance of the gauss-newton direction. */+ iter = 0;+ wa2 = diag.cwiseProduct(x);+ dxnorm = wa2.blueNorm();+ fp = dxnorm - m_delta;+ if (fp <= Scalar(0.1) * m_delta) {+ par = 0;+ return;+ }++ /* if the jacobian is not rank deficient, the newton */+ /* step provides a lower bound, parl, for the zero of */+ /* the function. otherwise set this bound to zero. */+ parl = 0.;+ if (rank==n) {+ wa1 = qr.colsPermutation().inverse() * diag.cwiseProduct(wa2)/dxnorm;+ s.topLeftCorner(n,n).transpose().template triangularView<Lower>().solveInPlace(wa1);+ temp = wa1.blueNorm();+ parl = fp / m_delta / temp / temp;+ }++ /* calculate an upper bound, paru, for the zero of the function. */+ for (j = 0; j < n; ++j)+ wa1[j] = s.col(j).head(j+1).dot(qtb.head(j+1)) / diag[qr.colsPermutation().indices()(j)];++ gnorm = wa1.stableNorm();+ paru = gnorm / m_delta;+ if (paru == 0.)+ paru = dwarf / (std::min)(m_delta,Scalar(0.1));++ /* if the input par lies outside of the interval (parl,paru), */+ /* set par to the closer endpoint. */+ par = (std::max)(par,parl);+ par = (std::min)(par,paru);+ if (par == 0.)+ par = gnorm / dxnorm;++ /* beginning of an iteration. */+ while (true) {+ ++iter;++ /* evaluate the function at the current value of par. */+ if (par == 0.)+ par = (std::max)(dwarf,Scalar(.001) * paru); /* Computing MAX */+ wa1 = sqrt(par)* diag;++ VectorType sdiag(n);+ lmqrsolv(s, qr.colsPermutation(), wa1, qtb, x, sdiag);++ wa2 = diag.cwiseProduct(x);+ dxnorm = wa2.blueNorm();+ temp = fp;+ fp = dxnorm - m_delta;++ /* if the function is small enough, accept the current value */+ /* of par. also test for the exceptional cases where parl */+ /* is zero or the number of iterations has reached 10. */+ if (abs(fp) <= Scalar(0.1) * m_delta || (parl == 0. && fp <= temp && temp < 0.) || iter == 10)+ break;++ /* compute the newton correction. */+ wa1 = qr.colsPermutation().inverse() * diag.cwiseProduct(wa2/dxnorm);+ // we could almost use this here, but the diagonal is outside qr, in sdiag[]+ for (j = 0; j < n; ++j) {+ wa1[j] /= sdiag[j];+ temp = wa1[j];+ for (Index i = j+1; i < n; ++i)+ wa1[i] -= s.coeff(i,j) * temp;+ }+ temp = wa1.blueNorm();+ parc = fp / m_delta / temp / temp;++ /* depending on the sign of the function, update parl or paru. */+ if (fp > 0.)+ parl = (std::max)(parl,par);+ if (fp < 0.)+ paru = (std::min)(paru,par);++ /* compute an improved estimate for par. */+ par = (std::max)(parl,par+parc);+ }+ if (iter == 0)+ par = 0.;+ return;+ }+} // end namespace internal++} // end namespace Eigen++#endif // EIGEN_LMPAR_H
+ eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMqrsolv.h view
@@ -0,0 +1,189 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>+// Copyright (C) 2012 Desire Nuentsa <desire.nuentsa_wakam@inria.fr>+//+// This code initially comes from MINPACK whose original authors are:+// Copyright Jorge More - Argonne National Laboratory+// Copyright Burt Garbow - Argonne National Laboratory+// Copyright Ken Hillstrom - Argonne National Laboratory+//+// This Source Code Form is subject to the terms of the Minpack license+// (a BSD-like license) described in the campaigned CopyrightMINPACK.txt file.++#ifndef EIGEN_LMQRSOLV_H+#define EIGEN_LMQRSOLV_H++namespace Eigen { ++namespace internal {++template <typename Scalar,int Rows, int Cols, typename Index>+void lmqrsolv(+ Matrix<Scalar,Rows,Cols> &s,+ const PermutationMatrix<Dynamic,Dynamic,Index> &iPerm,+ const Matrix<Scalar,Dynamic,1> &diag,+ const Matrix<Scalar,Dynamic,1> &qtb,+ Matrix<Scalar,Dynamic,1> &x,+ Matrix<Scalar,Dynamic,1> &sdiag)+{++ /* Local variables */+ Index i, j, k, l;+ Scalar temp;+ Index n = s.cols();+ Matrix<Scalar,Dynamic,1> wa(n);+ JacobiRotation<Scalar> givens;++ /* Function Body */+ // the following will only change the lower triangular part of s, including+ // the diagonal, though the diagonal is restored afterward++ /* copy r and (q transpose)*b to preserve input and initialize s. */+ /* in particular, save the diagonal elements of r in x. */+ x = s.diagonal();+ wa = qtb;+ + + s.topLeftCorner(n,n).template triangularView<StrictlyLower>() = s.topLeftCorner(n,n).transpose();+ /* eliminate the diagonal matrix d using a givens rotation. */+ for (j = 0; j < n; ++j) {++ /* prepare the row of d to be eliminated, locating the */+ /* diagonal element using p from the qr factorization. */+ l = iPerm.indices()(j);+ if (diag[l] == 0.)+ break;+ sdiag.tail(n-j).setZero();+ sdiag[j] = diag[l];++ /* the transformations to eliminate the row of d */+ /* modify only a single element of (q transpose)*b */+ /* beyond the first n, which is initially zero. */+ Scalar qtbpj = 0.;+ for (k = j; k < n; ++k) {+ /* determine a givens rotation which eliminates the */+ /* appropriate element in the current row of d. */+ givens.makeGivens(-s(k,k), sdiag[k]);++ /* compute the modified diagonal element of r and */+ /* the modified element of ((q transpose)*b,0). */+ s(k,k) = givens.c() * s(k,k) + givens.s() * sdiag[k];+ temp = givens.c() * wa[k] + givens.s() * qtbpj;+ qtbpj = -givens.s() * wa[k] + givens.c() * qtbpj;+ wa[k] = temp;++ /* accumulate the tranformation in the row of s. */+ for (i = k+1; i<n; ++i) {+ temp = givens.c() * s(i,k) + givens.s() * sdiag[i];+ sdiag[i] = -givens.s() * s(i,k) + givens.c() * sdiag[i];+ s(i,k) = temp;+ }+ }+ }+ + /* solve the triangular system for z. if the system is */+ /* singular, then obtain a least squares solution. */+ Index nsing;+ for(nsing=0; nsing<n && sdiag[nsing]!=0; nsing++) {}++ wa.tail(n-nsing).setZero();+ s.topLeftCorner(nsing, nsing).transpose().template triangularView<Upper>().solveInPlace(wa.head(nsing));+ + // restore+ sdiag = s.diagonal();+ s.diagonal() = x;++ /* permute the components of z back to components of x. */+ x = iPerm * wa; +}++template <typename Scalar, int _Options, typename Index>+void lmqrsolv(+ SparseMatrix<Scalar,_Options,Index> &s,+ const PermutationMatrix<Dynamic,Dynamic> &iPerm,+ const Matrix<Scalar,Dynamic,1> &diag,+ const Matrix<Scalar,Dynamic,1> &qtb,+ Matrix<Scalar,Dynamic,1> &x,+ Matrix<Scalar,Dynamic,1> &sdiag)+{+ /* Local variables */+ typedef SparseMatrix<Scalar,RowMajor,Index> FactorType;+ Index i, j, k, l;+ Scalar temp;+ Index n = s.cols();+ Matrix<Scalar,Dynamic,1> wa(n);+ JacobiRotation<Scalar> givens;++ /* Function Body */+ // the following will only change the lower triangular part of s, including+ // the diagonal, though the diagonal is restored afterward++ /* copy r and (q transpose)*b to preserve input and initialize R. */+ wa = qtb;+ FactorType R(s);+ // Eliminate the diagonal matrix d using a givens rotation+ for (j = 0; j < n; ++j)+ {+ // Prepare the row of d to be eliminated, locating the + // diagonal element using p from the qr factorization+ l = iPerm.indices()(j);+ if (diag(l) == Scalar(0)) + break; + sdiag.tail(n-j).setZero();+ sdiag[j] = diag[l];+ // the transformations to eliminate the row of d+ // modify only a single element of (q transpose)*b+ // beyond the first n, which is initially zero. + + Scalar qtbpj = 0; + // Browse the nonzero elements of row j of the upper triangular s+ for (k = j; k < n; ++k)+ {+ typename FactorType::InnerIterator itk(R,k);+ for (; itk; ++itk){+ if (itk.index() < k) continue;+ else break;+ }+ //At this point, we have the diagonal element R(k,k)+ // Determine a givens rotation which eliminates + // the appropriate element in the current row of d+ givens.makeGivens(-itk.value(), sdiag(k));+ + // Compute the modified diagonal element of r and + // the modified element of ((q transpose)*b,0).+ itk.valueRef() = givens.c() * itk.value() + givens.s() * sdiag(k);+ temp = givens.c() * wa(k) + givens.s() * qtbpj; + qtbpj = -givens.s() * wa(k) + givens.c() * qtbpj;+ wa(k) = temp;+ + // Accumulate the transformation in the remaining k row/column of R+ for (++itk; itk; ++itk)+ {+ i = itk.index();+ temp = givens.c() * itk.value() + givens.s() * sdiag(i);+ sdiag(i) = -givens.s() * itk.value() + givens.c() * sdiag(i);+ itk.valueRef() = temp;+ }+ }+ }+ + // Solve the triangular system for z. If the system is + // singular, then obtain a least squares solution+ Index nsing;+ for(nsing = 0; nsing<n && sdiag(nsing) !=0; nsing++) {}+ + wa.tail(n-nsing).setZero();+// x = wa; + wa.head(nsing) = R.topLeftCorner(nsing,nsing).template triangularView<Upper>().solve/*InPlace*/(wa.head(nsing));+ + sdiag = R.diagonal();+ // Permute the components of z back to components of x+ x = iPerm * wa; +}+} // end namespace internal++} // end namespace Eigen++#endif // EIGEN_LMQRSOLV_H
+ eigen3/unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h view
@@ -0,0 +1,377 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>+// Copyright (C) 2012 Desire Nuentsa <desire.nuentsa_wakam@inria.fr>+//+// The algorithm of this class initially comes from MINPACK whose original authors are:+// Copyright Jorge More - Argonne National Laboratory+// Copyright Burt Garbow - Argonne National Laboratory+// Copyright Ken Hillstrom - Argonne National Laboratory+//+// This Source Code Form is subject to the terms of the Minpack license+// (a BSD-like license) described in the campaigned CopyrightMINPACK.txt file.+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_LEVENBERGMARQUARDT_H+#define EIGEN_LEVENBERGMARQUARDT_H+++namespace Eigen {+namespace LevenbergMarquardtSpace {+ enum Status {+ NotStarted = -2,+ Running = -1,+ ImproperInputParameters = 0,+ RelativeReductionTooSmall = 1,+ RelativeErrorTooSmall = 2,+ RelativeErrorAndReductionTooSmall = 3,+ CosinusTooSmall = 4,+ TooManyFunctionEvaluation = 5,+ FtolTooSmall = 6,+ XtolTooSmall = 7,+ GtolTooSmall = 8,+ UserAsked = 9+ };+}++template <typename _Scalar, int NX=Dynamic, int NY=Dynamic>+struct DenseFunctor+{+ typedef _Scalar Scalar;+ enum {+ InputsAtCompileTime = NX,+ ValuesAtCompileTime = NY+ };+ typedef Matrix<Scalar,InputsAtCompileTime,1> InputType;+ typedef Matrix<Scalar,ValuesAtCompileTime,1> ValueType;+ typedef Matrix<Scalar,ValuesAtCompileTime,InputsAtCompileTime> JacobianType;+ typedef ColPivHouseholderQR<JacobianType> QRSolver;+ const int m_inputs, m_values;++ DenseFunctor() : m_inputs(InputsAtCompileTime), m_values(ValuesAtCompileTime) {}+ DenseFunctor(int inputs, int values) : m_inputs(inputs), m_values(values) {}++ int inputs() const { return m_inputs; }+ int values() const { return m_values; }++ //int operator()(const InputType &x, ValueType& fvec) { }+ // should be defined in derived classes+ + //int df(const InputType &x, JacobianType& fjac) { }+ // should be defined in derived classes+};++template <typename _Scalar, typename _Index>+struct SparseFunctor+{+ typedef _Scalar Scalar;+ typedef _Index Index;+ typedef Matrix<Scalar,Dynamic,1> InputType;+ typedef Matrix<Scalar,Dynamic,1> ValueType;+ typedef SparseMatrix<Scalar, ColMajor, Index> JacobianType;+ typedef SparseQR<JacobianType, COLAMDOrdering<int> > QRSolver;+ enum {+ InputsAtCompileTime = Dynamic,+ ValuesAtCompileTime = Dynamic+ };+ + SparseFunctor(int inputs, int values) : m_inputs(inputs), m_values(values) {}++ int inputs() const { return m_inputs; }+ int values() const { return m_values; }+ + const int m_inputs, m_values;+ //int operator()(const InputType &x, ValueType& fvec) { }+ // to be defined in the functor+ + //int df(const InputType &x, JacobianType& fjac) { }+ // to be defined in the functor if no automatic differentiation+ +};+namespace internal {+template <typename QRSolver, typename VectorType>+void lmpar2(const QRSolver &qr, const VectorType &diag, const VectorType &qtb,+ typename VectorType::Scalar m_delta, typename VectorType::Scalar &par,+ VectorType &x);+ }+/**+ * \ingroup NonLinearOptimization_Module+ * \brief Performs non linear optimization over a non-linear function,+ * using a variant of the Levenberg Marquardt algorithm.+ *+ * Check wikipedia for more information.+ * http://en.wikipedia.org/wiki/Levenberg%E2%80%93Marquardt_algorithm+ */+template<typename _FunctorType>+class LevenbergMarquardt : internal::no_assignment_operator+{+ public:+ typedef _FunctorType FunctorType;+ typedef typename FunctorType::QRSolver QRSolver;+ typedef typename FunctorType::JacobianType JacobianType;+ typedef typename JacobianType::Scalar Scalar;+ typedef typename JacobianType::RealScalar RealScalar; + typedef typename JacobianType::Index Index;+ typedef typename QRSolver::Index PermIndex;+ typedef Matrix<Scalar,Dynamic,1> FVectorType;+ typedef PermutationMatrix<Dynamic,Dynamic> PermutationType;+ public:+ LevenbergMarquardt(FunctorType& functor) + : m_functor(functor),m_nfev(0),m_njev(0),m_fnorm(0.0),m_gnorm(0),+ m_isInitialized(false),m_info(InvalidInput)+ {+ resetParameters();+ m_useExternalScaling=false; + }+ + LevenbergMarquardtSpace::Status minimize(FVectorType &x);+ LevenbergMarquardtSpace::Status minimizeInit(FVectorType &x);+ LevenbergMarquardtSpace::Status minimizeOneStep(FVectorType &x);+ LevenbergMarquardtSpace::Status lmder1(+ FVectorType &x, + const Scalar tol = std::sqrt(NumTraits<Scalar>::epsilon())+ );+ static LevenbergMarquardtSpace::Status lmdif1(+ FunctorType &functor,+ FVectorType &x,+ Index *nfev,+ const Scalar tol = std::sqrt(NumTraits<Scalar>::epsilon())+ );+ + /** Sets the default parameters */+ void resetParameters() + { + m_factor = 100.; + m_maxfev = 400; + m_ftol = std::sqrt(NumTraits<RealScalar>::epsilon());+ m_xtol = std::sqrt(NumTraits<RealScalar>::epsilon());+ m_gtol = 0. ; + m_epsfcn = 0. ;+ }+ + /** Sets the tolerance for the norm of the solution vector*/+ void setXtol(RealScalar xtol) { m_xtol = xtol; }+ + /** Sets the tolerance for the norm of the vector function*/+ void setFtol(RealScalar ftol) { m_ftol = ftol; }+ + /** Sets the tolerance for the norm of the gradient of the error vector*/+ void setGtol(RealScalar gtol) { m_gtol = gtol; }+ + /** Sets the step bound for the diagonal shift */+ void setFactor(RealScalar factor) { m_factor = factor; } + + /** Sets the error precision */+ void setEpsilon (RealScalar epsfcn) { m_epsfcn = epsfcn; }+ + /** Sets the maximum number of function evaluation */+ void setMaxfev(Index maxfev) {m_maxfev = maxfev; }+ + /** Use an external Scaling. If set to true, pass a nonzero diagonal to diag() */+ void setExternalScaling(bool value) {m_useExternalScaling = value; }+ + /** \returns a reference to the diagonal of the jacobian */+ FVectorType& diag() {return m_diag; }+ + /** \returns the number of iterations performed */+ Index iterations() { return m_iter; }+ + /** \returns the number of functions evaluation */+ Index nfev() { return m_nfev; }+ + /** \returns the number of jacobian evaluation */+ Index njev() { return m_njev; }+ + /** \returns the norm of current vector function */+ RealScalar fnorm() {return m_fnorm; }+ + /** \returns the norm of the gradient of the error */+ RealScalar gnorm() {return m_gnorm; }+ + /** \returns the LevenbergMarquardt parameter */+ RealScalar lm_param(void) { return m_par; }+ + /** \returns a reference to the current vector function + */+ FVectorType& fvec() {return m_fvec; }+ + /** \returns a reference to the matrix where the current Jacobian matrix is stored+ */+ JacobianType& jacobian() {return m_fjac; }+ + /** \returns a reference to the triangular matrix R from the QR of the jacobian matrix.+ * \sa jacobian()+ */+ JacobianType& matrixR() {return m_rfactor; }+ + /** the permutation used in the QR factorization+ */+ PermutationType permutation() {return m_permutation; }+ + /** + * \brief Reports whether the minimization was successful+ * \returns \c Success if the minimization was succesful,+ * \c NumericalIssue if a numerical problem arises during the + * minimization process, for exemple during the QR factorization+ * \c NoConvergence if the minimization did not converge after + * the maximum number of function evaluation allowed+ * \c InvalidInput if the input matrix is invalid+ */+ ComputationInfo info() const+ {+ + return m_info;+ }+ private:+ JacobianType m_fjac; + JacobianType m_rfactor; // The triangular matrix R from the QR of the jacobian matrix m_fjac+ FunctorType &m_functor;+ FVectorType m_fvec, m_qtf, m_diag; + Index n;+ Index m; + Index m_nfev;+ Index m_njev; + RealScalar m_fnorm; // Norm of the current vector function+ RealScalar m_gnorm; //Norm of the gradient of the error + RealScalar m_factor; //+ Index m_maxfev; // Maximum number of function evaluation+ RealScalar m_ftol; //Tolerance in the norm of the vector function+ RealScalar m_xtol; // + RealScalar m_gtol; //tolerance of the norm of the error gradient+ RealScalar m_epsfcn; //+ Index m_iter; // Number of iterations performed+ RealScalar m_delta;+ bool m_useExternalScaling;+ PermutationType m_permutation;+ FVectorType m_wa1, m_wa2, m_wa3, m_wa4; //Temporary vectors+ RealScalar m_par;+ bool m_isInitialized; // Check whether the minimization step has been called+ ComputationInfo m_info; +};++template<typename FunctorType>+LevenbergMarquardtSpace::Status+LevenbergMarquardt<FunctorType>::minimize(FVectorType &x)+{+ LevenbergMarquardtSpace::Status status = minimizeInit(x);+ if (status==LevenbergMarquardtSpace::ImproperInputParameters) {+ m_isInitialized = true;+ return status;+ }+ do {+// std::cout << " uv " << x.transpose() << "\n";+ status = minimizeOneStep(x);+ } while (status==LevenbergMarquardtSpace::Running);+ m_isInitialized = true;+ return status;+}++template<typename FunctorType>+LevenbergMarquardtSpace::Status+LevenbergMarquardt<FunctorType>::minimizeInit(FVectorType &x)+{+ n = x.size();+ m = m_functor.values();++ m_wa1.resize(n); m_wa2.resize(n); m_wa3.resize(n);+ m_wa4.resize(m);+ m_fvec.resize(m);+ //FIXME Sparse Case : Allocate space for the jacobian+ m_fjac.resize(m, n);+// m_fjac.reserve(VectorXi::Constant(n,5)); // FIXME Find a better alternative+ if (!m_useExternalScaling)+ m_diag.resize(n);+ eigen_assert( (!m_useExternalScaling || m_diag.size()==n) || "When m_useExternalScaling is set, the caller must provide a valid 'm_diag'");+ m_qtf.resize(n);++ /* Function Body */+ m_nfev = 0;+ m_njev = 0;++ /* check the input parameters for errors. */+ if (n <= 0 || m < n || m_ftol < 0. || m_xtol < 0. || m_gtol < 0. || m_maxfev <= 0 || m_factor <= 0.){+ m_info = InvalidInput;+ return LevenbergMarquardtSpace::ImproperInputParameters;+ }++ if (m_useExternalScaling)+ for (Index j = 0; j < n; ++j)+ if (m_diag[j] <= 0.) + {+ m_info = InvalidInput;+ return LevenbergMarquardtSpace::ImproperInputParameters;+ }++ /* evaluate the function at the starting point */+ /* and calculate its norm. */+ m_nfev = 1;+ if ( m_functor(x, m_fvec) < 0)+ return LevenbergMarquardtSpace::UserAsked;+ m_fnorm = m_fvec.stableNorm();++ /* initialize levenberg-marquardt parameter and iteration counter. */+ m_par = 0.;+ m_iter = 1;++ return LevenbergMarquardtSpace::NotStarted;+}++template<typename FunctorType>+LevenbergMarquardtSpace::Status+LevenbergMarquardt<FunctorType>::lmder1(+ FVectorType &x,+ const Scalar tol+ )+{+ n = x.size();+ m = m_functor.values();++ /* check the input parameters for errors. */+ if (n <= 0 || m < n || tol < 0.)+ return LevenbergMarquardtSpace::ImproperInputParameters;++ resetParameters();+ m_ftol = tol;+ m_xtol = tol;+ m_maxfev = 100*(n+1);++ return minimize(x);+}+++template<typename FunctorType>+LevenbergMarquardtSpace::Status+LevenbergMarquardt<FunctorType>::lmdif1(+ FunctorType &functor,+ FVectorType &x,+ Index *nfev,+ const Scalar tol+ )+{+ Index n = x.size();+ Index m = functor.values();++ /* check the input parameters for errors. */+ if (n <= 0 || m < n || tol < 0.)+ return LevenbergMarquardtSpace::ImproperInputParameters;++ NumericalDiff<FunctorType> numDiff(functor);+ // embedded LevenbergMarquardt+ LevenbergMarquardt<NumericalDiff<FunctorType> > lm(numDiff);+ lm.setFtol(tol);+ lm.setXtol(tol);+ lm.setMaxfev(200*(n+1));++ LevenbergMarquardtSpace::Status info = LevenbergMarquardtSpace::Status(lm.minimize(x));+ if (nfev)+ * nfev = lm.nfev();+ return info;+}++} // end namespace Eigen++#endif // EIGEN_LEVENBERGMARQUARDT_H
+ eigen3/unsupported/Eigen/src/MatrixFunctions/CMakeLists.txt view
@@ -0,0 +1,6 @@+FILE(GLOB Eigen_MatrixFunctions_SRCS "*.h")++INSTALL(FILES+ ${Eigen_MatrixFunctions_SRCS}+ DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/MatrixFunctions COMPONENT Devel+ )
+ eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h view
@@ -0,0 +1,451 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009, 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>+// Copyright (C) 2011 Chen-Pang He <jdh8@ms63.hinet.net>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_MATRIX_EXPONENTIAL+#define EIGEN_MATRIX_EXPONENTIAL++#include "StemFunction.h"++namespace Eigen {++/** \ingroup MatrixFunctions_Module+ * \brief Class for computing the matrix exponential.+ * \tparam MatrixType type of the argument of the exponential,+ * expected to be an instantiation of the Matrix class template.+ */+template <typename MatrixType>+class MatrixExponential {++ public:++ /** \brief Constructor.+ * + * The class stores a reference to \p M, so it should not be+ * changed (or destroyed) before compute() is called.+ *+ * \param[in] M matrix whose exponential is to be computed.+ */+ MatrixExponential(const MatrixType &M);++ /** \brief Computes the matrix exponential.+ *+ * \param[out] result the matrix exponential of \p M in the constructor.+ */+ template <typename ResultType> + void compute(ResultType &result);++ private:++ // Prevent copying+ MatrixExponential(const MatrixExponential&);+ MatrixExponential& operator=(const MatrixExponential&);++ /** \brief Compute the (3,3)-Padé approximant to the exponential.+ *+ * After exit, \f$ (V+U)(V-U)^{-1} \f$ is the Padé+ * approximant of \f$ \exp(A) \f$ around \f$ A = 0 \f$.+ *+ * \param[in] A Argument of matrix exponential+ */+ void pade3(const MatrixType &A);++ /** \brief Compute the (5,5)-Padé approximant to the exponential.+ *+ * After exit, \f$ (V+U)(V-U)^{-1} \f$ is the Padé+ * approximant of \f$ \exp(A) \f$ around \f$ A = 0 \f$.+ *+ * \param[in] A Argument of matrix exponential+ */+ void pade5(const MatrixType &A);++ /** \brief Compute the (7,7)-Padé approximant to the exponential.+ *+ * After exit, \f$ (V+U)(V-U)^{-1} \f$ is the Padé+ * approximant of \f$ \exp(A) \f$ around \f$ A = 0 \f$.+ *+ * \param[in] A Argument of matrix exponential+ */+ void pade7(const MatrixType &A);++ /** \brief Compute the (9,9)-Padé approximant to the exponential.+ *+ * After exit, \f$ (V+U)(V-U)^{-1} \f$ is the Padé+ * approximant of \f$ \exp(A) \f$ around \f$ A = 0 \f$.+ *+ * \param[in] A Argument of matrix exponential+ */+ void pade9(const MatrixType &A);++ /** \brief Compute the (13,13)-Padé approximant to the exponential.+ *+ * After exit, \f$ (V+U)(V-U)^{-1} \f$ is the Padé+ * approximant of \f$ \exp(A) \f$ around \f$ A = 0 \f$.+ *+ * \param[in] A Argument of matrix exponential+ */+ void pade13(const MatrixType &A);++ /** \brief Compute the (17,17)-Padé approximant to the exponential.+ *+ * After exit, \f$ (V+U)(V-U)^{-1} \f$ is the Padé+ * approximant of \f$ \exp(A) \f$ around \f$ A = 0 \f$.+ *+ * This function activates only if your long double is double-double or quadruple.+ *+ * \param[in] A Argument of matrix exponential+ */+ void pade17(const MatrixType &A);++ /** \brief Compute Padé approximant to the exponential.+ *+ * Computes \c m_U, \c m_V and \c m_squarings such that+ * \f$ (V+U)(V-U)^{-1} \f$ is a Padé of+ * \f$ \exp(2^{-\mbox{squarings}}M) \f$ around \f$ M = 0 \f$. The+ * degree of the Padé approximant and the value of+ * squarings are chosen such that the approximation error is no+ * more than the round-off error.+ *+ * The argument of this function should correspond with the (real+ * part of) the entries of \c m_M. It is used to select the+ * correct implementation using overloading.+ */+ void computeUV(double);++ /** \brief Compute Padé approximant to the exponential.+ *+ * \sa computeUV(double);+ */+ void computeUV(float);+ + /** \brief Compute Padé approximant to the exponential.+ *+ * \sa computeUV(double);+ */+ void computeUV(long double);++ typedef typename internal::traits<MatrixType>::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef typename std::complex<RealScalar> ComplexScalar;++ /** \brief Reference to matrix whose exponential is to be computed. */+ typename internal::nested<MatrixType>::type m_M;++ /** \brief Odd-degree terms in numerator of Padé approximant. */+ MatrixType m_U;++ /** \brief Even-degree terms in numerator of Padé approximant. */+ MatrixType m_V;++ /** \brief Used for temporary storage. */+ MatrixType m_tmp1;++ /** \brief Used for temporary storage. */+ MatrixType m_tmp2;++ /** \brief Identity matrix of the same size as \c m_M. */+ MatrixType m_Id;++ /** \brief Number of squarings required in the last step. */+ int m_squarings;++ /** \brief L1 norm of m_M. */+ RealScalar m_l1norm;+};++template <typename MatrixType>+MatrixExponential<MatrixType>::MatrixExponential(const MatrixType &M) :+ m_M(M),+ m_U(M.rows(),M.cols()),+ m_V(M.rows(),M.cols()),+ m_tmp1(M.rows(),M.cols()),+ m_tmp2(M.rows(),M.cols()),+ m_Id(MatrixType::Identity(M.rows(), M.cols())),+ m_squarings(0),+ m_l1norm(M.cwiseAbs().colwise().sum().maxCoeff())+{+ /* empty body */+}++template <typename MatrixType>+template <typename ResultType> +void MatrixExponential<MatrixType>::compute(ResultType &result)+{+#if LDBL_MANT_DIG > 112 // rarely happens+ if(sizeof(RealScalar) > 14) {+ result = m_M.matrixFunction(StdStemFunctions<ComplexScalar>::exp);+ return;+ }+#endif+ computeUV(RealScalar());+ m_tmp1 = m_U + m_V; // numerator of Pade approximant+ m_tmp2 = -m_U + m_V; // denominator of Pade approximant+ result = m_tmp2.partialPivLu().solve(m_tmp1);+ for (int i=0; i<m_squarings; i++)+ result *= result; // undo scaling by repeated squaring+}++template <typename MatrixType>+EIGEN_STRONG_INLINE void MatrixExponential<MatrixType>::pade3(const MatrixType &A)+{+ const RealScalar b[] = {120., 60., 12., 1.};+ m_tmp1.noalias() = A * A;+ m_tmp2 = b[3]*m_tmp1 + b[1]*m_Id;+ m_U.noalias() = A * m_tmp2;+ m_V = b[2]*m_tmp1 + b[0]*m_Id;+}++template <typename MatrixType>+EIGEN_STRONG_INLINE void MatrixExponential<MatrixType>::pade5(const MatrixType &A)+{+ const RealScalar b[] = {30240., 15120., 3360., 420., 30., 1.};+ MatrixType A2 = A * A;+ m_tmp1.noalias() = A2 * A2;+ m_tmp2 = b[5]*m_tmp1 + b[3]*A2 + b[1]*m_Id;+ m_U.noalias() = A * m_tmp2;+ m_V = b[4]*m_tmp1 + b[2]*A2 + b[0]*m_Id;+}++template <typename MatrixType>+EIGEN_STRONG_INLINE void MatrixExponential<MatrixType>::pade7(const MatrixType &A)+{+ const RealScalar b[] = {17297280., 8648640., 1995840., 277200., 25200., 1512., 56., 1.};+ MatrixType A2 = A * A;+ MatrixType A4 = A2 * A2;+ m_tmp1.noalias() = A4 * A2;+ m_tmp2 = b[7]*m_tmp1 + b[5]*A4 + b[3]*A2 + b[1]*m_Id;+ m_U.noalias() = A * m_tmp2;+ m_V = b[6]*m_tmp1 + b[4]*A4 + b[2]*A2 + b[0]*m_Id;+}++template <typename MatrixType>+EIGEN_STRONG_INLINE void MatrixExponential<MatrixType>::pade9(const MatrixType &A)+{+ const RealScalar b[] = {17643225600., 8821612800., 2075673600., 302702400., 30270240.,+ 2162160., 110880., 3960., 90., 1.};+ MatrixType A2 = A * A;+ MatrixType A4 = A2 * A2;+ MatrixType A6 = A4 * A2;+ m_tmp1.noalias() = A6 * A2;+ m_tmp2 = b[9]*m_tmp1 + b[7]*A6 + b[5]*A4 + b[3]*A2 + b[1]*m_Id;+ m_U.noalias() = A * m_tmp2;+ m_V = b[8]*m_tmp1 + b[6]*A6 + b[4]*A4 + b[2]*A2 + b[0]*m_Id;+}++template <typename MatrixType>+EIGEN_STRONG_INLINE void MatrixExponential<MatrixType>::pade13(const MatrixType &A)+{+ const RealScalar b[] = {64764752532480000., 32382376266240000., 7771770303897600.,+ 1187353796428800., 129060195264000., 10559470521600., 670442572800.,+ 33522128640., 1323241920., 40840800., 960960., 16380., 182., 1.};+ MatrixType A2 = A * A;+ MatrixType A4 = A2 * A2;+ m_tmp1.noalias() = A4 * A2;+ m_V = b[13]*m_tmp1 + b[11]*A4 + b[9]*A2; // used for temporary storage+ m_tmp2.noalias() = m_tmp1 * m_V;+ m_tmp2 += b[7]*m_tmp1 + b[5]*A4 + b[3]*A2 + b[1]*m_Id;+ m_U.noalias() = A * m_tmp2;+ m_tmp2 = b[12]*m_tmp1 + b[10]*A4 + b[8]*A2;+ m_V.noalias() = m_tmp1 * m_tmp2;+ m_V += b[6]*m_tmp1 + b[4]*A4 + b[2]*A2 + b[0]*m_Id;+}++#if LDBL_MANT_DIG > 64+template <typename MatrixType>+EIGEN_STRONG_INLINE void MatrixExponential<MatrixType>::pade17(const MatrixType &A)+{+ const RealScalar b[] = {830034394580628357120000.L, 415017197290314178560000.L,+ 100610229646136770560000.L, 15720348382208870400000.L,+ 1774878043152614400000.L, 153822763739893248000.L, 10608466464820224000.L,+ 595373117923584000.L, 27563570274240000.L, 1060137318240000.L,+ 33924394183680.L, 899510451840.L, 19554575040.L, 341863200.L, 4651200.L,+ 46512.L, 306.L, 1.L};+ MatrixType A2 = A * A;+ MatrixType A4 = A2 * A2;+ MatrixType A6 = A4 * A2;+ m_tmp1.noalias() = A4 * A4;+ m_V = b[17]*m_tmp1 + b[15]*A6 + b[13]*A4 + b[11]*A2; // used for temporary storage+ m_tmp2.noalias() = m_tmp1 * m_V;+ m_tmp2 += b[9]*m_tmp1 + b[7]*A6 + b[5]*A4 + b[3]*A2 + b[1]*m_Id;+ m_U.noalias() = A * m_tmp2;+ m_tmp2 = b[16]*m_tmp1 + b[14]*A6 + b[12]*A4 + b[10]*A2;+ m_V.noalias() = m_tmp1 * m_tmp2;+ m_V += b[8]*m_tmp1 + b[6]*A6 + b[4]*A4 + b[2]*A2 + b[0]*m_Id;+}+#endif++template <typename MatrixType>+void MatrixExponential<MatrixType>::computeUV(float)+{+ using std::frexp;+ using std::pow;+ if (m_l1norm < 4.258730016922831e-001) {+ pade3(m_M);+ } else if (m_l1norm < 1.880152677804762e+000) {+ pade5(m_M);+ } else {+ const float maxnorm = 3.925724783138660f;+ frexp(m_l1norm / maxnorm, &m_squarings);+ if (m_squarings < 0) m_squarings = 0;+ MatrixType A = m_M / pow(Scalar(2), m_squarings);+ pade7(A);+ }+}++template <typename MatrixType>+void MatrixExponential<MatrixType>::computeUV(double)+{+ using std::frexp;+ using std::pow;+ if (m_l1norm < 1.495585217958292e-002) {+ pade3(m_M);+ } else if (m_l1norm < 2.539398330063230e-001) {+ pade5(m_M);+ } else if (m_l1norm < 9.504178996162932e-001) {+ pade7(m_M);+ } else if (m_l1norm < 2.097847961257068e+000) {+ pade9(m_M);+ } else {+ const double maxnorm = 5.371920351148152;+ frexp(m_l1norm / maxnorm, &m_squarings);+ if (m_squarings < 0) m_squarings = 0;+ MatrixType A = m_M / pow(Scalar(2), m_squarings);+ pade13(A);+ }+}++template <typename MatrixType>+void MatrixExponential<MatrixType>::computeUV(long double)+{+ using std::frexp;+ using std::pow;+#if LDBL_MANT_DIG == 53 // double precision+ computeUV(double());+#elif LDBL_MANT_DIG <= 64 // extended precision+ if (m_l1norm < 4.1968497232266989671e-003L) {+ pade3(m_M);+ } else if (m_l1norm < 1.1848116734693823091e-001L) {+ pade5(m_M);+ } else if (m_l1norm < 5.5170388480686700274e-001L) {+ pade7(m_M);+ } else if (m_l1norm < 1.3759868875587845383e+000L) {+ pade9(m_M);+ } else {+ const long double maxnorm = 4.0246098906697353063L;+ frexp(m_l1norm / maxnorm, &m_squarings);+ if (m_squarings < 0) m_squarings = 0;+ MatrixType A = m_M / pow(Scalar(2), m_squarings);+ pade13(A);+ }+#elif LDBL_MANT_DIG <= 106 // double-double+ if (m_l1norm < 3.2787892205607026992947488108213e-005L) {+ pade3(m_M);+ } else if (m_l1norm < 6.4467025060072760084130906076332e-003L) {+ pade5(m_M);+ } else if (m_l1norm < 6.8988028496595374751374122881143e-002L) {+ pade7(m_M);+ } else if (m_l1norm < 2.7339737518502231741495857201670e-001L) {+ pade9(m_M);+ } else if (m_l1norm < 1.3203382096514474905666448850278e+000L) {+ pade13(m_M);+ } else {+ const long double maxnorm = 3.2579440895405400856599663723517L;+ frexp(m_l1norm / maxnorm, &m_squarings);+ if (m_squarings < 0) m_squarings = 0;+ MatrixType A = m_M / pow(Scalar(2), m_squarings);+ pade17(A);+ }+#elif LDBL_MANT_DIG <= 112 // quadruple precison+ if (m_l1norm < 1.639394610288918690547467954466970e-005L) {+ pade3(m_M);+ } else if (m_l1norm < 4.253237712165275566025884344433009e-003L) {+ pade5(m_M);+ } else if (m_l1norm < 5.125804063165764409885122032933142e-002L) {+ pade7(m_M);+ } else if (m_l1norm < 2.170000765161155195453205651889853e-001L) {+ pade9(m_M);+ } else if (m_l1norm < 1.125358383453143065081397882891878e+000L) {+ pade13(m_M);+ } else {+ const long double maxnorm = 2.884233277829519311757165057717815L;+ frexp(m_l1norm / maxnorm, &m_squarings);+ if (m_squarings < 0) m_squarings = 0;+ MatrixType A = m_M / pow(Scalar(2), m_squarings);+ pade17(A);+ }+#else+ // this case should be handled in compute()+ eigen_assert(false && "Bug in MatrixExponential"); +#endif // LDBL_MANT_DIG+}++/** \ingroup MatrixFunctions_Module+ *+ * \brief Proxy for the matrix exponential of some matrix (expression).+ *+ * \tparam Derived Type of the argument to the matrix exponential.+ *+ * This class holds the argument to the matrix exponential until it+ * is assigned or evaluated for some other reason (so the argument+ * should not be changed in the meantime). It is the return type of+ * MatrixBase::exp() and most of the time this is the only way it is+ * used.+ */+template<typename Derived> struct MatrixExponentialReturnValue+: public ReturnByValue<MatrixExponentialReturnValue<Derived> >+{+ typedef typename Derived::Index Index;+ public:+ /** \brief Constructor.+ *+ * \param[in] src %Matrix (expression) forming the argument of the+ * matrix exponential.+ */+ MatrixExponentialReturnValue(const Derived& src) : m_src(src) { }++ /** \brief Compute the matrix exponential.+ *+ * \param[out] result the matrix exponential of \p src in the+ * constructor.+ */+ template <typename ResultType>+ inline void evalTo(ResultType& result) const+ {+ const typename Derived::PlainObject srcEvaluated = m_src.eval();+ MatrixExponential<typename Derived::PlainObject> me(srcEvaluated);+ me.compute(result);+ }++ Index rows() const { return m_src.rows(); }+ Index cols() const { return m_src.cols(); }++ protected:+ const Derived& m_src;+ private:+ MatrixExponentialReturnValue& operator=(const MatrixExponentialReturnValue&);+};++namespace internal {+template<typename Derived>+struct traits<MatrixExponentialReturnValue<Derived> >+{+ typedef typename Derived::PlainObject ReturnType;+};+}++template <typename Derived>+const MatrixExponentialReturnValue<Derived> MatrixBase<Derived>::exp() const+{+ eigen_assert(rows() == cols());+ return MatrixExponentialReturnValue<Derived>(derived());+}++} // end namespace Eigen++#endif // EIGEN_MATRIX_EXPONENTIAL
+ eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h view
@@ -0,0 +1,591 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009-2011 Jitse Niesen <jitse@maths.leeds.ac.uk>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_MATRIX_FUNCTION+#define EIGEN_MATRIX_FUNCTION++#include "StemFunction.h"+#include "MatrixFunctionAtomic.h"+++namespace Eigen { ++/** \ingroup MatrixFunctions_Module+ * \brief Class for computing matrix functions.+ * \tparam MatrixType type of the argument of the matrix function,+ * expected to be an instantiation of the Matrix class template.+ * \tparam AtomicType type for computing matrix function of atomic blocks.+ * \tparam IsComplex used internally to select correct specialization.+ *+ * This class implements the Schur-Parlett algorithm for computing matrix functions. The spectrum of the+ * matrix is divided in clustered of eigenvalues that lies close together. This class delegates the+ * computation of the matrix function on every block corresponding to these clusters to an object of type+ * \p AtomicType and uses these results to compute the matrix function of the whole matrix. The class+ * \p AtomicType should have a \p compute() member function for computing the matrix function of a block.+ *+ * \sa class MatrixFunctionAtomic, class MatrixLogarithmAtomic+ */+template <typename MatrixType, + typename AtomicType, + int IsComplex = NumTraits<typename internal::traits<MatrixType>::Scalar>::IsComplex>+class MatrixFunction+{ + public:++ /** \brief Constructor. + *+ * \param[in] A argument of matrix function, should be a square matrix.+ * \param[in] atomic class for computing matrix function of atomic blocks.+ *+ * The class stores references to \p A and \p atomic, so they should not be+ * changed (or destroyed) before compute() is called.+ */+ MatrixFunction(const MatrixType& A, AtomicType& atomic);++ /** \brief Compute the matrix function.+ *+ * \param[out] result the function \p f applied to \p A, as+ * specified in the constructor.+ *+ * See MatrixBase::matrixFunction() for details on how this computation+ * is implemented.+ */+ template <typename ResultType> + void compute(ResultType &result); +};+++/** \internal \ingroup MatrixFunctions_Module + * \brief Partial specialization of MatrixFunction for real matrices+ */+template <typename MatrixType, typename AtomicType>+class MatrixFunction<MatrixType, AtomicType, 0>+{ + private:++ typedef internal::traits<MatrixType> Traits;+ typedef typename Traits::Scalar Scalar;+ static const int Rows = Traits::RowsAtCompileTime;+ static const int Cols = Traits::ColsAtCompileTime;+ static const int Options = MatrixType::Options;+ static const int MaxRows = Traits::MaxRowsAtCompileTime;+ static const int MaxCols = Traits::MaxColsAtCompileTime;++ typedef std::complex<Scalar> ComplexScalar;+ typedef Matrix<ComplexScalar, Rows, Cols, Options, MaxRows, MaxCols> ComplexMatrix;++ public:++ /** \brief Constructor. + *+ * \param[in] A argument of matrix function, should be a square matrix.+ * \param[in] atomic class for computing matrix function of atomic blocks.+ */+ MatrixFunction(const MatrixType& A, AtomicType& atomic) : m_A(A), m_atomic(atomic) { }++ /** \brief Compute the matrix function.+ *+ * \param[out] result the function \p f applied to \p A, as+ * specified in the constructor.+ *+ * This function converts the real matrix \c A to a complex matrix,+ * uses MatrixFunction<MatrixType,1> and then converts the result back to+ * a real matrix.+ */+ template <typename ResultType>+ void compute(ResultType& result) + {+ ComplexMatrix CA = m_A.template cast<ComplexScalar>();+ ComplexMatrix Cresult;+ MatrixFunction<ComplexMatrix, AtomicType> mf(CA, m_atomic);+ mf.compute(Cresult);+ result = Cresult.real();+ }++ private:+ typename internal::nested<MatrixType>::type m_A; /**< \brief Reference to argument of matrix function. */+ AtomicType& m_atomic; /**< \brief Class for computing matrix function of atomic blocks. */++ MatrixFunction& operator=(const MatrixFunction&);+};++ +/** \internal \ingroup MatrixFunctions_Module + * \brief Partial specialization of MatrixFunction for complex matrices+ */+template <typename MatrixType, typename AtomicType>+class MatrixFunction<MatrixType, AtomicType, 1>+{+ private:++ typedef internal::traits<MatrixType> Traits;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::Index Index;+ static const int RowsAtCompileTime = Traits::RowsAtCompileTime;+ static const int ColsAtCompileTime = Traits::ColsAtCompileTime;+ static const int Options = MatrixType::Options;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, Traits::RowsAtCompileTime, 1> VectorType;+ typedef Matrix<Index, Traits::RowsAtCompileTime, 1> IntVectorType;+ typedef Matrix<Index, Dynamic, 1> DynamicIntVectorType;+ typedef std::list<Scalar> Cluster;+ typedef std::list<Cluster> ListOfClusters;+ typedef Matrix<Scalar, Dynamic, Dynamic, Options, RowsAtCompileTime, ColsAtCompileTime> DynMatrixType;++ public:++ MatrixFunction(const MatrixType& A, AtomicType& atomic);+ template <typename ResultType> void compute(ResultType& result);++ private:++ void computeSchurDecomposition();+ void partitionEigenvalues();+ typename ListOfClusters::iterator findCluster(Scalar key);+ void computeClusterSize();+ void computeBlockStart();+ void constructPermutation();+ void permuteSchur();+ void swapEntriesInSchur(Index index);+ void computeBlockAtomic();+ Block<MatrixType> block(MatrixType& A, Index i, Index j);+ void computeOffDiagonal();+ DynMatrixType solveTriangularSylvester(const DynMatrixType& A, const DynMatrixType& B, const DynMatrixType& C);++ typename internal::nested<MatrixType>::type m_A; /**< \brief Reference to argument of matrix function. */+ AtomicType& m_atomic; /**< \brief Class for computing matrix function of atomic blocks. */+ MatrixType m_T; /**< \brief Triangular part of Schur decomposition */+ MatrixType m_U; /**< \brief Unitary part of Schur decomposition */+ MatrixType m_fT; /**< \brief %Matrix function applied to #m_T */+ ListOfClusters m_clusters; /**< \brief Partition of eigenvalues into clusters of ei'vals "close" to each other */+ DynamicIntVectorType m_eivalToCluster; /**< \brief m_eivalToCluster[i] = j means i-th ei'val is in j-th cluster */+ DynamicIntVectorType m_clusterSize; /**< \brief Number of eigenvalues in each clusters */+ DynamicIntVectorType m_blockStart; /**< \brief Row index at which block corresponding to i-th cluster starts */+ IntVectorType m_permutation; /**< \brief Permutation which groups ei'vals in the same cluster together */++ /** \brief Maximum distance allowed between eigenvalues to be considered "close".+ *+ * This is morally a \c static \c const \c Scalar, but only+ * integers can be static constant class members in C++. The+ * separation constant is set to 0.1, a value taken from the+ * paper by Davies and Higham. */+ static const RealScalar separation() { return static_cast<RealScalar>(0.1); }++ MatrixFunction& operator=(const MatrixFunction&);+};++/** \brief Constructor. + *+ * \param[in] A argument of matrix function, should be a square matrix.+ * \param[in] atomic class for computing matrix function of atomic blocks.+ */+template <typename MatrixType, typename AtomicType>+MatrixFunction<MatrixType,AtomicType,1>::MatrixFunction(const MatrixType& A, AtomicType& atomic)+ : m_A(A), m_atomic(atomic)+{+ /* empty body */+}++/** \brief Compute the matrix function.+ *+ * \param[out] result the function \p f applied to \p A, as+ * specified in the constructor.+ */+template <typename MatrixType, typename AtomicType>+template <typename ResultType>+void MatrixFunction<MatrixType,AtomicType,1>::compute(ResultType& result) +{+ computeSchurDecomposition();+ partitionEigenvalues();+ computeClusterSize();+ computeBlockStart();+ constructPermutation();+ permuteSchur();+ computeBlockAtomic();+ computeOffDiagonal();+ result = m_U * (m_fT.template triangularView<Upper>() * m_U.adjoint());+}++/** \brief Store the Schur decomposition of #m_A in #m_T and #m_U */+template <typename MatrixType, typename AtomicType>+void MatrixFunction<MatrixType,AtomicType,1>::computeSchurDecomposition()+{+ const ComplexSchur<MatrixType> schurOfA(m_A); + m_T = schurOfA.matrixT();+ m_U = schurOfA.matrixU();+}++/** \brief Partition eigenvalues in clusters of ei'vals close to each other+ * + * This function computes #m_clusters. This is a partition of the+ * eigenvalues of #m_T in clusters, such that+ * # Any eigenvalue in a certain cluster is at most separation() away+ * from another eigenvalue in the same cluster.+ * # The distance between two eigenvalues in different clusters is+ * more than separation().+ * The implementation follows Algorithm 4.1 in the paper of Davies+ * and Higham. + */+template <typename MatrixType, typename AtomicType>+void MatrixFunction<MatrixType,AtomicType,1>::partitionEigenvalues()+{+ using std::abs;+ const Index rows = m_T.rows();+ VectorType diag = m_T.diagonal(); // contains eigenvalues of A++ for (Index i=0; i<rows; ++i) {+ // Find set containing diag(i), adding a new set if necessary+ typename ListOfClusters::iterator qi = findCluster(diag(i));+ if (qi == m_clusters.end()) {+ Cluster l;+ l.push_back(diag(i));+ m_clusters.push_back(l);+ qi = m_clusters.end();+ --qi;+ }++ // Look for other element to add to the set+ for (Index j=i+1; j<rows; ++j) {+ if (abs(diag(j) - diag(i)) <= separation() && std::find(qi->begin(), qi->end(), diag(j)) == qi->end()) {+ typename ListOfClusters::iterator qj = findCluster(diag(j));+ if (qj == m_clusters.end()) {+ qi->push_back(diag(j));+ } else {+ qi->insert(qi->end(), qj->begin(), qj->end());+ m_clusters.erase(qj);+ }+ }+ }+ }+}++/** \brief Find cluster in #m_clusters containing some value + * \param[in] key Value to find+ * \returns Iterator to cluster containing \c key, or+ * \c m_clusters.end() if no cluster in m_clusters contains \c key.+ */+template <typename MatrixType, typename AtomicType>+typename MatrixFunction<MatrixType,AtomicType,1>::ListOfClusters::iterator MatrixFunction<MatrixType,AtomicType,1>::findCluster(Scalar key)+{+ typename Cluster::iterator j;+ for (typename ListOfClusters::iterator i = m_clusters.begin(); i != m_clusters.end(); ++i) {+ j = std::find(i->begin(), i->end(), key);+ if (j != i->end())+ return i;+ }+ return m_clusters.end();+}++/** \brief Compute #m_clusterSize and #m_eivalToCluster using #m_clusters */+template <typename MatrixType, typename AtomicType>+void MatrixFunction<MatrixType,AtomicType,1>::computeClusterSize()+{+ const Index rows = m_T.rows();+ VectorType diag = m_T.diagonal(); + const Index numClusters = static_cast<Index>(m_clusters.size());++ m_clusterSize.setZero(numClusters);+ m_eivalToCluster.resize(rows);+ Index clusterIndex = 0;+ for (typename ListOfClusters::const_iterator cluster = m_clusters.begin(); cluster != m_clusters.end(); ++cluster) {+ for (Index i = 0; i < diag.rows(); ++i) {+ if (std::find(cluster->begin(), cluster->end(), diag(i)) != cluster->end()) {+ ++m_clusterSize[clusterIndex];+ m_eivalToCluster[i] = clusterIndex;+ }+ }+ ++clusterIndex;+ }+}++/** \brief Compute #m_blockStart using #m_clusterSize */+template <typename MatrixType, typename AtomicType>+void MatrixFunction<MatrixType,AtomicType,1>::computeBlockStart()+{+ m_blockStart.resize(m_clusterSize.rows());+ m_blockStart(0) = 0;+ for (Index i = 1; i < m_clusterSize.rows(); i++) {+ m_blockStart(i) = m_blockStart(i-1) + m_clusterSize(i-1);+ }+}++/** \brief Compute #m_permutation using #m_eivalToCluster and #m_blockStart */+template <typename MatrixType, typename AtomicType>+void MatrixFunction<MatrixType,AtomicType,1>::constructPermutation()+{+ DynamicIntVectorType indexNextEntry = m_blockStart;+ m_permutation.resize(m_T.rows());+ for (Index i = 0; i < m_T.rows(); i++) {+ Index cluster = m_eivalToCluster[i];+ m_permutation[i] = indexNextEntry[cluster];+ ++indexNextEntry[cluster];+ }+} ++/** \brief Permute Schur decomposition in #m_U and #m_T according to #m_permutation */+template <typename MatrixType, typename AtomicType>+void MatrixFunction<MatrixType,AtomicType,1>::permuteSchur()+{+ IntVectorType p = m_permutation;+ for (Index i = 0; i < p.rows() - 1; i++) {+ Index j;+ for (j = i; j < p.rows(); j++) {+ if (p(j) == i) break;+ }+ eigen_assert(p(j) == i);+ for (Index k = j-1; k >= i; k--) {+ swapEntriesInSchur(k);+ std::swap(p.coeffRef(k), p.coeffRef(k+1));+ }+ }+}++/** \brief Swap rows \a index and \a index+1 in Schur decomposition in #m_U and #m_T */+template <typename MatrixType, typename AtomicType>+void MatrixFunction<MatrixType,AtomicType,1>::swapEntriesInSchur(Index index)+{+ JacobiRotation<Scalar> rotation;+ rotation.makeGivens(m_T(index, index+1), m_T(index+1, index+1) - m_T(index, index));+ m_T.applyOnTheLeft(index, index+1, rotation.adjoint());+ m_T.applyOnTheRight(index, index+1, rotation);+ m_U.applyOnTheRight(index, index+1, rotation);+} ++/** \brief Compute block diagonal part of #m_fT.+ *+ * This routine computes the matrix function applied to the block diagonal part of #m_T, with the blocking+ * given by #m_blockStart. The matrix function of each diagonal block is computed by #m_atomic. The+ * off-diagonal parts of #m_fT are set to zero.+ */+template <typename MatrixType, typename AtomicType>+void MatrixFunction<MatrixType,AtomicType,1>::computeBlockAtomic()+{ + m_fT.resize(m_T.rows(), m_T.cols());+ m_fT.setZero();+ for (Index i = 0; i < m_clusterSize.rows(); ++i) {+ block(m_fT, i, i) = m_atomic.compute(block(m_T, i, i));+ }+}++/** \brief Return block of matrix according to blocking given by #m_blockStart */+template <typename MatrixType, typename AtomicType>+Block<MatrixType> MatrixFunction<MatrixType,AtomicType,1>::block(MatrixType& A, Index i, Index j)+{+ return A.block(m_blockStart(i), m_blockStart(j), m_clusterSize(i), m_clusterSize(j));+}++/** \brief Compute part of #m_fT above block diagonal.+ *+ * This routine assumes that the block diagonal part of #m_fT (which+ * equals the matrix function applied to #m_T) has already been computed and computes+ * the part above the block diagonal. The part below the diagonal is+ * zero, because #m_T is upper triangular.+ */+template <typename MatrixType, typename AtomicType>+void MatrixFunction<MatrixType,AtomicType,1>::computeOffDiagonal()+{ + for (Index diagIndex = 1; diagIndex < m_clusterSize.rows(); diagIndex++) {+ for (Index blockIndex = 0; blockIndex < m_clusterSize.rows() - diagIndex; blockIndex++) {+ // compute (blockIndex, blockIndex+diagIndex) block+ DynMatrixType A = block(m_T, blockIndex, blockIndex);+ DynMatrixType B = -block(m_T, blockIndex+diagIndex, blockIndex+diagIndex);+ DynMatrixType C = block(m_fT, blockIndex, blockIndex) * block(m_T, blockIndex, blockIndex+diagIndex);+ C -= block(m_T, blockIndex, blockIndex+diagIndex) * block(m_fT, blockIndex+diagIndex, blockIndex+diagIndex);+ for (Index k = blockIndex + 1; k < blockIndex + diagIndex; k++) {+ C += block(m_fT, blockIndex, k) * block(m_T, k, blockIndex+diagIndex);+ C -= block(m_T, blockIndex, k) * block(m_fT, k, blockIndex+diagIndex);+ }+ block(m_fT, blockIndex, blockIndex+diagIndex) = solveTriangularSylvester(A, B, C);+ }+ }+}++/** \brief Solve a triangular Sylvester equation AX + XB = C + *+ * \param[in] A the matrix A; should be square and upper triangular+ * \param[in] B the matrix B; should be square and upper triangular+ * \param[in] C the matrix C; should have correct size.+ *+ * \returns the solution X.+ *+ * If A is m-by-m and B is n-by-n, then both C and X are m-by-n. + * The (i,j)-th component of the Sylvester equation is+ * \f[ + * \sum_{k=i}^m A_{ik} X_{kj} + \sum_{k=1}^j X_{ik} B_{kj} = C_{ij}. + * \f]+ * This can be re-arranged to yield:+ * \f[ + * X_{ij} = \frac{1}{A_{ii} + B_{jj}} \Bigl( C_{ij}+ * - \sum_{k=i+1}^m A_{ik} X_{kj} - \sum_{k=1}^{j-1} X_{ik} B_{kj} \Bigr).+ * \f]+ * It is assumed that A and B are such that the numerator is never+ * zero (otherwise the Sylvester equation does not have a unique+ * solution). In that case, these equations can be evaluated in the+ * order \f$ i=m,\ldots,1 \f$ and \f$ j=1,\ldots,n \f$.+ */+template <typename MatrixType, typename AtomicType>+typename MatrixFunction<MatrixType,AtomicType,1>::DynMatrixType MatrixFunction<MatrixType,AtomicType,1>::solveTriangularSylvester(+ const DynMatrixType& A, + const DynMatrixType& B, + const DynMatrixType& C)+{+ eigen_assert(A.rows() == A.cols());+ eigen_assert(A.isUpperTriangular());+ eigen_assert(B.rows() == B.cols());+ eigen_assert(B.isUpperTriangular());+ eigen_assert(C.rows() == A.rows());+ eigen_assert(C.cols() == B.rows());++ Index m = A.rows();+ Index n = B.rows();+ DynMatrixType X(m, n);++ for (Index i = m - 1; i >= 0; --i) {+ for (Index j = 0; j < n; ++j) {++ // Compute AX = \sum_{k=i+1}^m A_{ik} X_{kj}+ Scalar AX;+ if (i == m - 1) {+ AX = 0; + } else {+ Matrix<Scalar,1,1> AXmatrix = A.row(i).tail(m-1-i) * X.col(j).tail(m-1-i);+ AX = AXmatrix(0,0);+ }++ // Compute XB = \sum_{k=1}^{j-1} X_{ik} B_{kj}+ Scalar XB;+ if (j == 0) {+ XB = 0; + } else {+ Matrix<Scalar,1,1> XBmatrix = X.row(i).head(j) * B.col(j).head(j);+ XB = XBmatrix(0,0);+ }++ X(i,j) = (C(i,j) - AX - XB) / (A(i,i) + B(j,j));+ }+ }+ return X;+}++/** \ingroup MatrixFunctions_Module+ *+ * \brief Proxy for the matrix function of some matrix (expression).+ *+ * \tparam Derived Type of the argument to the matrix function.+ *+ * This class holds the argument to the matrix function until it is+ * assigned or evaluated for some other reason (so the argument+ * should not be changed in the meantime). It is the return type of+ * matrixBase::matrixFunction() and related functions and most of the+ * time this is the only way it is used.+ */+template<typename Derived> class MatrixFunctionReturnValue+: public ReturnByValue<MatrixFunctionReturnValue<Derived> >+{+ public:++ typedef typename Derived::Scalar Scalar;+ typedef typename Derived::Index Index;+ typedef typename internal::stem_function<Scalar>::type StemFunction;++ /** \brief Constructor.+ *+ * \param[in] A %Matrix (expression) forming the argument of the+ * matrix function.+ * \param[in] f Stem function for matrix function under consideration.+ */+ MatrixFunctionReturnValue(const Derived& A, StemFunction f) : m_A(A), m_f(f) { }++ /** \brief Compute the matrix function.+ *+ * \param[out] result \p f applied to \p A, where \p f and \p A+ * are as in the constructor.+ */+ template <typename ResultType>+ inline void evalTo(ResultType& result) const+ {+ typedef typename Derived::PlainObject PlainObject;+ typedef internal::traits<PlainObject> Traits;+ static const int RowsAtCompileTime = Traits::RowsAtCompileTime;+ static const int ColsAtCompileTime = Traits::ColsAtCompileTime;+ static const int Options = PlainObject::Options;+ typedef std::complex<typename NumTraits<Scalar>::Real> ComplexScalar;+ typedef Matrix<ComplexScalar, Dynamic, Dynamic, Options, RowsAtCompileTime, ColsAtCompileTime> DynMatrixType;+ typedef MatrixFunctionAtomic<DynMatrixType> AtomicType;+ AtomicType atomic(m_f);++ const PlainObject Aevaluated = m_A.eval();+ MatrixFunction<PlainObject, AtomicType> mf(Aevaluated, atomic);+ mf.compute(result);+ }++ Index rows() const { return m_A.rows(); }+ Index cols() const { return m_A.cols(); }++ private:+ typename internal::nested<Derived>::type m_A;+ StemFunction *m_f;++ MatrixFunctionReturnValue& operator=(const MatrixFunctionReturnValue&);+};++namespace internal {+template<typename Derived>+struct traits<MatrixFunctionReturnValue<Derived> >+{+ typedef typename Derived::PlainObject ReturnType;+};+}+++/********** MatrixBase methods **********/+++template <typename Derived>+const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::matrixFunction(typename internal::stem_function<typename internal::traits<Derived>::Scalar>::type f) const+{+ eigen_assert(rows() == cols());+ return MatrixFunctionReturnValue<Derived>(derived(), f);+}++template <typename Derived>+const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::sin() const+{+ eigen_assert(rows() == cols());+ typedef typename internal::stem_function<Scalar>::ComplexScalar ComplexScalar;+ return MatrixFunctionReturnValue<Derived>(derived(), StdStemFunctions<ComplexScalar>::sin);+}++template <typename Derived>+const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::cos() const+{+ eigen_assert(rows() == cols());+ typedef typename internal::stem_function<Scalar>::ComplexScalar ComplexScalar;+ return MatrixFunctionReturnValue<Derived>(derived(), StdStemFunctions<ComplexScalar>::cos);+}++template <typename Derived>+const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::sinh() const+{+ eigen_assert(rows() == cols());+ typedef typename internal::stem_function<Scalar>::ComplexScalar ComplexScalar;+ return MatrixFunctionReturnValue<Derived>(derived(), StdStemFunctions<ComplexScalar>::sinh);+}++template <typename Derived>+const MatrixFunctionReturnValue<Derived> MatrixBase<Derived>::cosh() const+{+ eigen_assert(rows() == cols());+ typedef typename internal::stem_function<Scalar>::ComplexScalar ComplexScalar;+ return MatrixFunctionReturnValue<Derived>(derived(), StdStemFunctions<ComplexScalar>::cosh);+}++} // end namespace Eigen++#endif // EIGEN_MATRIX_FUNCTION
+ eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixFunctionAtomic.h view
@@ -0,0 +1,131 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Jitse Niesen <jitse@maths.leeds.ac.uk>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_MATRIX_FUNCTION_ATOMIC+#define EIGEN_MATRIX_FUNCTION_ATOMIC++namespace Eigen { ++/** \ingroup MatrixFunctions_Module+ * \class MatrixFunctionAtomic+ * \brief Helper class for computing matrix functions of atomic matrices.+ *+ * \internal+ * Here, an atomic matrix is a triangular matrix whose diagonal+ * entries are close to each other.+ */+template <typename MatrixType>+class MatrixFunctionAtomic+{+ public:++ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::Index Index;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef typename internal::stem_function<Scalar>::type StemFunction;+ typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ /** \brief Constructor+ * \param[in] f matrix function to compute.+ */+ MatrixFunctionAtomic(StemFunction f) : m_f(f) { }++ /** \brief Compute matrix function of atomic matrix+ * \param[in] A argument of matrix function, should be upper triangular and atomic+ * \returns f(A), the matrix function evaluated at the given matrix+ */+ MatrixType compute(const MatrixType& A);++ private:++ // Prevent copying+ MatrixFunctionAtomic(const MatrixFunctionAtomic&);+ MatrixFunctionAtomic& operator=(const MatrixFunctionAtomic&);++ void computeMu();+ bool taylorConverged(Index s, const MatrixType& F, const MatrixType& Fincr, const MatrixType& P);++ /** \brief Pointer to scalar function */+ StemFunction* m_f;++ /** \brief Size of matrix function */+ Index m_Arows;++ /** \brief Mean of eigenvalues */+ Scalar m_avgEival;++ /** \brief Argument shifted by mean of eigenvalues */+ MatrixType m_Ashifted;++ /** \brief Constant used to determine whether Taylor series has converged */+ RealScalar m_mu;+};++template <typename MatrixType>+MatrixType MatrixFunctionAtomic<MatrixType>::compute(const MatrixType& A)+{+ // TODO: Use that A is upper triangular+ m_Arows = A.rows();+ m_avgEival = A.trace() / Scalar(RealScalar(m_Arows));+ m_Ashifted = A - m_avgEival * MatrixType::Identity(m_Arows, m_Arows);+ computeMu();+ MatrixType F = m_f(m_avgEival, 0) * MatrixType::Identity(m_Arows, m_Arows);+ MatrixType P = m_Ashifted;+ MatrixType Fincr;+ for (Index s = 1; s < 1.1 * m_Arows + 10; s++) { // upper limit is fairly arbitrary+ Fincr = m_f(m_avgEival, static_cast<int>(s)) * P;+ F += Fincr;+ P = Scalar(RealScalar(1.0/(s + 1))) * P * m_Ashifted;+ if (taylorConverged(s, F, Fincr, P)) {+ return F;+ }+ }+ eigen_assert("Taylor series does not converge" && 0);+ return F;+}++/** \brief Compute \c m_mu. */+template <typename MatrixType>+void MatrixFunctionAtomic<MatrixType>::computeMu()+{+ const MatrixType N = MatrixType::Identity(m_Arows, m_Arows) - m_Ashifted;+ VectorType e = VectorType::Ones(m_Arows);+ N.template triangularView<Upper>().solveInPlace(e);+ m_mu = e.cwiseAbs().maxCoeff();+}++/** \brief Determine whether Taylor series has converged */+template <typename MatrixType>+bool MatrixFunctionAtomic<MatrixType>::taylorConverged(Index s, const MatrixType& F,+ const MatrixType& Fincr, const MatrixType& P)+{+ const Index n = F.rows();+ const RealScalar F_norm = F.cwiseAbs().rowwise().sum().maxCoeff();+ const RealScalar Fincr_norm = Fincr.cwiseAbs().rowwise().sum().maxCoeff();+ if (Fincr_norm < NumTraits<Scalar>::epsilon() * F_norm) {+ RealScalar delta = 0;+ RealScalar rfactorial = 1;+ for (Index r = 0; r < n; r++) {+ RealScalar mx = 0;+ for (Index i = 0; i < n; i++)+ mx = (std::max)(mx, std::abs(m_f(m_Ashifted(i, i) + m_avgEival, static_cast<int>(s+r))));+ if (r != 0)+ rfactorial *= RealScalar(r);+ delta = (std::max)(delta, mx / rfactorial);+ }+ const RealScalar P_norm = P.cwiseAbs().rowwise().sum().maxCoeff();+ if (m_mu * delta * P_norm < NumTraits<Scalar>::epsilon() * F_norm)+ return true;+ }+ return false;+}++} // end namespace Eigen++#endif // EIGEN_MATRIX_FUNCTION_ATOMIC
+ eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h view
@@ -0,0 +1,486 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Jitse Niesen <jitse@maths.leeds.ac.uk>+// Copyright (C) 2011 Chen-Pang He <jdh8@ms63.hinet.net>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_MATRIX_LOGARITHM+#define EIGEN_MATRIX_LOGARITHM++#ifndef M_PI+#define M_PI 3.141592653589793238462643383279503L+#endif++namespace Eigen { ++/** \ingroup MatrixFunctions_Module+ * \class MatrixLogarithmAtomic+ * \brief Helper class for computing matrix logarithm of atomic matrices.+ *+ * \internal+ * Here, an atomic matrix is a triangular matrix whose diagonal+ * entries are close to each other.+ *+ * \sa class MatrixFunctionAtomic, MatrixBase::log()+ */+template <typename MatrixType>+class MatrixLogarithmAtomic+{+public:++ typedef typename MatrixType::Scalar Scalar;+ // typedef typename MatrixType::Index Index;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ // typedef typename internal::stem_function<Scalar>::type StemFunction;+ // typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;++ /** \brief Constructor. */+ MatrixLogarithmAtomic() { }++ /** \brief Compute matrix logarithm of atomic matrix+ * \param[in] A argument of matrix logarithm, should be upper triangular and atomic+ * \returns The logarithm of \p A.+ */+ MatrixType compute(const MatrixType& A);++private:++ void compute2x2(const MatrixType& A, MatrixType& result);+ void computeBig(const MatrixType& A, MatrixType& result);+ int getPadeDegree(float normTminusI);+ int getPadeDegree(double normTminusI);+ int getPadeDegree(long double normTminusI);+ void computePade(MatrixType& result, const MatrixType& T, int degree);+ void computePade3(MatrixType& result, const MatrixType& T);+ void computePade4(MatrixType& result, const MatrixType& T);+ void computePade5(MatrixType& result, const MatrixType& T);+ void computePade6(MatrixType& result, const MatrixType& T);+ void computePade7(MatrixType& result, const MatrixType& T);+ void computePade8(MatrixType& result, const MatrixType& T);+ void computePade9(MatrixType& result, const MatrixType& T);+ void computePade10(MatrixType& result, const MatrixType& T);+ void computePade11(MatrixType& result, const MatrixType& T);++ static const int minPadeDegree = 3;+ static const int maxPadeDegree = std::numeric_limits<RealScalar>::digits<= 24? 5: // single precision+ std::numeric_limits<RealScalar>::digits<= 53? 7: // double precision+ std::numeric_limits<RealScalar>::digits<= 64? 8: // extended precision+ std::numeric_limits<RealScalar>::digits<=106? 10: // double-double+ 11; // quadruple precision++ // Prevent copying+ MatrixLogarithmAtomic(const MatrixLogarithmAtomic&);+ MatrixLogarithmAtomic& operator=(const MatrixLogarithmAtomic&);+};++/** \brief Compute logarithm of triangular matrix with clustered eigenvalues. */+template <typename MatrixType>+MatrixType MatrixLogarithmAtomic<MatrixType>::compute(const MatrixType& A)+{+ using std::log;+ MatrixType result(A.rows(), A.rows());+ if (A.rows() == 1)+ result(0,0) = log(A(0,0));+ else if (A.rows() == 2)+ compute2x2(A, result);+ else+ computeBig(A, result);+ return result;+}++/** \brief Compute logarithm of 2x2 triangular matrix. */+template <typename MatrixType>+void MatrixLogarithmAtomic<MatrixType>::compute2x2(const MatrixType& A, MatrixType& result)+{+ using std::abs;+ using std::ceil;+ using std::imag;+ using std::log;++ Scalar logA00 = log(A(0,0));+ Scalar logA11 = log(A(1,1));++ result(0,0) = logA00;+ result(1,0) = Scalar(0);+ result(1,1) = logA11;++ if (A(0,0) == A(1,1)) {+ result(0,1) = A(0,1) / A(0,0);+ } else if ((abs(A(0,0)) < 0.5*abs(A(1,1))) || (abs(A(0,0)) > 2*abs(A(1,1)))) {+ result(0,1) = A(0,1) * (logA11 - logA00) / (A(1,1) - A(0,0));+ } else {+ // computation in previous branch is inaccurate if A(1,1) \approx A(0,0)+ int unwindingNumber = static_cast<int>(ceil((imag(logA11 - logA00) - M_PI) / (2*M_PI)));+ Scalar y = A(1,1) - A(0,0), x = A(1,1) + A(0,0);+ result(0,1) = A(0,1) * (Scalar(2) * numext::atanh2(y,x) + Scalar(0,2*M_PI*unwindingNumber)) / y;+ }+}++/** \brief Compute logarithm of triangular matrices with size > 2. + * \details This uses a inverse scale-and-square algorithm. */+template <typename MatrixType>+void MatrixLogarithmAtomic<MatrixType>::computeBig(const MatrixType& A, MatrixType& result)+{+ using std::pow;+ int numberOfSquareRoots = 0;+ int numberOfExtraSquareRoots = 0;+ int degree;+ MatrixType T = A, sqrtT;+ const RealScalar maxNormForPade = maxPadeDegree<= 5? 5.3149729967117310e-1: // single precision+ maxPadeDegree<= 7? 2.6429608311114350e-1: // double precision+ maxPadeDegree<= 8? 2.32777776523703892094e-1L: // extended precision+ maxPadeDegree<=10? 1.05026503471351080481093652651105e-1L: // double-double+ 1.1880960220216759245467951592883642e-1L; // quadruple precision++ while (true) {+ RealScalar normTminusI = (T - MatrixType::Identity(T.rows(), T.rows())).cwiseAbs().colwise().sum().maxCoeff();+ if (normTminusI < maxNormForPade) {+ degree = getPadeDegree(normTminusI);+ int degree2 = getPadeDegree(normTminusI / RealScalar(2));+ if ((degree - degree2 <= 1) || (numberOfExtraSquareRoots == 1)) + break;+ ++numberOfExtraSquareRoots;+ }+ MatrixSquareRootTriangular<MatrixType>(T).compute(sqrtT);+ T = sqrtT.template triangularView<Upper>();+ ++numberOfSquareRoots;+ }++ computePade(result, T, degree);+ result *= pow(RealScalar(2), numberOfSquareRoots);+}++/* \brief Get suitable degree for Pade approximation. (specialized for RealScalar = float) */+template <typename MatrixType>+int MatrixLogarithmAtomic<MatrixType>::getPadeDegree(float normTminusI)+{+ const float maxNormForPade[] = { 2.5111573934555054e-1 /* degree = 3 */ , 4.0535837411880493e-1,+ 5.3149729967117310e-1 };+ int degree = 3;+ for (; degree <= maxPadeDegree; ++degree) + if (normTminusI <= maxNormForPade[degree - minPadeDegree])+ break;+ return degree;+}++/* \brief Get suitable degree for Pade approximation. (specialized for RealScalar = double) */+template <typename MatrixType>+int MatrixLogarithmAtomic<MatrixType>::getPadeDegree(double normTminusI)+{+ const double maxNormForPade[] = { 1.6206284795015624e-2 /* degree = 3 */ , 5.3873532631381171e-2,+ 1.1352802267628681e-1, 1.8662860613541288e-1, 2.642960831111435e-1 };+ int degree = 3;+ for (; degree <= maxPadeDegree; ++degree)+ if (normTminusI <= maxNormForPade[degree - minPadeDegree])+ break;+ return degree;+}++/* \brief Get suitable degree for Pade approximation. (specialized for RealScalar = long double) */+template <typename MatrixType>+int MatrixLogarithmAtomic<MatrixType>::getPadeDegree(long double normTminusI)+{+#if LDBL_MANT_DIG == 53 // double precision+ const long double maxNormForPade[] = { 1.6206284795015624e-2L /* degree = 3 */ , 5.3873532631381171e-2L,+ 1.1352802267628681e-1L, 1.8662860613541288e-1L, 2.642960831111435e-1L };+#elif LDBL_MANT_DIG <= 64 // extended precision+ const long double maxNormForPade[] = { 5.48256690357782863103e-3L /* degree = 3 */, 2.34559162387971167321e-2L,+ 5.84603923897347449857e-2L, 1.08486423756725170223e-1L, 1.68385767881294446649e-1L,+ 2.32777776523703892094e-1L };+#elif LDBL_MANT_DIG <= 106 // double-double+ const long double maxNormForPade[] = { 8.58970550342939562202529664318890e-5L /* degree = 3 */,+ 9.34074328446359654039446552677759e-4L, 4.26117194647672175773064114582860e-3L,+ 1.21546224740281848743149666560464e-2L, 2.61100544998339436713088248557444e-2L,+ 4.66170074627052749243018566390567e-2L, 7.32585144444135027565872014932387e-2L,+ 1.05026503471351080481093652651105e-1L };+#else // quadruple precision+ const long double maxNormForPade[] = { 4.7419931187193005048501568167858103e-5L /* degree = 3 */,+ 5.8853168473544560470387769480192666e-4L, 2.9216120366601315391789493628113520e-3L,+ 8.8415758124319434347116734705174308e-3L, 1.9850836029449446668518049562565291e-2L,+ 3.6688019729653446926585242192447447e-2L, 5.9290962294020186998954055264528393e-2L,+ 8.6998436081634343903250580992127677e-2L, 1.1880960220216759245467951592883642e-1L };+#endif+ int degree = 3;+ for (; degree <= maxPadeDegree; ++degree)+ if (normTminusI <= maxNormForPade[degree - minPadeDegree])+ break;+ return degree;+}++/* \brief Compute Pade approximation to matrix logarithm */+template <typename MatrixType>+void MatrixLogarithmAtomic<MatrixType>::computePade(MatrixType& result, const MatrixType& T, int degree)+{+ switch (degree) {+ case 3: computePade3(result, T); break;+ case 4: computePade4(result, T); break;+ case 5: computePade5(result, T); break;+ case 6: computePade6(result, T); break;+ case 7: computePade7(result, T); break;+ case 8: computePade8(result, T); break;+ case 9: computePade9(result, T); break;+ case 10: computePade10(result, T); break;+ case 11: computePade11(result, T); break;+ default: assert(false); // should never happen+ }+} ++template <typename MatrixType>+void MatrixLogarithmAtomic<MatrixType>::computePade3(MatrixType& result, const MatrixType& T)+{+ const int degree = 3;+ const RealScalar nodes[] = { 0.1127016653792583114820734600217600L, 0.5000000000000000000000000000000000L,+ 0.8872983346207416885179265399782400L };+ const RealScalar weights[] = { 0.2777777777777777777777777777777778L, 0.4444444444444444444444444444444444L,+ 0.2777777777777777777777777777777778L };+ eigen_assert(degree <= maxPadeDegree);+ MatrixType TminusI = T - MatrixType::Identity(T.rows(), T.rows());+ result.setZero(T.rows(), T.rows());+ for (int k = 0; k < degree; ++k)+ result += weights[k] * (MatrixType::Identity(T.rows(), T.rows()) + nodes[k] * TminusI)+ .template triangularView<Upper>().solve(TminusI);+}++template <typename MatrixType>+void MatrixLogarithmAtomic<MatrixType>::computePade4(MatrixType& result, const MatrixType& T)+{+ const int degree = 4;+ const RealScalar nodes[] = { 0.0694318442029737123880267555535953L, 0.3300094782075718675986671204483777L,+ 0.6699905217924281324013328795516223L, 0.9305681557970262876119732444464048L };+ const RealScalar weights[] = { 0.1739274225687269286865319746109997L, 0.3260725774312730713134680253890003L,+ 0.3260725774312730713134680253890003L, 0.1739274225687269286865319746109997L };+ eigen_assert(degree <= maxPadeDegree);+ MatrixType TminusI = T - MatrixType::Identity(T.rows(), T.rows());+ result.setZero(T.rows(), T.rows());+ for (int k = 0; k < degree; ++k)+ result += weights[k] * (MatrixType::Identity(T.rows(), T.rows()) + nodes[k] * TminusI)+ .template triangularView<Upper>().solve(TminusI);+}++template <typename MatrixType>+void MatrixLogarithmAtomic<MatrixType>::computePade5(MatrixType& result, const MatrixType& T)+{+ const int degree = 5;+ const RealScalar nodes[] = { 0.0469100770306680036011865608503035L, 0.2307653449471584544818427896498956L,+ 0.5000000000000000000000000000000000L, 0.7692346550528415455181572103501044L,+ 0.9530899229693319963988134391496965L };+ const RealScalar weights[] = { 0.1184634425280945437571320203599587L, 0.2393143352496832340206457574178191L,+ 0.2844444444444444444444444444444444L, 0.2393143352496832340206457574178191L,+ 0.1184634425280945437571320203599587L };+ eigen_assert(degree <= maxPadeDegree);+ MatrixType TminusI = T - MatrixType::Identity(T.rows(), T.rows());+ result.setZero(T.rows(), T.rows());+ for (int k = 0; k < degree; ++k)+ result += weights[k] * (MatrixType::Identity(T.rows(), T.rows()) + nodes[k] * TminusI)+ .template triangularView<Upper>().solve(TminusI);+}++template <typename MatrixType>+void MatrixLogarithmAtomic<MatrixType>::computePade6(MatrixType& result, const MatrixType& T)+{+ const int degree = 6;+ const RealScalar nodes[] = { 0.0337652428984239860938492227530027L, 0.1693953067668677431693002024900473L,+ 0.3806904069584015456847491391596440L, 0.6193095930415984543152508608403560L,+ 0.8306046932331322568306997975099527L, 0.9662347571015760139061507772469973L };+ const RealScalar weights[] = { 0.0856622461895851725201480710863665L, 0.1803807865240693037849167569188581L,+ 0.2339569672863455236949351719947755L, 0.2339569672863455236949351719947755L,+ 0.1803807865240693037849167569188581L, 0.0856622461895851725201480710863665L };+ eigen_assert(degree <= maxPadeDegree);+ MatrixType TminusI = T - MatrixType::Identity(T.rows(), T.rows());+ result.setZero(T.rows(), T.rows());+ for (int k = 0; k < degree; ++k)+ result += weights[k] * (MatrixType::Identity(T.rows(), T.rows()) + nodes[k] * TminusI)+ .template triangularView<Upper>().solve(TminusI);+}++template <typename MatrixType>+void MatrixLogarithmAtomic<MatrixType>::computePade7(MatrixType& result, const MatrixType& T)+{+ const int degree = 7;+ const RealScalar nodes[] = { 0.0254460438286207377369051579760744L, 0.1292344072003027800680676133596058L,+ 0.2970774243113014165466967939615193L, 0.5000000000000000000000000000000000L,+ 0.7029225756886985834533032060384807L, 0.8707655927996972199319323866403942L,+ 0.9745539561713792622630948420239256L };+ const RealScalar weights[] = { 0.0647424830844348466353057163395410L, 0.1398526957446383339507338857118898L,+ 0.1909150252525594724751848877444876L, 0.2089795918367346938775510204081633L,+ 0.1909150252525594724751848877444876L, 0.1398526957446383339507338857118898L,+ 0.0647424830844348466353057163395410L };+ eigen_assert(degree <= maxPadeDegree);+ MatrixType TminusI = T - MatrixType::Identity(T.rows(), T.rows());+ result.setZero(T.rows(), T.rows());+ for (int k = 0; k < degree; ++k)+ result += weights[k] * (MatrixType::Identity(T.rows(), T.rows()) + nodes[k] * TminusI)+ .template triangularView<Upper>().solve(TminusI);+}++template <typename MatrixType>+void MatrixLogarithmAtomic<MatrixType>::computePade8(MatrixType& result, const MatrixType& T)+{+ const int degree = 8;+ const RealScalar nodes[] = { 0.0198550717512318841582195657152635L, 0.1016667612931866302042230317620848L,+ 0.2372337950418355070911304754053768L, 0.4082826787521750975302619288199080L,+ 0.5917173212478249024697380711800920L, 0.7627662049581644929088695245946232L,+ 0.8983332387068133697957769682379152L, 0.9801449282487681158417804342847365L };+ const RealScalar weights[] = { 0.0506142681451881295762656771549811L, 0.1111905172266872352721779972131204L,+ 0.1568533229389436436689811009933007L, 0.1813418916891809914825752246385978L,+ 0.1813418916891809914825752246385978L, 0.1568533229389436436689811009933007L,+ 0.1111905172266872352721779972131204L, 0.0506142681451881295762656771549811L };+ eigen_assert(degree <= maxPadeDegree);+ MatrixType TminusI = T - MatrixType::Identity(T.rows(), T.rows());+ result.setZero(T.rows(), T.rows());+ for (int k = 0; k < degree; ++k)+ result += weights[k] * (MatrixType::Identity(T.rows(), T.rows()) + nodes[k] * TminusI)+ .template triangularView<Upper>().solve(TminusI);+}++template <typename MatrixType>+void MatrixLogarithmAtomic<MatrixType>::computePade9(MatrixType& result, const MatrixType& T)+{+ const int degree = 9;+ const RealScalar nodes[] = { 0.0159198802461869550822118985481636L, 0.0819844463366821028502851059651326L,+ 0.1933142836497048013456489803292629L, 0.3378732882980955354807309926783317L,+ 0.5000000000000000000000000000000000L, 0.6621267117019044645192690073216683L,+ 0.8066857163502951986543510196707371L, 0.9180155536633178971497148940348674L,+ 0.9840801197538130449177881014518364L };+ const RealScalar weights[] = { 0.0406371941807872059859460790552618L, 0.0903240803474287020292360156214564L,+ 0.1303053482014677311593714347093164L, 0.1561735385200014200343152032922218L,+ 0.1651196775006298815822625346434870L, 0.1561735385200014200343152032922218L,+ 0.1303053482014677311593714347093164L, 0.0903240803474287020292360156214564L,+ 0.0406371941807872059859460790552618L };+ eigen_assert(degree <= maxPadeDegree);+ MatrixType TminusI = T - MatrixType::Identity(T.rows(), T.rows());+ result.setZero(T.rows(), T.rows());+ for (int k = 0; k < degree; ++k)+ result += weights[k] * (MatrixType::Identity(T.rows(), T.rows()) + nodes[k] * TminusI)+ .template triangularView<Upper>().solve(TminusI);+}++template <typename MatrixType>+void MatrixLogarithmAtomic<MatrixType>::computePade10(MatrixType& result, const MatrixType& T)+{+ const int degree = 10;+ const RealScalar nodes[] = { 0.0130467357414141399610179939577740L, 0.0674683166555077446339516557882535L,+ 0.1602952158504877968828363174425632L, 0.2833023029353764046003670284171079L,+ 0.4255628305091843945575869994351400L, 0.5744371694908156054424130005648600L,+ 0.7166976970646235953996329715828921L, 0.8397047841495122031171636825574368L,+ 0.9325316833444922553660483442117465L, 0.9869532642585858600389820060422260L };+ const RealScalar weights[] = { 0.0333356721543440687967844049466659L, 0.0747256745752902965728881698288487L,+ 0.1095431812579910219977674671140816L, 0.1346333596549981775456134607847347L,+ 0.1477621123573764350869464973256692L, 0.1477621123573764350869464973256692L,+ 0.1346333596549981775456134607847347L, 0.1095431812579910219977674671140816L,+ 0.0747256745752902965728881698288487L, 0.0333356721543440687967844049466659L };+ eigen_assert(degree <= maxPadeDegree);+ MatrixType TminusI = T - MatrixType::Identity(T.rows(), T.rows());+ result.setZero(T.rows(), T.rows());+ for (int k = 0; k < degree; ++k)+ result += weights[k] * (MatrixType::Identity(T.rows(), T.rows()) + nodes[k] * TminusI)+ .template triangularView<Upper>().solve(TminusI);+}++template <typename MatrixType>+void MatrixLogarithmAtomic<MatrixType>::computePade11(MatrixType& result, const MatrixType& T)+{+ const int degree = 11;+ const RealScalar nodes[] = { 0.0108856709269715035980309994385713L, 0.0564687001159523504624211153480364L,+ 0.1349239972129753379532918739844233L, 0.2404519353965940920371371652706952L,+ 0.3652284220238275138342340072995692L, 0.5000000000000000000000000000000000L,+ 0.6347715779761724861657659927004308L, 0.7595480646034059079628628347293048L,+ 0.8650760027870246620467081260155767L, 0.9435312998840476495375788846519636L,+ 0.9891143290730284964019690005614287L };+ const RealScalar weights[] = { 0.0278342835580868332413768602212743L, 0.0627901847324523123173471496119701L,+ 0.0931451054638671257130488207158280L, 0.1165968822959952399592618524215876L,+ 0.1314022722551233310903444349452546L, 0.1364625433889503153572417641681711L,+ 0.1314022722551233310903444349452546L, 0.1165968822959952399592618524215876L,+ 0.0931451054638671257130488207158280L, 0.0627901847324523123173471496119701L,+ 0.0278342835580868332413768602212743L };+ eigen_assert(degree <= maxPadeDegree);+ MatrixType TminusI = T - MatrixType::Identity(T.rows(), T.rows());+ result.setZero(T.rows(), T.rows());+ for (int k = 0; k < degree; ++k)+ result += weights[k] * (MatrixType::Identity(T.rows(), T.rows()) + nodes[k] * TminusI)+ .template triangularView<Upper>().solve(TminusI);+}++/** \ingroup MatrixFunctions_Module+ *+ * \brief Proxy for the matrix logarithm of some matrix (expression).+ *+ * \tparam Derived Type of the argument to the matrix function.+ *+ * This class holds the argument to the matrix function until it is+ * assigned or evaluated for some other reason (so the argument+ * should not be changed in the meantime). It is the return type of+ * MatrixBase::log() and most of the time this is the only way it+ * is used.+ */+template<typename Derived> class MatrixLogarithmReturnValue+: public ReturnByValue<MatrixLogarithmReturnValue<Derived> >+{+public:++ typedef typename Derived::Scalar Scalar;+ typedef typename Derived::Index Index;++ /** \brief Constructor.+ *+ * \param[in] A %Matrix (expression) forming the argument of the matrix logarithm.+ */+ MatrixLogarithmReturnValue(const Derived& A) : m_A(A) { }+ + /** \brief Compute the matrix logarithm.+ *+ * \param[out] result Logarithm of \p A, where \A is as specified in the constructor.+ */+ template <typename ResultType>+ inline void evalTo(ResultType& result) const+ {+ typedef typename Derived::PlainObject PlainObject;+ typedef internal::traits<PlainObject> Traits;+ static const int RowsAtCompileTime = Traits::RowsAtCompileTime;+ static const int ColsAtCompileTime = Traits::ColsAtCompileTime;+ static const int Options = PlainObject::Options;+ typedef std::complex<typename NumTraits<Scalar>::Real> ComplexScalar;+ typedef Matrix<ComplexScalar, Dynamic, Dynamic, Options, RowsAtCompileTime, ColsAtCompileTime> DynMatrixType;+ typedef MatrixLogarithmAtomic<DynMatrixType> AtomicType;+ AtomicType atomic;+ + const PlainObject Aevaluated = m_A.eval();+ MatrixFunction<PlainObject, AtomicType> mf(Aevaluated, atomic);+ mf.compute(result);+ }++ Index rows() const { return m_A.rows(); }+ Index cols() const { return m_A.cols(); }+ +private:+ typename internal::nested<Derived>::type m_A;+ + MatrixLogarithmReturnValue& operator=(const MatrixLogarithmReturnValue&);+};++namespace internal {+ template<typename Derived>+ struct traits<MatrixLogarithmReturnValue<Derived> >+ {+ typedef typename Derived::PlainObject ReturnType;+ };+}+++/********** MatrixBase method **********/+++template <typename Derived>+const MatrixLogarithmReturnValue<Derived> MatrixBase<Derived>::log() const+{+ eigen_assert(rows() == cols());+ return MatrixLogarithmReturnValue<Derived>(derived());+}++} // end namespace Eigen++#endif // EIGEN_MATRIX_LOGARITHM
+ eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h view
@@ -0,0 +1,508 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012, 2013 Chen-Pang He <jdh8@ms63.hinet.net>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_MATRIX_POWER+#define EIGEN_MATRIX_POWER++namespace Eigen {++template<typename MatrixType> class MatrixPower;++template<typename MatrixType>+class MatrixPowerRetval : public ReturnByValue< MatrixPowerRetval<MatrixType> >+{+ public:+ typedef typename MatrixType::RealScalar RealScalar;+ typedef typename MatrixType::Index Index;++ MatrixPowerRetval(MatrixPower<MatrixType>& pow, RealScalar p) : m_pow(pow), m_p(p)+ { }++ template<typename ResultType>+ inline void evalTo(ResultType& res) const+ { m_pow.compute(res, m_p); }++ Index rows() const { return m_pow.rows(); }+ Index cols() const { return m_pow.cols(); }++ private:+ MatrixPower<MatrixType>& m_pow;+ const RealScalar m_p;+ MatrixPowerRetval& operator=(const MatrixPowerRetval&);+};++template<typename MatrixType>+class MatrixPowerAtomic+{+ private:+ enum {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime+ };+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::RealScalar RealScalar;+ typedef std::complex<RealScalar> ComplexScalar;+ typedef typename MatrixType::Index Index;+ typedef Array<Scalar, RowsAtCompileTime, 1, ColMajor, MaxRowsAtCompileTime> ArrayType;++ const MatrixType& m_A;+ RealScalar m_p;++ void computePade(int degree, const MatrixType& IminusT, MatrixType& res) const;+ void compute2x2(MatrixType& res, RealScalar p) const;+ void computeBig(MatrixType& res) const;+ static int getPadeDegree(float normIminusT);+ static int getPadeDegree(double normIminusT);+ static int getPadeDegree(long double normIminusT);+ static ComplexScalar computeSuperDiag(const ComplexScalar&, const ComplexScalar&, RealScalar p);+ static RealScalar computeSuperDiag(RealScalar, RealScalar, RealScalar p);++ public:+ MatrixPowerAtomic(const MatrixType& T, RealScalar p);+ void compute(MatrixType& res) const;+};++template<typename MatrixType>+MatrixPowerAtomic<MatrixType>::MatrixPowerAtomic(const MatrixType& T, RealScalar p) :+ m_A(T), m_p(p)+{ eigen_assert(T.rows() == T.cols()); }++template<typename MatrixType>+void MatrixPowerAtomic<MatrixType>::compute(MatrixType& res) const+{+ res.resizeLike(m_A);+ switch (m_A.rows()) {+ case 0:+ break;+ case 1:+ res(0,0) = std::pow(m_A(0,0), m_p);+ break;+ case 2:+ compute2x2(res, m_p);+ break;+ default:+ computeBig(res);+ }+}++template<typename MatrixType>+void MatrixPowerAtomic<MatrixType>::computePade(int degree, const MatrixType& IminusT, MatrixType& res) const+{+ int i = degree<<1;+ res = (m_p-degree) / ((i-1)<<1) * IminusT;+ for (--i; i; --i) {+ res = (MatrixType::Identity(IminusT.rows(), IminusT.cols()) + res).template triangularView<Upper>()+ .solve((i==1 ? -m_p : i&1 ? (-m_p-(i>>1))/(i<<1) : (m_p-(i>>1))/((i-1)<<1)) * IminusT).eval();+ }+ res += MatrixType::Identity(IminusT.rows(), IminusT.cols());+}++// This function assumes that res has the correct size (see bug 614)+template<typename MatrixType>+void MatrixPowerAtomic<MatrixType>::compute2x2(MatrixType& res, RealScalar p) const+{+ using std::abs;+ using std::pow;+ + res.coeffRef(0,0) = pow(m_A.coeff(0,0), p);++ for (Index i=1; i < m_A.cols(); ++i) {+ res.coeffRef(i,i) = pow(m_A.coeff(i,i), p);+ if (m_A.coeff(i-1,i-1) == m_A.coeff(i,i))+ res.coeffRef(i-1,i) = p * pow(m_A.coeff(i,i), p-1);+ else if (2*abs(m_A.coeff(i-1,i-1)) < abs(m_A.coeff(i,i)) || 2*abs(m_A.coeff(i,i)) < abs(m_A.coeff(i-1,i-1)))+ res.coeffRef(i-1,i) = (res.coeff(i,i)-res.coeff(i-1,i-1)) / (m_A.coeff(i,i)-m_A.coeff(i-1,i-1));+ else+ res.coeffRef(i-1,i) = computeSuperDiag(m_A.coeff(i,i), m_A.coeff(i-1,i-1), p);+ res.coeffRef(i-1,i) *= m_A.coeff(i-1,i);+ }+}++template<typename MatrixType>+void MatrixPowerAtomic<MatrixType>::computeBig(MatrixType& res) const+{+ const int digits = std::numeric_limits<RealScalar>::digits;+ const RealScalar maxNormForPade = digits <= 24? 4.3386528e-1f: // sigle precision+ digits <= 53? 2.789358995219730e-1: // double precision+ digits <= 64? 2.4471944416607995472e-1L: // extended precision+ digits <= 106? 1.1016843812851143391275867258512e-1L: // double-double+ 9.134603732914548552537150753385375e-2L; // quadruple precision+ MatrixType IminusT, sqrtT, T = m_A.template triangularView<Upper>();+ RealScalar normIminusT;+ int degree, degree2, numberOfSquareRoots = 0;+ bool hasExtraSquareRoot = false;++ /* FIXME+ * For singular T, norm(I - T) >= 1 but maxNormForPade < 1, leads to infinite+ * loop. We should move 0 eigenvalues to bottom right corner. We need not+ * worry about tiny values (e.g. 1e-300) because they will reach 1 if+ * repetitively sqrt'ed.+ *+ * If the 0 eigenvalues are semisimple, they can form a 0 matrix at the+ * bottom right corner.+ *+ * [ T A ]^p [ T^p (T^-1 T^p A) ]+ * [ ] = [ ]+ * [ 0 0 ] [ 0 0 ]+ */+ for (Index i=0; i < m_A.cols(); ++i)+ eigen_assert(m_A(i,i) != RealScalar(0));++ while (true) {+ IminusT = MatrixType::Identity(m_A.rows(), m_A.cols()) - T;+ normIminusT = IminusT.cwiseAbs().colwise().sum().maxCoeff();+ if (normIminusT < maxNormForPade) {+ degree = getPadeDegree(normIminusT);+ degree2 = getPadeDegree(normIminusT/2);+ if (degree - degree2 <= 1 || hasExtraSquareRoot)+ break;+ hasExtraSquareRoot = true;+ }+ MatrixSquareRootTriangular<MatrixType>(T).compute(sqrtT);+ T = sqrtT.template triangularView<Upper>();+ ++numberOfSquareRoots;+ }+ computePade(degree, IminusT, res);++ for (; numberOfSquareRoots; --numberOfSquareRoots) {+ compute2x2(res, std::ldexp(m_p, -numberOfSquareRoots));+ res = res.template triangularView<Upper>() * res;+ }+ compute2x2(res, m_p);+}+ +template<typename MatrixType>+inline int MatrixPowerAtomic<MatrixType>::getPadeDegree(float normIminusT)+{+ const float maxNormForPade[] = { 2.8064004e-1f /* degree = 3 */ , 4.3386528e-1f };+ int degree = 3;+ for (; degree <= 4; ++degree)+ if (normIminusT <= maxNormForPade[degree - 3])+ break;+ return degree;+}++template<typename MatrixType>+inline int MatrixPowerAtomic<MatrixType>::getPadeDegree(double normIminusT)+{+ const double maxNormForPade[] = { 1.884160592658218e-2 /* degree = 3 */ , 6.038881904059573e-2, 1.239917516308172e-1,+ 1.999045567181744e-1, 2.789358995219730e-1 };+ int degree = 3;+ for (; degree <= 7; ++degree)+ if (normIminusT <= maxNormForPade[degree - 3])+ break;+ return degree;+}++template<typename MatrixType>+inline int MatrixPowerAtomic<MatrixType>::getPadeDegree(long double normIminusT)+{+#if LDBL_MANT_DIG == 53+ const int maxPadeDegree = 7;+ const double maxNormForPade[] = { 1.884160592658218e-2L /* degree = 3 */ , 6.038881904059573e-2L, 1.239917516308172e-1L,+ 1.999045567181744e-1L, 2.789358995219730e-1L };+#elif LDBL_MANT_DIG <= 64+ const int maxPadeDegree = 8;+ const double maxNormForPade[] = { 6.3854693117491799460e-3L /* degree = 3 */ , 2.6394893435456973676e-2L,+ 6.4216043030404063729e-2L, 1.1701165502926694307e-1L, 1.7904284231268670284e-1L, 2.4471944416607995472e-1L };+#elif LDBL_MANT_DIG <= 106+ const int maxPadeDegree = 10;+ const double maxNormForPade[] = { 1.0007161601787493236741409687186e-4L /* degree = 3 */ ,+ 1.0007161601787493236741409687186e-3L, 4.7069769360887572939882574746264e-3L, 1.3220386624169159689406653101695e-2L,+ 2.8063482381631737920612944054906e-2L, 4.9625993951953473052385361085058e-2L, 7.7367040706027886224557538328171e-2L,+ 1.1016843812851143391275867258512e-1L };+#else+ const int maxPadeDegree = 10;+ const double maxNormForPade[] = { 5.524506147036624377378713555116378e-5L /* degree = 3 */ ,+ 6.640600568157479679823602193345995e-4L, 3.227716520106894279249709728084626e-3L,+ 9.619593944683432960546978734646284e-3L, 2.134595382433742403911124458161147e-2L,+ 3.908166513900489428442993794761185e-2L, 6.266780814639442865832535460550138e-2L,+ 9.134603732914548552537150753385375e-2L };+#endif+ int degree = 3;+ for (; degree <= maxPadeDegree; ++degree)+ if (normIminusT <= maxNormForPade[degree - 3])+ break;+ return degree;+}++template<typename MatrixType>+inline typename MatrixPowerAtomic<MatrixType>::ComplexScalar+MatrixPowerAtomic<MatrixType>::computeSuperDiag(const ComplexScalar& curr, const ComplexScalar& prev, RealScalar p)+{+ ComplexScalar logCurr = std::log(curr);+ ComplexScalar logPrev = std::log(prev);+ int unwindingNumber = std::ceil((numext::imag(logCurr - logPrev) - M_PI) / (2*M_PI));+ ComplexScalar w = numext::atanh2(curr - prev, curr + prev) + ComplexScalar(0, M_PI*unwindingNumber);+ return RealScalar(2) * std::exp(RealScalar(0.5) * p * (logCurr + logPrev)) * std::sinh(p * w) / (curr - prev);+}++template<typename MatrixType>+inline typename MatrixPowerAtomic<MatrixType>::RealScalar+MatrixPowerAtomic<MatrixType>::computeSuperDiag(RealScalar curr, RealScalar prev, RealScalar p)+{+ RealScalar w = numext::atanh2(curr - prev, curr + prev);+ return 2 * std::exp(p * (std::log(curr) + std::log(prev)) / 2) * std::sinh(p * w) / (curr - prev);+}++/**+ * \ingroup MatrixFunctions_Module+ *+ * \brief Class for computing matrix powers.+ *+ * \tparam MatrixType type of the base, expected to be an instantiation+ * of the Matrix class template.+ *+ * This class is capable of computing real/complex matrices raised to+ * an arbitrary real power. Meanwhile, it saves the result of Schur+ * decomposition if an non-integral power has even been calculated.+ * Therefore, if you want to compute multiple (>= 2) matrix powers+ * for the same matrix, using the class directly is more efficient than+ * calling MatrixBase::pow().+ *+ * Example:+ * \include MatrixPower_optimal.cpp+ * Output: \verbinclude MatrixPower_optimal.out+ */+template<typename MatrixType>+class MatrixPower+{+ private:+ enum {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime+ };+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::RealScalar RealScalar;+ typedef typename MatrixType::Index Index;++ public:+ /**+ * \brief Constructor.+ *+ * \param[in] A the base of the matrix power.+ *+ * The class stores a reference to A, so it should not be changed+ * (or destroyed) before evaluation.+ */+ explicit MatrixPower(const MatrixType& A) : m_A(A), m_conditionNumber(0)+ { eigen_assert(A.rows() == A.cols()); }++ /**+ * \brief Returns the matrix power.+ *+ * \param[in] p exponent, a real scalar.+ * \return The expression \f$ A^p \f$, where A is specified in the+ * constructor.+ */+ const MatrixPowerRetval<MatrixType> operator()(RealScalar p)+ { return MatrixPowerRetval<MatrixType>(*this, p); }++ /**+ * \brief Compute the matrix power.+ *+ * \param[in] p exponent, a real scalar.+ * \param[out] res \f$ A^p \f$ where A is specified in the+ * constructor.+ */+ template<typename ResultType>+ void compute(ResultType& res, RealScalar p);+ + Index rows() const { return m_A.rows(); }+ Index cols() const { return m_A.cols(); }++ private:+ typedef std::complex<RealScalar> ComplexScalar;+ typedef Matrix<ComplexScalar, RowsAtCompileTime, ColsAtCompileTime, MatrixType::Options,+ MaxRowsAtCompileTime, MaxColsAtCompileTime> ComplexMatrix;++ typename MatrixType::Nested m_A;+ MatrixType m_tmp;+ ComplexMatrix m_T, m_U, m_fT;+ RealScalar m_conditionNumber;++ RealScalar modfAndInit(RealScalar, RealScalar*);++ template<typename ResultType>+ void computeIntPower(ResultType&, RealScalar);++ template<typename ResultType>+ void computeFracPower(ResultType&, RealScalar);++ template<int Rows, int Cols, int Options, int MaxRows, int MaxCols>+ static void revertSchur(+ Matrix<ComplexScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,+ const ComplexMatrix& T,+ const ComplexMatrix& U);++ template<int Rows, int Cols, int Options, int MaxRows, int MaxCols>+ static void revertSchur(+ Matrix<RealScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,+ const ComplexMatrix& T,+ const ComplexMatrix& U);+};++template<typename MatrixType>+template<typename ResultType>+void MatrixPower<MatrixType>::compute(ResultType& res, RealScalar p)+{+ switch (cols()) {+ case 0:+ break;+ case 1:+ res(0,0) = std::pow(m_A.coeff(0,0), p);+ break;+ default:+ RealScalar intpart, x = modfAndInit(p, &intpart);+ computeIntPower(res, intpart);+ computeFracPower(res, x);+ }+}++template<typename MatrixType>+typename MatrixPower<MatrixType>::RealScalar+MatrixPower<MatrixType>::modfAndInit(RealScalar x, RealScalar* intpart)+{+ typedef Array<RealScalar, RowsAtCompileTime, 1, ColMajor, MaxRowsAtCompileTime> RealArray;++ *intpart = std::floor(x);+ RealScalar res = x - *intpart;++ if (!m_conditionNumber && res) {+ const ComplexSchur<MatrixType> schurOfA(m_A);+ m_T = schurOfA.matrixT();+ m_U = schurOfA.matrixU();+ + const RealArray absTdiag = m_T.diagonal().array().abs();+ m_conditionNumber = absTdiag.maxCoeff() / absTdiag.minCoeff();+ }++ if (res>RealScalar(0.5) && res>(1-res)*std::pow(m_conditionNumber, res)) {+ --res;+ ++*intpart;+ }+ return res;+}++template<typename MatrixType>+template<typename ResultType>+void MatrixPower<MatrixType>::computeIntPower(ResultType& res, RealScalar p)+{+ RealScalar pp = std::abs(p);++ if (p<0) m_tmp = m_A.inverse();+ else m_tmp = m_A;++ res = MatrixType::Identity(rows(), cols());+ while (pp >= 1) {+ if (std::fmod(pp, 2) >= 1)+ res = m_tmp * res;+ m_tmp *= m_tmp;+ pp /= 2;+ }+}++template<typename MatrixType>+template<typename ResultType>+void MatrixPower<MatrixType>::computeFracPower(ResultType& res, RealScalar p)+{+ if (p) {+ eigen_assert(m_conditionNumber);+ MatrixPowerAtomic<ComplexMatrix>(m_T, p).compute(m_fT);+ revertSchur(m_tmp, m_fT, m_U);+ res = m_tmp * res;+ }+}++template<typename MatrixType>+template<int Rows, int Cols, int Options, int MaxRows, int MaxCols>+inline void MatrixPower<MatrixType>::revertSchur(+ Matrix<ComplexScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,+ const ComplexMatrix& T,+ const ComplexMatrix& U)+{ res.noalias() = U * (T.template triangularView<Upper>() * U.adjoint()); }++template<typename MatrixType>+template<int Rows, int Cols, int Options, int MaxRows, int MaxCols>+inline void MatrixPower<MatrixType>::revertSchur(+ Matrix<RealScalar, Rows, Cols, Options, MaxRows, MaxCols>& res,+ const ComplexMatrix& T,+ const ComplexMatrix& U)+{ res.noalias() = (U * (T.template triangularView<Upper>() * U.adjoint())).real(); }++/**+ * \ingroup MatrixFunctions_Module+ *+ * \brief Proxy for the matrix power of some matrix (expression).+ *+ * \tparam Derived type of the base, a matrix (expression).+ *+ * This class holds the arguments to the matrix power until it is+ * assigned or evaluated for some other reason (so the argument+ * should not be changed in the meantime). It is the return type of+ * MatrixBase::pow() and related functions and most of the+ * time this is the only way it is used.+ */+template<typename Derived>+class MatrixPowerReturnValue : public ReturnByValue< MatrixPowerReturnValue<Derived> >+{+ public:+ typedef typename Derived::PlainObject PlainObject;+ typedef typename Derived::RealScalar RealScalar;+ typedef typename Derived::Index Index;++ /**+ * \brief Constructor.+ *+ * \param[in] A %Matrix (expression), the base of the matrix power.+ * \param[in] p scalar, the exponent of the matrix power.+ */+ MatrixPowerReturnValue(const Derived& A, RealScalar p) : m_A(A), m_p(p)+ { }++ /**+ * \brief Compute the matrix power.+ *+ * \param[out] result \f$ A^p \f$ where \p A and \p p are as in the+ * constructor.+ */+ template<typename ResultType>+ inline void evalTo(ResultType& res) const+ { MatrixPower<PlainObject>(m_A.eval()).compute(res, m_p); }++ Index rows() const { return m_A.rows(); }+ Index cols() const { return m_A.cols(); }++ private:+ const Derived& m_A;+ const RealScalar m_p;+ MatrixPowerReturnValue& operator=(const MatrixPowerReturnValue&);+};++namespace internal {++template<typename MatrixPowerType>+struct traits< MatrixPowerRetval<MatrixPowerType> >+{ typedef typename MatrixPowerType::PlainObject ReturnType; };++template<typename Derived>+struct traits< MatrixPowerReturnValue<Derived> >+{ typedef typename Derived::PlainObject ReturnType; };++}++template<typename Derived>+const MatrixPowerReturnValue<Derived> MatrixBase<Derived>::pow(const RealScalar& p) const+{ return MatrixPowerReturnValue<Derived>(derived(), p); }++} // namespace Eigen++#endif // EIGEN_MATRIX_POWER
+ eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h view
@@ -0,0 +1,466 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Jitse Niesen <jitse@maths.leeds.ac.uk>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_MATRIX_SQUARE_ROOT+#define EIGEN_MATRIX_SQUARE_ROOT++namespace Eigen { ++/** \ingroup MatrixFunctions_Module+ * \brief Class for computing matrix square roots of upper quasi-triangular matrices.+ * \tparam MatrixType type of the argument of the matrix square root,+ * expected to be an instantiation of the Matrix class template.+ *+ * This class computes the square root of the upper quasi-triangular+ * matrix stored in the upper Hessenberg part of the matrix passed to+ * the constructor.+ *+ * \sa MatrixSquareRoot, MatrixSquareRootTriangular+ */+template <typename MatrixType>+class MatrixSquareRootQuasiTriangular+{+ public:++ /** \brief Constructor. + *+ * \param[in] A upper quasi-triangular matrix whose square root + * is to be computed.+ *+ * The class stores a reference to \p A, so it should not be+ * changed (or destroyed) before compute() is called.+ */+ MatrixSquareRootQuasiTriangular(const MatrixType& A) + : m_A(A) + {+ eigen_assert(A.rows() == A.cols());+ }+ + /** \brief Compute the matrix square root+ *+ * \param[out] result square root of \p A, as specified in the constructor.+ *+ * Only the upper Hessenberg part of \p result is updated, the+ * rest is not touched. See MatrixBase::sqrt() for details on+ * how this computation is implemented.+ */+ template <typename ResultType> void compute(ResultType &result); + + private:+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ + void computeDiagonalPartOfSqrt(MatrixType& sqrtT, const MatrixType& T);+ void computeOffDiagonalPartOfSqrt(MatrixType& sqrtT, const MatrixType& T);+ void compute2x2diagonalBlock(MatrixType& sqrtT, const MatrixType& T, typename MatrixType::Index i);+ void compute1x1offDiagonalBlock(MatrixType& sqrtT, const MatrixType& T, + typename MatrixType::Index i, typename MatrixType::Index j);+ void compute1x2offDiagonalBlock(MatrixType& sqrtT, const MatrixType& T, + typename MatrixType::Index i, typename MatrixType::Index j);+ void compute2x1offDiagonalBlock(MatrixType& sqrtT, const MatrixType& T, + typename MatrixType::Index i, typename MatrixType::Index j);+ void compute2x2offDiagonalBlock(MatrixType& sqrtT, const MatrixType& T, + typename MatrixType::Index i, typename MatrixType::Index j);+ + template <typename SmallMatrixType>+ static void solveAuxiliaryEquation(SmallMatrixType& X, const SmallMatrixType& A, + const SmallMatrixType& B, const SmallMatrixType& C);+ + const MatrixType& m_A;+};++template <typename MatrixType>+template <typename ResultType> +void MatrixSquareRootQuasiTriangular<MatrixType>::compute(ResultType &result)+{+ result.resize(m_A.rows(), m_A.cols());+ computeDiagonalPartOfSqrt(result, m_A);+ computeOffDiagonalPartOfSqrt(result, m_A);+}++// pre: T is quasi-upper-triangular and sqrtT is a zero matrix of the same size+// post: the diagonal blocks of sqrtT are the square roots of the diagonal blocks of T+template <typename MatrixType>+void MatrixSquareRootQuasiTriangular<MatrixType>::computeDiagonalPartOfSqrt(MatrixType& sqrtT, + const MatrixType& T)+{+ using std::sqrt;+ const Index size = m_A.rows();+ for (Index i = 0; i < size; i++) {+ if (i == size - 1 || T.coeff(i+1, i) == 0) {+ eigen_assert(T(i,i) >= 0);+ sqrtT.coeffRef(i,i) = sqrt(T.coeff(i,i));+ }+ else {+ compute2x2diagonalBlock(sqrtT, T, i);+ ++i;+ }+ }+}++// pre: T is quasi-upper-triangular and diagonal blocks of sqrtT are square root of diagonal blocks of T.+// post: sqrtT is the square root of T.+template <typename MatrixType>+void MatrixSquareRootQuasiTriangular<MatrixType>::computeOffDiagonalPartOfSqrt(MatrixType& sqrtT, + const MatrixType& T)+{+ const Index size = m_A.rows();+ for (Index j = 1; j < size; j++) {+ if (T.coeff(j, j-1) != 0) // if T(j-1:j, j-1:j) is a 2-by-2 block+ continue;+ for (Index i = j-1; i >= 0; i--) {+ if (i > 0 && T.coeff(i, i-1) != 0) // if T(i-1:i, i-1:i) is a 2-by-2 block+ continue;+ bool iBlockIs2x2 = (i < size - 1) && (T.coeff(i+1, i) != 0);+ bool jBlockIs2x2 = (j < size - 1) && (T.coeff(j+1, j) != 0);+ if (iBlockIs2x2 && jBlockIs2x2) + compute2x2offDiagonalBlock(sqrtT, T, i, j);+ else if (iBlockIs2x2 && !jBlockIs2x2) + compute2x1offDiagonalBlock(sqrtT, T, i, j);+ else if (!iBlockIs2x2 && jBlockIs2x2) + compute1x2offDiagonalBlock(sqrtT, T, i, j);+ else if (!iBlockIs2x2 && !jBlockIs2x2) + compute1x1offDiagonalBlock(sqrtT, T, i, j);+ }+ }+}++// pre: T.block(i,i,2,2) has complex conjugate eigenvalues+// post: sqrtT.block(i,i,2,2) is square root of T.block(i,i,2,2)+template <typename MatrixType>+void MatrixSquareRootQuasiTriangular<MatrixType>+ ::compute2x2diagonalBlock(MatrixType& sqrtT, const MatrixType& T, typename MatrixType::Index i)+{+ // TODO: This case (2-by-2 blocks with complex conjugate eigenvalues) is probably hidden somewhere+ // in EigenSolver. If we expose it, we could call it directly from here.+ Matrix<Scalar,2,2> block = T.template block<2,2>(i,i);+ EigenSolver<Matrix<Scalar,2,2> > es(block);+ sqrtT.template block<2,2>(i,i)+ = (es.eigenvectors() * es.eigenvalues().cwiseSqrt().asDiagonal() * es.eigenvectors().inverse()).real();+}++// pre: block structure of T is such that (i,j) is a 1x1 block,+// all blocks of sqrtT to left of and below (i,j) are correct+// post: sqrtT(i,j) has the correct value+template <typename MatrixType>+void MatrixSquareRootQuasiTriangular<MatrixType>+ ::compute1x1offDiagonalBlock(MatrixType& sqrtT, const MatrixType& T, + typename MatrixType::Index i, typename MatrixType::Index j)+{+ Scalar tmp = (sqrtT.row(i).segment(i+1,j-i-1) * sqrtT.col(j).segment(i+1,j-i-1)).value();+ sqrtT.coeffRef(i,j) = (T.coeff(i,j) - tmp) / (sqrtT.coeff(i,i) + sqrtT.coeff(j,j));+}++// similar to compute1x1offDiagonalBlock()+template <typename MatrixType>+void MatrixSquareRootQuasiTriangular<MatrixType>+ ::compute1x2offDiagonalBlock(MatrixType& sqrtT, const MatrixType& T, + typename MatrixType::Index i, typename MatrixType::Index j)+{+ Matrix<Scalar,1,2> rhs = T.template block<1,2>(i,j);+ if (j-i > 1)+ rhs -= sqrtT.block(i, i+1, 1, j-i-1) * sqrtT.block(i+1, j, j-i-1, 2);+ Matrix<Scalar,2,2> A = sqrtT.coeff(i,i) * Matrix<Scalar,2,2>::Identity();+ A += sqrtT.template block<2,2>(j,j).transpose();+ sqrtT.template block<1,2>(i,j).transpose() = A.fullPivLu().solve(rhs.transpose());+}++// similar to compute1x1offDiagonalBlock()+template <typename MatrixType>+void MatrixSquareRootQuasiTriangular<MatrixType>+ ::compute2x1offDiagonalBlock(MatrixType& sqrtT, const MatrixType& T, + typename MatrixType::Index i, typename MatrixType::Index j)+{+ Matrix<Scalar,2,1> rhs = T.template block<2,1>(i,j);+ if (j-i > 2)+ rhs -= sqrtT.block(i, i+2, 2, j-i-2) * sqrtT.block(i+2, j, j-i-2, 1);+ Matrix<Scalar,2,2> A = sqrtT.coeff(j,j) * Matrix<Scalar,2,2>::Identity();+ A += sqrtT.template block<2,2>(i,i);+ sqrtT.template block<2,1>(i,j) = A.fullPivLu().solve(rhs);+}++// similar to compute1x1offDiagonalBlock()+template <typename MatrixType>+void MatrixSquareRootQuasiTriangular<MatrixType>+ ::compute2x2offDiagonalBlock(MatrixType& sqrtT, const MatrixType& T, + typename MatrixType::Index i, typename MatrixType::Index j)+{+ Matrix<Scalar,2,2> A = sqrtT.template block<2,2>(i,i);+ Matrix<Scalar,2,2> B = sqrtT.template block<2,2>(j,j);+ Matrix<Scalar,2,2> C = T.template block<2,2>(i,j);+ if (j-i > 2)+ C -= sqrtT.block(i, i+2, 2, j-i-2) * sqrtT.block(i+2, j, j-i-2, 2);+ Matrix<Scalar,2,2> X;+ solveAuxiliaryEquation(X, A, B, C);+ sqrtT.template block<2,2>(i,j) = X;+}++// solves the equation A X + X B = C where all matrices are 2-by-2+template <typename MatrixType>+template <typename SmallMatrixType>+void MatrixSquareRootQuasiTriangular<MatrixType>+ ::solveAuxiliaryEquation(SmallMatrixType& X, const SmallMatrixType& A,+ const SmallMatrixType& B, const SmallMatrixType& C)+{+ EIGEN_STATIC_ASSERT((internal::is_same<SmallMatrixType, Matrix<Scalar,2,2> >::value),+ EIGEN_INTERNAL_ERROR_PLEASE_FILE_A_BUG_REPORT);++ Matrix<Scalar,4,4> coeffMatrix = Matrix<Scalar,4,4>::Zero();+ coeffMatrix.coeffRef(0,0) = A.coeff(0,0) + B.coeff(0,0);+ coeffMatrix.coeffRef(1,1) = A.coeff(0,0) + B.coeff(1,1);+ coeffMatrix.coeffRef(2,2) = A.coeff(1,1) + B.coeff(0,0);+ coeffMatrix.coeffRef(3,3) = A.coeff(1,1) + B.coeff(1,1);+ coeffMatrix.coeffRef(0,1) = B.coeff(1,0);+ coeffMatrix.coeffRef(0,2) = A.coeff(0,1);+ coeffMatrix.coeffRef(1,0) = B.coeff(0,1);+ coeffMatrix.coeffRef(1,3) = A.coeff(0,1);+ coeffMatrix.coeffRef(2,0) = A.coeff(1,0);+ coeffMatrix.coeffRef(2,3) = B.coeff(1,0);+ coeffMatrix.coeffRef(3,1) = A.coeff(1,0);+ coeffMatrix.coeffRef(3,2) = B.coeff(0,1);+ + Matrix<Scalar,4,1> rhs;+ rhs.coeffRef(0) = C.coeff(0,0);+ rhs.coeffRef(1) = C.coeff(0,1);+ rhs.coeffRef(2) = C.coeff(1,0);+ rhs.coeffRef(3) = C.coeff(1,1);+ + Matrix<Scalar,4,1> result;+ result = coeffMatrix.fullPivLu().solve(rhs);++ X.coeffRef(0,0) = result.coeff(0);+ X.coeffRef(0,1) = result.coeff(1);+ X.coeffRef(1,0) = result.coeff(2);+ X.coeffRef(1,1) = result.coeff(3);+}+++/** \ingroup MatrixFunctions_Module+ * \brief Class for computing matrix square roots of upper triangular matrices.+ * \tparam MatrixType type of the argument of the matrix square root,+ * expected to be an instantiation of the Matrix class template.+ *+ * This class computes the square root of the upper triangular matrix+ * stored in the upper triangular part (including the diagonal) of+ * the matrix passed to the constructor.+ *+ * \sa MatrixSquareRoot, MatrixSquareRootQuasiTriangular+ */+template <typename MatrixType>+class MatrixSquareRootTriangular+{+ public:+ MatrixSquareRootTriangular(const MatrixType& A) + : m_A(A) + {+ eigen_assert(A.rows() == A.cols());+ }++ /** \brief Compute the matrix square root+ *+ * \param[out] result square root of \p A, as specified in the constructor.+ *+ * Only the upper triangular part (including the diagonal) of + * \p result is updated, the rest is not touched. See+ * MatrixBase::sqrt() for details on how this computation is+ * implemented.+ */+ template <typename ResultType> void compute(ResultType &result); ++ private:+ const MatrixType& m_A;+};++template <typename MatrixType>+template <typename ResultType> +void MatrixSquareRootTriangular<MatrixType>::compute(ResultType &result)+{+ using std::sqrt;++ // Compute square root of m_A and store it in upper triangular part of result+ // This uses that the square root of triangular matrices can be computed directly.+ result.resize(m_A.rows(), m_A.cols());+ typedef typename MatrixType::Index Index;+ for (Index i = 0; i < m_A.rows(); i++) {+ result.coeffRef(i,i) = sqrt(m_A.coeff(i,i));+ }+ for (Index j = 1; j < m_A.cols(); j++) {+ for (Index i = j-1; i >= 0; i--) {+ typedef typename MatrixType::Scalar Scalar;+ // if i = j-1, then segment has length 0 so tmp = 0+ Scalar tmp = (result.row(i).segment(i+1,j-i-1) * result.col(j).segment(i+1,j-i-1)).value();+ // denominator may be zero if original matrix is singular+ result.coeffRef(i,j) = (m_A.coeff(i,j) - tmp) / (result.coeff(i,i) + result.coeff(j,j));+ }+ }+}+++/** \ingroup MatrixFunctions_Module+ * \brief Class for computing matrix square roots of general matrices.+ * \tparam MatrixType type of the argument of the matrix square root,+ * expected to be an instantiation of the Matrix class template.+ *+ * \sa MatrixSquareRootTriangular, MatrixSquareRootQuasiTriangular, MatrixBase::sqrt()+ */+template <typename MatrixType, int IsComplex = NumTraits<typename internal::traits<MatrixType>::Scalar>::IsComplex>+class MatrixSquareRoot+{+ public:++ /** \brief Constructor. + *+ * \param[in] A matrix whose square root is to be computed.+ *+ * The class stores a reference to \p A, so it should not be+ * changed (or destroyed) before compute() is called.+ */+ MatrixSquareRoot(const MatrixType& A); + + /** \brief Compute the matrix square root+ *+ * \param[out] result square root of \p A, as specified in the constructor.+ *+ * See MatrixBase::sqrt() for details on how this computation is+ * implemented.+ */+ template <typename ResultType> void compute(ResultType &result); +};+++// ********** Partial specialization for real matrices **********++template <typename MatrixType>+class MatrixSquareRoot<MatrixType, 0>+{+ public:++ MatrixSquareRoot(const MatrixType& A) + : m_A(A) + { + eigen_assert(A.rows() == A.cols());+ }+ + template <typename ResultType> void compute(ResultType &result)+ {+ // Compute Schur decomposition of m_A+ const RealSchur<MatrixType> schurOfA(m_A); + const MatrixType& T = schurOfA.matrixT();+ const MatrixType& U = schurOfA.matrixU();+ + // Compute square root of T+ MatrixType sqrtT = MatrixType::Zero(m_A.rows(), m_A.cols());+ MatrixSquareRootQuasiTriangular<MatrixType>(T).compute(sqrtT);+ + // Compute square root of m_A+ result = U * sqrtT * U.adjoint();+ }+ + private:+ const MatrixType& m_A;+};+++// ********** Partial specialization for complex matrices **********++template <typename MatrixType>+class MatrixSquareRoot<MatrixType, 1>+{+ public:++ MatrixSquareRoot(const MatrixType& A) + : m_A(A) + { + eigen_assert(A.rows() == A.cols());+ }+ + template <typename ResultType> void compute(ResultType &result)+ {+ // Compute Schur decomposition of m_A+ const ComplexSchur<MatrixType> schurOfA(m_A); + const MatrixType& T = schurOfA.matrixT();+ const MatrixType& U = schurOfA.matrixU();+ + // Compute square root of T+ MatrixType sqrtT;+ MatrixSquareRootTriangular<MatrixType>(T).compute(sqrtT);+ + // Compute square root of m_A+ result = U * (sqrtT.template triangularView<Upper>() * U.adjoint());+ }+ + private:+ const MatrixType& m_A;+};+++/** \ingroup MatrixFunctions_Module+ *+ * \brief Proxy for the matrix square root of some matrix (expression).+ *+ * \tparam Derived Type of the argument to the matrix square root.+ *+ * This class holds the argument to the matrix square root until it+ * is assigned or evaluated for some other reason (so the argument+ * should not be changed in the meantime). It is the return type of+ * MatrixBase::sqrt() and most of the time this is the only way it is+ * used.+ */+template<typename Derived> class MatrixSquareRootReturnValue+: public ReturnByValue<MatrixSquareRootReturnValue<Derived> >+{+ typedef typename Derived::Index Index;+ public:+ /** \brief Constructor.+ *+ * \param[in] src %Matrix (expression) forming the argument of the+ * matrix square root.+ */+ MatrixSquareRootReturnValue(const Derived& src) : m_src(src) { }++ /** \brief Compute the matrix square root.+ *+ * \param[out] result the matrix square root of \p src in the+ * constructor.+ */+ template <typename ResultType>+ inline void evalTo(ResultType& result) const+ {+ const typename Derived::PlainObject srcEvaluated = m_src.eval();+ MatrixSquareRoot<typename Derived::PlainObject> me(srcEvaluated);+ me.compute(result);+ }++ Index rows() const { return m_src.rows(); }+ Index cols() const { return m_src.cols(); }++ protected:+ const Derived& m_src;+ private:+ MatrixSquareRootReturnValue& operator=(const MatrixSquareRootReturnValue&);+};++namespace internal {+template<typename Derived>+struct traits<MatrixSquareRootReturnValue<Derived> >+{+ typedef typename Derived::PlainObject ReturnType;+};+}++template <typename Derived>+const MatrixSquareRootReturnValue<Derived> MatrixBase<Derived>::sqrt() const+{+ eigen_assert(rows() == cols());+ return MatrixSquareRootReturnValue<Derived>(derived());+}++} // end namespace Eigen++#endif // EIGEN_MATRIX_FUNCTION
+ eigen3/unsupported/Eigen/src/MatrixFunctions/StemFunction.h view
@@ -0,0 +1,105 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_STEM_FUNCTION+#define EIGEN_STEM_FUNCTION++namespace Eigen { ++/** \ingroup MatrixFunctions_Module + * \brief Stem functions corresponding to standard mathematical functions.+ */+template <typename Scalar>+class StdStemFunctions+{+ public:++ /** \brief The exponential function (and its derivatives). */+ static Scalar exp(Scalar x, int)+ {+ return std::exp(x);+ }++ /** \brief Cosine (and its derivatives). */+ static Scalar cos(Scalar x, int n)+ {+ Scalar res;+ switch (n % 4) {+ case 0: + res = std::cos(x);+ break;+ case 1:+ res = -std::sin(x);+ break;+ case 2:+ res = -std::cos(x);+ break;+ case 3:+ res = std::sin(x);+ break;+ }+ return res;+ }++ /** \brief Sine (and its derivatives). */+ static Scalar sin(Scalar x, int n)+ {+ Scalar res;+ switch (n % 4) {+ case 0:+ res = std::sin(x);+ break;+ case 1:+ res = std::cos(x);+ break;+ case 2:+ res = -std::sin(x);+ break;+ case 3:+ res = -std::cos(x);+ break;+ }+ return res;+ }++ /** \brief Hyperbolic cosine (and its derivatives). */+ static Scalar cosh(Scalar x, int n)+ {+ Scalar res;+ switch (n % 2) {+ case 0:+ res = std::cosh(x);+ break;+ case 1:+ res = std::sinh(x);+ break;+ }+ return res;+ }+ + /** \brief Hyperbolic sine (and its derivatives). */+ static Scalar sinh(Scalar x, int n)+ {+ Scalar res;+ switch (n % 2) {+ case 0:+ res = std::sinh(x);+ break;+ case 1:+ res = std::cosh(x);+ break;+ }+ return res;+ }++}; // end of class StdStemFunctions++} // end namespace Eigen++#endif // EIGEN_STEM_FUNCTION
+ eigen3/unsupported/Eigen/src/MoreVectorization/CMakeLists.txt view
@@ -0,0 +1,6 @@+FILE(GLOB Eigen_MoreVectorization_SRCS "*.h")++INSTALL(FILES+ ${Eigen_MoreVectorization_SRCS}+ DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/MoreVectorization COMPONENT Devel+ )
+ eigen3/unsupported/Eigen/src/MoreVectorization/MathFunctions.h view
@@ -0,0 +1,95 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Rohit Garg <rpg.314@gmail.com>+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_MOREVECTORIZATION_MATHFUNCTIONS_H+#define EIGEN_MOREVECTORIZATION_MATHFUNCTIONS_H++namespace Eigen { ++namespace internal {++/** \internal \returns the arcsin of \a a (coeff-wise) */+template<typename Packet> inline static Packet pasin(Packet a) { return std::asin(a); }++#ifdef EIGEN_VECTORIZE_SSE++template<> EIGEN_DONT_INLINE Packet4f pasin(Packet4f x)+{+ _EIGEN_DECLARE_CONST_Packet4f(half, 0.5);+ _EIGEN_DECLARE_CONST_Packet4f(minus_half, -0.5);+ _EIGEN_DECLARE_CONST_Packet4f(3half, 1.5);++ _EIGEN_DECLARE_CONST_Packet4f_FROM_INT(sign_mask, 0x80000000);++ _EIGEN_DECLARE_CONST_Packet4f(pi, 3.141592654);+ _EIGEN_DECLARE_CONST_Packet4f(pi_over_2, 3.141592654*0.5);++ _EIGEN_DECLARE_CONST_Packet4f(asin1, 4.2163199048E-2);+ _EIGEN_DECLARE_CONST_Packet4f(asin2, 2.4181311049E-2);+ _EIGEN_DECLARE_CONST_Packet4f(asin3, 4.5470025998E-2);+ _EIGEN_DECLARE_CONST_Packet4f(asin4, 7.4953002686E-2);+ _EIGEN_DECLARE_CONST_Packet4f(asin5, 1.6666752422E-1);++ Packet4f a = pabs(x);//got the absolute value++ Packet4f sign_bit= _mm_and_ps(x, p4f_sign_mask);//extracted the sign bit++ Packet4f z1,z2;//will need them during computation +++//will compute the two branches for asin+//so first compare with half++ Packet4f branch_mask= _mm_cmpgt_ps(a, p4f_half);//this is to select which branch to take+//both will be taken, and finally results will be merged+//the branch for values >0.5++ {+//the core series expansion + z1=pmadd(p4f_minus_half,a,p4f_half);+ Packet4f x1=psqrt(z1);+ Packet4f s1=pmadd(p4f_asin1, z1, p4f_asin2);+ Packet4f s2=pmadd(s1, z1, p4f_asin3);+ Packet4f s3=pmadd(s2,z1, p4f_asin4);+ Packet4f s4=pmadd(s3,z1, p4f_asin5);+ Packet4f temp=pmul(s4,z1);//not really a madd but a mul by z so that the next term can be a madd+ z1=pmadd(temp,x1,x1);+ z1=padd(z1,z1);+ z1=psub(p4f_pi_over_2,z1);+ }++ {+//the core series expansion + Packet4f x2=a;+ z2=pmul(x2,x2);+ Packet4f s1=pmadd(p4f_asin1, z2, p4f_asin2);+ Packet4f s2=pmadd(s1, z2, p4f_asin3);+ Packet4f s3=pmadd(s2,z2, p4f_asin4);+ Packet4f s4=pmadd(s3,z2, p4f_asin5);+ Packet4f temp=pmul(s4,z2);//not really a madd but a mul by z so that the next term can be a madd+ z2=pmadd(temp,x2,x2);+ }++/* select the correct result from the two branch evaluations */+ z1 = _mm_and_ps(branch_mask, z1);+ z2 = _mm_andnot_ps(branch_mask, z2);+ Packet4f z = _mm_or_ps(z1,z2);++/* update the sign */+ return _mm_xor_ps(z, sign_bit);+}++#endif // EIGEN_VECTORIZE_SSE++} // end namespace internal++} // end namespace Eigen++#endif // EIGEN_MOREVECTORIZATION_MATHFUNCTIONS_H
+ eigen3/unsupported/Eigen/src/NonLinearOptimization/CMakeLists.txt view
@@ -0,0 +1,6 @@+FILE(GLOB Eigen_NonLinearOptimization_SRCS "*.h")++INSTALL(FILES+ ${Eigen_NonLinearOptimization_SRCS}+ DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/NonLinearOptimization COMPONENT Devel+ )
+ eigen3/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h view
@@ -0,0 +1,601 @@+// -*- coding: utf-8+// vim: set fileencoding=utf-8++// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_HYBRIDNONLINEARSOLVER_H+#define EIGEN_HYBRIDNONLINEARSOLVER_H++namespace Eigen { ++namespace HybridNonLinearSolverSpace { + enum Status {+ Running = -1,+ ImproperInputParameters = 0,+ RelativeErrorTooSmall = 1,+ TooManyFunctionEvaluation = 2,+ TolTooSmall = 3,+ NotMakingProgressJacobian = 4,+ NotMakingProgressIterations = 5,+ UserAsked = 6+ };+}++/**+ * \ingroup NonLinearOptimization_Module+ * \brief Finds a zero of a system of n+ * nonlinear functions in n variables by a modification of the Powell+ * hybrid method ("dogleg").+ *+ * The user must provide a subroutine which calculates the+ * functions. The Jacobian is either provided by the user, or approximated+ * using a forward-difference method.+ *+ */+template<typename FunctorType, typename Scalar=double>+class HybridNonLinearSolver+{+public:+ typedef DenseIndex Index;++ HybridNonLinearSolver(FunctorType &_functor)+ : functor(_functor) { nfev=njev=iter = 0; fnorm= 0.; useExternalScaling=false;}++ struct Parameters {+ Parameters()+ : factor(Scalar(100.))+ , maxfev(1000)+ , xtol(std::sqrt(NumTraits<Scalar>::epsilon()))+ , nb_of_subdiagonals(-1)+ , nb_of_superdiagonals(-1)+ , epsfcn(Scalar(0.)) {}+ Scalar factor;+ Index maxfev; // maximum number of function evaluation+ Scalar xtol;+ Index nb_of_subdiagonals;+ Index nb_of_superdiagonals;+ Scalar epsfcn;+ };+ typedef Matrix< Scalar, Dynamic, 1 > FVectorType;+ typedef Matrix< Scalar, Dynamic, Dynamic > JacobianType;+ /* TODO: if eigen provides a triangular storage, use it here */+ typedef Matrix< Scalar, Dynamic, Dynamic > UpperTriangularType;++ HybridNonLinearSolverSpace::Status hybrj1(+ FVectorType &x,+ const Scalar tol = std::sqrt(NumTraits<Scalar>::epsilon())+ );++ HybridNonLinearSolverSpace::Status solveInit(FVectorType &x);+ HybridNonLinearSolverSpace::Status solveOneStep(FVectorType &x);+ HybridNonLinearSolverSpace::Status solve(FVectorType &x);++ HybridNonLinearSolverSpace::Status hybrd1(+ FVectorType &x,+ const Scalar tol = std::sqrt(NumTraits<Scalar>::epsilon())+ );++ HybridNonLinearSolverSpace::Status solveNumericalDiffInit(FVectorType &x);+ HybridNonLinearSolverSpace::Status solveNumericalDiffOneStep(FVectorType &x);+ HybridNonLinearSolverSpace::Status solveNumericalDiff(FVectorType &x);++ void resetParameters(void) { parameters = Parameters(); }+ Parameters parameters;+ FVectorType fvec, qtf, diag;+ JacobianType fjac;+ UpperTriangularType R;+ Index nfev;+ Index njev;+ Index iter;+ Scalar fnorm;+ bool useExternalScaling; +private:+ FunctorType &functor;+ Index n;+ Scalar sum;+ bool sing;+ Scalar temp;+ Scalar delta;+ bool jeval;+ Index ncsuc;+ Scalar ratio;+ Scalar pnorm, xnorm, fnorm1;+ Index nslow1, nslow2;+ Index ncfail;+ Scalar actred, prered;+ FVectorType wa1, wa2, wa3, wa4;++ HybridNonLinearSolver& operator=(const HybridNonLinearSolver&);+};++++template<typename FunctorType, typename Scalar>+HybridNonLinearSolverSpace::Status+HybridNonLinearSolver<FunctorType,Scalar>::hybrj1(+ FVectorType &x,+ const Scalar tol+ )+{+ n = x.size();++ /* check the input parameters for errors. */+ if (n <= 0 || tol < 0.)+ return HybridNonLinearSolverSpace::ImproperInputParameters;++ resetParameters();+ parameters.maxfev = 100*(n+1);+ parameters.xtol = tol;+ diag.setConstant(n, 1.);+ useExternalScaling = true;+ return solve(x);+}++template<typename FunctorType, typename Scalar>+HybridNonLinearSolverSpace::Status+HybridNonLinearSolver<FunctorType,Scalar>::solveInit(FVectorType &x)+{+ n = x.size();++ wa1.resize(n); wa2.resize(n); wa3.resize(n); wa4.resize(n);+ fvec.resize(n);+ qtf.resize(n);+ fjac.resize(n, n);+ if (!useExternalScaling)+ diag.resize(n);+ eigen_assert( (!useExternalScaling || diag.size()==n) || "When useExternalScaling is set, the caller must provide a valid 'diag'");++ /* Function Body */+ nfev = 0;+ njev = 0;++ /* check the input parameters for errors. */+ if (n <= 0 || parameters.xtol < 0. || parameters.maxfev <= 0 || parameters.factor <= 0. )+ return HybridNonLinearSolverSpace::ImproperInputParameters;+ if (useExternalScaling)+ for (Index j = 0; j < n; ++j)+ if (diag[j] <= 0.)+ return HybridNonLinearSolverSpace::ImproperInputParameters;++ /* evaluate the function at the starting point */+ /* and calculate its norm. */+ nfev = 1;+ if ( functor(x, fvec) < 0)+ return HybridNonLinearSolverSpace::UserAsked;+ fnorm = fvec.stableNorm();++ /* initialize iteration counter and monitors. */+ iter = 1;+ ncsuc = 0;+ ncfail = 0;+ nslow1 = 0;+ nslow2 = 0;++ return HybridNonLinearSolverSpace::Running;+}++template<typename FunctorType, typename Scalar>+HybridNonLinearSolverSpace::Status+HybridNonLinearSolver<FunctorType,Scalar>::solveOneStep(FVectorType &x)+{+ using std::abs;+ + eigen_assert(x.size()==n); // check the caller is not cheating us++ Index j;+ std::vector<JacobiRotation<Scalar> > v_givens(n), w_givens(n);++ jeval = true;++ /* calculate the jacobian matrix. */+ if ( functor.df(x, fjac) < 0)+ return HybridNonLinearSolverSpace::UserAsked;+ ++njev;++ wa2 = fjac.colwise().blueNorm();++ /* on the first iteration and if external scaling is not used, scale according */+ /* to the norms of the columns of the initial jacobian. */+ if (iter == 1) {+ if (!useExternalScaling)+ for (j = 0; j < n; ++j)+ diag[j] = (wa2[j]==0.) ? 1. : wa2[j];++ /* on the first iteration, calculate the norm of the scaled x */+ /* and initialize the step bound delta. */+ xnorm = diag.cwiseProduct(x).stableNorm();+ delta = parameters.factor * xnorm;+ if (delta == 0.)+ delta = parameters.factor;+ }++ /* compute the qr factorization of the jacobian. */+ HouseholderQR<JacobianType> qrfac(fjac); // no pivoting:++ /* copy the triangular factor of the qr factorization into r. */+ R = qrfac.matrixQR();++ /* accumulate the orthogonal factor in fjac. */+ fjac = qrfac.householderQ();++ /* form (q transpose)*fvec and store in qtf. */+ qtf = fjac.transpose() * fvec;++ /* rescale if necessary. */+ if (!useExternalScaling)+ diag = diag.cwiseMax(wa2);++ while (true) {+ /* determine the direction p. */+ internal::dogleg<Scalar>(R, diag, qtf, delta, wa1);++ /* store the direction p and x + p. calculate the norm of p. */+ wa1 = -wa1;+ wa2 = x + wa1;+ pnorm = diag.cwiseProduct(wa1).stableNorm();++ /* on the first iteration, adjust the initial step bound. */+ if (iter == 1)+ delta = (std::min)(delta,pnorm);++ /* evaluate the function at x + p and calculate its norm. */+ if ( functor(wa2, wa4) < 0)+ return HybridNonLinearSolverSpace::UserAsked;+ ++nfev;+ fnorm1 = wa4.stableNorm();++ /* compute the scaled actual reduction. */+ actred = -1.;+ if (fnorm1 < fnorm) /* Computing 2nd power */+ actred = 1. - numext::abs2(fnorm1 / fnorm);++ /* compute the scaled predicted reduction. */+ wa3 = R.template triangularView<Upper>()*wa1 + qtf;+ temp = wa3.stableNorm();+ prered = 0.;+ if (temp < fnorm) /* Computing 2nd power */+ prered = 1. - numext::abs2(temp / fnorm);++ /* compute the ratio of the actual to the predicted reduction. */+ ratio = 0.;+ if (prered > 0.)+ ratio = actred / prered;++ /* update the step bound. */+ if (ratio < Scalar(.1)) {+ ncsuc = 0;+ ++ncfail;+ delta = Scalar(.5) * delta;+ } else {+ ncfail = 0;+ ++ncsuc;+ if (ratio >= Scalar(.5) || ncsuc > 1)+ delta = (std::max)(delta, pnorm / Scalar(.5));+ if (abs(ratio - 1.) <= Scalar(.1)) {+ delta = pnorm / Scalar(.5);+ }+ }++ /* test for successful iteration. */+ if (ratio >= Scalar(1e-4)) {+ /* successful iteration. update x, fvec, and their norms. */+ x = wa2;+ wa2 = diag.cwiseProduct(x);+ fvec = wa4;+ xnorm = wa2.stableNorm();+ fnorm = fnorm1;+ ++iter;+ }++ /* determine the progress of the iteration. */+ ++nslow1;+ if (actred >= Scalar(.001))+ nslow1 = 0;+ if (jeval)+ ++nslow2;+ if (actred >= Scalar(.1))+ nslow2 = 0;++ /* test for convergence. */+ if (delta <= parameters.xtol * xnorm || fnorm == 0.)+ return HybridNonLinearSolverSpace::RelativeErrorTooSmall;++ /* tests for termination and stringent tolerances. */+ if (nfev >= parameters.maxfev)+ return HybridNonLinearSolverSpace::TooManyFunctionEvaluation;+ if (Scalar(.1) * (std::max)(Scalar(.1) * delta, pnorm) <= NumTraits<Scalar>::epsilon() * xnorm)+ return HybridNonLinearSolverSpace::TolTooSmall;+ if (nslow2 == 5)+ return HybridNonLinearSolverSpace::NotMakingProgressJacobian;+ if (nslow1 == 10)+ return HybridNonLinearSolverSpace::NotMakingProgressIterations;++ /* criterion for recalculating jacobian. */+ if (ncfail == 2)+ break; // leave inner loop and go for the next outer loop iteration++ /* calculate the rank one modification to the jacobian */+ /* and update qtf if necessary. */+ wa1 = diag.cwiseProduct( diag.cwiseProduct(wa1)/pnorm );+ wa2 = fjac.transpose() * wa4;+ if (ratio >= Scalar(1e-4))+ qtf = wa2;+ wa2 = (wa2-wa3)/pnorm;++ /* compute the qr factorization of the updated jacobian. */+ internal::r1updt<Scalar>(R, wa1, v_givens, w_givens, wa2, wa3, &sing);+ internal::r1mpyq<Scalar>(n, n, fjac.data(), v_givens, w_givens);+ internal::r1mpyq<Scalar>(1, n, qtf.data(), v_givens, w_givens);++ jeval = false;+ }+ return HybridNonLinearSolverSpace::Running;+}++template<typename FunctorType, typename Scalar>+HybridNonLinearSolverSpace::Status+HybridNonLinearSolver<FunctorType,Scalar>::solve(FVectorType &x)+{+ HybridNonLinearSolverSpace::Status status = solveInit(x);+ if (status==HybridNonLinearSolverSpace::ImproperInputParameters)+ return status;+ while (status==HybridNonLinearSolverSpace::Running)+ status = solveOneStep(x);+ return status;+}++++template<typename FunctorType, typename Scalar>+HybridNonLinearSolverSpace::Status+HybridNonLinearSolver<FunctorType,Scalar>::hybrd1(+ FVectorType &x,+ const Scalar tol+ )+{+ n = x.size();++ /* check the input parameters for errors. */+ if (n <= 0 || tol < 0.)+ return HybridNonLinearSolverSpace::ImproperInputParameters;++ resetParameters();+ parameters.maxfev = 200*(n+1);+ parameters.xtol = tol;++ diag.setConstant(n, 1.);+ useExternalScaling = true;+ return solveNumericalDiff(x);+}++template<typename FunctorType, typename Scalar>+HybridNonLinearSolverSpace::Status+HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffInit(FVectorType &x)+{+ n = x.size();++ if (parameters.nb_of_subdiagonals<0) parameters.nb_of_subdiagonals= n-1;+ if (parameters.nb_of_superdiagonals<0) parameters.nb_of_superdiagonals= n-1;++ wa1.resize(n); wa2.resize(n); wa3.resize(n); wa4.resize(n);+ qtf.resize(n);+ fjac.resize(n, n);+ fvec.resize(n);+ if (!useExternalScaling)+ diag.resize(n);+ eigen_assert( (!useExternalScaling || diag.size()==n) || "When useExternalScaling is set, the caller must provide a valid 'diag'");++ /* Function Body */+ nfev = 0;+ njev = 0;++ /* check the input parameters for errors. */+ if (n <= 0 || parameters.xtol < 0. || parameters.maxfev <= 0 || parameters.nb_of_subdiagonals< 0 || parameters.nb_of_superdiagonals< 0 || parameters.factor <= 0. )+ return HybridNonLinearSolverSpace::ImproperInputParameters;+ if (useExternalScaling)+ for (Index j = 0; j < n; ++j)+ if (diag[j] <= 0.)+ return HybridNonLinearSolverSpace::ImproperInputParameters;++ /* evaluate the function at the starting point */+ /* and calculate its norm. */+ nfev = 1;+ if ( functor(x, fvec) < 0)+ return HybridNonLinearSolverSpace::UserAsked;+ fnorm = fvec.stableNorm();++ /* initialize iteration counter and monitors. */+ iter = 1;+ ncsuc = 0;+ ncfail = 0;+ nslow1 = 0;+ nslow2 = 0;++ return HybridNonLinearSolverSpace::Running;+}++template<typename FunctorType, typename Scalar>+HybridNonLinearSolverSpace::Status+HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiffOneStep(FVectorType &x)+{+ using std::sqrt;+ using std::abs;+ + assert(x.size()==n); // check the caller is not cheating us++ Index j;+ std::vector<JacobiRotation<Scalar> > v_givens(n), w_givens(n);++ jeval = true;+ if (parameters.nb_of_subdiagonals<0) parameters.nb_of_subdiagonals= n-1;+ if (parameters.nb_of_superdiagonals<0) parameters.nb_of_superdiagonals= n-1;++ /* calculate the jacobian matrix. */+ if (internal::fdjac1(functor, x, fvec, fjac, parameters.nb_of_subdiagonals, parameters.nb_of_superdiagonals, parameters.epsfcn) <0)+ return HybridNonLinearSolverSpace::UserAsked;+ nfev += (std::min)(parameters.nb_of_subdiagonals+parameters.nb_of_superdiagonals+ 1, n);++ wa2 = fjac.colwise().blueNorm();++ /* on the first iteration and if external scaling is not used, scale according */+ /* to the norms of the columns of the initial jacobian. */+ if (iter == 1) {+ if (!useExternalScaling)+ for (j = 0; j < n; ++j)+ diag[j] = (wa2[j]==0.) ? 1. : wa2[j];++ /* on the first iteration, calculate the norm of the scaled x */+ /* and initialize the step bound delta. */+ xnorm = diag.cwiseProduct(x).stableNorm();+ delta = parameters.factor * xnorm;+ if (delta == 0.)+ delta = parameters.factor;+ }++ /* compute the qr factorization of the jacobian. */+ HouseholderQR<JacobianType> qrfac(fjac); // no pivoting:++ /* copy the triangular factor of the qr factorization into r. */+ R = qrfac.matrixQR();++ /* accumulate the orthogonal factor in fjac. */+ fjac = qrfac.householderQ();++ /* form (q transpose)*fvec and store in qtf. */+ qtf = fjac.transpose() * fvec;++ /* rescale if necessary. */+ if (!useExternalScaling)+ diag = diag.cwiseMax(wa2);++ while (true) {+ /* determine the direction p. */+ internal::dogleg<Scalar>(R, diag, qtf, delta, wa1);++ /* store the direction p and x + p. calculate the norm of p. */+ wa1 = -wa1;+ wa2 = x + wa1;+ pnorm = diag.cwiseProduct(wa1).stableNorm();++ /* on the first iteration, adjust the initial step bound. */+ if (iter == 1)+ delta = (std::min)(delta,pnorm);++ /* evaluate the function at x + p and calculate its norm. */+ if ( functor(wa2, wa4) < 0)+ return HybridNonLinearSolverSpace::UserAsked;+ ++nfev;+ fnorm1 = wa4.stableNorm();++ /* compute the scaled actual reduction. */+ actred = -1.;+ if (fnorm1 < fnorm) /* Computing 2nd power */+ actred = 1. - numext::abs2(fnorm1 / fnorm);++ /* compute the scaled predicted reduction. */+ wa3 = R.template triangularView<Upper>()*wa1 + qtf;+ temp = wa3.stableNorm();+ prered = 0.;+ if (temp < fnorm) /* Computing 2nd power */+ prered = 1. - numext::abs2(temp / fnorm);++ /* compute the ratio of the actual to the predicted reduction. */+ ratio = 0.;+ if (prered > 0.)+ ratio = actred / prered;++ /* update the step bound. */+ if (ratio < Scalar(.1)) {+ ncsuc = 0;+ ++ncfail;+ delta = Scalar(.5) * delta;+ } else {+ ncfail = 0;+ ++ncsuc;+ if (ratio >= Scalar(.5) || ncsuc > 1)+ delta = (std::max)(delta, pnorm / Scalar(.5));+ if (abs(ratio - 1.) <= Scalar(.1)) {+ delta = pnorm / Scalar(.5);+ }+ }++ /* test for successful iteration. */+ if (ratio >= Scalar(1e-4)) {+ /* successful iteration. update x, fvec, and their norms. */+ x = wa2;+ wa2 = diag.cwiseProduct(x);+ fvec = wa4;+ xnorm = wa2.stableNorm();+ fnorm = fnorm1;+ ++iter;+ }++ /* determine the progress of the iteration. */+ ++nslow1;+ if (actred >= Scalar(.001))+ nslow1 = 0;+ if (jeval)+ ++nslow2;+ if (actred >= Scalar(.1))+ nslow2 = 0;++ /* test for convergence. */+ if (delta <= parameters.xtol * xnorm || fnorm == 0.)+ return HybridNonLinearSolverSpace::RelativeErrorTooSmall;++ /* tests for termination and stringent tolerances. */+ if (nfev >= parameters.maxfev)+ return HybridNonLinearSolverSpace::TooManyFunctionEvaluation;+ if (Scalar(.1) * (std::max)(Scalar(.1) * delta, pnorm) <= NumTraits<Scalar>::epsilon() * xnorm)+ return HybridNonLinearSolverSpace::TolTooSmall;+ if (nslow2 == 5)+ return HybridNonLinearSolverSpace::NotMakingProgressJacobian;+ if (nslow1 == 10)+ return HybridNonLinearSolverSpace::NotMakingProgressIterations;++ /* criterion for recalculating jacobian. */+ if (ncfail == 2)+ break; // leave inner loop and go for the next outer loop iteration++ /* calculate the rank one modification to the jacobian */+ /* and update qtf if necessary. */+ wa1 = diag.cwiseProduct( diag.cwiseProduct(wa1)/pnorm );+ wa2 = fjac.transpose() * wa4;+ if (ratio >= Scalar(1e-4))+ qtf = wa2;+ wa2 = (wa2-wa3)/pnorm;++ /* compute the qr factorization of the updated jacobian. */+ internal::r1updt<Scalar>(R, wa1, v_givens, w_givens, wa2, wa3, &sing);+ internal::r1mpyq<Scalar>(n, n, fjac.data(), v_givens, w_givens);+ internal::r1mpyq<Scalar>(1, n, qtf.data(), v_givens, w_givens);++ jeval = false;+ }+ return HybridNonLinearSolverSpace::Running;+}++template<typename FunctorType, typename Scalar>+HybridNonLinearSolverSpace::Status+HybridNonLinearSolver<FunctorType,Scalar>::solveNumericalDiff(FVectorType &x)+{+ HybridNonLinearSolverSpace::Status status = solveNumericalDiffInit(x);+ if (status==HybridNonLinearSolverSpace::ImproperInputParameters)+ return status;+ while (status==HybridNonLinearSolverSpace::Running)+ status = solveNumericalDiffOneStep(x);+ return status;+}++} // end namespace Eigen++#endif // EIGEN_HYBRIDNONLINEARSOLVER_H++//vim: ai ts=4 sts=4 et sw=4
+ eigen3/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h view
@@ -0,0 +1,650 @@+// -*- coding: utf-8+// vim: set fileencoding=utf-8++// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_LEVENBERGMARQUARDT__H+#define EIGEN_LEVENBERGMARQUARDT__H++namespace Eigen { ++namespace LevenbergMarquardtSpace {+ enum Status {+ NotStarted = -2,+ Running = -1,+ ImproperInputParameters = 0,+ RelativeReductionTooSmall = 1,+ RelativeErrorTooSmall = 2,+ RelativeErrorAndReductionTooSmall = 3,+ CosinusTooSmall = 4,+ TooManyFunctionEvaluation = 5,+ FtolTooSmall = 6,+ XtolTooSmall = 7,+ GtolTooSmall = 8,+ UserAsked = 9+ };+}++++/**+ * \ingroup NonLinearOptimization_Module+ * \brief Performs non linear optimization over a non-linear function,+ * using a variant of the Levenberg Marquardt algorithm.+ *+ * Check wikipedia for more information.+ * http://en.wikipedia.org/wiki/Levenberg%E2%80%93Marquardt_algorithm+ */+template<typename FunctorType, typename Scalar=double>+class LevenbergMarquardt+{+public:+ LevenbergMarquardt(FunctorType &_functor)+ : functor(_functor) { nfev = njev = iter = 0; fnorm = gnorm = 0.; useExternalScaling=false; }++ typedef DenseIndex Index;++ struct Parameters {+ Parameters()+ : factor(Scalar(100.))+ , maxfev(400)+ , ftol(std::sqrt(NumTraits<Scalar>::epsilon()))+ , xtol(std::sqrt(NumTraits<Scalar>::epsilon()))+ , gtol(Scalar(0.))+ , epsfcn(Scalar(0.)) {}+ Scalar factor;+ Index maxfev; // maximum number of function evaluation+ Scalar ftol;+ Scalar xtol;+ Scalar gtol;+ Scalar epsfcn;+ };++ typedef Matrix< Scalar, Dynamic, 1 > FVectorType;+ typedef Matrix< Scalar, Dynamic, Dynamic > JacobianType;++ LevenbergMarquardtSpace::Status lmder1(+ FVectorType &x,+ const Scalar tol = std::sqrt(NumTraits<Scalar>::epsilon())+ );++ LevenbergMarquardtSpace::Status minimize(FVectorType &x);+ LevenbergMarquardtSpace::Status minimizeInit(FVectorType &x);+ LevenbergMarquardtSpace::Status minimizeOneStep(FVectorType &x);++ static LevenbergMarquardtSpace::Status lmdif1(+ FunctorType &functor,+ FVectorType &x,+ Index *nfev,+ const Scalar tol = std::sqrt(NumTraits<Scalar>::epsilon())+ );++ LevenbergMarquardtSpace::Status lmstr1(+ FVectorType &x,+ const Scalar tol = std::sqrt(NumTraits<Scalar>::epsilon())+ );++ LevenbergMarquardtSpace::Status minimizeOptimumStorage(FVectorType &x);+ LevenbergMarquardtSpace::Status minimizeOptimumStorageInit(FVectorType &x);+ LevenbergMarquardtSpace::Status minimizeOptimumStorageOneStep(FVectorType &x);++ void resetParameters(void) { parameters = Parameters(); }++ Parameters parameters;+ FVectorType fvec, qtf, diag;+ JacobianType fjac;+ PermutationMatrix<Dynamic,Dynamic> permutation;+ Index nfev;+ Index njev;+ Index iter;+ Scalar fnorm, gnorm;+ bool useExternalScaling; ++ Scalar lm_param(void) { return par; }+private:+ FunctorType &functor;+ Index n;+ Index m;+ FVectorType wa1, wa2, wa3, wa4;++ Scalar par, sum;+ Scalar temp, temp1, temp2;+ Scalar delta;+ Scalar ratio;+ Scalar pnorm, xnorm, fnorm1, actred, dirder, prered;++ LevenbergMarquardt& operator=(const LevenbergMarquardt&);+};++template<typename FunctorType, typename Scalar>+LevenbergMarquardtSpace::Status+LevenbergMarquardt<FunctorType,Scalar>::lmder1(+ FVectorType &x,+ const Scalar tol+ )+{+ n = x.size();+ m = functor.values();++ /* check the input parameters for errors. */+ if (n <= 0 || m < n || tol < 0.)+ return LevenbergMarquardtSpace::ImproperInputParameters;++ resetParameters();+ parameters.ftol = tol;+ parameters.xtol = tol;+ parameters.maxfev = 100*(n+1);++ return minimize(x);+}+++template<typename FunctorType, typename Scalar>+LevenbergMarquardtSpace::Status+LevenbergMarquardt<FunctorType,Scalar>::minimize(FVectorType &x)+{+ LevenbergMarquardtSpace::Status status = minimizeInit(x);+ if (status==LevenbergMarquardtSpace::ImproperInputParameters)+ return status;+ do {+ status = minimizeOneStep(x);+ } while (status==LevenbergMarquardtSpace::Running);+ return status;+}++template<typename FunctorType, typename Scalar>+LevenbergMarquardtSpace::Status+LevenbergMarquardt<FunctorType,Scalar>::minimizeInit(FVectorType &x)+{+ n = x.size();+ m = functor.values();++ wa1.resize(n); wa2.resize(n); wa3.resize(n);+ wa4.resize(m);+ fvec.resize(m);+ fjac.resize(m, n);+ if (!useExternalScaling)+ diag.resize(n);+ eigen_assert( (!useExternalScaling || diag.size()==n) || "When useExternalScaling is set, the caller must provide a valid 'diag'");+ qtf.resize(n);++ /* Function Body */+ nfev = 0;+ njev = 0;++ /* check the input parameters for errors. */+ if (n <= 0 || m < n || parameters.ftol < 0. || parameters.xtol < 0. || parameters.gtol < 0. || parameters.maxfev <= 0 || parameters.factor <= 0.)+ return LevenbergMarquardtSpace::ImproperInputParameters;++ if (useExternalScaling)+ for (Index j = 0; j < n; ++j)+ if (diag[j] <= 0.)+ return LevenbergMarquardtSpace::ImproperInputParameters;++ /* evaluate the function at the starting point */+ /* and calculate its norm. */+ nfev = 1;+ if ( functor(x, fvec) < 0)+ return LevenbergMarquardtSpace::UserAsked;+ fnorm = fvec.stableNorm();++ /* initialize levenberg-marquardt parameter and iteration counter. */+ par = 0.;+ iter = 1;++ return LevenbergMarquardtSpace::NotStarted;+}++template<typename FunctorType, typename Scalar>+LevenbergMarquardtSpace::Status+LevenbergMarquardt<FunctorType,Scalar>::minimizeOneStep(FVectorType &x)+{+ using std::abs;+ using std::sqrt;+ + eigen_assert(x.size()==n); // check the caller is not cheating us++ /* calculate the jacobian matrix. */+ Index df_ret = functor.df(x, fjac);+ if (df_ret<0)+ return LevenbergMarquardtSpace::UserAsked;+ if (df_ret>0)+ // numerical diff, we evaluated the function df_ret times+ nfev += df_ret;+ else njev++;++ /* compute the qr factorization of the jacobian. */+ wa2 = fjac.colwise().blueNorm();+ ColPivHouseholderQR<JacobianType> qrfac(fjac);+ fjac = qrfac.matrixQR();+ permutation = qrfac.colsPermutation();++ /* on the first iteration and if external scaling is not used, scale according */+ /* to the norms of the columns of the initial jacobian. */+ if (iter == 1) {+ if (!useExternalScaling)+ for (Index j = 0; j < n; ++j)+ diag[j] = (wa2[j]==0.)? 1. : wa2[j];++ /* on the first iteration, calculate the norm of the scaled x */+ /* and initialize the step bound delta. */+ xnorm = diag.cwiseProduct(x).stableNorm();+ delta = parameters.factor * xnorm;+ if (delta == 0.)+ delta = parameters.factor;+ }++ /* form (q transpose)*fvec and store the first n components in */+ /* qtf. */+ wa4 = fvec;+ wa4.applyOnTheLeft(qrfac.householderQ().adjoint());+ qtf = wa4.head(n);++ /* compute the norm of the scaled gradient. */+ gnorm = 0.;+ if (fnorm != 0.)+ for (Index j = 0; j < n; ++j)+ if (wa2[permutation.indices()[j]] != 0.)+ gnorm = (std::max)(gnorm, abs( fjac.col(j).head(j+1).dot(qtf.head(j+1)/fnorm) / wa2[permutation.indices()[j]]));++ /* test for convergence of the gradient norm. */+ if (gnorm <= parameters.gtol)+ return LevenbergMarquardtSpace::CosinusTooSmall;++ /* rescale if necessary. */+ if (!useExternalScaling)+ diag = diag.cwiseMax(wa2);++ do {++ /* determine the levenberg-marquardt parameter. */+ internal::lmpar2<Scalar>(qrfac, diag, qtf, delta, par, wa1);++ /* store the direction p and x + p. calculate the norm of p. */+ wa1 = -wa1;+ wa2 = x + wa1;+ pnorm = diag.cwiseProduct(wa1).stableNorm();++ /* on the first iteration, adjust the initial step bound. */+ if (iter == 1)+ delta = (std::min)(delta,pnorm);++ /* evaluate the function at x + p and calculate its norm. */+ if ( functor(wa2, wa4) < 0)+ return LevenbergMarquardtSpace::UserAsked;+ ++nfev;+ fnorm1 = wa4.stableNorm();++ /* compute the scaled actual reduction. */+ actred = -1.;+ if (Scalar(.1) * fnorm1 < fnorm)+ actred = 1. - numext::abs2(fnorm1 / fnorm);++ /* compute the scaled predicted reduction and */+ /* the scaled directional derivative. */+ wa3 = fjac.template triangularView<Upper>() * (qrfac.colsPermutation().inverse() *wa1);+ temp1 = numext::abs2(wa3.stableNorm() / fnorm);+ temp2 = numext::abs2(sqrt(par) * pnorm / fnorm);+ prered = temp1 + temp2 / Scalar(.5);+ dirder = -(temp1 + temp2);++ /* compute the ratio of the actual to the predicted */+ /* reduction. */+ ratio = 0.;+ if (prered != 0.)+ ratio = actred / prered;++ /* update the step bound. */+ if (ratio <= Scalar(.25)) {+ if (actred >= 0.)+ temp = Scalar(.5);+ if (actred < 0.)+ temp = Scalar(.5) * dirder / (dirder + Scalar(.5) * actred);+ if (Scalar(.1) * fnorm1 >= fnorm || temp < Scalar(.1))+ temp = Scalar(.1);+ /* Computing MIN */+ delta = temp * (std::min)(delta, pnorm / Scalar(.1));+ par /= temp;+ } else if (!(par != 0. && ratio < Scalar(.75))) {+ delta = pnorm / Scalar(.5);+ par = Scalar(.5) * par;+ }++ /* test for successful iteration. */+ if (ratio >= Scalar(1e-4)) {+ /* successful iteration. update x, fvec, and their norms. */+ x = wa2;+ wa2 = diag.cwiseProduct(x);+ fvec = wa4;+ xnorm = wa2.stableNorm();+ fnorm = fnorm1;+ ++iter;+ }++ /* tests for convergence. */+ if (abs(actred) <= parameters.ftol && prered <= parameters.ftol && Scalar(.5) * ratio <= 1. && delta <= parameters.xtol * xnorm)+ return LevenbergMarquardtSpace::RelativeErrorAndReductionTooSmall;+ if (abs(actred) <= parameters.ftol && prered <= parameters.ftol && Scalar(.5) * ratio <= 1.)+ return LevenbergMarquardtSpace::RelativeReductionTooSmall;+ if (delta <= parameters.xtol * xnorm)+ return LevenbergMarquardtSpace::RelativeErrorTooSmall;++ /* tests for termination and stringent tolerances. */+ if (nfev >= parameters.maxfev)+ return LevenbergMarquardtSpace::TooManyFunctionEvaluation;+ if (abs(actred) <= NumTraits<Scalar>::epsilon() && prered <= NumTraits<Scalar>::epsilon() && Scalar(.5) * ratio <= 1.)+ return LevenbergMarquardtSpace::FtolTooSmall;+ if (delta <= NumTraits<Scalar>::epsilon() * xnorm)+ return LevenbergMarquardtSpace::XtolTooSmall;+ if (gnorm <= NumTraits<Scalar>::epsilon())+ return LevenbergMarquardtSpace::GtolTooSmall;++ } while (ratio < Scalar(1e-4));++ return LevenbergMarquardtSpace::Running;+}++template<typename FunctorType, typename Scalar>+LevenbergMarquardtSpace::Status+LevenbergMarquardt<FunctorType,Scalar>::lmstr1(+ FVectorType &x,+ const Scalar tol+ )+{+ n = x.size();+ m = functor.values();++ /* check the input parameters for errors. */+ if (n <= 0 || m < n || tol < 0.)+ return LevenbergMarquardtSpace::ImproperInputParameters;++ resetParameters();+ parameters.ftol = tol;+ parameters.xtol = tol;+ parameters.maxfev = 100*(n+1);++ return minimizeOptimumStorage(x);+}++template<typename FunctorType, typename Scalar>+LevenbergMarquardtSpace::Status+LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageInit(FVectorType &x)+{+ n = x.size();+ m = functor.values();++ wa1.resize(n); wa2.resize(n); wa3.resize(n);+ wa4.resize(m);+ fvec.resize(m);+ // Only R is stored in fjac. Q is only used to compute 'qtf', which is+ // Q.transpose()*rhs. qtf will be updated using givens rotation,+ // instead of storing them in Q.+ // The purpose it to only use a nxn matrix, instead of mxn here, so+ // that we can handle cases where m>>n :+ fjac.resize(n, n);+ if (!useExternalScaling)+ diag.resize(n);+ eigen_assert( (!useExternalScaling || diag.size()==n) || "When useExternalScaling is set, the caller must provide a valid 'diag'");+ qtf.resize(n);++ /* Function Body */+ nfev = 0;+ njev = 0;++ /* check the input parameters for errors. */+ if (n <= 0 || m < n || parameters.ftol < 0. || parameters.xtol < 0. || parameters.gtol < 0. || parameters.maxfev <= 0 || parameters.factor <= 0.)+ return LevenbergMarquardtSpace::ImproperInputParameters;++ if (useExternalScaling)+ for (Index j = 0; j < n; ++j)+ if (diag[j] <= 0.)+ return LevenbergMarquardtSpace::ImproperInputParameters;++ /* evaluate the function at the starting point */+ /* and calculate its norm. */+ nfev = 1;+ if ( functor(x, fvec) < 0)+ return LevenbergMarquardtSpace::UserAsked;+ fnorm = fvec.stableNorm();++ /* initialize levenberg-marquardt parameter and iteration counter. */+ par = 0.;+ iter = 1;++ return LevenbergMarquardtSpace::NotStarted;+}+++template<typename FunctorType, typename Scalar>+LevenbergMarquardtSpace::Status+LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorageOneStep(FVectorType &x)+{+ using std::abs;+ using std::sqrt;+ + eigen_assert(x.size()==n); // check the caller is not cheating us++ Index i, j;+ bool sing;++ /* compute the qr factorization of the jacobian matrix */+ /* calculated one row at a time, while simultaneously */+ /* forming (q transpose)*fvec and storing the first */+ /* n components in qtf. */+ qtf.fill(0.);+ fjac.fill(0.);+ Index rownb = 2;+ for (i = 0; i < m; ++i) {+ if (functor.df(x, wa3, rownb) < 0) return LevenbergMarquardtSpace::UserAsked;+ internal::rwupdt<Scalar>(fjac, wa3, qtf, fvec[i]);+ ++rownb;+ }+ ++njev;++ /* if the jacobian is rank deficient, call qrfac to */+ /* reorder its columns and update the components of qtf. */+ sing = false;+ for (j = 0; j < n; ++j) {+ if (fjac(j,j) == 0.)+ sing = true;+ wa2[j] = fjac.col(j).head(j).stableNorm();+ }+ permutation.setIdentity(n);+ if (sing) {+ wa2 = fjac.colwise().blueNorm();+ // TODO We have no unit test covering this code path, do not modify+ // until it is carefully tested+ ColPivHouseholderQR<JacobianType> qrfac(fjac);+ fjac = qrfac.matrixQR();+ wa1 = fjac.diagonal();+ fjac.diagonal() = qrfac.hCoeffs();+ permutation = qrfac.colsPermutation();+ // TODO : avoid this:+ for(Index ii=0; ii< fjac.cols(); ii++) fjac.col(ii).segment(ii+1, fjac.rows()-ii-1) *= fjac(ii,ii); // rescale vectors++ for (j = 0; j < n; ++j) {+ if (fjac(j,j) != 0.) {+ sum = 0.;+ for (i = j; i < n; ++i)+ sum += fjac(i,j) * qtf[i];+ temp = -sum / fjac(j,j);+ for (i = j; i < n; ++i)+ qtf[i] += fjac(i,j) * temp;+ }+ fjac(j,j) = wa1[j];+ }+ }++ /* on the first iteration and if external scaling is not used, scale according */+ /* to the norms of the columns of the initial jacobian. */+ if (iter == 1) {+ if (!useExternalScaling)+ for (j = 0; j < n; ++j)+ diag[j] = (wa2[j]==0.)? 1. : wa2[j];++ /* on the first iteration, calculate the norm of the scaled x */+ /* and initialize the step bound delta. */+ xnorm = diag.cwiseProduct(x).stableNorm();+ delta = parameters.factor * xnorm;+ if (delta == 0.)+ delta = parameters.factor;+ }++ /* compute the norm of the scaled gradient. */+ gnorm = 0.;+ if (fnorm != 0.)+ for (j = 0; j < n; ++j)+ if (wa2[permutation.indices()[j]] != 0.)+ gnorm = (std::max)(gnorm, abs( fjac.col(j).head(j+1).dot(qtf.head(j+1)/fnorm) / wa2[permutation.indices()[j]]));++ /* test for convergence of the gradient norm. */+ if (gnorm <= parameters.gtol)+ return LevenbergMarquardtSpace::CosinusTooSmall;++ /* rescale if necessary. */+ if (!useExternalScaling)+ diag = diag.cwiseMax(wa2);++ do {++ /* determine the levenberg-marquardt parameter. */+ internal::lmpar<Scalar>(fjac, permutation.indices(), diag, qtf, delta, par, wa1);++ /* store the direction p and x + p. calculate the norm of p. */+ wa1 = -wa1;+ wa2 = x + wa1;+ pnorm = diag.cwiseProduct(wa1).stableNorm();++ /* on the first iteration, adjust the initial step bound. */+ if (iter == 1)+ delta = (std::min)(delta,pnorm);++ /* evaluate the function at x + p and calculate its norm. */+ if ( functor(wa2, wa4) < 0)+ return LevenbergMarquardtSpace::UserAsked;+ ++nfev;+ fnorm1 = wa4.stableNorm();++ /* compute the scaled actual reduction. */+ actred = -1.;+ if (Scalar(.1) * fnorm1 < fnorm)+ actred = 1. - numext::abs2(fnorm1 / fnorm);++ /* compute the scaled predicted reduction and */+ /* the scaled directional derivative. */+ wa3 = fjac.topLeftCorner(n,n).template triangularView<Upper>() * (permutation.inverse() * wa1);+ temp1 = numext::abs2(wa3.stableNorm() / fnorm);+ temp2 = numext::abs2(sqrt(par) * pnorm / fnorm);+ prered = temp1 + temp2 / Scalar(.5);+ dirder = -(temp1 + temp2);++ /* compute the ratio of the actual to the predicted */+ /* reduction. */+ ratio = 0.;+ if (prered != 0.)+ ratio = actred / prered;++ /* update the step bound. */+ if (ratio <= Scalar(.25)) {+ if (actred >= 0.)+ temp = Scalar(.5);+ if (actred < 0.)+ temp = Scalar(.5) * dirder / (dirder + Scalar(.5) * actred);+ if (Scalar(.1) * fnorm1 >= fnorm || temp < Scalar(.1))+ temp = Scalar(.1);+ /* Computing MIN */+ delta = temp * (std::min)(delta, pnorm / Scalar(.1));+ par /= temp;+ } else if (!(par != 0. && ratio < Scalar(.75))) {+ delta = pnorm / Scalar(.5);+ par = Scalar(.5) * par;+ }++ /* test for successful iteration. */+ if (ratio >= Scalar(1e-4)) {+ /* successful iteration. update x, fvec, and their norms. */+ x = wa2;+ wa2 = diag.cwiseProduct(x);+ fvec = wa4;+ xnorm = wa2.stableNorm();+ fnorm = fnorm1;+ ++iter;+ }++ /* tests for convergence. */+ if (abs(actred) <= parameters.ftol && prered <= parameters.ftol && Scalar(.5) * ratio <= 1. && delta <= parameters.xtol * xnorm)+ return LevenbergMarquardtSpace::RelativeErrorAndReductionTooSmall;+ if (abs(actred) <= parameters.ftol && prered <= parameters.ftol && Scalar(.5) * ratio <= 1.)+ return LevenbergMarquardtSpace::RelativeReductionTooSmall;+ if (delta <= parameters.xtol * xnorm)+ return LevenbergMarquardtSpace::RelativeErrorTooSmall;++ /* tests for termination and stringent tolerances. */+ if (nfev >= parameters.maxfev)+ return LevenbergMarquardtSpace::TooManyFunctionEvaluation;+ if (abs(actred) <= NumTraits<Scalar>::epsilon() && prered <= NumTraits<Scalar>::epsilon() && Scalar(.5) * ratio <= 1.)+ return LevenbergMarquardtSpace::FtolTooSmall;+ if (delta <= NumTraits<Scalar>::epsilon() * xnorm)+ return LevenbergMarquardtSpace::XtolTooSmall;+ if (gnorm <= NumTraits<Scalar>::epsilon())+ return LevenbergMarquardtSpace::GtolTooSmall;++ } while (ratio < Scalar(1e-4));++ return LevenbergMarquardtSpace::Running;+}++template<typename FunctorType, typename Scalar>+LevenbergMarquardtSpace::Status+LevenbergMarquardt<FunctorType,Scalar>::minimizeOptimumStorage(FVectorType &x)+{+ LevenbergMarquardtSpace::Status status = minimizeOptimumStorageInit(x);+ if (status==LevenbergMarquardtSpace::ImproperInputParameters)+ return status;+ do {+ status = minimizeOptimumStorageOneStep(x);+ } while (status==LevenbergMarquardtSpace::Running);+ return status;+}++template<typename FunctorType, typename Scalar>+LevenbergMarquardtSpace::Status+LevenbergMarquardt<FunctorType,Scalar>::lmdif1(+ FunctorType &functor,+ FVectorType &x,+ Index *nfev,+ const Scalar tol+ )+{+ Index n = x.size();+ Index m = functor.values();++ /* check the input parameters for errors. */+ if (n <= 0 || m < n || tol < 0.)+ return LevenbergMarquardtSpace::ImproperInputParameters;++ NumericalDiff<FunctorType> numDiff(functor);+ // embedded LevenbergMarquardt+ LevenbergMarquardt<NumericalDiff<FunctorType>, Scalar > lm(numDiff);+ lm.parameters.ftol = tol;+ lm.parameters.xtol = tol;+ lm.parameters.maxfev = 200*(n+1);++ LevenbergMarquardtSpace::Status info = LevenbergMarquardtSpace::Status(lm.minimize(x));+ if (nfev)+ * nfev = lm.nfev;+ return info;+}++} // end namespace Eigen++#endif // EIGEN_LEVENBERGMARQUARDT__H++//vim: ai ts=4 sts=4 et sw=4
+ eigen3/unsupported/Eigen/src/NonLinearOptimization/chkder.h view
@@ -0,0 +1,66 @@+#define chkder_log10e 0.43429448190325182765+#define chkder_factor 100.++namespace Eigen { ++namespace internal {++template<typename Scalar>+void chkder(+ const Matrix< Scalar, Dynamic, 1 > &x,+ const Matrix< Scalar, Dynamic, 1 > &fvec,+ const Matrix< Scalar, Dynamic, Dynamic > &fjac,+ Matrix< Scalar, Dynamic, 1 > &xp,+ const Matrix< Scalar, Dynamic, 1 > &fvecp,+ int mode,+ Matrix< Scalar, Dynamic, 1 > &err+ )+{+ using std::sqrt;+ using std::abs;+ using std::log;+ + typedef DenseIndex Index;++ const Scalar eps = sqrt(NumTraits<Scalar>::epsilon());+ const Scalar epsf = chkder_factor * NumTraits<Scalar>::epsilon();+ const Scalar epslog = chkder_log10e * log(eps);+ Scalar temp;++ const Index m = fvec.size(), n = x.size();++ if (mode != 2) {+ /* mode = 1. */+ xp.resize(n);+ for (Index j = 0; j < n; ++j) {+ temp = eps * abs(x[j]);+ if (temp == 0.)+ temp = eps;+ xp[j] = x[j] + temp;+ }+ }+ else {+ /* mode = 2. */+ err.setZero(m); + for (Index j = 0; j < n; ++j) {+ temp = abs(x[j]);+ if (temp == 0.)+ temp = 1.;+ err += temp * fjac.col(j);+ }+ for (Index i = 0; i < m; ++i) {+ temp = 1.;+ if (fvec[i] != 0. && fvecp[i] != 0. && abs(fvecp[i] - fvec[i]) >= epsf * abs(fvec[i]))+ temp = eps * abs((fvecp[i] - fvec[i]) / eps - err[i]) / (abs(fvec[i]) + abs(fvecp[i]));+ err[i] = 1.;+ if (temp > NumTraits<Scalar>::epsilon() && temp < eps)+ err[i] = (chkder_log10e * log(temp) - epslog) / epslog;+ if (temp >= eps)+ err[i] = 0.;+ }+ }+}++} // end namespace internal++} // end namespace Eigen
+ eigen3/unsupported/Eigen/src/NonLinearOptimization/covar.h view
@@ -0,0 +1,70 @@+namespace Eigen { ++namespace internal {++template <typename Scalar>+void covar(+ Matrix< Scalar, Dynamic, Dynamic > &r,+ const VectorXi &ipvt,+ Scalar tol = std::sqrt(NumTraits<Scalar>::epsilon()) )+{+ using std::abs;+ typedef DenseIndex Index;++ /* Local variables */+ Index i, j, k, l, ii, jj;+ bool sing;+ Scalar temp;++ /* Function Body */+ const Index n = r.cols();+ const Scalar tolr = tol * abs(r(0,0));+ Matrix< Scalar, Dynamic, 1 > wa(n);+ eigen_assert(ipvt.size()==n);++ /* form the inverse of r in the full upper triangle of r. */+ l = -1;+ for (k = 0; k < n; ++k)+ if (abs(r(k,k)) > tolr) {+ r(k,k) = 1. / r(k,k);+ for (j = 0; j <= k-1; ++j) {+ temp = r(k,k) * r(j,k);+ r(j,k) = 0.;+ r.col(k).head(j+1) -= r.col(j).head(j+1) * temp;+ }+ l = k;+ }++ /* form the full upper triangle of the inverse of (r transpose)*r */+ /* in the full upper triangle of r. */+ for (k = 0; k <= l; ++k) {+ for (j = 0; j <= k-1; ++j)+ r.col(j).head(j+1) += r.col(k).head(j+1) * r(j,k);+ r.col(k).head(k+1) *= r(k,k);+ }++ /* form the full lower triangle of the covariance matrix */+ /* in the strict lower triangle of r and in wa. */+ for (j = 0; j < n; ++j) {+ jj = ipvt[j];+ sing = j > l;+ for (i = 0; i <= j; ++i) {+ if (sing)+ r(i,j) = 0.;+ ii = ipvt[i];+ if (ii > jj)+ r(ii,jj) = r(i,j);+ if (ii < jj)+ r(jj,ii) = r(i,j);+ }+ wa[jj] = r(j,j);+ }++ /* symmetrize the covariance matrix in r. */+ r.topLeftCorner(n,n).template triangularView<StrictlyUpper>() = r.topLeftCorner(n,n).transpose();+ r.diagonal() = wa;+}++} // end namespace internal++} // end namespace Eigen
+ eigen3/unsupported/Eigen/src/NonLinearOptimization/dogleg.h view
@@ -0,0 +1,107 @@+namespace Eigen { ++namespace internal {++template <typename Scalar>+void dogleg(+ const Matrix< Scalar, Dynamic, Dynamic > &qrfac,+ const Matrix< Scalar, Dynamic, 1 > &diag,+ const Matrix< Scalar, Dynamic, 1 > &qtb,+ Scalar delta,+ Matrix< Scalar, Dynamic, 1 > &x)+{+ using std::abs;+ using std::sqrt;+ + typedef DenseIndex Index;++ /* Local variables */+ Index i, j;+ Scalar sum, temp, alpha, bnorm;+ Scalar gnorm, qnorm;+ Scalar sgnorm;++ /* Function Body */+ const Scalar epsmch = NumTraits<Scalar>::epsilon();+ const Index n = qrfac.cols();+ eigen_assert(n==qtb.size());+ eigen_assert(n==x.size());+ eigen_assert(n==diag.size());+ Matrix< Scalar, Dynamic, 1 > wa1(n), wa2(n);++ /* first, calculate the gauss-newton direction. */+ for (j = n-1; j >=0; --j) {+ temp = qrfac(j,j);+ if (temp == 0.) {+ temp = epsmch * qrfac.col(j).head(j+1).maxCoeff();+ if (temp == 0.)+ temp = epsmch;+ }+ if (j==n-1)+ x[j] = qtb[j] / temp;+ else+ x[j] = (qtb[j] - qrfac.row(j).tail(n-j-1).dot(x.tail(n-j-1))) / temp;+ }++ /* test whether the gauss-newton direction is acceptable. */+ qnorm = diag.cwiseProduct(x).stableNorm();+ if (qnorm <= delta)+ return;++ // TODO : this path is not tested by Eigen unit tests++ /* the gauss-newton direction is not acceptable. */+ /* next, calculate the scaled gradient direction. */++ wa1.fill(0.);+ for (j = 0; j < n; ++j) {+ wa1.tail(n-j) += qrfac.row(j).tail(n-j) * qtb[j];+ wa1[j] /= diag[j];+ }++ /* calculate the norm of the scaled gradient and test for */+ /* the special case in which the scaled gradient is zero. */+ gnorm = wa1.stableNorm();+ sgnorm = 0.;+ alpha = delta / qnorm;+ if (gnorm == 0.)+ goto algo_end;++ /* calculate the point along the scaled gradient */+ /* at which the quadratic is minimized. */+ wa1.array() /= (diag*gnorm).array();+ // TODO : once unit tests cover this part,:+ // wa2 = qrfac.template triangularView<Upper>() * wa1;+ for (j = 0; j < n; ++j) {+ sum = 0.;+ for (i = j; i < n; ++i) {+ sum += qrfac(j,i) * wa1[i];+ }+ wa2[j] = sum;+ }+ temp = wa2.stableNorm();+ sgnorm = gnorm / temp / temp;++ /* test whether the scaled gradient direction is acceptable. */+ alpha = 0.;+ if (sgnorm >= delta)+ goto algo_end;++ /* the scaled gradient direction is not acceptable. */+ /* finally, calculate the point along the dogleg */+ /* at which the quadratic is minimized. */+ bnorm = qtb.stableNorm();+ temp = bnorm / gnorm * (bnorm / qnorm) * (sgnorm / delta);+ temp = temp - delta / qnorm * numext::abs2(sgnorm / delta) + sqrt(numext::abs2(temp - delta / qnorm) + (1.-numext::abs2(delta / qnorm)) * (1.-numext::abs2(sgnorm / delta)));+ alpha = delta / qnorm * (1. - numext::abs2(sgnorm / delta)) / temp;+algo_end:++ /* form appropriate convex combination of the gauss-newton */+ /* direction and the scaled gradient direction. */+ temp = (1.-alpha) * (std::min)(sgnorm,delta);+ x = temp * wa1 + alpha * x;+}++} // end namespace internal++} // end namespace Eigen
+ eigen3/unsupported/Eigen/src/NonLinearOptimization/fdjac1.h view
@@ -0,0 +1,79 @@+namespace Eigen { ++namespace internal {++template<typename FunctorType, typename Scalar>+DenseIndex fdjac1(+ const FunctorType &Functor,+ Matrix< Scalar, Dynamic, 1 > &x,+ Matrix< Scalar, Dynamic, 1 > &fvec,+ Matrix< Scalar, Dynamic, Dynamic > &fjac,+ DenseIndex ml, DenseIndex mu,+ Scalar epsfcn)+{+ using std::sqrt;+ using std::abs;+ + typedef DenseIndex Index;++ /* Local variables */+ Scalar h;+ Index j, k;+ Scalar eps, temp;+ Index msum;+ int iflag;+ Index start, length;++ /* Function Body */+ const Scalar epsmch = NumTraits<Scalar>::epsilon();+ const Index n = x.size();+ eigen_assert(fvec.size()==n);+ Matrix< Scalar, Dynamic, 1 > wa1(n);+ Matrix< Scalar, Dynamic, 1 > wa2(n);++ eps = sqrt((std::max)(epsfcn,epsmch));+ msum = ml + mu + 1;+ if (msum >= n) {+ /* computation of dense approximate jacobian. */+ for (j = 0; j < n; ++j) {+ temp = x[j];+ h = eps * abs(temp);+ if (h == 0.)+ h = eps;+ x[j] = temp + h;+ iflag = Functor(x, wa1);+ if (iflag < 0)+ return iflag;+ x[j] = temp;+ fjac.col(j) = (wa1-fvec)/h;+ }++ }else {+ /* computation of banded approximate jacobian. */+ for (k = 0; k < msum; ++k) {+ for (j = k; (msum<0) ? (j>n): (j<n); j += msum) {+ wa2[j] = x[j];+ h = eps * abs(wa2[j]);+ if (h == 0.) h = eps;+ x[j] = wa2[j] + h;+ }+ iflag = Functor(x, wa1);+ if (iflag < 0)+ return iflag;+ for (j = k; (msum<0) ? (j>n): (j<n); j += msum) {+ x[j] = wa2[j];+ h = eps * abs(wa2[j]);+ if (h == 0.) h = eps;+ fjac.col(j).setZero();+ start = std::max<Index>(0,j-mu);+ length = (std::min)(n-1, j+ml) - start + 1;+ fjac.col(j).segment(start, length) = ( wa1.segment(start, length)-fvec.segment(start, length))/h;+ }+ }+ }+ return 0;+}++} // end namespace internal++} // end namespace Eigen
+ eigen3/unsupported/Eigen/src/NonLinearOptimization/lmpar.h view
@@ -0,0 +1,298 @@+namespace Eigen { ++namespace internal {++template <typename Scalar>+void lmpar(+ Matrix< Scalar, Dynamic, Dynamic > &r,+ const VectorXi &ipvt,+ const Matrix< Scalar, Dynamic, 1 > &diag,+ const Matrix< Scalar, Dynamic, 1 > &qtb,+ Scalar delta,+ Scalar &par,+ Matrix< Scalar, Dynamic, 1 > &x)+{+ using std::abs;+ using std::sqrt;+ typedef DenseIndex Index;++ /* Local variables */+ Index i, j, l;+ Scalar fp;+ Scalar parc, parl;+ Index iter;+ Scalar temp, paru;+ Scalar gnorm;+ Scalar dxnorm;+++ /* Function Body */+ const Scalar dwarf = (std::numeric_limits<Scalar>::min)();+ const Index n = r.cols();+ eigen_assert(n==diag.size());+ eigen_assert(n==qtb.size());+ eigen_assert(n==x.size());++ Matrix< Scalar, Dynamic, 1 > wa1, wa2;++ /* compute and store in x the gauss-newton direction. if the */+ /* jacobian is rank-deficient, obtain a least squares solution. */+ Index nsing = n-1;+ wa1 = qtb;+ for (j = 0; j < n; ++j) {+ if (r(j,j) == 0. && nsing == n-1)+ nsing = j - 1;+ if (nsing < n-1)+ wa1[j] = 0.;+ }+ for (j = nsing; j>=0; --j) {+ wa1[j] /= r(j,j);+ temp = wa1[j];+ for (i = 0; i < j ; ++i)+ wa1[i] -= r(i,j) * temp;+ }++ for (j = 0; j < n; ++j)+ x[ipvt[j]] = wa1[j];++ /* initialize the iteration counter. */+ /* evaluate the function at the origin, and test */+ /* for acceptance of the gauss-newton direction. */+ iter = 0;+ wa2 = diag.cwiseProduct(x);+ dxnorm = wa2.blueNorm();+ fp = dxnorm - delta;+ if (fp <= Scalar(0.1) * delta) {+ par = 0;+ return;+ }++ /* if the jacobian is not rank deficient, the newton */+ /* step provides a lower bound, parl, for the zero of */+ /* the function. otherwise set this bound to zero. */+ parl = 0.;+ if (nsing >= n-1) {+ for (j = 0; j < n; ++j) {+ l = ipvt[j];+ wa1[j] = diag[l] * (wa2[l] / dxnorm);+ }+ // it's actually a triangularView.solveInplace(), though in a weird+ // way:+ for (j = 0; j < n; ++j) {+ Scalar sum = 0.;+ for (i = 0; i < j; ++i)+ sum += r(i,j) * wa1[i];+ wa1[j] = (wa1[j] - sum) / r(j,j);+ }+ temp = wa1.blueNorm();+ parl = fp / delta / temp / temp;+ }++ /* calculate an upper bound, paru, for the zero of the function. */+ for (j = 0; j < n; ++j)+ wa1[j] = r.col(j).head(j+1).dot(qtb.head(j+1)) / diag[ipvt[j]];++ gnorm = wa1.stableNorm();+ paru = gnorm / delta;+ if (paru == 0.)+ paru = dwarf / (std::min)(delta,Scalar(0.1));++ /* if the input par lies outside of the interval (parl,paru), */+ /* set par to the closer endpoint. */+ par = (std::max)(par,parl);+ par = (std::min)(par,paru);+ if (par == 0.)+ par = gnorm / dxnorm;++ /* beginning of an iteration. */+ while (true) {+ ++iter;++ /* evaluate the function at the current value of par. */+ if (par == 0.)+ par = (std::max)(dwarf,Scalar(.001) * paru); /* Computing MAX */+ wa1 = sqrt(par)* diag;++ Matrix< Scalar, Dynamic, 1 > sdiag(n);+ qrsolv<Scalar>(r, ipvt, wa1, qtb, x, sdiag);++ wa2 = diag.cwiseProduct(x);+ dxnorm = wa2.blueNorm();+ temp = fp;+ fp = dxnorm - delta;++ /* if the function is small enough, accept the current value */+ /* of par. also test for the exceptional cases where parl */+ /* is zero or the number of iterations has reached 10. */+ if (abs(fp) <= Scalar(0.1) * delta || (parl == 0. && fp <= temp && temp < 0.) || iter == 10)+ break;++ /* compute the newton correction. */+ for (j = 0; j < n; ++j) {+ l = ipvt[j];+ wa1[j] = diag[l] * (wa2[l] / dxnorm);+ }+ for (j = 0; j < n; ++j) {+ wa1[j] /= sdiag[j];+ temp = wa1[j];+ for (i = j+1; i < n; ++i)+ wa1[i] -= r(i,j) * temp;+ }+ temp = wa1.blueNorm();+ parc = fp / delta / temp / temp;++ /* depending on the sign of the function, update parl or paru. */+ if (fp > 0.)+ parl = (std::max)(parl,par);+ if (fp < 0.)+ paru = (std::min)(paru,par);++ /* compute an improved estimate for par. */+ /* Computing MAX */+ par = (std::max)(parl,par+parc);++ /* end of an iteration. */+ }++ /* termination. */+ if (iter == 0)+ par = 0.;+ return;+}++template <typename Scalar>+void lmpar2(+ const ColPivHouseholderQR<Matrix< Scalar, Dynamic, Dynamic> > &qr,+ const Matrix< Scalar, Dynamic, 1 > &diag,+ const Matrix< Scalar, Dynamic, 1 > &qtb,+ Scalar delta,+ Scalar &par,+ Matrix< Scalar, Dynamic, 1 > &x)++{+ using std::sqrt;+ using std::abs;+ typedef DenseIndex Index;++ /* Local variables */+ Index j;+ Scalar fp;+ Scalar parc, parl;+ Index iter;+ Scalar temp, paru;+ Scalar gnorm;+ Scalar dxnorm;+++ /* Function Body */+ const Scalar dwarf = (std::numeric_limits<Scalar>::min)();+ const Index n = qr.matrixQR().cols();+ eigen_assert(n==diag.size());+ eigen_assert(n==qtb.size());++ Matrix< Scalar, Dynamic, 1 > wa1, wa2;++ /* compute and store in x the gauss-newton direction. if the */+ /* jacobian is rank-deficient, obtain a least squares solution. */++// const Index rank = qr.nonzeroPivots(); // exactly double(0.)+ const Index rank = qr.rank(); // use a threshold+ wa1 = qtb;+ wa1.tail(n-rank).setZero();+ qr.matrixQR().topLeftCorner(rank, rank).template triangularView<Upper>().solveInPlace(wa1.head(rank));++ x = qr.colsPermutation()*wa1;++ /* initialize the iteration counter. */+ /* evaluate the function at the origin, and test */+ /* for acceptance of the gauss-newton direction. */+ iter = 0;+ wa2 = diag.cwiseProduct(x);+ dxnorm = wa2.blueNorm();+ fp = dxnorm - delta;+ if (fp <= Scalar(0.1) * delta) {+ par = 0;+ return;+ }++ /* if the jacobian is not rank deficient, the newton */+ /* step provides a lower bound, parl, for the zero of */+ /* the function. otherwise set this bound to zero. */+ parl = 0.;+ if (rank==n) {+ wa1 = qr.colsPermutation().inverse() * diag.cwiseProduct(wa2)/dxnorm;+ qr.matrixQR().topLeftCorner(n, n).transpose().template triangularView<Lower>().solveInPlace(wa1);+ temp = wa1.blueNorm();+ parl = fp / delta / temp / temp;+ }++ /* calculate an upper bound, paru, for the zero of the function. */+ for (j = 0; j < n; ++j)+ wa1[j] = qr.matrixQR().col(j).head(j+1).dot(qtb.head(j+1)) / diag[qr.colsPermutation().indices()(j)];++ gnorm = wa1.stableNorm();+ paru = gnorm / delta;+ if (paru == 0.)+ paru = dwarf / (std::min)(delta,Scalar(0.1));++ /* if the input par lies outside of the interval (parl,paru), */+ /* set par to the closer endpoint. */+ par = (std::max)(par,parl);+ par = (std::min)(par,paru);+ if (par == 0.)+ par = gnorm / dxnorm;++ /* beginning of an iteration. */+ Matrix< Scalar, Dynamic, Dynamic > s = qr.matrixQR();+ while (true) {+ ++iter;++ /* evaluate the function at the current value of par. */+ if (par == 0.)+ par = (std::max)(dwarf,Scalar(.001) * paru); /* Computing MAX */+ wa1 = sqrt(par)* diag;++ Matrix< Scalar, Dynamic, 1 > sdiag(n);+ qrsolv<Scalar>(s, qr.colsPermutation().indices(), wa1, qtb, x, sdiag);++ wa2 = diag.cwiseProduct(x);+ dxnorm = wa2.blueNorm();+ temp = fp;+ fp = dxnorm - delta;++ /* if the function is small enough, accept the current value */+ /* of par. also test for the exceptional cases where parl */+ /* is zero or the number of iterations has reached 10. */+ if (abs(fp) <= Scalar(0.1) * delta || (parl == 0. && fp <= temp && temp < 0.) || iter == 10)+ break;++ /* compute the newton correction. */+ wa1 = qr.colsPermutation().inverse() * diag.cwiseProduct(wa2/dxnorm);+ // we could almost use this here, but the diagonal is outside qr, in sdiag[]+ // qr.matrixQR().topLeftCorner(n, n).transpose().template triangularView<Lower>().solveInPlace(wa1);+ for (j = 0; j < n; ++j) {+ wa1[j] /= sdiag[j];+ temp = wa1[j];+ for (Index i = j+1; i < n; ++i)+ wa1[i] -= s(i,j) * temp;+ }+ temp = wa1.blueNorm();+ parc = fp / delta / temp / temp;++ /* depending on the sign of the function, update parl or paru. */+ if (fp > 0.)+ parl = (std::max)(parl,par);+ if (fp < 0.)+ paru = (std::min)(paru,par);++ /* compute an improved estimate for par. */+ par = (std::max)(parl,par+parc);+ }+ if (iter == 0)+ par = 0.;+ return;+}++} // end namespace internal++} // end namespace Eigen
+ eigen3/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h view
@@ -0,0 +1,91 @@+namespace Eigen { ++namespace internal {++// TODO : once qrsolv2 is removed, use ColPivHouseholderQR or PermutationMatrix instead of ipvt+template <typename Scalar>+void qrsolv(+ Matrix< Scalar, Dynamic, Dynamic > &s,+ // TODO : use a PermutationMatrix once lmpar is no more:+ const VectorXi &ipvt,+ const Matrix< Scalar, Dynamic, 1 > &diag,+ const Matrix< Scalar, Dynamic, 1 > &qtb,+ Matrix< Scalar, Dynamic, 1 > &x,+ Matrix< Scalar, Dynamic, 1 > &sdiag)++{+ typedef DenseIndex Index;++ /* Local variables */+ Index i, j, k, l;+ Scalar temp;+ Index n = s.cols();+ Matrix< Scalar, Dynamic, 1 > wa(n);+ JacobiRotation<Scalar> givens;++ /* Function Body */+ // the following will only change the lower triangular part of s, including+ // the diagonal, though the diagonal is restored afterward++ /* copy r and (q transpose)*b to preserve input and initialize s. */+ /* in particular, save the diagonal elements of r in x. */+ x = s.diagonal();+ wa = qtb;++ s.topLeftCorner(n,n).template triangularView<StrictlyLower>() = s.topLeftCorner(n,n).transpose();++ /* eliminate the diagonal matrix d using a givens rotation. */+ for (j = 0; j < n; ++j) {++ /* prepare the row of d to be eliminated, locating the */+ /* diagonal element using p from the qr factorization. */+ l = ipvt[j];+ if (diag[l] == 0.)+ break;+ sdiag.tail(n-j).setZero();+ sdiag[j] = diag[l];++ /* the transformations to eliminate the row of d */+ /* modify only a single element of (q transpose)*b */+ /* beyond the first n, which is initially zero. */+ Scalar qtbpj = 0.;+ for (k = j; k < n; ++k) {+ /* determine a givens rotation which eliminates the */+ /* appropriate element in the current row of d. */+ givens.makeGivens(-s(k,k), sdiag[k]);++ /* compute the modified diagonal element of r and */+ /* the modified element of ((q transpose)*b,0). */+ s(k,k) = givens.c() * s(k,k) + givens.s() * sdiag[k];+ temp = givens.c() * wa[k] + givens.s() * qtbpj;+ qtbpj = -givens.s() * wa[k] + givens.c() * qtbpj;+ wa[k] = temp;++ /* accumulate the tranformation in the row of s. */+ for (i = k+1; i<n; ++i) {+ temp = givens.c() * s(i,k) + givens.s() * sdiag[i];+ sdiag[i] = -givens.s() * s(i,k) + givens.c() * sdiag[i];+ s(i,k) = temp;+ }+ }+ }++ /* solve the triangular system for z. if the system is */+ /* singular, then obtain a least squares solution. */+ Index nsing;+ for(nsing=0; nsing<n && sdiag[nsing]!=0; nsing++) {}++ wa.tail(n-nsing).setZero();+ s.topLeftCorner(nsing, nsing).transpose().template triangularView<Upper>().solveInPlace(wa.head(nsing));++ // restore+ sdiag = s.diagonal();+ s.diagonal() = x;++ /* permute the components of z back to components of x. */+ for (j = 0; j < n; ++j) x[ipvt[j]] = wa[j];+}++} // end namespace internal++} // end namespace Eigen
+ eigen3/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h view
@@ -0,0 +1,30 @@+namespace Eigen { ++namespace internal {++// TODO : move this to GivensQR once there's such a thing in Eigen++template <typename Scalar>+void r1mpyq(DenseIndex m, DenseIndex n, Scalar *a, const std::vector<JacobiRotation<Scalar> > &v_givens, const std::vector<JacobiRotation<Scalar> > &w_givens)+{+ typedef DenseIndex Index;++ /* apply the first set of givens rotations to a. */+ for (Index j = n-2; j>=0; --j)+ for (Index i = 0; i<m; ++i) {+ Scalar temp = v_givens[j].c() * a[i+m*j] - v_givens[j].s() * a[i+m*(n-1)];+ a[i+m*(n-1)] = v_givens[j].s() * a[i+m*j] + v_givens[j].c() * a[i+m*(n-1)];+ a[i+m*j] = temp;+ }+ /* apply the second set of givens rotations to a. */+ for (Index j = 0; j<n-1; ++j)+ for (Index i = 0; i<m; ++i) {+ Scalar temp = w_givens[j].c() * a[i+m*j] + w_givens[j].s() * a[i+m*(n-1)];+ a[i+m*(n-1)] = -w_givens[j].s() * a[i+m*j] + w_givens[j].c() * a[i+m*(n-1)];+ a[i+m*j] = temp;+ }+}++} // end namespace internal++} // end namespace Eigen
+ eigen3/unsupported/Eigen/src/NonLinearOptimization/r1updt.h view
@@ -0,0 +1,99 @@+namespace Eigen { ++namespace internal {++template <typename Scalar>+void r1updt(+ Matrix< Scalar, Dynamic, Dynamic > &s,+ const Matrix< Scalar, Dynamic, 1> &u,+ std::vector<JacobiRotation<Scalar> > &v_givens,+ std::vector<JacobiRotation<Scalar> > &w_givens,+ Matrix< Scalar, Dynamic, 1> &v,+ Matrix< Scalar, Dynamic, 1> &w,+ bool *sing)+{+ typedef DenseIndex Index;+ const JacobiRotation<Scalar> IdentityRotation = JacobiRotation<Scalar>(1,0);++ /* Local variables */+ const Index m = s.rows();+ const Index n = s.cols();+ Index i, j=1;+ Scalar temp;+ JacobiRotation<Scalar> givens;++ // r1updt had a broader usecase, but we dont use it here. And, more+ // importantly, we can not test it.+ eigen_assert(m==n);+ eigen_assert(u.size()==m);+ eigen_assert(v.size()==n);+ eigen_assert(w.size()==n);++ /* move the nontrivial part of the last column of s into w. */+ w[n-1] = s(n-1,n-1);++ /* rotate the vector v into a multiple of the n-th unit vector */+ /* in such a way that a spike is introduced into w. */+ for (j=n-2; j>=0; --j) {+ w[j] = 0.;+ if (v[j] != 0.) {+ /* determine a givens rotation which eliminates the */+ /* j-th element of v. */+ givens.makeGivens(-v[n-1], v[j]);++ /* apply the transformation to v and store the information */+ /* necessary to recover the givens rotation. */+ v[n-1] = givens.s() * v[j] + givens.c() * v[n-1];+ v_givens[j] = givens;++ /* apply the transformation to s and extend the spike in w. */+ for (i = j; i < m; ++i) {+ temp = givens.c() * s(j,i) - givens.s() * w[i];+ w[i] = givens.s() * s(j,i) + givens.c() * w[i];+ s(j,i) = temp;+ }+ } else+ v_givens[j] = IdentityRotation;+ }++ /* add the spike from the rank 1 update to w. */+ w += v[n-1] * u;++ /* eliminate the spike. */+ *sing = false;+ for (j = 0; j < n-1; ++j) {+ if (w[j] != 0.) {+ /* determine a givens rotation which eliminates the */+ /* j-th element of the spike. */+ givens.makeGivens(-s(j,j), w[j]);++ /* apply the transformation to s and reduce the spike in w. */+ for (i = j; i < m; ++i) {+ temp = givens.c() * s(j,i) + givens.s() * w[i];+ w[i] = -givens.s() * s(j,i) + givens.c() * w[i];+ s(j,i) = temp;+ }++ /* store the information necessary to recover the */+ /* givens rotation. */+ w_givens[j] = givens;+ } else+ v_givens[j] = IdentityRotation;++ /* test for zero diagonal elements in the output s. */+ if (s(j,j) == 0.) {+ *sing = true;+ }+ }+ /* move w back into the last column of the output s. */+ s(n-1,n-1) = w[n-1];++ if (s(j,j) == 0.) {+ *sing = true;+ }+ return;+}++} // end namespace internal++} // end namespace Eigen
+ eigen3/unsupported/Eigen/src/NonLinearOptimization/rwupdt.h view
@@ -0,0 +1,49 @@+namespace Eigen { ++namespace internal {++template <typename Scalar>+void rwupdt(+ Matrix< Scalar, Dynamic, Dynamic > &r,+ const Matrix< Scalar, Dynamic, 1> &w,+ Matrix< Scalar, Dynamic, 1> &b,+ Scalar alpha)+{+ typedef DenseIndex Index;++ const Index n = r.cols();+ eigen_assert(r.rows()>=n);+ std::vector<JacobiRotation<Scalar> > givens(n);++ /* Local variables */+ Scalar temp, rowj;++ /* Function Body */+ for (Index j = 0; j < n; ++j) {+ rowj = w[j];++ /* apply the previous transformations to */+ /* r(i,j), i=0,1,...,j-1, and to w(j). */+ for (Index i = 0; i < j; ++i) {+ temp = givens[i].c() * r(i,j) + givens[i].s() * rowj;+ rowj = -givens[i].s() * r(i,j) + givens[i].c() * rowj;+ r(i,j) = temp;+ }++ /* determine a givens rotation which eliminates w(j). */+ givens[j].makeGivens(-r(j,j), rowj);++ if (rowj == 0.)+ continue; // givens[j] is identity++ /* apply the current transformation to r(j,j), b(j), and alpha. */+ r(j,j) = givens[j].c() * r(j,j) + givens[j].s() * rowj;+ temp = givens[j].c() * b[j] + givens[j].s() * alpha;+ alpha = -givens[j].s() * b[j] + givens[j].c() * alpha;+ b[j] = temp;+ }+}++} // end namespace internal++} // end namespace Eigen
+ eigen3/unsupported/Eigen/src/NumericalDiff/CMakeLists.txt view
@@ -0,0 +1,6 @@+FILE(GLOB Eigen_NumericalDiff_SRCS "*.h")++INSTALL(FILES+ ${Eigen_NumericalDiff_SRCS}+ DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/NumericalDiff COMPONENT Devel+ )
+ eigen3/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h view
@@ -0,0 +1,130 @@+// -*- coding: utf-8+// vim: set fileencoding=utf-8++// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_NUMERICAL_DIFF_H+#define EIGEN_NUMERICAL_DIFF_H++namespace Eigen { ++enum NumericalDiffMode {+ Forward,+ Central+};+++/**+ * This class allows you to add a method df() to your functor, which will + * use numerical differentiation to compute an approximate of the+ * derivative for the functor. Of course, if you have an analytical form+ * for the derivative, you should rather implement df() by yourself.+ *+ * More information on+ * http://en.wikipedia.org/wiki/Numerical_differentiation+ *+ * Currently only "Forward" and "Central" scheme are implemented.+ */+template<typename _Functor, NumericalDiffMode mode=Forward>+class NumericalDiff : public _Functor+{+public:+ typedef _Functor Functor;+ typedef typename Functor::Scalar Scalar;+ typedef typename Functor::InputType InputType;+ typedef typename Functor::ValueType ValueType;+ typedef typename Functor::JacobianType JacobianType;++ NumericalDiff(Scalar _epsfcn=0.) : Functor(), epsfcn(_epsfcn) {}+ NumericalDiff(const Functor& f, Scalar _epsfcn=0.) : Functor(f), epsfcn(_epsfcn) {}++ // forward constructors+ template<typename T0>+ NumericalDiff(const T0& a0) : Functor(a0), epsfcn(0) {}+ template<typename T0, typename T1>+ NumericalDiff(const T0& a0, const T1& a1) : Functor(a0, a1), epsfcn(0) {}+ template<typename T0, typename T1, typename T2>+ NumericalDiff(const T0& a0, const T1& a1, const T2& a2) : Functor(a0, a1, a2), epsfcn(0) {}++ enum {+ InputsAtCompileTime = Functor::InputsAtCompileTime,+ ValuesAtCompileTime = Functor::ValuesAtCompileTime+ };++ /**+ * return the number of evaluation of functor+ */+ int df(const InputType& _x, JacobianType &jac) const+ {+ using std::sqrt;+ using std::abs;+ /* Local variables */+ Scalar h;+ int nfev=0;+ const typename InputType::Index n = _x.size();+ const Scalar eps = sqrt(((std::max)(epsfcn,NumTraits<Scalar>::epsilon() )));+ ValueType val1, val2;+ InputType x = _x;+ // TODO : we should do this only if the size is not already known+ val1.resize(Functor::values());+ val2.resize(Functor::values());++ // initialization+ switch(mode) {+ case Forward:+ // compute f(x)+ Functor::operator()(x, val1); nfev++;+ break;+ case Central:+ // do nothing+ break;+ default:+ eigen_assert(false);+ };++ // Function Body+ for (int j = 0; j < n; ++j) {+ h = eps * abs(x[j]);+ if (h == 0.) {+ h = eps;+ }+ switch(mode) {+ case Forward:+ x[j] += h;+ Functor::operator()(x, val2);+ nfev++;+ x[j] = _x[j];+ jac.col(j) = (val2-val1)/h;+ break;+ case Central:+ x[j] += h;+ Functor::operator()(x, val2); nfev++;+ x[j] -= 2*h;+ Functor::operator()(x, val1); nfev++;+ x[j] = _x[j];+ jac.col(j) = (val2-val1)/(2*h);+ break;+ default:+ eigen_assert(false);+ };+ }+ return nfev;+ }+private:+ Scalar epsfcn;++ NumericalDiff& operator=(const NumericalDiff&);+};++} // end namespace Eigen++//vim: ai ts=4 sts=4 et sw=4+#endif // EIGEN_NUMERICAL_DIFF_H+
+ eigen3/unsupported/Eigen/src/Polynomials/CMakeLists.txt view
@@ -0,0 +1,6 @@+FILE(GLOB Eigen_Polynomials_SRCS "*.h")++INSTALL(FILES+ ${Eigen_Polynomials_SRCS}+ DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/Polynomials COMPONENT Devel+ )
+ eigen3/unsupported/Eigen/src/Polynomials/Companion.h view
@@ -0,0 +1,276 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010 Manuel Yguel <manuel.yguel@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_COMPANION_H+#define EIGEN_COMPANION_H++// This file requires the user to include+// * Eigen/Core+// * Eigen/src/PolynomialSolver.h++namespace Eigen { ++namespace internal {++#ifndef EIGEN_PARSED_BY_DOXYGEN++template <typename T>+T radix(){ return 2; }++template <typename T>+T radix2(){ return radix<T>()*radix<T>(); }++template<int Size>+struct decrement_if_fixed_size+{+ enum {+ ret = (Size == Dynamic) ? Dynamic : Size-1 };+};++#endif++template< typename _Scalar, int _Deg >+class companion+{+ public:+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Deg==Dynamic ? Dynamic : _Deg)++ enum {+ Deg = _Deg,+ Deg_1=decrement_if_fixed_size<Deg>::ret+ };++ typedef _Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef Matrix<Scalar, Deg, 1> RightColumn;+ //typedef DiagonalMatrix< Scalar, Deg_1, Deg_1 > BottomLeftDiagonal;+ typedef Matrix<Scalar, Deg_1, 1> BottomLeftDiagonal;++ typedef Matrix<Scalar, Deg, Deg> DenseCompanionMatrixType;+ typedef Matrix< Scalar, _Deg, Deg_1 > LeftBlock;+ typedef Matrix< Scalar, Deg_1, Deg_1 > BottomLeftBlock;+ typedef Matrix< Scalar, 1, Deg_1 > LeftBlockFirstRow;++ typedef DenseIndex Index;++ public:+ EIGEN_STRONG_INLINE const _Scalar operator()(Index row, Index col ) const+ {+ if( m_bl_diag.rows() > col )+ {+ if( 0 < row ){ return m_bl_diag[col]; }+ else{ return 0; }+ }+ else{ return m_monic[row]; }+ }++ public:+ template<typename VectorType>+ void setPolynomial( const VectorType& poly )+ {+ const Index deg = poly.size()-1;+ m_monic = -1/poly[deg] * poly.head(deg);+ //m_bl_diag.setIdentity( deg-1 );+ m_bl_diag.setOnes(deg-1);+ }++ template<typename VectorType>+ companion( const VectorType& poly ){+ setPolynomial( poly ); }++ public:+ DenseCompanionMatrixType denseMatrix() const+ {+ const Index deg = m_monic.size();+ const Index deg_1 = deg-1;+ DenseCompanionMatrixType companion(deg,deg);+ companion <<+ ( LeftBlock(deg,deg_1)+ << LeftBlockFirstRow::Zero(1,deg_1),+ BottomLeftBlock::Identity(deg-1,deg-1)*m_bl_diag.asDiagonal() ).finished()+ , m_monic;+ return companion;+ }++++ protected:+ /** Helper function for the balancing algorithm.+ * \returns true if the row and the column, having colNorm and rowNorm+ * as norms, are balanced, false otherwise.+ * colB and rowB are repectively the multipliers for+ * the column and the row in order to balance them.+ * */+ bool balanced( Scalar colNorm, Scalar rowNorm,+ bool& isBalanced, Scalar& colB, Scalar& rowB );++ /** Helper function for the balancing algorithm.+ * \returns true if the row and the column, having colNorm and rowNorm+ * as norms, are balanced, false otherwise.+ * colB and rowB are repectively the multipliers for+ * the column and the row in order to balance them.+ * */+ bool balancedR( Scalar colNorm, Scalar rowNorm,+ bool& isBalanced, Scalar& colB, Scalar& rowB );++ public:+ /**+ * Balancing algorithm from B. N. PARLETT and C. REINSCH (1969)+ * "Balancing a matrix for calculation of eigenvalues and eigenvectors"+ * adapted to the case of companion matrices.+ * A matrix with non zero row and non zero column is balanced+ * for a certain norm if the i-th row and the i-th column+ * have same norm for all i.+ */+ void balance();++ protected:+ RightColumn m_monic;+ BottomLeftDiagonal m_bl_diag;+};++++template< typename _Scalar, int _Deg >+inline+bool companion<_Scalar,_Deg>::balanced( Scalar colNorm, Scalar rowNorm,+ bool& isBalanced, Scalar& colB, Scalar& rowB )+{+ if( Scalar(0) == colNorm || Scalar(0) == rowNorm ){ return true; }+ else+ {+ //To find the balancing coefficients, if the radix is 2,+ //one finds \f$ \sigma \f$ such that+ // \f$ 2^{2\sigma-1} < rowNorm / colNorm \le 2^{2\sigma+1} \f$+ // then the balancing coefficient for the row is \f$ 1/2^{\sigma} \f$+ // and the balancing coefficient for the column is \f$ 2^{\sigma} \f$+ rowB = rowNorm / radix<Scalar>();+ colB = Scalar(1);+ const Scalar s = colNorm + rowNorm;++ while (colNorm < rowB)+ {+ colB *= radix<Scalar>();+ colNorm *= radix2<Scalar>();+ }++ rowB = rowNorm * radix<Scalar>();++ while (colNorm >= rowB)+ {+ colB /= radix<Scalar>();+ colNorm /= radix2<Scalar>();+ }++ //This line is used to avoid insubstantial balancing+ if ((rowNorm + colNorm) < Scalar(0.95) * s * colB)+ {+ isBalanced = false;+ rowB = Scalar(1) / colB;+ return false;+ }+ else{+ return true; }+ }+}++template< typename _Scalar, int _Deg >+inline+bool companion<_Scalar,_Deg>::balancedR( Scalar colNorm, Scalar rowNorm,+ bool& isBalanced, Scalar& colB, Scalar& rowB )+{+ if( Scalar(0) == colNorm || Scalar(0) == rowNorm ){ return true; }+ else+ {+ /**+ * Set the norm of the column and the row to the geometric mean+ * of the row and column norm+ */+ const _Scalar q = colNorm/rowNorm;+ if( !isApprox( q, _Scalar(1) ) )+ {+ rowB = sqrt( colNorm/rowNorm );+ colB = Scalar(1)/rowB;++ isBalanced = false;+ return false;+ }+ else{+ return true; }+ }+}+++template< typename _Scalar, int _Deg >+void companion<_Scalar,_Deg>::balance()+{+ using std::abs;+ EIGEN_STATIC_ASSERT( Deg == Dynamic || 1 < Deg, YOU_MADE_A_PROGRAMMING_MISTAKE );+ const Index deg = m_monic.size();+ const Index deg_1 = deg-1;++ bool hasConverged=false;+ while( !hasConverged )+ {+ hasConverged = true;+ Scalar colNorm,rowNorm;+ Scalar colB,rowB;++ //First row, first column excluding the diagonal+ //==============================================+ colNorm = abs(m_bl_diag[0]);+ rowNorm = abs(m_monic[0]);++ //Compute balancing of the row and the column+ if( !balanced( colNorm, rowNorm, hasConverged, colB, rowB ) )+ {+ m_bl_diag[0] *= colB;+ m_monic[0] *= rowB;+ }++ //Middle rows and columns excluding the diagonal+ //==============================================+ for( Index i=1; i<deg_1; ++i )+ {+ // column norm, excluding the diagonal+ colNorm = abs(m_bl_diag[i]);++ // row norm, excluding the diagonal+ rowNorm = abs(m_bl_diag[i-1]) + abs(m_monic[i]);++ //Compute balancing of the row and the column+ if( !balanced( colNorm, rowNorm, hasConverged, colB, rowB ) )+ {+ m_bl_diag[i] *= colB;+ m_bl_diag[i-1] *= rowB;+ m_monic[i] *= rowB;+ }+ }++ //Last row, last column excluding the diagonal+ //============================================+ const Index ebl = m_bl_diag.size()-1;+ VectorBlock<RightColumn,Deg_1> headMonic( m_monic, 0, deg_1 );+ colNorm = headMonic.array().abs().sum();+ rowNorm = abs( m_bl_diag[ebl] );++ //Compute balancing of the row and the column+ if( !balanced( colNorm, rowNorm, hasConverged, colB, rowB ) )+ {+ headMonic *= colB;+ m_bl_diag[ebl] *= rowB;+ }+ }+}++} // end namespace internal++} // end namespace Eigen++#endif // EIGEN_COMPANION_H
+ eigen3/unsupported/Eigen/src/Polynomials/PolynomialSolver.h view
@@ -0,0 +1,389 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010 Manuel Yguel <manuel.yguel@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_POLYNOMIAL_SOLVER_H+#define EIGEN_POLYNOMIAL_SOLVER_H++namespace Eigen { ++/** \ingroup Polynomials_Module+ * \class PolynomialSolverBase.+ *+ * \brief Defined to be inherited by polynomial solvers: it provides+ * convenient methods such as+ * - real roots,+ * - greatest, smallest complex roots,+ * - real roots with greatest, smallest absolute real value,+ * - greatest, smallest real roots.+ *+ * It stores the set of roots as a vector of complexes.+ *+ */+template< typename _Scalar, int _Deg >+class PolynomialSolverBase+{+ public:+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Deg==Dynamic ? Dynamic : _Deg)++ typedef _Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef std::complex<RealScalar> RootType;+ typedef Matrix<RootType,_Deg,1> RootsType;++ typedef DenseIndex Index;++ protected:+ template< typename OtherPolynomial >+ inline void setPolynomial( const OtherPolynomial& poly ){+ m_roots.resize(poly.size()); }++ public:+ template< typename OtherPolynomial >+ inline PolynomialSolverBase( const OtherPolynomial& poly ){+ setPolynomial( poly() ); }++ inline PolynomialSolverBase(){}++ public:+ /** \returns the complex roots of the polynomial */+ inline const RootsType& roots() const { return m_roots; }++ public:+ /** Clear and fills the back insertion sequence with the real roots of the polynomial+ * i.e. the real part of the complex roots that have an imaginary part which+ * absolute value is smaller than absImaginaryThreshold.+ * absImaginaryThreshold takes the dummy_precision associated+ * with the _Scalar template parameter of the PolynomialSolver class as the default value.+ *+ * \param[out] bi_seq : the back insertion sequence (stl concept)+ * \param[in] absImaginaryThreshold : the maximum bound of the imaginary part of a complex+ * number that is considered as real.+ * */+ template<typename Stl_back_insertion_sequence>+ inline void realRoots( Stl_back_insertion_sequence& bi_seq,+ const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() ) const+ {+ using std::abs;+ bi_seq.clear();+ for(Index i=0; i<m_roots.size(); ++i )+ {+ if( abs( m_roots[i].imag() ) < absImaginaryThreshold ){+ bi_seq.push_back( m_roots[i].real() ); }+ }+ }++ protected:+ template<typename squaredNormBinaryPredicate>+ inline const RootType& selectComplexRoot_withRespectToNorm( squaredNormBinaryPredicate& pred ) const+ {+ Index res=0;+ RealScalar norm2 = numext::abs2( m_roots[0] );+ for( Index i=1; i<m_roots.size(); ++i )+ {+ const RealScalar currNorm2 = numext::abs2( m_roots[i] );+ if( pred( currNorm2, norm2 ) ){+ res=i; norm2=currNorm2; }+ }+ return m_roots[res];+ }++ public:+ /**+ * \returns the complex root with greatest norm.+ */+ inline const RootType& greatestRoot() const+ {+ std::greater<Scalar> greater;+ return selectComplexRoot_withRespectToNorm( greater );+ }++ /**+ * \returns the complex root with smallest norm.+ */+ inline const RootType& smallestRoot() const+ {+ std::less<Scalar> less;+ return selectComplexRoot_withRespectToNorm( less );+ }++ protected:+ template<typename squaredRealPartBinaryPredicate>+ inline const RealScalar& selectRealRoot_withRespectToAbsRealPart(+ squaredRealPartBinaryPredicate& pred,+ bool& hasArealRoot,+ const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() ) const+ {+ using std::abs;+ hasArealRoot = false;+ Index res=0;+ RealScalar abs2(0);++ for( Index i=0; i<m_roots.size(); ++i )+ {+ if( abs( m_roots[i].imag() ) < absImaginaryThreshold )+ {+ if( !hasArealRoot )+ {+ hasArealRoot = true;+ res = i;+ abs2 = m_roots[i].real() * m_roots[i].real();+ }+ else+ {+ const RealScalar currAbs2 = m_roots[i].real() * m_roots[i].real();+ if( pred( currAbs2, abs2 ) )+ {+ abs2 = currAbs2;+ res = i;+ }+ }+ }+ else+ {+ if( abs( m_roots[i].imag() ) < abs( m_roots[res].imag() ) ){+ res = i; }+ }+ }+ return numext::real_ref(m_roots[res]);+ }+++ template<typename RealPartBinaryPredicate>+ inline const RealScalar& selectRealRoot_withRespectToRealPart(+ RealPartBinaryPredicate& pred,+ bool& hasArealRoot,+ const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() ) const+ {+ using std::abs;+ hasArealRoot = false;+ Index res=0;+ RealScalar val(0);++ for( Index i=0; i<m_roots.size(); ++i )+ {+ if( abs( m_roots[i].imag() ) < absImaginaryThreshold )+ {+ if( !hasArealRoot )+ {+ hasArealRoot = true;+ res = i;+ val = m_roots[i].real();+ }+ else+ {+ const RealScalar curr = m_roots[i].real();+ if( pred( curr, val ) )+ {+ val = curr;+ res = i;+ }+ }+ }+ else+ {+ if( abs( m_roots[i].imag() ) < abs( m_roots[res].imag() ) ){+ res = i; }+ }+ }+ return numext::real_ref(m_roots[res]);+ }++ public:+ /**+ * \returns a real root with greatest absolute magnitude.+ * A real root is defined as the real part of a complex root with absolute imaginary+ * part smallest than absImaginaryThreshold.+ * absImaginaryThreshold takes the dummy_precision associated+ * with the _Scalar template parameter of the PolynomialSolver class as the default value.+ * If no real root is found the boolean hasArealRoot is set to false and the real part of+ * the root with smallest absolute imaginary part is returned instead.+ *+ * \param[out] hasArealRoot : boolean true if a real root is found according to the+ * absImaginaryThreshold criterion, false otherwise.+ * \param[in] absImaginaryThreshold : threshold on the absolute imaginary part to decide+ * whether or not a root is real.+ */+ inline const RealScalar& absGreatestRealRoot(+ bool& hasArealRoot,+ const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() ) const+ {+ std::greater<Scalar> greater;+ return selectRealRoot_withRespectToAbsRealPart( greater, hasArealRoot, absImaginaryThreshold );+ }+++ /**+ * \returns a real root with smallest absolute magnitude.+ * A real root is defined as the real part of a complex root with absolute imaginary+ * part smallest than absImaginaryThreshold.+ * absImaginaryThreshold takes the dummy_precision associated+ * with the _Scalar template parameter of the PolynomialSolver class as the default value.+ * If no real root is found the boolean hasArealRoot is set to false and the real part of+ * the root with smallest absolute imaginary part is returned instead.+ *+ * \param[out] hasArealRoot : boolean true if a real root is found according to the+ * absImaginaryThreshold criterion, false otherwise.+ * \param[in] absImaginaryThreshold : threshold on the absolute imaginary part to decide+ * whether or not a root is real.+ */+ inline const RealScalar& absSmallestRealRoot(+ bool& hasArealRoot,+ const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() ) const+ {+ std::less<Scalar> less;+ return selectRealRoot_withRespectToAbsRealPart( less, hasArealRoot, absImaginaryThreshold );+ }+++ /**+ * \returns the real root with greatest value.+ * A real root is defined as the real part of a complex root with absolute imaginary+ * part smallest than absImaginaryThreshold.+ * absImaginaryThreshold takes the dummy_precision associated+ * with the _Scalar template parameter of the PolynomialSolver class as the default value.+ * If no real root is found the boolean hasArealRoot is set to false and the real part of+ * the root with smallest absolute imaginary part is returned instead.+ *+ * \param[out] hasArealRoot : boolean true if a real root is found according to the+ * absImaginaryThreshold criterion, false otherwise.+ * \param[in] absImaginaryThreshold : threshold on the absolute imaginary part to decide+ * whether or not a root is real.+ */+ inline const RealScalar& greatestRealRoot(+ bool& hasArealRoot,+ const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() ) const+ {+ std::greater<Scalar> greater;+ return selectRealRoot_withRespectToRealPart( greater, hasArealRoot, absImaginaryThreshold );+ }+++ /**+ * \returns the real root with smallest value.+ * A real root is defined as the real part of a complex root with absolute imaginary+ * part smallest than absImaginaryThreshold.+ * absImaginaryThreshold takes the dummy_precision associated+ * with the _Scalar template parameter of the PolynomialSolver class as the default value.+ * If no real root is found the boolean hasArealRoot is set to false and the real part of+ * the root with smallest absolute imaginary part is returned instead.+ *+ * \param[out] hasArealRoot : boolean true if a real root is found according to the+ * absImaginaryThreshold criterion, false otherwise.+ * \param[in] absImaginaryThreshold : threshold on the absolute imaginary part to decide+ * whether or not a root is real.+ */+ inline const RealScalar& smallestRealRoot(+ bool& hasArealRoot,+ const RealScalar& absImaginaryThreshold = NumTraits<Scalar>::dummy_precision() ) const+ {+ std::less<Scalar> less;+ return selectRealRoot_withRespectToRealPart( less, hasArealRoot, absImaginaryThreshold );+ }++ protected:+ RootsType m_roots;+};++#define EIGEN_POLYNOMIAL_SOLVER_BASE_INHERITED_TYPES( BASE ) \+ typedef typename BASE::Scalar Scalar; \+ typedef typename BASE::RealScalar RealScalar; \+ typedef typename BASE::RootType RootType; \+ typedef typename BASE::RootsType RootsType;++++/** \ingroup Polynomials_Module+ *+ * \class PolynomialSolver+ *+ * \brief A polynomial solver+ *+ * Computes the complex roots of a real polynomial.+ *+ * \param _Scalar the scalar type, i.e., the type of the polynomial coefficients+ * \param _Deg the degree of the polynomial, can be a compile time value or Dynamic.+ * Notice that the number of polynomial coefficients is _Deg+1.+ *+ * This class implements a polynomial solver and provides convenient methods such as+ * - real roots,+ * - greatest, smallest complex roots,+ * - real roots with greatest, smallest absolute real value.+ * - greatest, smallest real roots.+ *+ * WARNING: this polynomial solver is experimental, part of the unsuported Eigen modules.+ *+ *+ * Currently a QR algorithm is used to compute the eigenvalues of the companion matrix of+ * the polynomial to compute its roots.+ * This supposes that the complex moduli of the roots are all distinct: e.g. there should+ * be no multiple roots or conjugate roots for instance.+ * With 32bit (float) floating types this problem shows up frequently.+ * However, almost always, correct accuracy is reached even in these cases for 64bit+ * (double) floating types and small polynomial degree (<20).+ */+template< typename _Scalar, int _Deg >+class PolynomialSolver : public PolynomialSolverBase<_Scalar,_Deg>+{+ public:+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_Deg==Dynamic ? Dynamic : _Deg)++ typedef PolynomialSolverBase<_Scalar,_Deg> PS_Base;+ EIGEN_POLYNOMIAL_SOLVER_BASE_INHERITED_TYPES( PS_Base )++ typedef Matrix<Scalar,_Deg,_Deg> CompanionMatrixType;+ typedef EigenSolver<CompanionMatrixType> EigenSolverType;++ public:+ /** Computes the complex roots of a new polynomial. */+ template< typename OtherPolynomial >+ void compute( const OtherPolynomial& poly )+ {+ eigen_assert( Scalar(0) != poly[poly.size()-1] );+ internal::companion<Scalar,_Deg> companion( poly );+ companion.balance();+ m_eigenSolver.compute( companion.denseMatrix() );+ m_roots = m_eigenSolver.eigenvalues();+ }++ public:+ template< typename OtherPolynomial >+ inline PolynomialSolver( const OtherPolynomial& poly ){+ compute( poly ); }++ inline PolynomialSolver(){}++ protected:+ using PS_Base::m_roots;+ EigenSolverType m_eigenSolver;+};+++template< typename _Scalar >+class PolynomialSolver<_Scalar,1> : public PolynomialSolverBase<_Scalar,1>+{+ public:+ typedef PolynomialSolverBase<_Scalar,1> PS_Base;+ EIGEN_POLYNOMIAL_SOLVER_BASE_INHERITED_TYPES( PS_Base )++ public:+ /** Computes the complex roots of a new polynomial. */+ template< typename OtherPolynomial >+ void compute( const OtherPolynomial& poly )+ {+ eigen_assert( Scalar(0) != poly[poly.size()-1] );+ m_roots[0] = -poly[0]/poly[poly.size()-1];+ }++ protected:+ using PS_Base::m_roots;+};++} // end namespace Eigen++#endif // EIGEN_POLYNOMIAL_SOLVER_H
+ eigen3/unsupported/Eigen/src/Polynomials/PolynomialUtils.h view
@@ -0,0 +1,143 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010 Manuel Yguel <manuel.yguel@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_POLYNOMIAL_UTILS_H+#define EIGEN_POLYNOMIAL_UTILS_H++namespace Eigen { ++/** \ingroup Polynomials_Module+ * \returns the evaluation of the polynomial at x using Horner algorithm.+ *+ * \param[in] poly : the vector of coefficients of the polynomial ordered+ * by degrees i.e. poly[i] is the coefficient of degree i of the polynomial+ * e.g. \f$ 1 + 3x^2 \f$ is stored as a vector \f$ [ 1, 0, 3 ] \f$.+ * \param[in] x : the value to evaluate the polynomial at.+ *+ * <i><b>Note for stability:</b></i>+ * <dd> \f$ |x| \le 1 \f$ </dd>+ */+template <typename Polynomials, typename T>+inline+T poly_eval_horner( const Polynomials& poly, const T& x )+{+ T val=poly[poly.size()-1];+ for(DenseIndex i=poly.size()-2; i>=0; --i ){+ val = val*x + poly[i]; }+ return val;+}++/** \ingroup Polynomials_Module+ * \returns the evaluation of the polynomial at x using stabilized Horner algorithm.+ *+ * \param[in] poly : the vector of coefficients of the polynomial ordered+ * by degrees i.e. poly[i] is the coefficient of degree i of the polynomial+ * e.g. \f$ 1 + 3x^2 \f$ is stored as a vector \f$ [ 1, 0, 3 ] \f$.+ * \param[in] x : the value to evaluate the polynomial at.+ */+template <typename Polynomials, typename T>+inline+T poly_eval( const Polynomials& poly, const T& x )+{+ typedef typename NumTraits<T>::Real Real;++ if( numext::abs2( x ) <= Real(1) ){+ return poly_eval_horner( poly, x ); }+ else+ {+ T val=poly[0];+ T inv_x = T(1)/x;+ for( DenseIndex i=1; i<poly.size(); ++i ){+ val = val*inv_x + poly[i]; }++ return std::pow(x,(T)(poly.size()-1)) * val;+ }+}++/** \ingroup Polynomials_Module+ * \returns a maximum bound for the absolute value of any root of the polynomial.+ *+ * \param[in] poly : the vector of coefficients of the polynomial ordered+ * by degrees i.e. poly[i] is the coefficient of degree i of the polynomial+ * e.g. \f$ 1 + 3x^2 \f$ is stored as a vector \f$ [ 1, 0, 3 ] \f$.+ *+ * <i><b>Precondition:</b></i>+ * <dd> the leading coefficient of the input polynomial poly must be non zero </dd>+ */+template <typename Polynomial>+inline+typename NumTraits<typename Polynomial::Scalar>::Real cauchy_max_bound( const Polynomial& poly )+{+ using std::abs;+ typedef typename Polynomial::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real Real;++ eigen_assert( Scalar(0) != poly[poly.size()-1] );+ const Scalar inv_leading_coeff = Scalar(1)/poly[poly.size()-1];+ Real cb(0);++ for( DenseIndex i=0; i<poly.size()-1; ++i ){+ cb += abs(poly[i]*inv_leading_coeff); }+ return cb + Real(1);+}++/** \ingroup Polynomials_Module+ * \returns a minimum bound for the absolute value of any non zero root of the polynomial.+ * \param[in] poly : the vector of coefficients of the polynomial ordered+ * by degrees i.e. poly[i] is the coefficient of degree i of the polynomial+ * e.g. \f$ 1 + 3x^2 \f$ is stored as a vector \f$ [ 1, 0, 3 ] \f$.+ */+template <typename Polynomial>+inline+typename NumTraits<typename Polynomial::Scalar>::Real cauchy_min_bound( const Polynomial& poly )+{+ using std::abs;+ typedef typename Polynomial::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real Real;++ DenseIndex i=0;+ while( i<poly.size()-1 && Scalar(0) == poly(i) ){ ++i; }+ if( poly.size()-1 == i ){+ return Real(1); }++ const Scalar inv_min_coeff = Scalar(1)/poly[i];+ Real cb(1);+ for( DenseIndex j=i+1; j<poly.size(); ++j ){+ cb += abs(poly[j]*inv_min_coeff); }+ return Real(1)/cb;+}++/** \ingroup Polynomials_Module+ * Given the roots of a polynomial compute the coefficients in the+ * monomial basis of the monic polynomial with same roots and minimal degree.+ * If RootVector is a vector of complexes, Polynomial should also be a vector+ * of complexes.+ * \param[in] rv : a vector containing the roots of a polynomial.+ * \param[out] poly : the vector of coefficients of the polynomial ordered+ * by degrees i.e. poly[i] is the coefficient of degree i of the polynomial+ * e.g. \f$ 3 + x^2 \f$ is stored as a vector \f$ [ 3, 0, 1 ] \f$.+ */+template <typename RootVector, typename Polynomial>+void roots_to_monicPolynomial( const RootVector& rv, Polynomial& poly )+{++ typedef typename Polynomial::Scalar Scalar;++ poly.setZero( rv.size()+1 );+ poly[0] = -rv[0]; poly[1] = Scalar(1);+ for( DenseIndex i=1; i< rv.size(); ++i )+ {+ for( DenseIndex j=i+1; j>0; --j ){ poly[j] = poly[j-1] - rv[i]*poly[j]; }+ poly[0] = -rv[i]*poly[0];+ }+}++} // end namespace Eigen++#endif // EIGEN_POLYNOMIAL_UTILS_H
+ eigen3/unsupported/Eigen/src/SVD/BDCSVD.h view
@@ -0,0 +1,748 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+// +// We used the "A Divide-And-Conquer Algorithm for the Bidiagonal SVD"+// research report written by Ming Gu and Stanley C.Eisenstat+// The code variable names correspond to the names they used in their +// report+//+// Copyright (C) 2013 Gauthier Brun <brun.gauthier@gmail.com>+// Copyright (C) 2013 Nicolas Carre <nicolas.carre@ensimag.fr>+// Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>+// Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>+//+// Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_BDCSVD_H+#define EIGEN_BDCSVD_H++#define EPSILON 0.0000000000000001++#define ALGOSWAP 32++namespace Eigen {+/** \ingroup SVD_Module+ *+ *+ * \class BDCSVD+ *+ * \brief class Bidiagonal Divide and Conquer SVD+ *+ * \param MatrixType the type of the matrix of which we are computing the SVD decomposition+ * We plan to have a very similar interface to JacobiSVD on this class.+ * It should be used to speed up the calcul of SVD for big matrices. + */+template<typename _MatrixType> +class BDCSVD : public SVDBase<_MatrixType>+{+ typedef SVDBase<_MatrixType> Base;+ +public:+ using Base::rows;+ using Base::cols;+ + typedef _MatrixType MatrixType;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;+ typedef typename MatrixType::Index Index;+ enum {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::ColsAtCompileTime, + DiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime, ColsAtCompileTime), + MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime, + MaxDiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(MaxRowsAtCompileTime, MaxColsAtCompileTime), + MatrixOptions = MatrixType::Options+ };++ typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime, + MatrixOptions, MaxRowsAtCompileTime, MaxRowsAtCompileTime>+ MatrixUType;+ typedef Matrix<Scalar, ColsAtCompileTime, ColsAtCompileTime, + MatrixOptions, MaxColsAtCompileTime, MaxColsAtCompileTime>+ MatrixVType;+ typedef typename internal::plain_diag_type<MatrixType, RealScalar>::type SingularValuesType;+ typedef typename internal::plain_row_type<MatrixType>::type RowType;+ typedef typename internal::plain_col_type<MatrixType>::type ColType;+ typedef Matrix<Scalar, Dynamic, Dynamic> MatrixX;+ typedef Matrix<RealScalar, Dynamic, Dynamic> MatrixXr;+ typedef Matrix<RealScalar, Dynamic, 1> VectorType;++ /** \brief Default Constructor.+ *+ * The default constructor is useful in cases in which the user intends to+ * perform decompositions via BDCSVD::compute(const MatrixType&).+ */+ BDCSVD()+ : SVDBase<_MatrixType>::SVDBase(), + algoswap(ALGOSWAP)+ {}+++ /** \brief Default Constructor with memory preallocation+ *+ * Like the default constructor but with preallocation of the internal data+ * according to the specified problem size.+ * \sa BDCSVD()+ */+ BDCSVD(Index rows, Index cols, unsigned int computationOptions = 0)+ : SVDBase<_MatrixType>::SVDBase(), + algoswap(ALGOSWAP)+ {+ allocate(rows, cols, computationOptions);+ }++ /** \brief Constructor performing the decomposition of given matrix.+ *+ * \param matrix the matrix to decompose+ * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed.+ * By default, none is computed. This is a bit - field, the possible bits are #ComputeFullU, #ComputeThinU, + * #ComputeFullV, #ComputeThinV.+ *+ * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not+ * available with the (non - default) FullPivHouseholderQR preconditioner.+ */+ BDCSVD(const MatrixType& matrix, unsigned int computationOptions = 0)+ : SVDBase<_MatrixType>::SVDBase(), + algoswap(ALGOSWAP)+ {+ compute(matrix, computationOptions);+ }++ ~BDCSVD() + {+ }+ /** \brief Method performing the decomposition of given matrix using custom options.+ *+ * \param matrix the matrix to decompose+ * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed.+ * By default, none is computed. This is a bit - field, the possible bits are #ComputeFullU, #ComputeThinU, + * #ComputeFullV, #ComputeThinV.+ *+ * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not+ * available with the (non - default) FullPivHouseholderQR preconditioner.+ */+ SVDBase<MatrixType>& compute(const MatrixType& matrix, unsigned int computationOptions);++ /** \brief Method performing the decomposition of given matrix using current options.+ *+ * \param matrix the matrix to decompose+ *+ * This method uses the current \a computationOptions, as already passed to the constructor or to compute(const MatrixType&, unsigned int).+ */+ SVDBase<MatrixType>& compute(const MatrixType& matrix)+ {+ return compute(matrix, this->m_computationOptions);+ }++ void setSwitchSize(int s) + {+ eigen_assert(s>3 && "BDCSVD the size of the algo switch has to be greater than 4");+ algoswap = s;+ }+++ /** \returns a (least squares) solution of \f$ A x = b \f$ using the current SVD decomposition of A.+ *+ * \param b the right - hand - side of the equation to solve.+ *+ * \note Solving requires both U and V to be computed. Thin U and V are enough, there is no need for full U or V.+ *+ * \note SVD solving is implicitly least - squares. Thus, this method serves both purposes of exact solving and least - squares solving.+ * In other words, the returned solution is guaranteed to minimize the Euclidean norm \f$ \Vert A x - b \Vert \f$.+ */+ template<typename Rhs>+ inline const internal::solve_retval<BDCSVD, Rhs>+ solve(const MatrixBase<Rhs>& b) const+ {+ eigen_assert(this->m_isInitialized && "BDCSVD is not initialized.");+ eigen_assert(SVDBase<_MatrixType>::computeU() && SVDBase<_MatrixType>::computeV() && + "BDCSVD::solve() requires both unitaries U and V to be computed (thin unitaries suffice).");+ return internal::solve_retval<BDCSVD, Rhs>(*this, b.derived());+ }++ + const MatrixUType& matrixU() const+ {+ eigen_assert(this->m_isInitialized && "SVD is not initialized.");+ if (isTranspose){+ eigen_assert(this->computeV() && "This SVD decomposition didn't compute U. Did you ask for it?");+ return this->m_matrixV;+ }+ else + {+ eigen_assert(this->computeU() && "This SVD decomposition didn't compute U. Did you ask for it?");+ return this->m_matrixU;+ }+ + }+++ const MatrixVType& matrixV() const+ {+ eigen_assert(this->m_isInitialized && "SVD is not initialized.");+ if (isTranspose){+ eigen_assert(this->computeU() && "This SVD decomposition didn't compute V. Did you ask for it?");+ return this->m_matrixU;+ }+ else+ {+ eigen_assert(this->computeV() && "This SVD decomposition didn't compute V. Did you ask for it?");+ return this->m_matrixV;+ }+ }+ +private:+ void allocate(Index rows, Index cols, unsigned int computationOptions);+ void divide (Index firstCol, Index lastCol, Index firstRowW, + Index firstColW, Index shift);+ void deflation43(Index firstCol, Index shift, Index i, Index size);+ void deflation44(Index firstColu , Index firstColm, Index firstRowW, Index firstColW, Index i, Index j, Index size);+ void deflation(Index firstCol, Index lastCol, Index k, Index firstRowW, Index firstColW, Index shift);+ void copyUV(MatrixXr naiveU, MatrixXr naiveV, MatrixX householderU, MatrixX houseHolderV);++protected:+ MatrixXr m_naiveU, m_naiveV;+ MatrixXr m_computed;+ Index nRec;+ int algoswap;+ bool isTranspose, compU, compV;+ +}; //end class BDCSVD+++// Methode to allocate ans initialize matrix and attributs+template<typename MatrixType>+void BDCSVD<MatrixType>::allocate(Index rows, Index cols, unsigned int computationOptions)+{+ isTranspose = (cols > rows);+ if (SVDBase<MatrixType>::allocate(rows, cols, computationOptions)) return;+ m_computed = MatrixXr::Zero(this->m_diagSize + 1, this->m_diagSize );+ if (isTranspose){+ compU = this->computeU();+ compV = this->computeV(); + } + else+ {+ compV = this->computeU();+ compU = this->computeV(); + }+ if (compU) m_naiveU = MatrixXr::Zero(this->m_diagSize + 1, this->m_diagSize + 1 );+ else m_naiveU = MatrixXr::Zero(2, this->m_diagSize + 1 );+ + if (compV) m_naiveV = MatrixXr::Zero(this->m_diagSize, this->m_diagSize);+ ++ //should be changed for a cleaner implementation+ if (isTranspose){+ bool aux;+ if (this->computeU()||this->computeV()){+ aux = this->m_computeFullU;+ this->m_computeFullU = this->m_computeFullV;+ this->m_computeFullV = aux;+ aux = this->m_computeThinU;+ this->m_computeThinU = this->m_computeThinV;+ this->m_computeThinV = aux;+ } + }+}// end allocate++// Methode which compute the BDCSVD for the int+template<>+SVDBase<Matrix<int, Dynamic, Dynamic> >&+BDCSVD<Matrix<int, Dynamic, Dynamic> >::compute(const MatrixType& matrix, unsigned int computationOptions) {+ allocate(matrix.rows(), matrix.cols(), computationOptions);+ this->m_nonzeroSingularValues = 0;+ m_computed = Matrix<int, Dynamic, Dynamic>::Zero(rows(), cols());+ for (int i=0; i<this->m_diagSize; i++) {+ this->m_singularValues.coeffRef(i) = 0;+ }+ if (this->m_computeFullU) this->m_matrixU = Matrix<int, Dynamic, Dynamic>::Zero(rows(), rows());+ if (this->m_computeFullV) this->m_matrixV = Matrix<int, Dynamic, Dynamic>::Zero(cols(), cols()); + this->m_isInitialized = true;+ return *this;+}+++// Methode which compute the BDCSVD+template<typename MatrixType>+SVDBase<MatrixType>&+BDCSVD<MatrixType>::compute(const MatrixType& matrix, unsigned int computationOptions) +{+ allocate(matrix.rows(), matrix.cols(), computationOptions);+ using std::abs;++ //**** step 1 Bidiagonalization isTranspose = (matrix.cols()>matrix.rows()) ;+ MatrixType copy;+ if (isTranspose) copy = matrix.adjoint();+ else copy = matrix;+ + internal::UpperBidiagonalization<MatrixX > bid(copy);++ //**** step 2 Divide+ // this is ugly and has to be redone (care of complex cast)+ MatrixXr temp;+ temp = bid.bidiagonal().toDenseMatrix().transpose();+ m_computed.setZero();+ for (int i=0; i<this->m_diagSize - 1; i++) {+ m_computed(i, i) = temp(i, i);+ m_computed(i + 1, i) = temp(i + 1, i);+ }+ m_computed(this->m_diagSize - 1, this->m_diagSize - 1) = temp(this->m_diagSize - 1, this->m_diagSize - 1);+ divide(0, this->m_diagSize - 1, 0, 0, 0);++ //**** step 3 copy+ for (int i=0; i<this->m_diagSize; i++) {+ RealScalar a = abs(m_computed.coeff(i, i));+ this->m_singularValues.coeffRef(i) = a;+ if (a == 0){+ this->m_nonzeroSingularValues = i;+ break;+ }+ else if (i == this->m_diagSize - 1)+ {+ this->m_nonzeroSingularValues = i + 1;+ break;+ }+ }+ copyUV(m_naiveV, m_naiveU, bid.householderU(), bid.householderV());+ this->m_isInitialized = true;+ return *this;+}// end compute+++template<typename MatrixType>+void BDCSVD<MatrixType>::copyUV(MatrixXr naiveU, MatrixXr naiveV, MatrixX householderU, MatrixX householderV){+ if (this->computeU()){+ MatrixX temp = MatrixX::Zero(naiveU.rows(), naiveU.cols());+ temp.real() = naiveU;+ if (this->m_computeThinU){+ this->m_matrixU = MatrixX::Identity(householderU.cols(), this->m_nonzeroSingularValues );+ this->m_matrixU.block(0, 0, this->m_diagSize, this->m_nonzeroSingularValues) = + temp.block(0, 0, this->m_diagSize, this->m_nonzeroSingularValues);+ this->m_matrixU = householderU * this->m_matrixU ;+ }+ else+ {+ this->m_matrixU = MatrixX::Identity(householderU.cols(), householderU.cols());+ this->m_matrixU.block(0, 0, this->m_diagSize, this->m_diagSize) = temp.block(0, 0, this->m_diagSize, this->m_diagSize);+ this->m_matrixU = householderU * this->m_matrixU ;+ }+ }+ if (this->computeV()){+ MatrixX temp = MatrixX::Zero(naiveV.rows(), naiveV.cols());+ temp.real() = naiveV;+ if (this->m_computeThinV){+ this->m_matrixV = MatrixX::Identity(householderV.cols(),this->m_nonzeroSingularValues );+ this->m_matrixV.block(0, 0, this->m_nonzeroSingularValues, this->m_nonzeroSingularValues) = + temp.block(0, 0, this->m_nonzeroSingularValues, this->m_nonzeroSingularValues);+ this->m_matrixV = householderV * this->m_matrixV ;+ }+ else + {+ this->m_matrixV = MatrixX::Identity(householderV.cols(), householderV.cols());+ this->m_matrixV.block(0, 0, this->m_diagSize, this->m_diagSize) = temp.block(0, 0, this->m_diagSize, this->m_diagSize);+ this->m_matrixV = householderV * this->m_matrixV;+ }+ }+}++// The divide algorithm is done "in place", we are always working on subsets of the same matrix. The divide methods takes as argument the +// place of the submatrix we are currently working on.++//@param firstCol : The Index of the first column of the submatrix of m_computed and for m_naiveU;+//@param lastCol : The Index of the last column of the submatrix of m_computed and for m_naiveU; +// lastCol + 1 - firstCol is the size of the submatrix.+//@param firstRowW : The Index of the first row of the matrix W that we are to change. (see the reference paper section 1 for more information on W)+//@param firstRowW : Same as firstRowW with the column.+//@param shift : Each time one takes the left submatrix, one must add 1 to the shift. Why? Because! We actually want the last column of the U submatrix +// to become the first column (*coeff) and to shift all the other columns to the right. There are more details on the reference paper.+template<typename MatrixType>+void BDCSVD<MatrixType>::divide (Index firstCol, Index lastCol, Index firstRowW, + Index firstColW, Index shift)+{+ // requires nbRows = nbCols + 1;+ using std::pow;+ using std::sqrt;+ using std::abs;+ const Index n = lastCol - firstCol + 1;+ const Index k = n/2;+ RealScalar alphaK;+ RealScalar betaK; + RealScalar r0; + RealScalar lambda, phi, c0, s0;+ MatrixXr l, f;+ // We use the other algorithm which is more efficient for small + // matrices.+ if (n < algoswap){+ JacobiSVD<MatrixXr> b(m_computed.block(firstCol, firstCol, n + 1, n), + ComputeFullU | (ComputeFullV * compV)) ;+ if (compU) m_naiveU.block(firstCol, firstCol, n + 1, n + 1).real() << b.matrixU();+ else + {+ m_naiveU.row(0).segment(firstCol, n + 1).real() << b.matrixU().row(0);+ m_naiveU.row(1).segment(firstCol, n + 1).real() << b.matrixU().row(n);+ }+ if (compV) m_naiveV.block(firstRowW, firstColW, n, n).real() << b.matrixV();+ m_computed.block(firstCol + shift, firstCol + shift, n + 1, n).setZero();+ for (int i=0; i<n; i++)+ {+ m_computed(firstCol + shift + i, firstCol + shift +i) = b.singularValues().coeffRef(i);+ }+ return;+ }+ // We use the divide and conquer algorithm+ alphaK = m_computed(firstCol + k, firstCol + k);+ betaK = m_computed(firstCol + k + 1, firstCol + k);+ // The divide must be done in that order in order to have good results. Divide change the data inside the submatrices+ // and the divide of the right submatrice reads one column of the left submatrice. That's why we need to treat the + // right submatrix before the left one. + divide(k + 1 + firstCol, lastCol, k + 1 + firstRowW, k + 1 + firstColW, shift);+ divide(firstCol, k - 1 + firstCol, firstRowW, firstColW + 1, shift + 1);+ if (compU)+ {+ lambda = m_naiveU(firstCol + k, firstCol + k);+ phi = m_naiveU(firstCol + k + 1, lastCol + 1);+ } + else + {+ lambda = m_naiveU(1, firstCol + k);+ phi = m_naiveU(0, lastCol + 1);+ }+ r0 = sqrt((abs(alphaK * lambda) * abs(alphaK * lambda))+ + abs(betaK * phi) * abs(betaK * phi));+ if (compU)+ {+ l = m_naiveU.row(firstCol + k).segment(firstCol, k);+ f = m_naiveU.row(firstCol + k + 1).segment(firstCol + k + 1, n - k - 1);+ } + else + {+ l = m_naiveU.row(1).segment(firstCol, k);+ f = m_naiveU.row(0).segment(firstCol + k + 1, n - k - 1);+ }+ if (compV) m_naiveV(firstRowW+k, firstColW) = 1;+ if (r0 == 0)+ {+ c0 = 1;+ s0 = 0;+ }+ else+ {+ c0 = alphaK * lambda / r0;+ s0 = betaK * phi / r0;+ }+ if (compU)+ {+ MatrixXr q1 (m_naiveU.col(firstCol + k).segment(firstCol, k + 1)); + // we shiftW Q1 to the right+ for (Index i = firstCol + k - 1; i >= firstCol; i--) + {+ m_naiveU.col(i + 1).segment(firstCol, k + 1) << m_naiveU.col(i).segment(firstCol, k + 1);+ }+ // we shift q1 at the left with a factor c0+ m_naiveU.col(firstCol).segment( firstCol, k + 1) << (q1 * c0);+ // last column = q1 * - s0+ m_naiveU.col(lastCol + 1).segment(firstCol, k + 1) << (q1 * ( - s0));+ // first column = q2 * s0+ m_naiveU.col(firstCol).segment(firstCol + k + 1, n - k) << + m_naiveU.col(lastCol + 1).segment(firstCol + k + 1, n - k) *s0; + // q2 *= c0+ m_naiveU.col(lastCol + 1).segment(firstCol + k + 1, n - k) *= c0; + } + else + {+ RealScalar q1 = (m_naiveU(0, firstCol + k));+ // we shift Q1 to the right+ for (Index i = firstCol + k - 1; i >= firstCol; i--) + {+ m_naiveU(0, i + 1) = m_naiveU(0, i);+ }+ // we shift q1 at the left with a factor c0+ m_naiveU(0, firstCol) = (q1 * c0);+ // last column = q1 * - s0+ m_naiveU(0, lastCol + 1) = (q1 * ( - s0));+ // first column = q2 * s0+ m_naiveU(1, firstCol) = m_naiveU(1, lastCol + 1) *s0; + // q2 *= c0+ m_naiveU(1, lastCol + 1) *= c0;+ m_naiveU.row(1).segment(firstCol + 1, k).setZero();+ m_naiveU.row(0).segment(firstCol + k + 1, n - k - 1).setZero();+ }+ m_computed(firstCol + shift, firstCol + shift) = r0;+ m_computed.col(firstCol + shift).segment(firstCol + shift + 1, k) << alphaK * l.transpose().real();+ m_computed.col(firstCol + shift).segment(firstCol + shift + k + 1, n - k - 1) << betaK * f.transpose().real();+++ // the line below do the deflation of the matrix for the third part of the algorithm+ // Here the deflation is commented because the third part of the algorithm is not implemented+ // the third part of the algorithm is a fast SVD on the matrix m_computed which works thanks to the deflation++ deflation(firstCol, lastCol, k, firstRowW, firstColW, shift);++ // Third part of the algorithm, since the real third part of the algorithm is not implemeted we use a JacobiSVD+ JacobiSVD<MatrixXr> res= JacobiSVD<MatrixXr>(m_computed.block(firstCol + shift, firstCol +shift, n + 1, n), + ComputeFullU | (ComputeFullV * compV)) ;+ if (compU) m_naiveU.block(firstCol, firstCol, n + 1, n + 1) *= res.matrixU();+ else m_naiveU.block(0, firstCol, 2, n + 1) *= res.matrixU();+ + if (compV) m_naiveV.block(firstRowW, firstColW, n, n) *= res.matrixV();+ m_computed.block(firstCol + shift, firstCol + shift, n, n) << MatrixXr::Zero(n, n);+ for (int i=0; i<n; i++)+ m_computed(firstCol + shift + i, firstCol + shift +i) = res.singularValues().coeffRef(i);+ // end of the third part+++}// end divide+++// page 12_13+// i >= 1, di almost null and zi non null.+// We use a rotation to zero out zi applied to the left of M+template <typename MatrixType>+void BDCSVD<MatrixType>::deflation43(Index firstCol, Index shift, Index i, Index size){+ using std::abs;+ using std::sqrt;+ using std::pow;+ RealScalar c = m_computed(firstCol + shift, firstCol + shift);+ RealScalar s = m_computed(i, firstCol + shift);+ RealScalar r = sqrt(pow(abs(c), 2) + pow(abs(s), 2));+ if (r == 0){+ m_computed(i, i)=0;+ return;+ }+ c/=r;+ s/=r;+ m_computed(firstCol + shift, firstCol + shift) = r; + m_computed(i, firstCol + shift) = 0;+ m_computed(i, i) = 0;+ if (compU){+ m_naiveU.col(firstCol).segment(firstCol,size) = + c * m_naiveU.col(firstCol).segment(firstCol, size) - + s * m_naiveU.col(i).segment(firstCol, size) ;++ m_naiveU.col(i).segment(firstCol, size) = + (c + s*s/c) * m_naiveU.col(i).segment(firstCol, size) + + (s/c) * m_naiveU.col(firstCol).segment(firstCol,size);+ }+}// end deflation 43+++// page 13+// i,j >= 1, i != j and |di - dj| < epsilon * norm2(M)+// We apply two rotations to have zj = 0;+template <typename MatrixType>+void BDCSVD<MatrixType>::deflation44(Index firstColu , Index firstColm, Index firstRowW, Index firstColW, Index i, Index j, Index size){+ using std::abs;+ using std::sqrt;+ using std::conj;+ using std::pow;+ RealScalar c = m_computed(firstColm, firstColm + j - 1);+ RealScalar s = m_computed(firstColm, firstColm + i - 1);+ RealScalar r = sqrt(pow(abs(c), 2) + pow(abs(s), 2));+ if (r==0){+ m_computed(firstColm + i, firstColm + i) = m_computed(firstColm + j, firstColm + j);+ return;+ }+ c/=r;+ s/=r;+ m_computed(firstColm + i, firstColm) = r; + m_computed(firstColm + i, firstColm + i) = m_computed(firstColm + j, firstColm + j);+ m_computed(firstColm + j, firstColm) = 0;+ if (compU){+ m_naiveU.col(firstColu + i).segment(firstColu, size) = + c * m_naiveU.col(firstColu + i).segment(firstColu, size) - + s * m_naiveU.col(firstColu + j).segment(firstColu, size) ;++ m_naiveU.col(firstColu + j).segment(firstColu, size) = + (c + s*s/c) * m_naiveU.col(firstColu + j).segment(firstColu, size) + + (s/c) * m_naiveU.col(firstColu + i).segment(firstColu, size);+ } + if (compV){+ m_naiveV.col(firstColW + i).segment(firstRowW, size - 1) = + c * m_naiveV.col(firstColW + i).segment(firstRowW, size - 1) + + s * m_naiveV.col(firstColW + j).segment(firstRowW, size - 1) ;++ m_naiveV.col(firstColW + j).segment(firstRowW, size - 1) = + (c + s*s/c) * m_naiveV.col(firstColW + j).segment(firstRowW, size - 1) - + (s/c) * m_naiveV.col(firstColW + i).segment(firstRowW, size - 1);+ }+}// end deflation 44++++template <typename MatrixType>+void BDCSVD<MatrixType>::deflation(Index firstCol, Index lastCol, Index k, Index firstRowW, Index firstColW, Index shift){+ //condition 4.1+ RealScalar EPS = EPSILON * (std::max<RealScalar>(m_computed(firstCol + shift + 1, firstCol + shift + 1), m_computed(firstCol + k, firstCol + k)));+ const Index length = lastCol + 1 - firstCol;+ if (m_computed(firstCol + shift, firstCol + shift) < EPS){+ m_computed(firstCol + shift, firstCol + shift) = EPS;+ }+ //condition 4.2+ for (Index i=firstCol + shift + 1;i<=lastCol + shift;i++){+ if (std::abs(m_computed(i, firstCol + shift)) < EPS){+ m_computed(i, firstCol + shift) = 0;+ }+ }++ //condition 4.3+ for (Index i=firstCol + shift + 1;i<=lastCol + shift; i++){+ if (m_computed(i, i) < EPS){+ deflation43(firstCol, shift, i, length);+ }+ }++ //condition 4.4+ + Index i=firstCol + shift + 1, j=firstCol + shift + k + 1;+ //we stock the final place of each line+ Index *permutation = new Index[length];++ for (Index p =1; p < length; p++) {+ if (i> firstCol + shift + k){+ permutation[p] = j;+ j++;+ } else if (j> lastCol + shift) + {+ permutation[p] = i;+ i++;+ }+ else + {+ if (m_computed(i, i) < m_computed(j, j)){+ permutation[p] = j;+ j++;+ } + else+ {+ permutation[p] = i;+ i++;+ }+ }+ }+ //we do the permutation+ RealScalar aux;+ //we stock the current index of each col+ //and the column of each index+ Index *realInd = new Index[length];+ Index *realCol = new Index[length];+ for (int pos = 0; pos< length; pos++){+ realCol[pos] = pos + firstCol + shift;+ realInd[pos] = pos;+ }+ const Index Zero = firstCol + shift;+ VectorType temp;+ for (int i = 1; i < length - 1; i++){+ const Index I = i + Zero;+ const Index realI = realInd[i];+ const Index j = permutation[length - i] - Zero;+ const Index J = realCol[j];+ + //diag displace+ aux = m_computed(I, I); + m_computed(I, I) = m_computed(J, J);+ m_computed(J, J) = aux;+ + //firstrow displace+ aux = m_computed(I, Zero); + m_computed(I, Zero) = m_computed(J, Zero);+ m_computed(J, Zero) = aux;++ // change columns+ if (compU) {+ temp = m_naiveU.col(I - shift).segment(firstCol, length + 1);+ m_naiveU.col(I - shift).segment(firstCol, length + 1) << + m_naiveU.col(J - shift).segment(firstCol, length + 1);+ m_naiveU.col(J - shift).segment(firstCol, length + 1) << temp;+ } + else+ {+ temp = m_naiveU.col(I - shift).segment(0, 2);+ m_naiveU.col(I - shift).segment(0, 2) << + m_naiveU.col(J - shift).segment(0, 2);+ m_naiveU.col(J - shift).segment(0, 2) << temp; + }+ if (compV) {+ const Index CWI = I + firstColW - Zero;+ const Index CWJ = J + firstColW - Zero;+ temp = m_naiveV.col(CWI).segment(firstRowW, length);+ m_naiveV.col(CWI).segment(firstRowW, length) << m_naiveV.col(CWJ).segment(firstRowW, length);+ m_naiveV.col(CWJ).segment(firstRowW, length) << temp;+ }++ //update real pos+ realCol[realI] = J;+ realCol[j] = I;+ realInd[J - Zero] = realI;+ realInd[I - Zero] = j;+ }+ for (Index i = firstCol + shift + 1; i<lastCol + shift;i++){+ if ((m_computed(i + 1, i + 1) - m_computed(i, i)) < EPS){+ deflation44(firstCol , + firstCol + shift, + firstRowW, + firstColW, + i - Zero, + i + 1 - Zero, + length);+ }+ }+ delete [] permutation;+ delete [] realInd;+ delete [] realCol;++}//end deflation+++namespace internal{++template<typename _MatrixType, typename Rhs>+struct solve_retval<BDCSVD<_MatrixType>, Rhs>+ : solve_retval_base<BDCSVD<_MatrixType>, Rhs>+{+ typedef BDCSVD<_MatrixType> BDCSVDType;+ EIGEN_MAKE_SOLVE_HELPERS(BDCSVDType, Rhs)++ template<typename Dest> void evalTo(Dest& dst) const+ {+ eigen_assert(rhs().rows() == dec().rows());+ // A = U S V^*+ // So A^{ - 1} = V S^{ - 1} U^* + Index diagSize = (std::min)(dec().rows(), dec().cols());+ typename BDCSVDType::SingularValuesType invertedSingVals(diagSize);+ Index nonzeroSingVals = dec().nonzeroSingularValues();+ invertedSingVals.head(nonzeroSingVals) = dec().singularValues().head(nonzeroSingVals).array().inverse();+ invertedSingVals.tail(diagSize - nonzeroSingVals).setZero();+ + dst = dec().matrixV().leftCols(diagSize)+ * invertedSingVals.asDiagonal()+ * dec().matrixU().leftCols(diagSize).adjoint()+ * rhs(); + return;+ }+};++} //end namespace internal++ /** \svd_module+ *+ * \return the singular value decomposition of \c *this computed by + * BDC Algorithm+ *+ * \sa class BDCSVD+ */+/*+template<typename Derived>+BDCSVD<typename MatrixBase<Derived>::PlainObject>+MatrixBase<Derived>::bdcSvd(unsigned int computationOptions) const+{+ return BDCSVD<PlainObject>(*this, computationOptions);+}+*/++} // end namespace Eigen++#endif
+ eigen3/unsupported/Eigen/src/SVD/CMakeLists.txt view
@@ -0,0 +1,6 @@+FILE(GLOB Eigen_SVD_SRCS "*.h")++INSTALL(FILES+ ${Eigen_SVD_SRCS}+ DESTINATION ${INCLUDE_INSTALL_DIR}unsupported/Eigen/src/SVD COMPONENT Devel+ )
+ eigen3/unsupported/Eigen/src/SVD/JacobiSVD.h view
@@ -0,0 +1,782 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_JACOBISVD_H+#define EIGEN_JACOBISVD_H++namespace Eigen { ++namespace internal {+// forward declaration (needed by ICC)+// the empty body is required by MSVC+template<typename MatrixType, int QRPreconditioner,+ bool IsComplex = NumTraits<typename MatrixType::Scalar>::IsComplex>+struct svd_precondition_2x2_block_to_be_real {};++/*** QR preconditioners (R-SVD)+ ***+ *** Their role is to reduce the problem of computing the SVD to the case of a square matrix.+ *** This approach, known as R-SVD, is an optimization for rectangular-enough matrices, and is a requirement for+ *** JacobiSVD which by itself is only able to work on square matrices.+ ***/++enum { PreconditionIfMoreColsThanRows, PreconditionIfMoreRowsThanCols };++template<typename MatrixType, int QRPreconditioner, int Case>+struct qr_preconditioner_should_do_anything+{+ enum { a = MatrixType::RowsAtCompileTime != Dynamic &&+ MatrixType::ColsAtCompileTime != Dynamic &&+ MatrixType::ColsAtCompileTime <= MatrixType::RowsAtCompileTime,+ b = MatrixType::RowsAtCompileTime != Dynamic &&+ MatrixType::ColsAtCompileTime != Dynamic &&+ MatrixType::RowsAtCompileTime <= MatrixType::ColsAtCompileTime,+ ret = !( (QRPreconditioner == NoQRPreconditioner) ||+ (Case == PreconditionIfMoreColsThanRows && bool(a)) ||+ (Case == PreconditionIfMoreRowsThanCols && bool(b)) )+ };+};++template<typename MatrixType, int QRPreconditioner, int Case,+ bool DoAnything = qr_preconditioner_should_do_anything<MatrixType, QRPreconditioner, Case>::ret+> struct qr_preconditioner_impl {};++template<typename MatrixType, int QRPreconditioner, int Case>+class qr_preconditioner_impl<MatrixType, QRPreconditioner, Case, false>+{+public:+ typedef typename MatrixType::Index Index;+ void allocate(const JacobiSVD<MatrixType, QRPreconditioner>&) {}+ bool run(JacobiSVD<MatrixType, QRPreconditioner>&, const MatrixType&)+ {+ return false;+ }+};++/*** preconditioner using FullPivHouseholderQR ***/++template<typename MatrixType>+class qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>+{+public:+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ enum+ {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime+ };+ typedef Matrix<Scalar, 1, RowsAtCompileTime, RowMajor, 1, MaxRowsAtCompileTime> WorkspaceType;++ void allocate(const JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd)+ {+ if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())+ {+ m_qr.~QRType();+ ::new (&m_qr) QRType(svd.rows(), svd.cols());+ }+ if (svd.m_computeFullU) m_workspace.resize(svd.rows());+ }++ bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)+ {+ if(matrix.rows() > matrix.cols())+ {+ m_qr.compute(matrix);+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>();+ if(svd.m_computeFullU) m_qr.matrixQ().evalTo(svd.m_matrixU, m_workspace);+ if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation();+ return true;+ }+ return false;+ }+private:+ typedef FullPivHouseholderQR<MatrixType> QRType;+ QRType m_qr;+ WorkspaceType m_workspace;+};++template<typename MatrixType>+class qr_preconditioner_impl<MatrixType, FullPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>+{+public:+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ enum+ {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,+ Options = MatrixType::Options+ };+ typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime>+ TransposeTypeWithSameStorageOrder;++ void allocate(const JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd)+ {+ if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())+ {+ m_qr.~QRType();+ ::new (&m_qr) QRType(svd.cols(), svd.rows());+ }+ m_adjoint.resize(svd.cols(), svd.rows());+ if (svd.m_computeFullV) m_workspace.resize(svd.cols());+ }++ bool run(JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)+ {+ if(matrix.cols() > matrix.rows())+ {+ m_adjoint = matrix.adjoint();+ m_qr.compute(m_adjoint);+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint();+ if(svd.m_computeFullV) m_qr.matrixQ().evalTo(svd.m_matrixV, m_workspace);+ if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation();+ return true;+ }+ else return false;+ }+private:+ typedef FullPivHouseholderQR<TransposeTypeWithSameStorageOrder> QRType;+ QRType m_qr;+ TransposeTypeWithSameStorageOrder m_adjoint;+ typename internal::plain_row_type<MatrixType>::type m_workspace;+};++/*** preconditioner using ColPivHouseholderQR ***/++template<typename MatrixType>+class qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>+{+public:+ typedef typename MatrixType::Index Index;++ void allocate(const JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd)+ {+ if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())+ {+ m_qr.~QRType();+ ::new (&m_qr) QRType(svd.rows(), svd.cols());+ }+ if (svd.m_computeFullU) m_workspace.resize(svd.rows());+ else if (svd.m_computeThinU) m_workspace.resize(svd.cols());+ }++ bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)+ {+ if(matrix.rows() > matrix.cols())+ {+ m_qr.compute(matrix);+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>();+ if(svd.m_computeFullU) m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace);+ else if(svd.m_computeThinU)+ {+ svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols());+ m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace);+ }+ if(svd.computeV()) svd.m_matrixV = m_qr.colsPermutation();+ return true;+ }+ return false;+ }++private:+ typedef ColPivHouseholderQR<MatrixType> QRType;+ QRType m_qr;+ typename internal::plain_col_type<MatrixType>::type m_workspace;+};++template<typename MatrixType>+class qr_preconditioner_impl<MatrixType, ColPivHouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>+{+public:+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ enum+ {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,+ Options = MatrixType::Options+ };++ typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime>+ TransposeTypeWithSameStorageOrder;++ void allocate(const JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd)+ {+ if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())+ {+ m_qr.~QRType();+ ::new (&m_qr) QRType(svd.cols(), svd.rows());+ }+ if (svd.m_computeFullV) m_workspace.resize(svd.cols());+ else if (svd.m_computeThinV) m_workspace.resize(svd.rows());+ m_adjoint.resize(svd.cols(), svd.rows());+ }++ bool run(JacobiSVD<MatrixType, ColPivHouseholderQRPreconditioner>& svd, const MatrixType& matrix)+ {+ if(matrix.cols() > matrix.rows())+ {+ m_adjoint = matrix.adjoint();+ m_qr.compute(m_adjoint);++ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint();+ if(svd.m_computeFullV) m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace);+ else if(svd.m_computeThinV)+ {+ svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows());+ m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace);+ }+ if(svd.computeU()) svd.m_matrixU = m_qr.colsPermutation();+ return true;+ }+ else return false;+ }++private:+ typedef ColPivHouseholderQR<TransposeTypeWithSameStorageOrder> QRType;+ QRType m_qr;+ TransposeTypeWithSameStorageOrder m_adjoint;+ typename internal::plain_row_type<MatrixType>::type m_workspace;+};++/*** preconditioner using HouseholderQR ***/++template<typename MatrixType>+class qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreRowsThanCols, true>+{+public:+ typedef typename MatrixType::Index Index;++ void allocate(const JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd)+ {+ if (svd.rows() != m_qr.rows() || svd.cols() != m_qr.cols())+ {+ m_qr.~QRType();+ ::new (&m_qr) QRType(svd.rows(), svd.cols());+ }+ if (svd.m_computeFullU) m_workspace.resize(svd.rows());+ else if (svd.m_computeThinU) m_workspace.resize(svd.cols());+ }++ bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix)+ {+ if(matrix.rows() > matrix.cols())+ {+ m_qr.compute(matrix);+ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.cols(),matrix.cols()).template triangularView<Upper>();+ if(svd.m_computeFullU) m_qr.householderQ().evalTo(svd.m_matrixU, m_workspace);+ else if(svd.m_computeThinU)+ {+ svd.m_matrixU.setIdentity(matrix.rows(), matrix.cols());+ m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixU, m_workspace);+ }+ if(svd.computeV()) svd.m_matrixV.setIdentity(matrix.cols(), matrix.cols());+ return true;+ }+ return false;+ }+private:+ typedef HouseholderQR<MatrixType> QRType;+ QRType m_qr;+ typename internal::plain_col_type<MatrixType>::type m_workspace;+};++template<typename MatrixType>+class qr_preconditioner_impl<MatrixType, HouseholderQRPreconditioner, PreconditionIfMoreColsThanRows, true>+{+public:+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ enum+ {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,+ Options = MatrixType::Options+ };++ typedef Matrix<Scalar, ColsAtCompileTime, RowsAtCompileTime, Options, MaxColsAtCompileTime, MaxRowsAtCompileTime>+ TransposeTypeWithSameStorageOrder;++ void allocate(const JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd)+ {+ if (svd.cols() != m_qr.rows() || svd.rows() != m_qr.cols())+ {+ m_qr.~QRType();+ ::new (&m_qr) QRType(svd.cols(), svd.rows());+ }+ if (svd.m_computeFullV) m_workspace.resize(svd.cols());+ else if (svd.m_computeThinV) m_workspace.resize(svd.rows());+ m_adjoint.resize(svd.cols(), svd.rows());+ }++ bool run(JacobiSVD<MatrixType, HouseholderQRPreconditioner>& svd, const MatrixType& matrix)+ {+ if(matrix.cols() > matrix.rows())+ {+ m_adjoint = matrix.adjoint();+ m_qr.compute(m_adjoint);++ svd.m_workMatrix = m_qr.matrixQR().block(0,0,matrix.rows(),matrix.rows()).template triangularView<Upper>().adjoint();+ if(svd.m_computeFullV) m_qr.householderQ().evalTo(svd.m_matrixV, m_workspace);+ else if(svd.m_computeThinV)+ {+ svd.m_matrixV.setIdentity(matrix.cols(), matrix.rows());+ m_qr.householderQ().applyThisOnTheLeft(svd.m_matrixV, m_workspace);+ }+ if(svd.computeU()) svd.m_matrixU.setIdentity(matrix.rows(), matrix.rows());+ return true;+ }+ else return false;+ }++private:+ typedef HouseholderQR<TransposeTypeWithSameStorageOrder> QRType;+ QRType m_qr;+ TransposeTypeWithSameStorageOrder m_adjoint;+ typename internal::plain_row_type<MatrixType>::type m_workspace;+};++/*** 2x2 SVD implementation+ ***+ *** JacobiSVD consists in performing a series of 2x2 SVD subproblems+ ***/++template<typename MatrixType, int QRPreconditioner>+struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, false>+{+ typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;+ typedef typename SVD::Index Index;+ static void run(typename SVD::WorkMatrixType&, SVD&, Index, Index) {}+};++template<typename MatrixType, int QRPreconditioner>+struct svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner, true>+{+ typedef JacobiSVD<MatrixType, QRPreconditioner> SVD;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::RealScalar RealScalar;+ typedef typename SVD::Index Index;+ static void run(typename SVD::WorkMatrixType& work_matrix, SVD& svd, Index p, Index q)+ {+ using std::sqrt;+ Scalar z;+ JacobiRotation<Scalar> rot;+ RealScalar n = sqrt(numext::abs2(work_matrix.coeff(p,p)) + numext::abs2(work_matrix.coeff(q,p)));+ if(n==0)+ {+ z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);+ work_matrix.row(p) *= z;+ if(svd.computeU()) svd.m_matrixU.col(p) *= conj(z);+ z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);+ work_matrix.row(q) *= z;+ if(svd.computeU()) svd.m_matrixU.col(q) *= conj(z);+ }+ else+ {+ rot.c() = conj(work_matrix.coeff(p,p)) / n;+ rot.s() = work_matrix.coeff(q,p) / n;+ work_matrix.applyOnTheLeft(p,q,rot);+ if(svd.computeU()) svd.m_matrixU.applyOnTheRight(p,q,rot.adjoint());+ if(work_matrix.coeff(p,q) != Scalar(0))+ {+ Scalar z = abs(work_matrix.coeff(p,q)) / work_matrix.coeff(p,q);+ work_matrix.col(q) *= z;+ if(svd.computeV()) svd.m_matrixV.col(q) *= z;+ }+ if(work_matrix.coeff(q,q) != Scalar(0))+ {+ z = abs(work_matrix.coeff(q,q)) / work_matrix.coeff(q,q);+ work_matrix.row(q) *= z;+ if(svd.computeU()) svd.m_matrixU.col(q) *= conj(z);+ }+ }+ }+};++template<typename MatrixType, typename RealScalar, typename Index>+void real_2x2_jacobi_svd(const MatrixType& matrix, Index p, Index q,+ JacobiRotation<RealScalar> *j_left,+ JacobiRotation<RealScalar> *j_right)+{+ using std::sqrt;+ Matrix<RealScalar,2,2> m;+ m << numext::real(matrix.coeff(p,p)), numext::real(matrix.coeff(p,q)),+ numext::real(matrix.coeff(q,p)), numext::real(matrix.coeff(q,q));+ JacobiRotation<RealScalar> rot1;+ RealScalar t = m.coeff(0,0) + m.coeff(1,1);+ RealScalar d = m.coeff(1,0) - m.coeff(0,1);+ if(t == RealScalar(0))+ {+ rot1.c() = RealScalar(0);+ rot1.s() = d > RealScalar(0) ? RealScalar(1) : RealScalar(-1);+ }+ else+ {+ RealScalar u = d / t;+ rot1.c() = RealScalar(1) / sqrt(RealScalar(1) + numext::abs2(u));+ rot1.s() = rot1.c() * u;+ }+ m.applyOnTheLeft(0,1,rot1);+ j_right->makeJacobi(m,0,1);+ *j_left = rot1 * j_right->transpose();+}++} // end namespace internal++/** \ingroup SVD_Module+ *+ *+ * \class JacobiSVD+ *+ * \brief Two-sided Jacobi SVD decomposition of a rectangular matrix+ *+ * \param MatrixType the type of the matrix of which we are computing the SVD decomposition+ * \param QRPreconditioner this optional parameter allows to specify the type of QR decomposition that will be used internally+ * for the R-SVD step for non-square matrices. See discussion of possible values below.+ *+ * SVD decomposition consists in decomposing any n-by-p matrix \a A as a product+ * \f[ A = U S V^* \f]+ * where \a U is a n-by-n unitary, \a V is a p-by-p unitary, and \a S is a n-by-p real positive matrix which is zero outside of its main diagonal;+ * the diagonal entries of S are known as the \em singular \em values of \a A and the columns of \a U and \a V are known as the left+ * and right \em singular \em vectors of \a A respectively.+ *+ * Singular values are always sorted in decreasing order.+ *+ * This JacobiSVD decomposition computes only the singular values by default. If you want \a U or \a V, you need to ask for them explicitly.+ *+ * You can ask for only \em thin \a U or \a V to be computed, meaning the following. In case of a rectangular n-by-p matrix, letting \a m be the+ * smaller value among \a n and \a p, there are only \a m singular vectors; the remaining columns of \a U and \a V do not correspond to actual+ * singular vectors. Asking for \em thin \a U or \a V means asking for only their \a m first columns to be formed. So \a U is then a n-by-m matrix,+ * and \a V is then a p-by-m matrix. Notice that thin \a U and \a V are all you need for (least squares) solving.+ *+ * Here's an example demonstrating basic usage:+ * \include JacobiSVD_basic.cpp+ * Output: \verbinclude JacobiSVD_basic.out+ *+ * This JacobiSVD class is a two-sided Jacobi R-SVD decomposition, ensuring optimal reliability and accuracy. The downside is that it's slower than+ * bidiagonalizing SVD algorithms for large square matrices; however its complexity is still \f$ O(n^2p) \f$ where \a n is the smaller dimension and+ * \a p is the greater dimension, meaning that it is still of the same order of complexity as the faster bidiagonalizing R-SVD algorithms.+ * In particular, like any R-SVD, it takes advantage of non-squareness in that its complexity is only linear in the greater dimension.+ *+ * If the input matrix has inf or nan coefficients, the result of the computation is undefined, but the computation is guaranteed to+ * terminate in finite (and reasonable) time.+ *+ * The possible values for QRPreconditioner are:+ * \li ColPivHouseholderQRPreconditioner is the default. In practice it's very safe. It uses column-pivoting QR.+ * \li FullPivHouseholderQRPreconditioner, is the safest and slowest. It uses full-pivoting QR.+ * Contrary to other QRs, it doesn't allow computing thin unitaries.+ * \li HouseholderQRPreconditioner is the fastest, and less safe and accurate than the pivoting variants. It uses non-pivoting QR.+ * This is very similar in safety and accuracy to the bidiagonalization process used by bidiagonalizing SVD algorithms (since bidiagonalization+ * is inherently non-pivoting). However the resulting SVD is still more reliable than bidiagonalizing SVDs because the Jacobi-based iterarive+ * process is more reliable than the optimized bidiagonal SVD iterations.+ * \li NoQRPreconditioner allows not to use a QR preconditioner at all. This is useful if you know that you will only be computing+ * JacobiSVD decompositions of square matrices. Non-square matrices require a QR preconditioner. Using this option will result in+ * faster compilation and smaller executable code. It won't significantly speed up computation, since JacobiSVD is always checking+ * if QR preconditioning is needed before applying it anyway.+ *+ * \sa MatrixBase::jacobiSvd()+ */+template<typename _MatrixType, int QRPreconditioner> +class JacobiSVD : public SVDBase<_MatrixType>+{+ public:++ typedef _MatrixType MatrixType;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;+ typedef typename MatrixType::Index Index;+ enum {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,+ DiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime),+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,+ MaxDiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(MaxRowsAtCompileTime,MaxColsAtCompileTime),+ MatrixOptions = MatrixType::Options+ };++ typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime,+ MatrixOptions, MaxRowsAtCompileTime, MaxRowsAtCompileTime>+ MatrixUType;+ typedef Matrix<Scalar, ColsAtCompileTime, ColsAtCompileTime,+ MatrixOptions, MaxColsAtCompileTime, MaxColsAtCompileTime>+ MatrixVType;+ typedef typename internal::plain_diag_type<MatrixType, RealScalar>::type SingularValuesType;+ typedef typename internal::plain_row_type<MatrixType>::type RowType;+ typedef typename internal::plain_col_type<MatrixType>::type ColType;+ typedef Matrix<Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime,+ MatrixOptions, MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTime>+ WorkMatrixType;++ /** \brief Default Constructor.+ *+ * The default constructor is useful in cases in which the user intends to+ * perform decompositions via JacobiSVD::compute(const MatrixType&).+ */+ JacobiSVD()+ : SVDBase<_MatrixType>::SVDBase()+ {}+++ /** \brief Default Constructor with memory preallocation+ *+ * Like the default constructor but with preallocation of the internal data+ * according to the specified problem size.+ * \sa JacobiSVD()+ */+ JacobiSVD(Index rows, Index cols, unsigned int computationOptions = 0)+ : SVDBase<_MatrixType>::SVDBase() + {+ allocate(rows, cols, computationOptions);+ }++ /** \brief Constructor performing the decomposition of given matrix.+ *+ * \param matrix the matrix to decompose+ * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed.+ * By default, none is computed. This is a bit-field, the possible bits are #ComputeFullU, #ComputeThinU,+ * #ComputeFullV, #ComputeThinV.+ *+ * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not+ * available with the (non-default) FullPivHouseholderQR preconditioner.+ */+ JacobiSVD(const MatrixType& matrix, unsigned int computationOptions = 0)+ : SVDBase<_MatrixType>::SVDBase()+ {+ compute(matrix, computationOptions);+ }++ /** \brief Method performing the decomposition of given matrix using custom options.+ *+ * \param matrix the matrix to decompose+ * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed.+ * By default, none is computed. This is a bit-field, the possible bits are #ComputeFullU, #ComputeThinU,+ * #ComputeFullV, #ComputeThinV.+ *+ * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not+ * available with the (non-default) FullPivHouseholderQR preconditioner.+ */+ SVDBase<MatrixType>& compute(const MatrixType& matrix, unsigned int computationOptions);++ /** \brief Method performing the decomposition of given matrix using current options.+ *+ * \param matrix the matrix to decompose+ *+ * This method uses the current \a computationOptions, as already passed to the constructor or to compute(const MatrixType&, unsigned int).+ */+ SVDBase<MatrixType>& compute(const MatrixType& matrix)+ {+ return compute(matrix, this->m_computationOptions);+ }+ + /** \returns a (least squares) solution of \f$ A x = b \f$ using the current SVD decomposition of A.+ *+ * \param b the right-hand-side of the equation to solve.+ *+ * \note Solving requires both U and V to be computed. Thin U and V are enough, there is no need for full U or V.+ *+ * \note SVD solving is implicitly least-squares. Thus, this method serves both purposes of exact solving and least-squares solving.+ * In other words, the returned solution is guaranteed to minimize the Euclidean norm \f$ \Vert A x - b \Vert \f$.+ */+ template<typename Rhs>+ inline const internal::solve_retval<JacobiSVD, Rhs>+ solve(const MatrixBase<Rhs>& b) const+ {+ eigen_assert(this->m_isInitialized && "JacobiSVD is not initialized.");+ eigen_assert(SVDBase<MatrixType>::computeU() && SVDBase<MatrixType>::computeV() && "JacobiSVD::solve() requires both unitaries U and V to be computed (thin unitaries suffice).");+ return internal::solve_retval<JacobiSVD, Rhs>(*this, b.derived());+ }++ ++ private:+ void allocate(Index rows, Index cols, unsigned int computationOptions);++ protected:+ WorkMatrixType m_workMatrix;+ + template<typename __MatrixType, int _QRPreconditioner, bool _IsComplex>+ friend struct internal::svd_precondition_2x2_block_to_be_real;+ template<typename __MatrixType, int _QRPreconditioner, int _Case, bool _DoAnything>+ friend struct internal::qr_preconditioner_impl;++ internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreColsThanRows> m_qr_precond_morecols;+ internal::qr_preconditioner_impl<MatrixType, QRPreconditioner, internal::PreconditionIfMoreRowsThanCols> m_qr_precond_morerows;+};++template<typename MatrixType, int QRPreconditioner>+void JacobiSVD<MatrixType, QRPreconditioner>::allocate(Index rows, Index cols, unsigned int computationOptions)+{+ if (SVDBase<MatrixType>::allocate(rows, cols, computationOptions)) return;++ if (QRPreconditioner == FullPivHouseholderQRPreconditioner)+ {+ eigen_assert(!(this->m_computeThinU || this->m_computeThinV) &&+ "JacobiSVD: can't compute thin U or thin V with the FullPivHouseholderQR preconditioner. "+ "Use the ColPivHouseholderQR preconditioner instead.");+ }++ m_workMatrix.resize(this->m_diagSize, this->m_diagSize);+ + if(this->m_cols>this->m_rows) m_qr_precond_morecols.allocate(*this);+ if(this->m_rows>this->m_cols) m_qr_precond_morerows.allocate(*this);+}++template<typename MatrixType, int QRPreconditioner>+SVDBase<MatrixType>&+JacobiSVD<MatrixType, QRPreconditioner>::compute(const MatrixType& matrix, unsigned int computationOptions)+{+ using std::abs;+ allocate(matrix.rows(), matrix.cols(), computationOptions);++ // currently we stop when we reach precision 2*epsilon as the last bit of precision can require an unreasonable number of iterations,+ // only worsening the precision of U and V as we accumulate more rotations+ const RealScalar precision = RealScalar(2) * NumTraits<Scalar>::epsilon();++ // limit for very small denormal numbers to be considered zero in order to avoid infinite loops (see bug 286)+ const RealScalar considerAsZero = RealScalar(2) * std::numeric_limits<RealScalar>::denorm_min();++ /*** step 1. The R-SVD step: we use a QR decomposition to reduce to the case of a square matrix */++ if(!m_qr_precond_morecols.run(*this, matrix) && !m_qr_precond_morerows.run(*this, matrix))+ {+ m_workMatrix = matrix.block(0,0,this->m_diagSize,this->m_diagSize);+ if(this->m_computeFullU) this->m_matrixU.setIdentity(this->m_rows,this->m_rows);+ if(this->m_computeThinU) this->m_matrixU.setIdentity(this->m_rows,this->m_diagSize);+ if(this->m_computeFullV) this->m_matrixV.setIdentity(this->m_cols,this->m_cols);+ if(this->m_computeThinV) this->m_matrixV.setIdentity(this->m_cols, this->m_diagSize);+ }++ /*** step 2. The main Jacobi SVD iteration. ***/++ bool finished = false;+ while(!finished)+ {+ finished = true;++ // do a sweep: for all index pairs (p,q), perform SVD of the corresponding 2x2 sub-matrix++ for(Index p = 1; p < this->m_diagSize; ++p)+ {+ for(Index q = 0; q < p; ++q)+ {+ // if this 2x2 sub-matrix is not diagonal already...+ // notice that this comparison will evaluate to false if any NaN is involved, ensuring that NaN's don't+ // keep us iterating forever. Similarly, small denormal numbers are considered zero.+ using std::max;+ RealScalar threshold = (max)(considerAsZero, precision * (max)(abs(m_workMatrix.coeff(p,p)),+ abs(m_workMatrix.coeff(q,q))));+ if((max)(abs(m_workMatrix.coeff(p,q)),abs(m_workMatrix.coeff(q,p))) > threshold)+ {+ finished = false;++ // perform SVD decomposition of 2x2 sub-matrix corresponding to indices p,q to make it diagonal+ internal::svd_precondition_2x2_block_to_be_real<MatrixType, QRPreconditioner>::run(m_workMatrix, *this, p, q);+ JacobiRotation<RealScalar> j_left, j_right;+ internal::real_2x2_jacobi_svd(m_workMatrix, p, q, &j_left, &j_right);++ // accumulate resulting Jacobi rotations+ m_workMatrix.applyOnTheLeft(p,q,j_left);+ if(SVDBase<MatrixType>::computeU()) this->m_matrixU.applyOnTheRight(p,q,j_left.transpose());++ m_workMatrix.applyOnTheRight(p,q,j_right);+ if(SVDBase<MatrixType>::computeV()) this->m_matrixV.applyOnTheRight(p,q,j_right);+ }+ }+ }+ }++ /*** step 3. The work matrix is now diagonal, so ensure it's positive so its diagonal entries are the singular values ***/++ for(Index i = 0; i < this->m_diagSize; ++i)+ {+ RealScalar a = abs(m_workMatrix.coeff(i,i));+ this->m_singularValues.coeffRef(i) = a;+ if(SVDBase<MatrixType>::computeU() && (a!=RealScalar(0))) this->m_matrixU.col(i) *= this->m_workMatrix.coeff(i,i)/a;+ }++ /*** step 4. Sort singular values in descending order and compute the number of nonzero singular values ***/++ this->m_nonzeroSingularValues = this->m_diagSize;+ for(Index i = 0; i < this->m_diagSize; i++)+ {+ Index pos;+ RealScalar maxRemainingSingularValue = this->m_singularValues.tail(this->m_diagSize-i).maxCoeff(&pos);+ if(maxRemainingSingularValue == RealScalar(0))+ {+ this->m_nonzeroSingularValues = i;+ break;+ }+ if(pos)+ {+ pos += i;+ std::swap(this->m_singularValues.coeffRef(i), this->m_singularValues.coeffRef(pos));+ if(SVDBase<MatrixType>::computeU()) this->m_matrixU.col(pos).swap(this->m_matrixU.col(i));+ if(SVDBase<MatrixType>::computeV()) this->m_matrixV.col(pos).swap(this->m_matrixV.col(i));+ }+ }++ this->m_isInitialized = true;+ return *this;+}++namespace internal {+template<typename _MatrixType, int QRPreconditioner, typename Rhs>+struct solve_retval<JacobiSVD<_MatrixType, QRPreconditioner>, Rhs>+ : solve_retval_base<JacobiSVD<_MatrixType, QRPreconditioner>, Rhs>+{+ typedef JacobiSVD<_MatrixType, QRPreconditioner> JacobiSVDType;+ EIGEN_MAKE_SOLVE_HELPERS(JacobiSVDType,Rhs)++ template<typename Dest> void evalTo(Dest& dst) const+ {+ eigen_assert(rhs().rows() == dec().rows());++ // A = U S V^*+ // So A^{-1} = V S^{-1} U^*++ Index diagSize = (std::min)(dec().rows(), dec().cols());+ typename JacobiSVDType::SingularValuesType invertedSingVals(diagSize);++ Index nonzeroSingVals = dec().nonzeroSingularValues();+ invertedSingVals.head(nonzeroSingVals) = dec().singularValues().head(nonzeroSingVals).array().inverse();+ invertedSingVals.tail(diagSize - nonzeroSingVals).setZero();++ dst = dec().matrixV().leftCols(diagSize)+ * invertedSingVals.asDiagonal()+ * dec().matrixU().leftCols(diagSize).adjoint()+ * rhs();+ }+};+} // end namespace internal++/** \svd_module+ *+ * \return the singular value decomposition of \c *this computed by two-sided+ * Jacobi transformations.+ *+ * \sa class JacobiSVD+ */+template<typename Derived>+JacobiSVD<typename MatrixBase<Derived>::PlainObject>+MatrixBase<Derived>::jacobiSvd(unsigned int computationOptions) const+{+ return JacobiSVD<PlainObject>(*this, computationOptions);+}++} // end namespace Eigen++#endif // EIGEN_JACOBISVD_H
+ eigen3/unsupported/Eigen/src/SVD/SVDBase.h view
@@ -0,0 +1,236 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009-2010 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// Copyright (C) 2013 Gauthier Brun <brun.gauthier@gmail.com>+// Copyright (C) 2013 Nicolas Carre <nicolas.carre@ensimag.fr>+// Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>+// Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_SVD_H+#define EIGEN_SVD_H++namespace Eigen {+/** \ingroup SVD_Module+ *+ *+ * \class SVDBase+ *+ * \brief Mother class of SVD classes algorithms+ *+ * \param MatrixType the type of the matrix of which we are computing the SVD decomposition+ * SVD decomposition consists in decomposing any n-by-p matrix \a A as a product+ * \f[ A = U S V^* \f]+ * where \a U is a n-by-n unitary, \a V is a p-by-p unitary, and \a S is a n-by-p real positive matrix which is zero outside of its main diagonal;+ * the diagonal entries of S are known as the \em singular \em values of \a A and the columns of \a U and \a V are known as the left+ * and right \em singular \em vectors of \a A respectively.+ *+ * Singular values are always sorted in decreasing order.+ *+ * + * You can ask for only \em thin \a U or \a V to be computed, meaning the following. In case of a rectangular n-by-p matrix, letting \a m be the+ * smaller value among \a n and \a p, there are only \a m singular vectors; the remaining columns of \a U and \a V do not correspond to actual+ * singular vectors. Asking for \em thin \a U or \a V means asking for only their \a m first columns to be formed. So \a U is then a n-by-m matrix,+ * and \a V is then a p-by-m matrix. Notice that thin \a U and \a V are all you need for (least squares) solving.+ * + * If the input matrix has inf or nan coefficients, the result of the computation is undefined, but the computation is guaranteed to+ * terminate in finite (and reasonable) time.+ * \sa MatrixBase::genericSvd()+ */+template<typename _MatrixType> +class SVDBase+{++public:+ typedef _MatrixType MatrixType;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;+ typedef typename MatrixType::Index Index;+ enum {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,+ ColsAtCompileTime = MatrixType::ColsAtCompileTime,+ DiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime),+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime,+ MaxDiagSizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_FIXED(MaxRowsAtCompileTime,MaxColsAtCompileTime),+ MatrixOptions = MatrixType::Options+ };++ typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime,+ MatrixOptions, MaxRowsAtCompileTime, MaxRowsAtCompileTime>+ MatrixUType;+ typedef Matrix<Scalar, ColsAtCompileTime, ColsAtCompileTime,+ MatrixOptions, MaxColsAtCompileTime, MaxColsAtCompileTime>+ MatrixVType;+ typedef typename internal::plain_diag_type<MatrixType, RealScalar>::type SingularValuesType;+ typedef typename internal::plain_row_type<MatrixType>::type RowType;+ typedef typename internal::plain_col_type<MatrixType>::type ColType;+ typedef Matrix<Scalar, DiagSizeAtCompileTime, DiagSizeAtCompileTime,+ MatrixOptions, MaxDiagSizeAtCompileTime, MaxDiagSizeAtCompileTime>+ WorkMatrixType;+ ++++ /** \brief Method performing the decomposition of given matrix using custom options.+ *+ * \param matrix the matrix to decompose+ * \param computationOptions optional parameter allowing to specify if you want full or thin U or V unitaries to be computed.+ * By default, none is computed. This is a bit-field, the possible bits are #ComputeFullU, #ComputeThinU,+ * #ComputeFullV, #ComputeThinV.+ *+ * Thin unitaries are only available if your matrix type has a Dynamic number of columns (for example MatrixXf). They also are not+ * available with the (non-default) FullPivHouseholderQR preconditioner.+ */+ SVDBase& compute(const MatrixType& matrix, unsigned int computationOptions);++ /** \brief Method performing the decomposition of given matrix using current options.+ *+ * \param matrix the matrix to decompose+ *+ * This method uses the current \a computationOptions, as already passed to the constructor or to compute(const MatrixType&, unsigned int).+ */+ //virtual SVDBase& compute(const MatrixType& matrix) = 0;+ SVDBase& compute(const MatrixType& matrix);++ /** \returns the \a U matrix.+ *+ * For the SVDBase decomposition of a n-by-p matrix, letting \a m be the minimum of \a n and \a p,+ * the U matrix is n-by-n if you asked for #ComputeFullU, and is n-by-m if you asked for #ComputeThinU.+ *+ * The \a m first columns of \a U are the left singular vectors of the matrix being decomposed.+ *+ * This method asserts that you asked for \a U to be computed.+ */+ const MatrixUType& matrixU() const+ {+ eigen_assert(m_isInitialized && "SVD is not initialized.");+ eigen_assert(computeU() && "This SVD decomposition didn't compute U. Did you ask for it?");+ return m_matrixU;+ }++ /** \returns the \a V matrix.+ *+ * For the SVD decomposition of a n-by-p matrix, letting \a m be the minimum of \a n and \a p,+ * the V matrix is p-by-p if you asked for #ComputeFullV, and is p-by-m if you asked for ComputeThinV.+ *+ * The \a m first columns of \a V are the right singular vectors of the matrix being decomposed.+ *+ * This method asserts that you asked for \a V to be computed.+ */+ const MatrixVType& matrixV() const+ {+ eigen_assert(m_isInitialized && "SVD is not initialized.");+ eigen_assert(computeV() && "This SVD decomposition didn't compute V. Did you ask for it?");+ return m_matrixV;+ }++ /** \returns the vector of singular values.+ *+ * For the SVD decomposition of a n-by-p matrix, letting \a m be the minimum of \a n and \a p, the+ * returned vector has size \a m. Singular values are always sorted in decreasing order.+ */+ const SingularValuesType& singularValues() const+ {+ eigen_assert(m_isInitialized && "SVD is not initialized.");+ return m_singularValues;+ }++ ++ /** \returns the number of singular values that are not exactly 0 */+ Index nonzeroSingularValues() const+ {+ eigen_assert(m_isInitialized && "SVD is not initialized.");+ return m_nonzeroSingularValues;+ }+++ /** \returns true if \a U (full or thin) is asked for in this SVD decomposition */+ inline bool computeU() const { return m_computeFullU || m_computeThinU; }+ /** \returns true if \a V (full or thin) is asked for in this SVD decomposition */+ inline bool computeV() const { return m_computeFullV || m_computeThinV; }+++ inline Index rows() const { return m_rows; }+ inline Index cols() const { return m_cols; }+++protected:+ // return true if already allocated+ bool allocate(Index rows, Index cols, unsigned int computationOptions) ;++ MatrixUType m_matrixU;+ MatrixVType m_matrixV;+ SingularValuesType m_singularValues;+ bool m_isInitialized, m_isAllocated;+ bool m_computeFullU, m_computeThinU;+ bool m_computeFullV, m_computeThinV;+ unsigned int m_computationOptions;+ Index m_nonzeroSingularValues, m_rows, m_cols, m_diagSize;+++ /** \brief Default Constructor.+ *+ * Default constructor of SVDBase+ */+ SVDBase()+ : m_isInitialized(false),+ m_isAllocated(false),+ m_computationOptions(0),+ m_rows(-1), m_cols(-1)+ {}+++};+++template<typename MatrixType>+bool SVDBase<MatrixType>::allocate(Index rows, Index cols, unsigned int computationOptions)+{+ eigen_assert(rows >= 0 && cols >= 0);++ if (m_isAllocated &&+ rows == m_rows &&+ cols == m_cols &&+ computationOptions == m_computationOptions)+ {+ return true;+ }++ m_rows = rows;+ m_cols = cols;+ m_isInitialized = false;+ m_isAllocated = true;+ m_computationOptions = computationOptions;+ m_computeFullU = (computationOptions & ComputeFullU) != 0;+ m_computeThinU = (computationOptions & ComputeThinU) != 0;+ m_computeFullV = (computationOptions & ComputeFullV) != 0;+ m_computeThinV = (computationOptions & ComputeThinV) != 0;+ eigen_assert(!(m_computeFullU && m_computeThinU) && "SVDBase: you can't ask for both full and thin U");+ eigen_assert(!(m_computeFullV && m_computeThinV) && "SVDBase: you can't ask for both full and thin V");+ eigen_assert(EIGEN_IMPLIES(m_computeThinU || m_computeThinV, MatrixType::ColsAtCompileTime==Dynamic) &&+ "SVDBase: thin U and V are only available when your matrix has a dynamic number of columns.");++ m_diagSize = (std::min)(m_rows, m_cols);+ m_singularValues.resize(m_diagSize);+ if(RowsAtCompileTime==Dynamic)+ m_matrixU.resize(m_rows, m_computeFullU ? m_rows+ : m_computeThinU ? m_diagSize+ : 0);+ if(ColsAtCompileTime==Dynamic)+ m_matrixV.resize(m_cols, m_computeFullV ? m_cols+ : m_computeThinV ? m_diagSize+ : 0);++ return false;+}++}// end namespace++#endif // EIGEN_SVD_H
+ eigen3/unsupported/Eigen/src/SVD/TODOBdcsvd.txt view
@@ -0,0 +1,29 @@+TO DO LIST++++(optional optimization) - do all the allocations in the allocate part + - support static matrices+ - return a error at compilation time when using integer matrices (int, long, std::complex<int>, ...)++to finish the algorithm :+ -implement the last part of the algorithm as described on the reference paper. + You may find more information on that part on this paper++ -to replace the call to JacobiSVD at the end of the divide algorithm, just after the call to + deflation.++(suggested step by step resolution)+ 0) comment the call to Jacobi in the last part of the divide method and everything right after+ until the end of the method. What is commented can be a guideline to steps 3) 4) and 6)+ 1) solve the secular equation (Characteristic equation) on the values that are not null (zi!=0 and di!=0), after the deflation+ wich should be uncommented in the divide method+ 2) remember the values of the singular values that are already computed (zi=0)+ 3) assign the singular values found in m_computed at the right places (with the ones found in step 2) )+ in decreasing order+ 4) set the firstcol to zero (except the first element) in m_computed+ 5) compute all the singular vectors when CompV is set to true and only the left vectors when+ CompV is set to false+ 6) multiply naiveU and naiveV to the right by the matrices found, only naiveU when CompV is set to+ false, /!\ if CompU is false NaiveU has only 2 rows+ 7) delete everything commented in step 0)
+ eigen3/unsupported/Eigen/src/SVD/doneInBDCSVD.txt view
@@ -0,0 +1,21 @@+This unsupported package is about a divide and conquer algorithm to compute SVD.++The implementation follows as closely as possible the following reference paper : +http://www.cs.yale.edu/publications/techreports/tr933.pdf++The code documentation uses the same names for variables as the reference paper. The code, deflation included, is+working but there are a few things that could be optimised as explained in the TODOBdsvd. ++In the code comments were put at the line where would be the third step of the algorithm so one could simply add the call +of a function doing the last part of the algorithm and that would not require any knowledge of the part we implemented.++In the TODOBdcsvd we explain what is the main difficulty of the last part and suggest a reference paper to help solve it.++The implemented has trouble with fixed size matrices. ++In the actual implementation, it returns matrices of zero when ask to do a svd on an int matrix. +++Paper for the third part:+http://www.stat.uchicago.edu/~lekheng/courses/302/classics/greengard-rokhlin.pdf+
+ eigen3/unsupported/Eigen/src/Skyline/CMakeLists.txt view
@@ -0,0 +1,6 @@+FILE(GLOB Eigen_Skyline_SRCS "*.h")++INSTALL(FILES+ ${Eigen_Skyline_SRCS}+ DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/Skyline COMPONENT Devel+ )
+ eigen3/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h view
@@ -0,0 +1,352 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Guillaume Saupin <guillaume.saupin@cea.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_SKYLINEINPLACELU_H+#define EIGEN_SKYLINEINPLACELU_H++namespace Eigen { ++/** \ingroup Skyline_Module+ *+ * \class SkylineInplaceLU+ *+ * \brief Inplace LU decomposition of a skyline matrix and associated features+ *+ * \param MatrixType the type of the matrix of which we are computing the LU factorization+ *+ */+template<typename MatrixType>+class SkylineInplaceLU {+protected:+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::Index Index;+ + typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;++public:++ /** Creates a LU object and compute the respective factorization of \a matrix using+ * flags \a flags. */+ SkylineInplaceLU(MatrixType& matrix, int flags = 0)+ : /*m_matrix(matrix.rows(), matrix.cols()),*/ m_flags(flags), m_status(0), m_lu(matrix) {+ m_precision = RealScalar(0.1) * Eigen::dummy_precision<RealScalar > ();+ m_lu.IsRowMajor ? computeRowMajor() : compute();+ }++ /** Sets the relative threshold value used to prune zero coefficients during the decomposition.+ *+ * Setting a value greater than zero speeds up computation, and yields to an imcomplete+ * factorization with fewer non zero coefficients. Such approximate factors are especially+ * useful to initialize an iterative solver.+ *+ * Note that the exact meaning of this parameter might depends on the actual+ * backend. Moreover, not all backends support this feature.+ *+ * \sa precision() */+ void setPrecision(RealScalar v) {+ m_precision = v;+ }++ /** \returns the current precision.+ *+ * \sa setPrecision() */+ RealScalar precision() const {+ return m_precision;+ }++ /** Sets the flags. Possible values are:+ * - CompleteFactorization+ * - IncompleteFactorization+ * - MemoryEfficient+ * - one of the ordering methods+ * - etc...+ *+ * \sa flags() */+ void setFlags(int f) {+ m_flags = f;+ }++ /** \returns the current flags */+ int flags() const {+ return m_flags;+ }++ void setOrderingMethod(int m) {+ m_flags = m;+ }++ int orderingMethod() const {+ return m_flags;+ }++ /** Computes/re-computes the LU factorization */+ void compute();+ void computeRowMajor();++ /** \returns the lower triangular matrix L */+ //inline const MatrixType& matrixL() const { return m_matrixL; }++ /** \returns the upper triangular matrix U */+ //inline const MatrixType& matrixU() const { return m_matrixU; }++ template<typename BDerived, typename XDerived>+ bool solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived>* x,+ const int transposed = 0) const;++ /** \returns true if the factorization succeeded */+ inline bool succeeded(void) const {+ return m_succeeded;+ }++protected:+ RealScalar m_precision;+ int m_flags;+ mutable int m_status;+ bool m_succeeded;+ MatrixType& m_lu;+};++/** Computes / recomputes the in place LU decomposition of the SkylineInplaceLU.+ * using the default algorithm.+ */+template<typename MatrixType>+//template<typename _Scalar>+void SkylineInplaceLU<MatrixType>::compute() {+ const size_t rows = m_lu.rows();+ const size_t cols = m_lu.cols();++ eigen_assert(rows == cols && "We do not (yet) support rectangular LU.");+ eigen_assert(!m_lu.IsRowMajor && "LU decomposition does not work with rowMajor Storage");++ for (Index row = 0; row < rows; row++) {+ const double pivot = m_lu.coeffDiag(row);++ //Lower matrix Columns update+ const Index& col = row;+ for (typename MatrixType::InnerLowerIterator lIt(m_lu, col); lIt; ++lIt) {+ lIt.valueRef() /= pivot;+ }++ //Upper matrix update -> contiguous memory access+ typename MatrixType::InnerLowerIterator lIt(m_lu, col);+ for (Index rrow = row + 1; rrow < m_lu.rows(); rrow++) {+ typename MatrixType::InnerUpperIterator uItPivot(m_lu, row);+ typename MatrixType::InnerUpperIterator uIt(m_lu, rrow);+ const double coef = lIt.value();++ uItPivot += (rrow - row - 1);++ //update upper part -> contiguous memory access+ for (++uItPivot; uIt && uItPivot;) {+ uIt.valueRef() -= uItPivot.value() * coef;++ ++uIt;+ ++uItPivot;+ }+ ++lIt;+ }++ //Upper matrix update -> non contiguous memory access+ typename MatrixType::InnerLowerIterator lIt3(m_lu, col);+ for (Index rrow = row + 1; rrow < m_lu.rows(); rrow++) {+ typename MatrixType::InnerUpperIterator uItPivot(m_lu, row);+ const double coef = lIt3.value();++ //update lower part -> non contiguous memory access+ for (Index i = 0; i < rrow - row - 1; i++) {+ m_lu.coeffRefLower(rrow, row + i + 1) -= uItPivot.value() * coef;+ ++uItPivot;+ }+ ++lIt3;+ }+ //update diag -> contiguous+ typename MatrixType::InnerLowerIterator lIt2(m_lu, col);+ for (Index rrow = row + 1; rrow < m_lu.rows(); rrow++) {++ typename MatrixType::InnerUpperIterator uItPivot(m_lu, row);+ typename MatrixType::InnerUpperIterator uIt(m_lu, rrow);+ const double coef = lIt2.value();++ uItPivot += (rrow - row - 1);+ m_lu.coeffRefDiag(rrow) -= uItPivot.value() * coef;+ ++lIt2;+ }+ }+}++template<typename MatrixType>+void SkylineInplaceLU<MatrixType>::computeRowMajor() {+ const size_t rows = m_lu.rows();+ const size_t cols = m_lu.cols();++ eigen_assert(rows == cols && "We do not (yet) support rectangular LU.");+ eigen_assert(m_lu.IsRowMajor && "You're trying to apply rowMajor decomposition on a ColMajor matrix !");++ for (Index row = 0; row < rows; row++) {+ typename MatrixType::InnerLowerIterator llIt(m_lu, row);+++ for (Index col = llIt.col(); col < row; col++) {+ if (m_lu.coeffExistLower(row, col)) {+ const double diag = m_lu.coeffDiag(col);++ typename MatrixType::InnerLowerIterator lIt(m_lu, row);+ typename MatrixType::InnerUpperIterator uIt(m_lu, col);+++ const Index offset = lIt.col() - uIt.row();+++ Index stop = offset > 0 ? col - lIt.col() : col - uIt.row();++ //#define VECTORIZE+#ifdef VECTORIZE+ Map<VectorXd > rowVal(lIt.valuePtr() + (offset > 0 ? 0 : -offset), stop);+ Map<VectorXd > colVal(uIt.valuePtr() + (offset > 0 ? offset : 0), stop);+++ Scalar newCoeff = m_lu.coeffLower(row, col) - rowVal.dot(colVal);+#else+ if (offset > 0) //Skip zero value of lIt+ uIt += offset;+ else //Skip zero values of uIt+ lIt += -offset;+ Scalar newCoeff = m_lu.coeffLower(row, col);++ for (Index k = 0; k < stop; ++k) {+ const Scalar tmp = newCoeff;+ newCoeff = tmp - lIt.value() * uIt.value();+ ++lIt;+ ++uIt;+ }+#endif++ m_lu.coeffRefLower(row, col) = newCoeff / diag;+ }+ }++ //Upper matrix update+ const Index col = row;+ typename MatrixType::InnerUpperIterator uuIt(m_lu, col);+ for (Index rrow = uuIt.row(); rrow < col; rrow++) {++ typename MatrixType::InnerLowerIterator lIt(m_lu, rrow);+ typename MatrixType::InnerUpperIterator uIt(m_lu, col);+ const Index offset = lIt.col() - uIt.row();++ Index stop = offset > 0 ? rrow - lIt.col() : rrow - uIt.row();++#ifdef VECTORIZE+ Map<VectorXd > rowVal(lIt.valuePtr() + (offset > 0 ? 0 : -offset), stop);+ Map<VectorXd > colVal(uIt.valuePtr() + (offset > 0 ? offset : 0), stop);++ Scalar newCoeff = m_lu.coeffUpper(rrow, col) - rowVal.dot(colVal);+#else+ if (offset > 0) //Skip zero value of lIt+ uIt += offset;+ else //Skip zero values of uIt+ lIt += -offset;+ Scalar newCoeff = m_lu.coeffUpper(rrow, col);+ for (Index k = 0; k < stop; ++k) {+ const Scalar tmp = newCoeff;+ newCoeff = tmp - lIt.value() * uIt.value();++ ++lIt;+ ++uIt;+ }+#endif+ m_lu.coeffRefUpper(rrow, col) = newCoeff;+ }+++ //Diag matrix update+ typename MatrixType::InnerLowerIterator lIt(m_lu, row);+ typename MatrixType::InnerUpperIterator uIt(m_lu, row);++ const Index offset = lIt.col() - uIt.row();+++ Index stop = offset > 0 ? lIt.size() : uIt.size();+#ifdef VECTORIZE+ Map<VectorXd > rowVal(lIt.valuePtr() + (offset > 0 ? 0 : -offset), stop);+ Map<VectorXd > colVal(uIt.valuePtr() + (offset > 0 ? offset : 0), stop);+ Scalar newCoeff = m_lu.coeffDiag(row) - rowVal.dot(colVal);+#else+ if (offset > 0) //Skip zero value of lIt+ uIt += offset;+ else //Skip zero values of uIt+ lIt += -offset;+ Scalar newCoeff = m_lu.coeffDiag(row);+ for (Index k = 0; k < stop; ++k) {+ const Scalar tmp = newCoeff;+ newCoeff = tmp - lIt.value() * uIt.value();+ ++lIt;+ ++uIt;+ }+#endif+ m_lu.coeffRefDiag(row) = newCoeff;+ }+}++/** Computes *x = U^-1 L^-1 b+ *+ * If \a transpose is set to SvTranspose or SvAdjoint, the solution+ * of the transposed/adjoint system is computed instead.+ *+ * Not all backends implement the solution of the transposed or+ * adjoint system.+ */+template<typename MatrixType>+template<typename BDerived, typename XDerived>+bool SkylineInplaceLU<MatrixType>::solve(const MatrixBase<BDerived> &b, MatrixBase<XDerived>* x, const int transposed) const {+ const size_t rows = m_lu.rows();+ const size_t cols = m_lu.cols();+++ for (Index row = 0; row < rows; row++) {+ x->coeffRef(row) = b.coeff(row);+ Scalar newVal = x->coeff(row);+ typename MatrixType::InnerLowerIterator lIt(m_lu, row);++ Index col = lIt.col();+ while (lIt.col() < row) {++ newVal -= x->coeff(col++) * lIt.value();+ ++lIt;+ }++ x->coeffRef(row) = newVal;+ }+++ for (Index col = rows - 1; col > 0; col--) {+ x->coeffRef(col) = x->coeff(col) / m_lu.coeffDiag(col);++ const Scalar x_col = x->coeff(col);++ typename MatrixType::InnerUpperIterator uIt(m_lu, col);+ uIt += uIt.size()-1;+++ while (uIt) {+ x->coeffRef(uIt.row()) -= x_col * uIt.value();+ //TODO : introduce --operator+ uIt += -1;+ }+++ }+ x->coeffRef(0) = x->coeff(0) / m_lu.coeffDiag(0);++ return true;+}++} // end namespace Eigen++#endif // EIGEN_SKYLINELU_H
+ eigen3/unsupported/Eigen/src/Skyline/SkylineMatrix.h view
@@ -0,0 +1,862 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Guillaume Saupin <guillaume.saupin@cea.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_SKYLINEMATRIX_H+#define EIGEN_SKYLINEMATRIX_H++#include "SkylineStorage.h"+#include "SkylineMatrixBase.h"++namespace Eigen { ++/** \ingroup Skyline_Module+ *+ * \class SkylineMatrix+ *+ * \brief The main skyline matrix class+ *+ * This class implements a skyline matrix using the very uncommon storage+ * scheme.+ *+ * \param _Scalar the scalar type, i.e. the type of the coefficients+ * \param _Options Union of bit flags controlling the storage scheme. Currently the only possibility+ * is RowMajor. The default is 0 which means column-major.+ *+ *+ */+namespace internal {+template<typename _Scalar, int _Options>+struct traits<SkylineMatrix<_Scalar, _Options> > {+ typedef _Scalar Scalar;+ typedef Sparse StorageKind;++ enum {+ RowsAtCompileTime = Dynamic,+ ColsAtCompileTime = Dynamic,+ MaxRowsAtCompileTime = Dynamic,+ MaxColsAtCompileTime = Dynamic,+ Flags = SkylineBit | _Options,+ CoeffReadCost = NumTraits<Scalar>::ReadCost,+ };+};+}++template<typename _Scalar, int _Options>+class SkylineMatrix+: public SkylineMatrixBase<SkylineMatrix<_Scalar, _Options> > {+public:+ EIGEN_SKYLINE_GENERIC_PUBLIC_INTERFACE(SkylineMatrix)+ EIGEN_SKYLINE_INHERIT_ASSIGNMENT_OPERATOR(SkylineMatrix, +=)+ EIGEN_SKYLINE_INHERIT_ASSIGNMENT_OPERATOR(SkylineMatrix, -=)++ using Base::IsRowMajor;++protected:++ typedef SkylineMatrix<Scalar, (Flags&~RowMajorBit) | (IsRowMajor ? RowMajorBit : 0) > TransposedSkylineMatrix;++ Index m_outerSize;+ Index m_innerSize;++public:+ Index* m_colStartIndex;+ Index* m_rowStartIndex;+ SkylineStorage<Scalar> m_data;++public:++ inline Index rows() const {+ return IsRowMajor ? m_outerSize : m_innerSize;+ }++ inline Index cols() const {+ return IsRowMajor ? m_innerSize : m_outerSize;+ }++ inline Index innerSize() const {+ return m_innerSize;+ }++ inline Index outerSize() const {+ return m_outerSize;+ }++ inline Index upperNonZeros() const {+ return m_data.upperSize();+ }++ inline Index lowerNonZeros() const {+ return m_data.lowerSize();+ }++ inline Index upperNonZeros(Index j) const {+ return m_colStartIndex[j + 1] - m_colStartIndex[j];+ }++ inline Index lowerNonZeros(Index j) const {+ return m_rowStartIndex[j + 1] - m_rowStartIndex[j];+ }++ inline const Scalar* _diagPtr() const {+ return &m_data.diag(0);+ }++ inline Scalar* _diagPtr() {+ return &m_data.diag(0);+ }++ inline const Scalar* _upperPtr() const {+ return &m_data.upper(0);+ }++ inline Scalar* _upperPtr() {+ return &m_data.upper(0);+ }++ inline const Scalar* _lowerPtr() const {+ return &m_data.lower(0);+ }++ inline Scalar* _lowerPtr() {+ return &m_data.lower(0);+ }++ inline const Index* _upperProfilePtr() const {+ return &m_data.upperProfile(0);+ }++ inline Index* _upperProfilePtr() {+ return &m_data.upperProfile(0);+ }++ inline const Index* _lowerProfilePtr() const {+ return &m_data.lowerProfile(0);+ }++ inline Index* _lowerProfilePtr() {+ return &m_data.lowerProfile(0);+ }++ inline Scalar coeff(Index row, Index col) const {+ const Index outer = IsRowMajor ? row : col;+ const Index inner = IsRowMajor ? col : row;++ eigen_assert(outer < outerSize());+ eigen_assert(inner < innerSize());++ if (outer == inner)+ return this->m_data.diag(outer);++ if (IsRowMajor) {+ if (inner > outer) //upper matrix+ {+ const Index minOuterIndex = inner - m_data.upperProfile(inner);+ if (outer >= minOuterIndex)+ return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));+ else+ return Scalar(0);+ }+ if (inner < outer) //lower matrix+ {+ const Index minInnerIndex = outer - m_data.lowerProfile(outer);+ if (inner >= minInnerIndex)+ return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));+ else+ return Scalar(0);+ }+ return m_data.upper(m_colStartIndex[inner] + outer - inner);+ } else {+ if (outer > inner) //upper matrix+ {+ const Index maxOuterIndex = inner + m_data.upperProfile(inner);+ if (outer <= maxOuterIndex)+ return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));+ else+ return Scalar(0);+ }+ if (outer < inner) //lower matrix+ {+ const Index maxInnerIndex = outer + m_data.lowerProfile(outer);++ if (inner <= maxInnerIndex)+ return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));+ else+ return Scalar(0);+ }+ }+ }++ inline Scalar& coeffRef(Index row, Index col) {+ const Index outer = IsRowMajor ? row : col;+ const Index inner = IsRowMajor ? col : row;++ eigen_assert(outer < outerSize());+ eigen_assert(inner < innerSize());++ if (outer == inner)+ return this->m_data.diag(outer);++ if (IsRowMajor) {+ if (col > row) //upper matrix+ {+ const Index minOuterIndex = inner - m_data.upperProfile(inner);+ eigen_assert(outer >= minOuterIndex && "you try to acces a coeff that do not exist in the storage");+ return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));+ }+ if (col < row) //lower matrix+ {+ const Index minInnerIndex = outer - m_data.lowerProfile(outer);+ eigen_assert(inner >= minInnerIndex && "you try to acces a coeff that do not exist in the storage");+ return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));+ }+ } else {+ if (outer > inner) //upper matrix+ {+ const Index maxOuterIndex = inner + m_data.upperProfile(inner);+ eigen_assert(outer <= maxOuterIndex && "you try to acces a coeff that do not exist in the storage");+ return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));+ }+ if (outer < inner) //lower matrix+ {+ const Index maxInnerIndex = outer + m_data.lowerProfile(outer);+ eigen_assert(inner <= maxInnerIndex && "you try to acces a coeff that do not exist in the storage");+ return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));+ }+ }+ }++ inline Scalar coeffDiag(Index idx) const {+ eigen_assert(idx < outerSize());+ eigen_assert(idx < innerSize());+ return this->m_data.diag(idx);+ }++ inline Scalar coeffLower(Index row, Index col) const {+ const Index outer = IsRowMajor ? row : col;+ const Index inner = IsRowMajor ? col : row;++ eigen_assert(outer < outerSize());+ eigen_assert(inner < innerSize());+ eigen_assert(inner != outer);++ if (IsRowMajor) {+ const Index minInnerIndex = outer - m_data.lowerProfile(outer);+ if (inner >= minInnerIndex)+ return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));+ else+ return Scalar(0);++ } else {+ const Index maxInnerIndex = outer + m_data.lowerProfile(outer);+ if (inner <= maxInnerIndex)+ return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));+ else+ return Scalar(0);+ }+ }++ inline Scalar coeffUpper(Index row, Index col) const {+ const Index outer = IsRowMajor ? row : col;+ const Index inner = IsRowMajor ? col : row;++ eigen_assert(outer < outerSize());+ eigen_assert(inner < innerSize());+ eigen_assert(inner != outer);++ if (IsRowMajor) {+ const Index minOuterIndex = inner - m_data.upperProfile(inner);+ if (outer >= minOuterIndex)+ return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));+ else+ return Scalar(0);+ } else {+ const Index maxOuterIndex = inner + m_data.upperProfile(inner);+ if (outer <= maxOuterIndex)+ return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));+ else+ return Scalar(0);+ }+ }++ inline Scalar& coeffRefDiag(Index idx) {+ eigen_assert(idx < outerSize());+ eigen_assert(idx < innerSize());+ return this->m_data.diag(idx);+ }++ inline Scalar& coeffRefLower(Index row, Index col) {+ const Index outer = IsRowMajor ? row : col;+ const Index inner = IsRowMajor ? col : row;++ eigen_assert(outer < outerSize());+ eigen_assert(inner < innerSize());+ eigen_assert(inner != outer);++ if (IsRowMajor) {+ const Index minInnerIndex = outer - m_data.lowerProfile(outer);+ eigen_assert(inner >= minInnerIndex && "you try to acces a coeff that do not exist in the storage");+ return this->m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));+ } else {+ const Index maxInnerIndex = outer + m_data.lowerProfile(outer);+ eigen_assert(inner <= maxInnerIndex && "you try to acces a coeff that do not exist in the storage");+ return this->m_data.lower(m_rowStartIndex[outer] + (inner - outer));+ }+ }++ inline bool coeffExistLower(Index row, Index col) {+ const Index outer = IsRowMajor ? row : col;+ const Index inner = IsRowMajor ? col : row;++ eigen_assert(outer < outerSize());+ eigen_assert(inner < innerSize());+ eigen_assert(inner != outer);++ if (IsRowMajor) {+ const Index minInnerIndex = outer - m_data.lowerProfile(outer);+ return inner >= minInnerIndex;+ } else {+ const Index maxInnerIndex = outer + m_data.lowerProfile(outer);+ return inner <= maxInnerIndex;+ }+ }++ inline Scalar& coeffRefUpper(Index row, Index col) {+ const Index outer = IsRowMajor ? row : col;+ const Index inner = IsRowMajor ? col : row;++ eigen_assert(outer < outerSize());+ eigen_assert(inner < innerSize());+ eigen_assert(inner != outer);++ if (IsRowMajor) {+ const Index minOuterIndex = inner - m_data.upperProfile(inner);+ eigen_assert(outer >= minOuterIndex && "you try to acces a coeff that do not exist in the storage");+ return this->m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));+ } else {+ const Index maxOuterIndex = inner + m_data.upperProfile(inner);+ eigen_assert(outer <= maxOuterIndex && "you try to acces a coeff that do not exist in the storage");+ return this->m_data.upper(m_colStartIndex[inner] + (outer - inner));+ }+ }++ inline bool coeffExistUpper(Index row, Index col) {+ const Index outer = IsRowMajor ? row : col;+ const Index inner = IsRowMajor ? col : row;++ eigen_assert(outer < outerSize());+ eigen_assert(inner < innerSize());+ eigen_assert(inner != outer);++ if (IsRowMajor) {+ const Index minOuterIndex = inner - m_data.upperProfile(inner);+ return outer >= minOuterIndex;+ } else {+ const Index maxOuterIndex = inner + m_data.upperProfile(inner);+ return outer <= maxOuterIndex;+ }+ }+++protected:++public:+ class InnerUpperIterator;+ class InnerLowerIterator;++ class OuterUpperIterator;+ class OuterLowerIterator;++ /** Removes all non zeros */+ inline void setZero() {+ m_data.clear();+ memset(m_colStartIndex, 0, (m_outerSize + 1) * sizeof (Index));+ memset(m_rowStartIndex, 0, (m_outerSize + 1) * sizeof (Index));+ }++ /** \returns the number of non zero coefficients */+ inline Index nonZeros() const {+ return m_data.diagSize() + m_data.upperSize() + m_data.lowerSize();+ }++ /** Preallocates \a reserveSize non zeros */+ inline void reserve(Index reserveSize, Index reserveUpperSize, Index reserveLowerSize) {+ m_data.reserve(reserveSize, reserveUpperSize, reserveLowerSize);+ }++ /** \returns a reference to a novel non zero coefficient with coordinates \a row x \a col.++ *+ * \warning This function can be extremely slow if the non zero coefficients+ * are not inserted in a coherent order.+ *+ * After an insertion session, you should call the finalize() function.+ */+ EIGEN_DONT_INLINE Scalar & insert(Index row, Index col) {+ const Index outer = IsRowMajor ? row : col;+ const Index inner = IsRowMajor ? col : row;++ eigen_assert(outer < outerSize());+ eigen_assert(inner < innerSize());++ if (outer == inner)+ return m_data.diag(col);++ if (IsRowMajor) {+ if (outer < inner) //upper matrix+ {+ Index minOuterIndex = 0;+ minOuterIndex = inner - m_data.upperProfile(inner);++ if (outer < minOuterIndex) //The value does not yet exist+ {+ const Index previousProfile = m_data.upperProfile(inner);++ m_data.upperProfile(inner) = inner - outer;+++ const Index bandIncrement = m_data.upperProfile(inner) - previousProfile;+ //shift data stored after this new one+ const Index stop = m_colStartIndex[cols()];+ const Index start = m_colStartIndex[inner];+++ for (Index innerIdx = stop; innerIdx >= start; innerIdx--) {+ m_data.upper(innerIdx + bandIncrement) = m_data.upper(innerIdx);+ }++ for (Index innerIdx = cols(); innerIdx > inner; innerIdx--) {+ m_colStartIndex[innerIdx] += bandIncrement;+ }++ //zeros new data+ memset(this->_upperPtr() + start, 0, (bandIncrement - 1) * sizeof (Scalar));++ return m_data.upper(m_colStartIndex[inner]);+ } else {+ return m_data.upper(m_colStartIndex[inner] + outer - (inner - m_data.upperProfile(inner)));+ }+ }++ if (outer > inner) //lower matrix+ {+ const Index minInnerIndex = outer - m_data.lowerProfile(outer);+ if (inner < minInnerIndex) //The value does not yet exist+ {+ const Index previousProfile = m_data.lowerProfile(outer);+ m_data.lowerProfile(outer) = outer - inner;++ const Index bandIncrement = m_data.lowerProfile(outer) - previousProfile;+ //shift data stored after this new one+ const Index stop = m_rowStartIndex[rows()];+ const Index start = m_rowStartIndex[outer];+++ for (Index innerIdx = stop; innerIdx >= start; innerIdx--) {+ m_data.lower(innerIdx + bandIncrement) = m_data.lower(innerIdx);+ }++ for (Index innerIdx = rows(); innerIdx > outer; innerIdx--) {+ m_rowStartIndex[innerIdx] += bandIncrement;+ }++ //zeros new data+ memset(this->_lowerPtr() + start, 0, (bandIncrement - 1) * sizeof (Scalar));+ return m_data.lower(m_rowStartIndex[outer]);+ } else {+ return m_data.lower(m_rowStartIndex[outer] + inner - (outer - m_data.lowerProfile(outer)));+ }+ }+ } else {+ if (outer > inner) //upper matrix+ {+ const Index maxOuterIndex = inner + m_data.upperProfile(inner);+ if (outer > maxOuterIndex) //The value does not yet exist+ {+ const Index previousProfile = m_data.upperProfile(inner);+ m_data.upperProfile(inner) = outer - inner;++ const Index bandIncrement = m_data.upperProfile(inner) - previousProfile;+ //shift data stored after this new one+ const Index stop = m_rowStartIndex[rows()];+ const Index start = m_rowStartIndex[inner + 1];++ for (Index innerIdx = stop; innerIdx >= start; innerIdx--) {+ m_data.upper(innerIdx + bandIncrement) = m_data.upper(innerIdx);+ }++ for (Index innerIdx = inner + 1; innerIdx < outerSize() + 1; innerIdx++) {+ m_rowStartIndex[innerIdx] += bandIncrement;+ }+ memset(this->_upperPtr() + m_rowStartIndex[inner] + previousProfile + 1, 0, (bandIncrement - 1) * sizeof (Scalar));+ return m_data.upper(m_rowStartIndex[inner] + m_data.upperProfile(inner));+ } else {+ return m_data.upper(m_rowStartIndex[inner] + (outer - inner));+ }+ }++ if (outer < inner) //lower matrix+ {+ const Index maxInnerIndex = outer + m_data.lowerProfile(outer);+ if (inner > maxInnerIndex) //The value does not yet exist+ {+ const Index previousProfile = m_data.lowerProfile(outer);+ m_data.lowerProfile(outer) = inner - outer;++ const Index bandIncrement = m_data.lowerProfile(outer) - previousProfile;+ //shift data stored after this new one+ const Index stop = m_colStartIndex[cols()];+ const Index start = m_colStartIndex[outer + 1];++ for (Index innerIdx = stop; innerIdx >= start; innerIdx--) {+ m_data.lower(innerIdx + bandIncrement) = m_data.lower(innerIdx);+ }++ for (Index innerIdx = outer + 1; innerIdx < outerSize() + 1; innerIdx++) {+ m_colStartIndex[innerIdx] += bandIncrement;+ }+ memset(this->_lowerPtr() + m_colStartIndex[outer] + previousProfile + 1, 0, (bandIncrement - 1) * sizeof (Scalar));+ return m_data.lower(m_colStartIndex[outer] + m_data.lowerProfile(outer));+ } else {+ return m_data.lower(m_colStartIndex[outer] + (inner - outer));+ }+ }+ }+ }++ /** Must be called after inserting a set of non zero entries.+ */+ inline void finalize() {+ if (IsRowMajor) {+ if (rows() > cols())+ m_data.resize(cols(), cols(), rows(), m_colStartIndex[cols()] + 1, m_rowStartIndex[rows()] + 1);+ else+ m_data.resize(rows(), cols(), rows(), m_colStartIndex[cols()] + 1, m_rowStartIndex[rows()] + 1);++ // eigen_assert(rows() == cols() && "memory reorganisatrion only works with suare matrix");+ //+ // Scalar* newArray = new Scalar[m_colStartIndex[cols()] + 1 + m_rowStartIndex[rows()] + 1];+ // Index dataIdx = 0;+ // for (Index row = 0; row < rows(); row++) {+ //+ // const Index nbLowerElts = m_rowStartIndex[row + 1] - m_rowStartIndex[row];+ // // std::cout << "nbLowerElts" << nbLowerElts << std::endl;+ // memcpy(newArray + dataIdx, m_data.m_lower + m_rowStartIndex[row], nbLowerElts * sizeof (Scalar));+ // m_rowStartIndex[row] = dataIdx;+ // dataIdx += nbLowerElts;+ //+ // const Index nbUpperElts = m_colStartIndex[row + 1] - m_colStartIndex[row];+ // memcpy(newArray + dataIdx, m_data.m_upper + m_colStartIndex[row], nbUpperElts * sizeof (Scalar));+ // m_colStartIndex[row] = dataIdx;+ // dataIdx += nbUpperElts;+ //+ //+ // }+ // //todo : don't access m_data profile directly : add an accessor from SkylineMatrix+ // m_rowStartIndex[rows()] = m_rowStartIndex[rows()-1] + m_data.lowerProfile(rows()-1);+ // m_colStartIndex[cols()] = m_colStartIndex[cols()-1] + m_data.upperProfile(cols()-1);+ //+ // delete[] m_data.m_lower;+ // delete[] m_data.m_upper;+ //+ // m_data.m_lower = newArray;+ // m_data.m_upper = newArray;+ } else {+ if (rows() > cols())+ m_data.resize(cols(), rows(), cols(), m_rowStartIndex[cols()] + 1, m_colStartIndex[cols()] + 1);+ else+ m_data.resize(rows(), rows(), cols(), m_rowStartIndex[rows()] + 1, m_colStartIndex[rows()] + 1);+ }+ }++ inline void squeeze() {+ finalize();+ m_data.squeeze();+ }++ void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar > ()) {+ //TODO+ }++ /** Resizes the matrix to a \a rows x \a cols matrix and initializes it to zero+ * \sa resizeNonZeros(Index), reserve(), setZero()+ */+ void resize(size_t rows, size_t cols) {+ const Index diagSize = rows > cols ? cols : rows;+ m_innerSize = IsRowMajor ? cols : rows;++ eigen_assert(rows == cols && "Skyline matrix must be square matrix");++ if (diagSize % 2) { // diagSize is odd+ const Index k = (diagSize - 1) / 2;++ m_data.resize(diagSize, IsRowMajor ? cols : rows, IsRowMajor ? rows : cols,+ 2 * k * k + k + 1,+ 2 * k * k + k + 1);++ } else // diagSize is even+ {+ const Index k = diagSize / 2;+ m_data.resize(diagSize, IsRowMajor ? cols : rows, IsRowMajor ? rows : cols,+ 2 * k * k - k + 1,+ 2 * k * k - k + 1);+ }++ if (m_colStartIndex && m_rowStartIndex) {+ delete[] m_colStartIndex;+ delete[] m_rowStartIndex;+ }+ m_colStartIndex = new Index [cols + 1];+ m_rowStartIndex = new Index [rows + 1];+ m_outerSize = diagSize;++ m_data.reset();+ m_data.clear();++ m_outerSize = diagSize;+ memset(m_colStartIndex, 0, (cols + 1) * sizeof (Index));+ memset(m_rowStartIndex, 0, (rows + 1) * sizeof (Index));+ }++ void resizeNonZeros(Index size) {+ m_data.resize(size);+ }++ inline SkylineMatrix()+ : m_outerSize(-1), m_innerSize(0), m_colStartIndex(0), m_rowStartIndex(0) {+ resize(0, 0);+ }++ inline SkylineMatrix(size_t rows, size_t cols)+ : m_outerSize(0), m_innerSize(0), m_colStartIndex(0), m_rowStartIndex(0) {+ resize(rows, cols);+ }++ template<typename OtherDerived>+ inline SkylineMatrix(const SkylineMatrixBase<OtherDerived>& other)+ : m_outerSize(0), m_innerSize(0), m_colStartIndex(0), m_rowStartIndex(0) {+ *this = other.derived();+ }++ inline SkylineMatrix(const SkylineMatrix & other)+ : Base(), m_outerSize(0), m_innerSize(0), m_colStartIndex(0), m_rowStartIndex(0) {+ *this = other.derived();+ }++ inline void swap(SkylineMatrix & other) {+ //EIGEN_DBG_SKYLINE(std::cout << "SkylineMatrix:: swap\n");+ std::swap(m_colStartIndex, other.m_colStartIndex);+ std::swap(m_rowStartIndex, other.m_rowStartIndex);+ std::swap(m_innerSize, other.m_innerSize);+ std::swap(m_outerSize, other.m_outerSize);+ m_data.swap(other.m_data);+ }++ inline SkylineMatrix & operator=(const SkylineMatrix & other) {+ std::cout << "SkylineMatrix& operator=(const SkylineMatrix& other)\n";+ if (other.isRValue()) {+ swap(other.const_cast_derived());+ } else {+ resize(other.rows(), other.cols());+ memcpy(m_colStartIndex, other.m_colStartIndex, (m_outerSize + 1) * sizeof (Index));+ memcpy(m_rowStartIndex, other.m_rowStartIndex, (m_outerSize + 1) * sizeof (Index));+ m_data = other.m_data;+ }+ return *this;+ }++ template<typename OtherDerived>+ inline SkylineMatrix & operator=(const SkylineMatrixBase<OtherDerived>& other) {+ const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);+ if (needToTranspose) {+ // TODO+ // return *this;+ } else {+ // there is no special optimization+ return SkylineMatrixBase<SkylineMatrix>::operator=(other.derived());+ }+ }++ friend std::ostream & operator <<(std::ostream & s, const SkylineMatrix & m) {++ EIGEN_DBG_SKYLINE(+ std::cout << "upper elements : " << std::endl;+ for (Index i = 0; i < m.m_data.upperSize(); i++)+ std::cout << m.m_data.upper(i) << "\t";+ std::cout << std::endl;+ std::cout << "upper profile : " << std::endl;+ for (Index i = 0; i < m.m_data.upperProfileSize(); i++)+ std::cout << m.m_data.upperProfile(i) << "\t";+ std::cout << std::endl;+ std::cout << "lower startIdx : " << std::endl;+ for (Index i = 0; i < m.m_data.upperProfileSize(); i++)+ std::cout << (IsRowMajor ? m.m_colStartIndex[i] : m.m_rowStartIndex[i]) << "\t";+ std::cout << std::endl;+++ std::cout << "lower elements : " << std::endl;+ for (Index i = 0; i < m.m_data.lowerSize(); i++)+ std::cout << m.m_data.lower(i) << "\t";+ std::cout << std::endl;+ std::cout << "lower profile : " << std::endl;+ for (Index i = 0; i < m.m_data.lowerProfileSize(); i++)+ std::cout << m.m_data.lowerProfile(i) << "\t";+ std::cout << std::endl;+ std::cout << "lower startIdx : " << std::endl;+ for (Index i = 0; i < m.m_data.lowerProfileSize(); i++)+ std::cout << (IsRowMajor ? m.m_rowStartIndex[i] : m.m_colStartIndex[i]) << "\t";+ std::cout << std::endl;+ );+ for (Index rowIdx = 0; rowIdx < m.rows(); rowIdx++) {+ for (Index colIdx = 0; colIdx < m.cols(); colIdx++) {+ s << m.coeff(rowIdx, colIdx) << "\t";+ }+ s << std::endl;+ }+ return s;+ }++ /** Destructor */+ inline ~SkylineMatrix() {+ delete[] m_colStartIndex;+ delete[] m_rowStartIndex;+ }++ /** Overloaded for performance */+ Scalar sum() const;+};++template<typename Scalar, int _Options>+class SkylineMatrix<Scalar, _Options>::InnerUpperIterator {+public:++ InnerUpperIterator(const SkylineMatrix& mat, Index outer)+ : m_matrix(mat), m_outer(outer),+ m_id(_Options == RowMajor ? mat.m_colStartIndex[outer] : mat.m_rowStartIndex[outer] + 1),+ m_start(m_id),+ m_end(_Options == RowMajor ? mat.m_colStartIndex[outer + 1] : mat.m_rowStartIndex[outer + 1] + 1) {+ }++ inline InnerUpperIterator & operator++() {+ m_id++;+ return *this;+ }++ inline InnerUpperIterator & operator+=(Index shift) {+ m_id += shift;+ return *this;+ }++ inline Scalar value() const {+ return m_matrix.m_data.upper(m_id);+ }++ inline Scalar* valuePtr() {+ return const_cast<Scalar*> (&(m_matrix.m_data.upper(m_id)));+ }++ inline Scalar& valueRef() {+ return const_cast<Scalar&> (m_matrix.m_data.upper(m_id));+ }++ inline Index index() const {+ return IsRowMajor ? m_outer - m_matrix.m_data.upperProfile(m_outer) + (m_id - m_start) :+ m_outer + (m_id - m_start) + 1;+ }++ inline Index row() const {+ return IsRowMajor ? index() : m_outer;+ }++ inline Index col() const {+ return IsRowMajor ? m_outer : index();+ }++ inline size_t size() const {+ return m_matrix.m_data.upperProfile(m_outer);+ }++ inline operator bool() const {+ return (m_id < m_end) && (m_id >= m_start);+ }++protected:+ const SkylineMatrix& m_matrix;+ const Index m_outer;+ Index m_id;+ const Index m_start;+ const Index m_end;+};++template<typename Scalar, int _Options>+class SkylineMatrix<Scalar, _Options>::InnerLowerIterator {+public:++ InnerLowerIterator(const SkylineMatrix& mat, Index outer)+ : m_matrix(mat),+ m_outer(outer),+ m_id(_Options == RowMajor ? mat.m_rowStartIndex[outer] : mat.m_colStartIndex[outer] + 1),+ m_start(m_id),+ m_end(_Options == RowMajor ? mat.m_rowStartIndex[outer + 1] : mat.m_colStartIndex[outer + 1] + 1) {+ }++ inline InnerLowerIterator & operator++() {+ m_id++;+ return *this;+ }++ inline InnerLowerIterator & operator+=(Index shift) {+ m_id += shift;+ return *this;+ }++ inline Scalar value() const {+ return m_matrix.m_data.lower(m_id);+ }++ inline Scalar* valuePtr() {+ return const_cast<Scalar*> (&(m_matrix.m_data.lower(m_id)));+ }++ inline Scalar& valueRef() {+ return const_cast<Scalar&> (m_matrix.m_data.lower(m_id));+ }++ inline Index index() const {+ return IsRowMajor ? m_outer - m_matrix.m_data.lowerProfile(m_outer) + (m_id - m_start) :+ m_outer + (m_id - m_start) + 1;+ ;+ }++ inline Index row() const {+ return IsRowMajor ? m_outer : index();+ }++ inline Index col() const {+ return IsRowMajor ? index() : m_outer;+ }++ inline size_t size() const {+ return m_matrix.m_data.lowerProfile(m_outer);+ }++ inline operator bool() const {+ return (m_id < m_end) && (m_id >= m_start);+ }++protected:+ const SkylineMatrix& m_matrix;+ const Index m_outer;+ Index m_id;+ const Index m_start;+ const Index m_end;+};++} // end namespace Eigen++#endif // EIGEN_SkylineMatrix_H
+ eigen3/unsupported/Eigen/src/Skyline/SkylineMatrixBase.h view
@@ -0,0 +1,212 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Guillaume Saupin <guillaume.saupin@cea.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_SKYLINEMATRIXBASE_H+#define EIGEN_SKYLINEMATRIXBASE_H++#include "SkylineUtil.h"++namespace Eigen { ++/** \ingroup Skyline_Module+ *+ * \class SkylineMatrixBase+ *+ * \brief Base class of any skyline matrices or skyline expressions+ *+ * \param Derived+ *+ */+template<typename Derived> class SkylineMatrixBase : public EigenBase<Derived> {+public:++ typedef typename internal::traits<Derived>::Scalar Scalar;+ typedef typename internal::traits<Derived>::StorageKind StorageKind;+ typedef typename internal::index<StorageKind>::type Index;++ enum {+ RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,+ /**< The number of rows at compile-time. This is just a copy of the value provided+ * by the \a Derived type. If a value is not known at compile-time,+ * it is set to the \a Dynamic constant.+ * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */++ ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,+ /**< The number of columns at compile-time. This is just a copy of the value provided+ * by the \a Derived type. If a value is not known at compile-time,+ * it is set to the \a Dynamic constant.+ * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */+++ SizeAtCompileTime = (internal::size_at_compile_time<internal::traits<Derived>::RowsAtCompileTime,+ internal::traits<Derived>::ColsAtCompileTime>::ret),+ /**< This is equal to the number of coefficients, i.e. the number of+ * rows times the number of columns, or to \a Dynamic if this is not+ * known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */++ MaxRowsAtCompileTime = RowsAtCompileTime,+ MaxColsAtCompileTime = ColsAtCompileTime,++ MaxSizeAtCompileTime = (internal::size_at_compile_time<MaxRowsAtCompileTime,+ MaxColsAtCompileTime>::ret),++ IsVectorAtCompileTime = RowsAtCompileTime == 1 || ColsAtCompileTime == 1,+ /**< This is set to true if either the number of rows or the number of+ * columns is known at compile-time to be equal to 1. Indeed, in that case,+ * we are dealing with a column-vector (if there is only one column) or with+ * a row-vector (if there is only one row). */++ Flags = internal::traits<Derived>::Flags,+ /**< This stores expression \ref flags flags which may or may not be inherited by new expressions+ * constructed from this one. See the \ref flags "list of flags".+ */++ CoeffReadCost = internal::traits<Derived>::CoeffReadCost,+ /**< This is a rough measure of how expensive it is to read one coefficient from+ * this expression.+ */++ IsRowMajor = Flags & RowMajorBit ? 1 : 0+ };++#ifndef EIGEN_PARSED_BY_DOXYGEN+ /** This is the "real scalar" type; if the \a Scalar type is already real numbers+ * (e.g. int, float or double) then \a RealScalar is just the same as \a Scalar. If+ * \a Scalar is \a std::complex<T> then RealScalar is \a T.+ *+ * \sa class NumTraits+ */+ typedef typename NumTraits<Scalar>::Real RealScalar;++ /** type of the equivalent square matrix */+ typedef Matrix<Scalar, EIGEN_SIZE_MAX(RowsAtCompileTime, ColsAtCompileTime),+ EIGEN_SIZE_MAX(RowsAtCompileTime, ColsAtCompileTime) > SquareMatrixType;++ inline const Derived& derived() const {+ return *static_cast<const Derived*> (this);+ }++ inline Derived& derived() {+ return *static_cast<Derived*> (this);+ }++ inline Derived& const_cast_derived() const {+ return *static_cast<Derived*> (const_cast<SkylineMatrixBase*> (this));+ }+#endif // not EIGEN_PARSED_BY_DOXYGEN++ /** \returns the number of rows. \sa cols(), RowsAtCompileTime */+ inline Index rows() const {+ return derived().rows();+ }++ /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/+ inline Index cols() const {+ return derived().cols();+ }++ /** \returns the number of coefficients, which is \a rows()*cols().+ * \sa rows(), cols(), SizeAtCompileTime. */+ inline Index size() const {+ return rows() * cols();+ }++ /** \returns the number of nonzero coefficients which is in practice the number+ * of stored coefficients. */+ inline Index nonZeros() const {+ return derived().nonZeros();+ }++ /** \returns the size of the storage major dimension,+ * i.e., the number of columns for a columns major matrix, and the number of rows otherwise */+ Index outerSize() const {+ return (int(Flags) & RowMajorBit) ? this->rows() : this->cols();+ }++ /** \returns the size of the inner dimension according to the storage order,+ * i.e., the number of rows for a columns major matrix, and the number of cols otherwise */+ Index innerSize() const {+ return (int(Flags) & RowMajorBit) ? this->cols() : this->rows();+ }++ bool isRValue() const {+ return m_isRValue;+ }++ Derived& markAsRValue() {+ m_isRValue = true;+ return derived();+ }++ SkylineMatrixBase() : m_isRValue(false) {+ /* TODO check flags */+ }++ inline Derived & operator=(const Derived& other) {+ this->operator=<Derived > (other);+ return derived();+ }++ template<typename OtherDerived>+ inline void assignGeneric(const OtherDerived& other) {+ derived().resize(other.rows(), other.cols());+ for (Index row = 0; row < rows(); row++)+ for (Index col = 0; col < cols(); col++) {+ if (other.coeff(row, col) != Scalar(0))+ derived().insert(row, col) = other.coeff(row, col);+ }+ derived().finalize();+ }++ template<typename OtherDerived>+ inline Derived & operator=(const SkylineMatrixBase<OtherDerived>& other) {+ //TODO+ }++ template<typename Lhs, typename Rhs>+ inline Derived & operator=(const SkylineProduct<Lhs, Rhs, SkylineTimeSkylineProduct>& product);++ friend std::ostream & operator <<(std::ostream & s, const SkylineMatrixBase& m) {+ s << m.derived();+ return s;+ }++ template<typename OtherDerived>+ const typename SkylineProductReturnType<Derived, OtherDerived>::Type+ operator*(const MatrixBase<OtherDerived> &other) const;++ /** \internal use operator= */+ template<typename DenseDerived>+ void evalTo(MatrixBase<DenseDerived>& dst) const {+ dst.setZero();+ for (Index i = 0; i < rows(); i++)+ for (Index j = 0; j < rows(); j++)+ dst(i, j) = derived().coeff(i, j);+ }++ Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime> toDense() const {+ return derived();+ }++ /** \returns the matrix or vector obtained by evaluating this expression.+ *+ * Notice that in the case of a plain matrix or vector (not an expression) this function just returns+ * a const reference, in order to avoid a useless copy.+ */+ EIGEN_STRONG_INLINE const typename internal::eval<Derived, IsSkyline>::type eval() const {+ return typename internal::eval<Derived>::type(derived());+ }++protected:+ bool m_isRValue;+};++} // end namespace Eigen++#endif // EIGEN_SkylineMatrixBase_H
+ eigen3/unsupported/Eigen/src/Skyline/SkylineProduct.h view
@@ -0,0 +1,295 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Guillaume Saupin <guillaume.saupin@cea.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_SKYLINEPRODUCT_H+#define EIGEN_SKYLINEPRODUCT_H++namespace Eigen { ++template<typename Lhs, typename Rhs, int ProductMode>+struct SkylineProductReturnType {+ typedef const typename internal::nested<Lhs, Rhs::RowsAtCompileTime>::type LhsNested;+ typedef const typename internal::nested<Rhs, Lhs::RowsAtCompileTime>::type RhsNested;++ typedef SkylineProduct<LhsNested, RhsNested, ProductMode> Type;+};++template<typename LhsNested, typename RhsNested, int ProductMode>+struct internal::traits<SkylineProduct<LhsNested, RhsNested, ProductMode> > {+ // clean the nested types:+ typedef typename internal::remove_all<LhsNested>::type _LhsNested;+ typedef typename internal::remove_all<RhsNested>::type _RhsNested;+ typedef typename _LhsNested::Scalar Scalar;++ enum {+ LhsCoeffReadCost = _LhsNested::CoeffReadCost,+ RhsCoeffReadCost = _RhsNested::CoeffReadCost,+ LhsFlags = _LhsNested::Flags,+ RhsFlags = _RhsNested::Flags,++ RowsAtCompileTime = _LhsNested::RowsAtCompileTime,+ ColsAtCompileTime = _RhsNested::ColsAtCompileTime,+ InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime),++ MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime,+ MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime,++ EvalToRowMajor = (RhsFlags & LhsFlags & RowMajorBit),+ ResultIsSkyline = ProductMode == SkylineTimeSkylineProduct,++ RemovedBits = ~((EvalToRowMajor ? 0 : RowMajorBit) | (ResultIsSkyline ? 0 : SkylineBit)),++ Flags = (int(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits)+ | EvalBeforeAssigningBit+ | EvalBeforeNestingBit,++ CoeffReadCost = Dynamic+ };++ typedef typename internal::conditional<ResultIsSkyline,+ SkylineMatrixBase<SkylineProduct<LhsNested, RhsNested, ProductMode> >,+ MatrixBase<SkylineProduct<LhsNested, RhsNested, ProductMode> > >::type Base;+};++namespace internal {+template<typename LhsNested, typename RhsNested, int ProductMode>+class SkylineProduct : no_assignment_operator,+public traits<SkylineProduct<LhsNested, RhsNested, ProductMode> >::Base {+public:++ EIGEN_GENERIC_PUBLIC_INTERFACE(SkylineProduct)++private:++ typedef typename traits<SkylineProduct>::_LhsNested _LhsNested;+ typedef typename traits<SkylineProduct>::_RhsNested _RhsNested;++public:++ template<typename Lhs, typename Rhs>+ EIGEN_STRONG_INLINE SkylineProduct(const Lhs& lhs, const Rhs& rhs)+ : m_lhs(lhs), m_rhs(rhs) {+ eigen_assert(lhs.cols() == rhs.rows());++ enum {+ ProductIsValid = _LhsNested::ColsAtCompileTime == Dynamic+ || _RhsNested::RowsAtCompileTime == Dynamic+ || int(_LhsNested::ColsAtCompileTime) == int(_RhsNested::RowsAtCompileTime),+ AreVectors = _LhsNested::IsVectorAtCompileTime && _RhsNested::IsVectorAtCompileTime,+ SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(_LhsNested, _RhsNested)+ };+ // note to the lost user:+ // * for a dot product use: v1.dot(v2)+ // * for a coeff-wise product use: v1.cwise()*v2+ EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),+ INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)+ EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),+ INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)+ EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)+ }++ EIGEN_STRONG_INLINE Index rows() const {+ return m_lhs.rows();+ }++ EIGEN_STRONG_INLINE Index cols() const {+ return m_rhs.cols();+ }++ EIGEN_STRONG_INLINE const _LhsNested& lhs() const {+ return m_lhs;+ }++ EIGEN_STRONG_INLINE const _RhsNested& rhs() const {+ return m_rhs;+ }++protected:+ LhsNested m_lhs;+ RhsNested m_rhs;+};++// dense = skyline * dense+// Note that here we force no inlining and separate the setZero() because GCC messes up otherwise++template<typename Lhs, typename Rhs, typename Dest>+EIGEN_DONT_INLINE void skyline_row_major_time_dense_product(const Lhs& lhs, const Rhs& rhs, Dest& dst) {+ typedef typename remove_all<Lhs>::type _Lhs;+ typedef typename remove_all<Rhs>::type _Rhs;+ typedef typename traits<Lhs>::Scalar Scalar;++ enum {+ LhsIsRowMajor = (_Lhs::Flags & RowMajorBit) == RowMajorBit,+ LhsIsSelfAdjoint = (_Lhs::Flags & SelfAdjointBit) == SelfAdjointBit,+ ProcessFirstHalf = LhsIsSelfAdjoint+ && (((_Lhs::Flags & (UpperTriangularBit | LowerTriangularBit)) == 0)+ || ((_Lhs::Flags & UpperTriangularBit) && !LhsIsRowMajor)+ || ((_Lhs::Flags & LowerTriangularBit) && LhsIsRowMajor)),+ ProcessSecondHalf = LhsIsSelfAdjoint && (!ProcessFirstHalf)+ };++ //Use matrix diagonal part <- Improvement : use inner iterator on dense matrix.+ for (Index col = 0; col < rhs.cols(); col++) {+ for (Index row = 0; row < lhs.rows(); row++) {+ dst(row, col) = lhs.coeffDiag(row) * rhs(row, col);+ }+ }+ //Use matrix lower triangular part+ for (Index row = 0; row < lhs.rows(); row++) {+ typename _Lhs::InnerLowerIterator lIt(lhs, row);+ const Index stop = lIt.col() + lIt.size();+ for (Index col = 0; col < rhs.cols(); col++) {++ Index k = lIt.col();+ Scalar tmp = 0;+ while (k < stop) {+ tmp +=+ lIt.value() *+ rhs(k++, col);+ ++lIt;+ }+ dst(row, col) += tmp;+ lIt += -lIt.size();+ }++ }++ //Use matrix upper triangular part+ for (Index lhscol = 0; lhscol < lhs.cols(); lhscol++) {+ typename _Lhs::InnerUpperIterator uIt(lhs, lhscol);+ const Index stop = uIt.size() + uIt.row();+ for (Index rhscol = 0; rhscol < rhs.cols(); rhscol++) {+++ const Scalar rhsCoeff = rhs.coeff(lhscol, rhscol);+ Index k = uIt.row();+ while (k < stop) {+ dst(k++, rhscol) +=+ uIt.value() *+ rhsCoeff;+ ++uIt;+ }+ uIt += -uIt.size();+ }+ }++}++template<typename Lhs, typename Rhs, typename Dest>+EIGEN_DONT_INLINE void skyline_col_major_time_dense_product(const Lhs& lhs, const Rhs& rhs, Dest& dst) {+ typedef typename remove_all<Lhs>::type _Lhs;+ typedef typename remove_all<Rhs>::type _Rhs;+ typedef typename traits<Lhs>::Scalar Scalar;++ enum {+ LhsIsRowMajor = (_Lhs::Flags & RowMajorBit) == RowMajorBit,+ LhsIsSelfAdjoint = (_Lhs::Flags & SelfAdjointBit) == SelfAdjointBit,+ ProcessFirstHalf = LhsIsSelfAdjoint+ && (((_Lhs::Flags & (UpperTriangularBit | LowerTriangularBit)) == 0)+ || ((_Lhs::Flags & UpperTriangularBit) && !LhsIsRowMajor)+ || ((_Lhs::Flags & LowerTriangularBit) && LhsIsRowMajor)),+ ProcessSecondHalf = LhsIsSelfAdjoint && (!ProcessFirstHalf)+ };++ //Use matrix diagonal part <- Improvement : use inner iterator on dense matrix.+ for (Index col = 0; col < rhs.cols(); col++) {+ for (Index row = 0; row < lhs.rows(); row++) {+ dst(row, col) = lhs.coeffDiag(row) * rhs(row, col);+ }+ }++ //Use matrix upper triangular part+ for (Index row = 0; row < lhs.rows(); row++) {+ typename _Lhs::InnerUpperIterator uIt(lhs, row);+ const Index stop = uIt.col() + uIt.size();+ for (Index col = 0; col < rhs.cols(); col++) {++ Index k = uIt.col();+ Scalar tmp = 0;+ while (k < stop) {+ tmp +=+ uIt.value() *+ rhs(k++, col);+ ++uIt;+ }+++ dst(row, col) += tmp;+ uIt += -uIt.size();+ }+ }++ //Use matrix lower triangular part+ for (Index lhscol = 0; lhscol < lhs.cols(); lhscol++) {+ typename _Lhs::InnerLowerIterator lIt(lhs, lhscol);+ const Index stop = lIt.size() + lIt.row();+ for (Index rhscol = 0; rhscol < rhs.cols(); rhscol++) {++ const Scalar rhsCoeff = rhs.coeff(lhscol, rhscol);+ Index k = lIt.row();+ while (k < stop) {+ dst(k++, rhscol) +=+ lIt.value() *+ rhsCoeff;+ ++lIt;+ }+ lIt += -lIt.size();+ }+ }++}++template<typename Lhs, typename Rhs, typename ResultType,+ int LhsStorageOrder = traits<Lhs>::Flags&RowMajorBit>+ struct skyline_product_selector;++template<typename Lhs, typename Rhs, typename ResultType>+struct skyline_product_selector<Lhs, Rhs, ResultType, RowMajor> {+ typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar;++ static void run(const Lhs& lhs, const Rhs& rhs, ResultType & res) {+ skyline_row_major_time_dense_product<Lhs, Rhs, ResultType > (lhs, rhs, res);+ }+};++template<typename Lhs, typename Rhs, typename ResultType>+struct skyline_product_selector<Lhs, Rhs, ResultType, ColMajor> {+ typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar;++ static void run(const Lhs& lhs, const Rhs& rhs, ResultType & res) {+ skyline_col_major_time_dense_product<Lhs, Rhs, ResultType > (lhs, rhs, res);+ }+};++} // end namespace internal++// template<typename Derived>+// template<typename Lhs, typename Rhs >+// Derived & MatrixBase<Derived>::lazyAssign(const SkylineProduct<Lhs, Rhs, SkylineTimeDenseProduct>& product) {+// typedef typename internal::remove_all<Lhs>::type _Lhs;+// internal::skyline_product_selector<typename internal::remove_all<Lhs>::type,+// typename internal::remove_all<Rhs>::type,+// Derived>::run(product.lhs(), product.rhs(), derived());+// +// return derived();+// }++// skyline * dense++template<typename Derived>+template<typename OtherDerived >+EIGEN_STRONG_INLINE const typename SkylineProductReturnType<Derived, OtherDerived>::Type+SkylineMatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const {++ return typename SkylineProductReturnType<Derived, OtherDerived>::Type(derived(), other.derived());+}++} // end namespace Eigen++#endif // EIGEN_SKYLINEPRODUCT_H
+ eigen3/unsupported/Eigen/src/Skyline/SkylineStorage.h view
@@ -0,0 +1,259 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Guillaume Saupin <guillaume.saupin@cea.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_SKYLINE_STORAGE_H+#define EIGEN_SKYLINE_STORAGE_H++namespace Eigen { ++/** Stores a skyline set of values in three structures :+ * The diagonal elements+ * The upper elements+ * The lower elements+ *+ */+template<typename Scalar>+class SkylineStorage {+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef SparseIndex Index;+public:++ SkylineStorage()+ : m_diag(0),+ m_lower(0),+ m_upper(0),+ m_lowerProfile(0),+ m_upperProfile(0),+ m_diagSize(0),+ m_upperSize(0),+ m_lowerSize(0),+ m_upperProfileSize(0),+ m_lowerProfileSize(0),+ m_allocatedSize(0) {+ }++ SkylineStorage(const SkylineStorage& other)+ : m_diag(0),+ m_lower(0),+ m_upper(0),+ m_lowerProfile(0),+ m_upperProfile(0),+ m_diagSize(0),+ m_upperSize(0),+ m_lowerSize(0),+ m_upperProfileSize(0),+ m_lowerProfileSize(0),+ m_allocatedSize(0) {+ *this = other;+ }++ SkylineStorage & operator=(const SkylineStorage& other) {+ resize(other.diagSize(), other.m_upperProfileSize, other.m_lowerProfileSize, other.upperSize(), other.lowerSize());+ memcpy(m_diag, other.m_diag, m_diagSize * sizeof (Scalar));+ memcpy(m_upper, other.m_upper, other.upperSize() * sizeof (Scalar));+ memcpy(m_lower, other.m_lower, other.lowerSize() * sizeof (Scalar));+ memcpy(m_upperProfile, other.m_upperProfile, m_upperProfileSize * sizeof (Index));+ memcpy(m_lowerProfile, other.m_lowerProfile, m_lowerProfileSize * sizeof (Index));+ return *this;+ }++ void swap(SkylineStorage& other) {+ std::swap(m_diag, other.m_diag);+ std::swap(m_upper, other.m_upper);+ std::swap(m_lower, other.m_lower);+ std::swap(m_upperProfile, other.m_upperProfile);+ std::swap(m_lowerProfile, other.m_lowerProfile);+ std::swap(m_diagSize, other.m_diagSize);+ std::swap(m_upperSize, other.m_upperSize);+ std::swap(m_lowerSize, other.m_lowerSize);+ std::swap(m_allocatedSize, other.m_allocatedSize);+ }++ ~SkylineStorage() {+ delete[] m_diag;+ delete[] m_upper;+ if (m_upper != m_lower)+ delete[] m_lower;+ delete[] m_upperProfile;+ delete[] m_lowerProfile;+ }++ void reserve(Index size, Index upperProfileSize, Index lowerProfileSize, Index upperSize, Index lowerSize) {+ Index newAllocatedSize = size + upperSize + lowerSize;+ if (newAllocatedSize > m_allocatedSize)+ reallocate(size, upperProfileSize, lowerProfileSize, upperSize, lowerSize);+ }++ void squeeze() {+ if (m_allocatedSize > m_diagSize + m_upperSize + m_lowerSize)+ reallocate(m_diagSize, m_upperProfileSize, m_lowerProfileSize, m_upperSize, m_lowerSize);+ }++ void resize(Index diagSize, Index upperProfileSize, Index lowerProfileSize, Index upperSize, Index lowerSize, float reserveSizeFactor = 0) {+ if (m_allocatedSize < diagSize + upperSize + lowerSize)+ reallocate(diagSize, upperProfileSize, lowerProfileSize, upperSize + Index(reserveSizeFactor * upperSize), lowerSize + Index(reserveSizeFactor * lowerSize));+ m_diagSize = diagSize;+ m_upperSize = upperSize;+ m_lowerSize = lowerSize;+ m_upperProfileSize = upperProfileSize;+ m_lowerProfileSize = lowerProfileSize;+ }++ inline Index diagSize() const {+ return m_diagSize;+ }++ inline Index upperSize() const {+ return m_upperSize;+ }++ inline Index lowerSize() const {+ return m_lowerSize;+ }++ inline Index upperProfileSize() const {+ return m_upperProfileSize;+ }++ inline Index lowerProfileSize() const {+ return m_lowerProfileSize;+ }++ inline Index allocatedSize() const {+ return m_allocatedSize;+ }++ inline void clear() {+ m_diagSize = 0;+ }++ inline Scalar& diag(Index i) {+ return m_diag[i];+ }++ inline const Scalar& diag(Index i) const {+ return m_diag[i];+ }++ inline Scalar& upper(Index i) {+ return m_upper[i];+ }++ inline const Scalar& upper(Index i) const {+ return m_upper[i];+ }++ inline Scalar& lower(Index i) {+ return m_lower[i];+ }++ inline const Scalar& lower(Index i) const {+ return m_lower[i];+ }++ inline Index& upperProfile(Index i) {+ return m_upperProfile[i];+ }++ inline const Index& upperProfile(Index i) const {+ return m_upperProfile[i];+ }++ inline Index& lowerProfile(Index i) {+ return m_lowerProfile[i];+ }++ inline const Index& lowerProfile(Index i) const {+ return m_lowerProfile[i];+ }++ static SkylineStorage Map(Index* upperProfile, Index* lowerProfile, Scalar* diag, Scalar* upper, Scalar* lower, Index size, Index upperSize, Index lowerSize) {+ SkylineStorage res;+ res.m_upperProfile = upperProfile;+ res.m_lowerProfile = lowerProfile;+ res.m_diag = diag;+ res.m_upper = upper;+ res.m_lower = lower;+ res.m_allocatedSize = res.m_diagSize = size;+ res.m_upperSize = upperSize;+ res.m_lowerSize = lowerSize;+ return res;+ }++ inline void reset() {+ memset(m_diag, 0, m_diagSize * sizeof (Scalar));+ memset(m_upper, 0, m_upperSize * sizeof (Scalar));+ memset(m_lower, 0, m_lowerSize * sizeof (Scalar));+ memset(m_upperProfile, 0, m_diagSize * sizeof (Index));+ memset(m_lowerProfile, 0, m_diagSize * sizeof (Index));+ }++ void prune(Scalar reference, RealScalar epsilon = dummy_precision<RealScalar>()) {+ //TODO+ }++protected:++ inline void reallocate(Index diagSize, Index upperProfileSize, Index lowerProfileSize, Index upperSize, Index lowerSize) {++ Scalar* diag = new Scalar[diagSize];+ Scalar* upper = new Scalar[upperSize];+ Scalar* lower = new Scalar[lowerSize];+ Index* upperProfile = new Index[upperProfileSize];+ Index* lowerProfile = new Index[lowerProfileSize];++ Index copyDiagSize = (std::min)(diagSize, m_diagSize);+ Index copyUpperSize = (std::min)(upperSize, m_upperSize);+ Index copyLowerSize = (std::min)(lowerSize, m_lowerSize);+ Index copyUpperProfileSize = (std::min)(upperProfileSize, m_upperProfileSize);+ Index copyLowerProfileSize = (std::min)(lowerProfileSize, m_lowerProfileSize);++ // copy+ memcpy(diag, m_diag, copyDiagSize * sizeof (Scalar));+ memcpy(upper, m_upper, copyUpperSize * sizeof (Scalar));+ memcpy(lower, m_lower, copyLowerSize * sizeof (Scalar));+ memcpy(upperProfile, m_upperProfile, copyUpperProfileSize * sizeof (Index));+ memcpy(lowerProfile, m_lowerProfile, copyLowerProfileSize * sizeof (Index));++++ // delete old stuff+ delete[] m_diag;+ delete[] m_upper;+ delete[] m_lower;+ delete[] m_upperProfile;+ delete[] m_lowerProfile;+ m_diag = diag;+ m_upper = upper;+ m_lower = lower;+ m_upperProfile = upperProfile;+ m_lowerProfile = lowerProfile;+ m_allocatedSize = diagSize + upperSize + lowerSize;+ m_upperSize = upperSize;+ m_lowerSize = lowerSize;+ }++public:+ Scalar* m_diag;+ Scalar* m_upper;+ Scalar* m_lower;+ Index* m_upperProfile;+ Index* m_lowerProfile;+ Index m_diagSize;+ Index m_upperSize;+ Index m_lowerSize;+ Index m_upperProfileSize;+ Index m_lowerProfileSize;+ Index m_allocatedSize;++};++} // end namespace Eigen++#endif // EIGEN_COMPRESSED_STORAGE_H
+ eigen3/unsupported/Eigen/src/Skyline/SkylineUtil.h view
@@ -0,0 +1,89 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Guillaume Saupin <guillaume.saupin@cea.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_SKYLINEUTIL_H+#define EIGEN_SKYLINEUTIL_H++namespace Eigen { ++#ifdef NDEBUG+#define EIGEN_DBG_SKYLINE(X)+#else+#define EIGEN_DBG_SKYLINE(X) X+#endif++const unsigned int SkylineBit = 0x1200;+template<typename Lhs, typename Rhs, int ProductMode> class SkylineProduct;+enum AdditionalProductEvaluationMode {SkylineTimeDenseProduct, SkylineTimeSkylineProduct, DenseTimeSkylineProduct};+enum {IsSkyline = SkylineBit};+++#define EIGEN_SKYLINE_INHERIT_ASSIGNMENT_OPERATOR(Derived, Op) \+template<typename OtherDerived> \+EIGEN_STRONG_INLINE Derived& operator Op(const Eigen::SkylineMatrixBase<OtherDerived>& other) \+{ \+ return Base::operator Op(other.derived()); \+} \+EIGEN_STRONG_INLINE Derived& operator Op(const Derived& other) \+{ \+ return Base::operator Op(other); \+}++#define EIGEN_SKYLINE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, Op) \+template<typename Other> \+EIGEN_STRONG_INLINE Derived& operator Op(const Other& scalar) \+{ \+ return Base::operator Op(scalar); \+}++#define EIGEN_SKYLINE_INHERIT_ASSIGNMENT_OPERATORS(Derived) \+ EIGEN_SKYLINE_INHERIT_ASSIGNMENT_OPERATOR(Derived, =) \+ EIGEN_SKYLINE_INHERIT_ASSIGNMENT_OPERATOR(Derived, +=) \+ EIGEN_SKYLINE_INHERIT_ASSIGNMENT_OPERATOR(Derived, -=) \+ EIGEN_SKYLINE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, *=) \+ EIGEN_SKYLINE_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, /=)++#define _EIGEN_SKYLINE_GENERIC_PUBLIC_INTERFACE(Derived, BaseClass) \+ typedef BaseClass Base; \+ typedef typename Eigen::internal::traits<Derived>::Scalar Scalar; \+ typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; \+ typedef typename Eigen::internal::traits<Derived>::StorageKind StorageKind; \+ typedef typename Eigen::internal::index<StorageKind>::type Index; \+ enum { Flags = Eigen::internal::traits<Derived>::Flags, };++#define EIGEN_SKYLINE_GENERIC_PUBLIC_INTERFACE(Derived) \+ _EIGEN_SKYLINE_GENERIC_PUBLIC_INTERFACE(Derived, Eigen::SkylineMatrixBase<Derived>)++template<typename Derived> class SkylineMatrixBase;+template<typename _Scalar, int _Flags = 0> class SkylineMatrix;+template<typename _Scalar, int _Flags = 0> class DynamicSkylineMatrix;+template<typename _Scalar, int _Flags = 0> class SkylineVector;+template<typename _Scalar, int _Flags = 0> class MappedSkylineMatrix;++namespace internal {++template<typename Lhs, typename Rhs> struct skyline_product_mode;+template<typename Lhs, typename Rhs, int ProductMode = skyline_product_mode<Lhs,Rhs>::value> struct SkylineProductReturnType;++template<typename T> class eval<T,IsSkyline>+{+ typedef typename traits<T>::Scalar _Scalar;+ enum {+ _Flags = traits<T>::Flags+ };++ public:+ typedef SkylineMatrix<_Scalar, _Flags> type;+};++} // end namespace internal++} // end namespace Eigen++#endif // EIGEN_SKYLINEUTIL_H
+ eigen3/unsupported/Eigen/src/SparseExtra/BlockOfDynamicSparseMatrix.h view
@@ -0,0 +1,122 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H+#define EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H++namespace Eigen { ++#if 0++// NOTE Have to be reimplemented as a specialization of BlockImpl< DynamicSparseMatrix<_Scalar, _Options, _Index>, ... >+// See SparseBlock.h for an example+++/***************************************************************************+* specialisation for DynamicSparseMatrix+***************************************************************************/++template<typename _Scalar, int _Options, typename _Index, int Size>+class SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options, _Index>, Size>+ : public SparseMatrixBase<SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options, _Index>, Size> >+{+ typedef DynamicSparseMatrix<_Scalar, _Options, _Index> MatrixType;+ public:++ enum { IsRowMajor = internal::traits<SparseInnerVectorSet>::IsRowMajor };++ EIGEN_SPARSE_PUBLIC_INTERFACE(SparseInnerVectorSet)+ class InnerIterator: public MatrixType::InnerIterator+ {+ public:+ inline InnerIterator(const SparseInnerVectorSet& xpr, Index outer)+ : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)+ {}+ inline Index row() const { return IsRowMajor ? m_outer : this->index(); }+ inline Index col() const { return IsRowMajor ? this->index() : m_outer; }+ protected:+ Index m_outer;+ };++ inline SparseInnerVectorSet(const MatrixType& matrix, Index outerStart, Index outerSize)+ : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize)+ {+ eigen_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) );+ }++ inline SparseInnerVectorSet(const MatrixType& matrix, Index outer)+ : m_matrix(matrix), m_outerStart(outer), m_outerSize(Size)+ {+ eigen_assert(Size!=Dynamic);+ eigen_assert( (outer>=0) && (outer<matrix.outerSize()) );+ }++ template<typename OtherDerived>+ inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)+ {+ if (IsRowMajor != ((OtherDerived::Flags&RowMajorBit)==RowMajorBit))+ {+ // need to transpose => perform a block evaluation followed by a big swap+ DynamicSparseMatrix<Scalar,IsRowMajor?RowMajorBit:0> aux(other);+ *this = aux.markAsRValue();+ }+ else+ {+ // evaluate/copy vector per vector+ for (Index j=0; j<m_outerSize.value(); ++j)+ {+ SparseVector<Scalar,IsRowMajor ? RowMajorBit : 0> aux(other.innerVector(j));+ m_matrix.const_cast_derived()._data()[m_outerStart+j].swap(aux._data());+ }+ }+ return *this;+ }++ inline SparseInnerVectorSet& operator=(const SparseInnerVectorSet& other)+ {+ return operator=<SparseInnerVectorSet>(other);+ }++ Index nonZeros() const+ {+ Index count = 0;+ for (Index j=0; j<m_outerSize.value(); ++j)+ count += m_matrix._data()[m_outerStart+j].size();+ return count;+ }++ const Scalar& lastCoeff() const+ {+ EIGEN_STATIC_ASSERT_VECTOR_ONLY(SparseInnerVectorSet);+ eigen_assert(m_matrix.data()[m_outerStart].size()>0);+ return m_matrix.data()[m_outerStart].vale(m_matrix.data()[m_outerStart].size()-1);+ }++// template<typename Sparse>+// inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)+// {+// return *this;+// }++ EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }+ EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }++ protected:++ const typename MatrixType::Nested m_matrix;+ Index m_outerStart;+ const internal::variable_if_dynamic<Index, Size> m_outerSize;++};++#endif++} // end namespace Eigen++#endif // EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H
+ eigen3/unsupported/Eigen/src/SparseExtra/CMakeLists.txt view
@@ -0,0 +1,6 @@+FILE(GLOB Eigen_SparseExtra_SRCS "*.h")++INSTALL(FILES+ ${Eigen_SparseExtra_SRCS}+ DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/SparseExtra COMPONENT Devel+ )
+ eigen3/unsupported/Eigen/src/SparseExtra/DynamicSparseMatrix.h view
@@ -0,0 +1,357 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_DYNAMIC_SPARSEMATRIX_H+#define EIGEN_DYNAMIC_SPARSEMATRIX_H++namespace Eigen { ++/** \deprecated use a SparseMatrix in an uncompressed mode+ *+ * \class DynamicSparseMatrix+ *+ * \brief A sparse matrix class designed for matrix assembly purpose+ *+ * \param _Scalar the scalar type, i.e. the type of the coefficients+ *+ * Unlike SparseMatrix, this class provides a much higher degree of flexibility. In particular, it allows+ * random read/write accesses in log(rho*outer_size) where \c rho is the probability that a coefficient is+ * nonzero and outer_size is the number of columns if the matrix is column-major and the number of rows+ * otherwise.+ *+ * Internally, the data are stored as a std::vector of compressed vector. The performances of random writes might+ * decrease as the number of nonzeros per inner-vector increase. In practice, we observed very good performance+ * till about 100 nonzeros/vector, and the performance remains relatively good till 500 nonzeros/vectors.+ *+ * \see SparseMatrix+ */++namespace internal {+template<typename _Scalar, int _Options, typename _Index>+struct traits<DynamicSparseMatrix<_Scalar, _Options, _Index> >+{+ typedef _Scalar Scalar;+ typedef _Index Index;+ typedef Sparse StorageKind;+ typedef MatrixXpr XprKind;+ enum {+ RowsAtCompileTime = Dynamic,+ ColsAtCompileTime = Dynamic,+ MaxRowsAtCompileTime = Dynamic,+ MaxColsAtCompileTime = Dynamic,+ Flags = _Options | NestByRefBit | LvalueBit,+ CoeffReadCost = NumTraits<Scalar>::ReadCost,+ SupportedAccessPatterns = OuterRandomAccessPattern+ };+};+}++template<typename _Scalar, int _Options, typename _Index>+ class DynamicSparseMatrix+ : public SparseMatrixBase<DynamicSparseMatrix<_Scalar, _Options, _Index> >+{+ public:+ EIGEN_SPARSE_PUBLIC_INTERFACE(DynamicSparseMatrix)+ // FIXME: why are these operator already alvailable ???+ // EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(DynamicSparseMatrix, +=)+ // EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(DynamicSparseMatrix, -=)+ typedef MappedSparseMatrix<Scalar,Flags> Map;+ using Base::IsRowMajor;+ using Base::operator=;+ enum {+ Options = _Options+ };++ protected:++ typedef DynamicSparseMatrix<Scalar,(Flags&~RowMajorBit)|(IsRowMajor?RowMajorBit:0)> TransposedSparseMatrix;++ Index m_innerSize;+ std::vector<internal::CompressedStorage<Scalar,Index> > m_data;++ public:++ inline Index rows() const { return IsRowMajor ? outerSize() : m_innerSize; }+ inline Index cols() const { return IsRowMajor ? m_innerSize : outerSize(); }+ inline Index innerSize() const { return m_innerSize; }+ inline Index outerSize() const { return static_cast<Index>(m_data.size()); }+ inline Index innerNonZeros(Index j) const { return m_data[j].size(); }++ std::vector<internal::CompressedStorage<Scalar,Index> >& _data() { return m_data; }+ const std::vector<internal::CompressedStorage<Scalar,Index> >& _data() const { return m_data; }++ /** \returns the coefficient value at given position \a row, \a col+ * This operation involes a log(rho*outer_size) binary search.+ */+ inline Scalar coeff(Index row, Index col) const+ {+ const Index outer = IsRowMajor ? row : col;+ const Index inner = IsRowMajor ? col : row;+ return m_data[outer].at(inner);+ }++ /** \returns a reference to the coefficient value at given position \a row, \a col+ * This operation involes a log(rho*outer_size) binary search. If the coefficient does not+ * exist yet, then a sorted insertion into a sequential buffer is performed.+ */+ inline Scalar& coeffRef(Index row, Index col)+ {+ const Index outer = IsRowMajor ? row : col;+ const Index inner = IsRowMajor ? col : row;+ return m_data[outer].atWithInsertion(inner);+ }++ class InnerIterator;+ class ReverseInnerIterator;++ void setZero()+ {+ for (Index j=0; j<outerSize(); ++j)+ m_data[j].clear();+ }++ /** \returns the number of non zero coefficients */+ Index nonZeros() const+ {+ Index res = 0;+ for (Index j=0; j<outerSize(); ++j)+ res += static_cast<Index>(m_data[j].size());+ return res;+ }++++ void reserve(Index reserveSize = 1000)+ {+ if (outerSize()>0)+ {+ Index reserveSizePerVector = (std::max)(reserveSize/outerSize(),Index(4));+ for (Index j=0; j<outerSize(); ++j)+ {+ m_data[j].reserve(reserveSizePerVector);+ }+ }+ }++ /** Does nothing: provided for compatibility with SparseMatrix */+ inline void startVec(Index /*outer*/) {}++ /** \returns a reference to the non zero coefficient at position \a row, \a col assuming that:+ * - the nonzero does not already exist+ * - the new coefficient is the last one of the given inner vector.+ *+ * \sa insert, insertBackByOuterInner */+ inline Scalar& insertBack(Index row, Index col)+ {+ return insertBackByOuterInner(IsRowMajor?row:col, IsRowMajor?col:row);+ }++ /** \sa insertBack */+ inline Scalar& insertBackByOuterInner(Index outer, Index inner)+ {+ eigen_assert(outer<Index(m_data.size()) && inner<m_innerSize && "out of range");+ eigen_assert(((m_data[outer].size()==0) || (m_data[outer].index(m_data[outer].size()-1)<inner))+ && "wrong sorted insertion");+ m_data[outer].append(0, inner);+ return m_data[outer].value(m_data[outer].size()-1);+ }++ inline Scalar& insert(Index row, Index col)+ {+ const Index outer = IsRowMajor ? row : col;+ const Index inner = IsRowMajor ? col : row;++ Index startId = 0;+ Index id = static_cast<Index>(m_data[outer].size()) - 1;+ m_data[outer].resize(id+2,1);++ while ( (id >= startId) && (m_data[outer].index(id) > inner) )+ {+ m_data[outer].index(id+1) = m_data[outer].index(id);+ m_data[outer].value(id+1) = m_data[outer].value(id);+ --id;+ }+ m_data[outer].index(id+1) = inner;+ m_data[outer].value(id+1) = 0;+ return m_data[outer].value(id+1);+ }++ /** Does nothing: provided for compatibility with SparseMatrix */+ inline void finalize() {}++ /** Suppress all nonzeros which are smaller than \a reference under the tolerence \a epsilon */+ void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision())+ {+ for (Index j=0; j<outerSize(); ++j)+ m_data[j].prune(reference,epsilon);+ }++ /** Resize the matrix without preserving the data (the matrix is set to zero)+ */+ void resize(Index rows, Index cols)+ {+ const Index outerSize = IsRowMajor ? rows : cols;+ m_innerSize = IsRowMajor ? cols : rows;+ setZero();+ if (Index(m_data.size()) != outerSize)+ {+ m_data.resize(outerSize);+ }+ }++ void resizeAndKeepData(Index rows, Index cols)+ {+ const Index outerSize = IsRowMajor ? rows : cols;+ const Index innerSize = IsRowMajor ? cols : rows;+ if (m_innerSize>innerSize)+ {+ // remove all coefficients with innerCoord>=innerSize+ // TODO+ //std::cerr << "not implemented yet\n";+ exit(2);+ }+ if (m_data.size() != outerSize)+ {+ m_data.resize(outerSize);+ }+ }++ /** The class DynamicSparseMatrix is deprectaed */+ EIGEN_DEPRECATED inline DynamicSparseMatrix()+ : m_innerSize(0), m_data(0)+ {+ eigen_assert(innerSize()==0 && outerSize()==0);+ }++ /** The class DynamicSparseMatrix is deprectaed */+ EIGEN_DEPRECATED inline DynamicSparseMatrix(Index rows, Index cols)+ : m_innerSize(0)+ {+ resize(rows, cols);+ }++ /** The class DynamicSparseMatrix is deprectaed */+ template<typename OtherDerived>+ EIGEN_DEPRECATED explicit inline DynamicSparseMatrix(const SparseMatrixBase<OtherDerived>& other)+ : m_innerSize(0)+ {+ Base::operator=(other.derived());+ }++ inline DynamicSparseMatrix(const DynamicSparseMatrix& other)+ : Base(), m_innerSize(0)+ {+ *this = other.derived();+ }++ inline void swap(DynamicSparseMatrix& other)+ {+ //EIGEN_DBG_SPARSE(std::cout << "SparseMatrix:: swap\n");+ std::swap(m_innerSize, other.m_innerSize);+ //std::swap(m_outerSize, other.m_outerSize);+ m_data.swap(other.m_data);+ }++ inline DynamicSparseMatrix& operator=(const DynamicSparseMatrix& other)+ {+ if (other.isRValue())+ {+ swap(other.const_cast_derived());+ }+ else+ {+ resize(other.rows(), other.cols());+ m_data = other.m_data;+ }+ return *this;+ }++ /** Destructor */+ inline ~DynamicSparseMatrix() {}++ public:++ /** \deprecated+ * Set the matrix to zero and reserve the memory for \a reserveSize nonzero coefficients. */+ EIGEN_DEPRECATED void startFill(Index reserveSize = 1000)+ {+ setZero();+ reserve(reserveSize);+ }++ /** \deprecated use insert()+ * inserts a nonzero coefficient at given coordinates \a row, \a col and returns its reference assuming that:+ * 1 - the coefficient does not exist yet+ * 2 - this the coefficient with greater inner coordinate for the given outer coordinate.+ * In other words, assuming \c *this is column-major, then there must not exists any nonzero coefficient of coordinates+ * \c i \c x \a col such that \c i >= \a row. Otherwise the matrix is invalid.+ *+ * \see fillrand(), coeffRef()+ */+ EIGEN_DEPRECATED Scalar& fill(Index row, Index col)+ {+ const Index outer = IsRowMajor ? row : col;+ const Index inner = IsRowMajor ? col : row;+ return insertBack(outer,inner);+ }++ /** \deprecated use insert()+ * Like fill() but with random inner coordinates.+ * Compared to the generic coeffRef(), the unique limitation is that we assume+ * the coefficient does not exist yet.+ */+ EIGEN_DEPRECATED Scalar& fillrand(Index row, Index col)+ {+ return insert(row,col);+ }++ /** \deprecated use finalize()+ * Does nothing. Provided for compatibility with SparseMatrix. */+ EIGEN_DEPRECATED void endFill() {}+ +# ifdef EIGEN_DYNAMICSPARSEMATRIX_PLUGIN+# include EIGEN_DYNAMICSPARSEMATRIX_PLUGIN+# endif+ };++template<typename Scalar, int _Options, typename _Index>+class DynamicSparseMatrix<Scalar,_Options,_Index>::InnerIterator : public SparseVector<Scalar,_Options,_Index>::InnerIterator+{+ typedef typename SparseVector<Scalar,_Options,_Index>::InnerIterator Base;+ public:+ InnerIterator(const DynamicSparseMatrix& mat, Index outer)+ : Base(mat.m_data[outer]), m_outer(outer)+ {}++ inline Index row() const { return IsRowMajor ? m_outer : Base::index(); }+ inline Index col() const { return IsRowMajor ? Base::index() : m_outer; }++ protected:+ const Index m_outer;+};++template<typename Scalar, int _Options, typename _Index>+class DynamicSparseMatrix<Scalar,_Options,_Index>::ReverseInnerIterator : public SparseVector<Scalar,_Options,_Index>::ReverseInnerIterator+{+ typedef typename SparseVector<Scalar,_Options,_Index>::ReverseInnerIterator Base;+ public:+ ReverseInnerIterator(const DynamicSparseMatrix& mat, Index outer)+ : Base(mat.m_data[outer]), m_outer(outer)+ {}++ inline Index row() const { return IsRowMajor ? m_outer : Base::index(); }+ inline Index col() const { return IsRowMajor ? Base::index() : m_outer; }++ protected:+ const Index m_outer;+};++} // end namespace Eigen++#endif // EIGEN_DYNAMIC_SPARSEMATRIX_H
+ eigen3/unsupported/Eigen/src/SparseExtra/MarketIO.h view
@@ -0,0 +1,273 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2012 Desire NUENTSA WAKAM <desire.nuentsa_wakam@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_SPARSE_MARKET_IO_H+#define EIGEN_SPARSE_MARKET_IO_H++#include <iostream>++namespace Eigen { ++namespace internal +{+ template <typename Scalar>+ inline bool GetMarketLine (std::stringstream& line, int& M, int& N, int& i, int& j, Scalar& value)+ {+ line >> i >> j >> value;+ i--;+ j--;+ if(i>=0 && j>=0 && i<M && j<N)+ {+ return true; + }+ else+ return false;+ }+ template <typename Scalar>+ inline bool GetMarketLine (std::stringstream& line, int& M, int& N, int& i, int& j, std::complex<Scalar>& value)+ {+ Scalar valR, valI;+ line >> i >> j >> valR >> valI;+ i--;+ j--;+ if(i>=0 && j>=0 && i<M && j<N)+ {+ value = std::complex<Scalar>(valR, valI);+ return true; + }+ else+ return false;+ }++ template <typename RealScalar>+ inline void GetVectorElt (const std::string& line, RealScalar& val)+ {+ std::istringstream newline(line);+ newline >> val; + }++ template <typename RealScalar>+ inline void GetVectorElt (const std::string& line, std::complex<RealScalar>& val)+ {+ RealScalar valR, valI; + std::istringstream newline(line);+ newline >> valR >> valI; + val = std::complex<RealScalar>(valR, valI);+ }+ + template<typename Scalar>+ inline void putMarketHeader(std::string& header,int sym)+ {+ header= "%%MatrixMarket matrix coordinate ";+ if(internal::is_same<Scalar, std::complex<float> >::value || internal::is_same<Scalar, std::complex<double> >::value)+ {+ header += " complex"; + if(sym == Symmetric) header += " symmetric";+ else if (sym == SelfAdjoint) header += " Hermitian";+ else header += " general";+ }+ else+ {+ header += " real"; + if(sym == Symmetric) header += " symmetric";+ else header += " general";+ }+ }++ template<typename Scalar>+ inline void PutMatrixElt(Scalar value, int row, int col, std::ofstream& out)+ {+ out << row << " "<< col << " " << value << "\n";+ }+ template<typename Scalar>+ inline void PutMatrixElt(std::complex<Scalar> value, int row, int col, std::ofstream& out)+ {+ out << row << " " << col << " " << value.real() << " " << value.imag() << "\n";+ }+++ template<typename Scalar>+ inline void putVectorElt(Scalar value, std::ofstream& out)+ {+ out << value << "\n"; + }+ template<typename Scalar>+ inline void putVectorElt(std::complex<Scalar> value, std::ofstream& out)+ {+ out << value.real << " " << value.imag()<< "\n"; + }++} // end namepsace internal++inline bool getMarketHeader(const std::string& filename, int& sym, bool& iscomplex, bool& isvector)+{+ sym = 0; + isvector = false;+ std::ifstream in(filename.c_str(),std::ios::in);+ if(!in)+ return false;+ + std::string line; + // The matrix header is always the first line in the file + std::getline(in, line); eigen_assert(in.good());+ + std::stringstream fmtline(line); + std::string substr[5];+ fmtline>> substr[0] >> substr[1] >> substr[2] >> substr[3] >> substr[4];+ if(substr[2].compare("array") == 0) isvector = true;+ if(substr[3].compare("complex") == 0) iscomplex = true;+ if(substr[4].compare("symmetric") == 0) sym = Symmetric;+ else if (substr[4].compare("Hermitian") == 0) sym = SelfAdjoint;+ + return true;+}+ +template<typename SparseMatrixType>+bool loadMarket(SparseMatrixType& mat, const std::string& filename)+{+ typedef typename SparseMatrixType::Scalar Scalar;+ std::ifstream input(filename.c_str(),std::ios::in);+ if(!input)+ return false;+ + const int maxBuffersize = 2048;+ char buffer[maxBuffersize];+ + bool readsizes = false;++ typedef Triplet<Scalar,int> T;+ std::vector<T> elements;+ + int M(-1), N(-1), NNZ(-1);+ int count = 0;+ while(input.getline(buffer, maxBuffersize))+ {+ // skip comments + //NOTE An appropriate test should be done on the header to get the symmetry+ if(buffer[0]=='%')+ continue;+ + std::stringstream line(buffer);+ + if(!readsizes)+ {+ line >> M >> N >> NNZ;+ if(M > 0 && N > 0 && NNZ > 0) + {+ readsizes = true;+ std::cout << "sizes: " << M << "," << N << "," << NNZ << "\n";+ mat.resize(M,N);+ mat.reserve(NNZ);+ }+ }+ else+ { + int i(-1), j(-1);+ Scalar value; + if( internal::GetMarketLine(line, M, N, i, j, value) ) + {+ ++ count;+ elements.push_back(T(i,j,value));+ }+ else + std::cerr << "Invalid read: " << i << "," << j << "\n"; + }+ }+ mat.setFromTriplets(elements.begin(), elements.end());+ if(count!=NNZ)+ std::cerr << count << "!=" << NNZ << "\n";+ + input.close();+ return true;+}++template<typename VectorType>+bool loadMarketVector(VectorType& vec, const std::string& filename)+{+ typedef typename VectorType::Scalar Scalar;+ std::ifstream in(filename.c_str(), std::ios::in);+ if(!in)+ return false;+ + std::string line; + int n(0), col(0); + do + { // Skip comments+ std::getline(in, line); eigen_assert(in.good());+ } while (line[0] == '%');+ std::istringstream newline(line);+ newline >> n >> col; + eigen_assert(n>0 && col>0);+ vec.resize(n);+ int i = 0; + Scalar value; + while ( std::getline(in, line) && (i < n) ){+ internal::GetVectorElt(line, value); + vec(i++) = value; + }+ in.close();+ if (i!=n){+ std::cerr<< "Unable to read all elements from file " << filename << "\n";+ return false;+ }+ return true;+}++template<typename SparseMatrixType>+bool saveMarket(const SparseMatrixType& mat, const std::string& filename, int sym = 0)+{+ typedef typename SparseMatrixType::Scalar Scalar;+ std::ofstream out(filename.c_str(),std::ios::out);+ if(!out)+ return false;+ + out.flags(std::ios_base::scientific);+ out.precision(64);+ std::string header; + internal::putMarketHeader<Scalar>(header, sym); + out << header << std::endl; + out << mat.rows() << " " << mat.cols() << " " << mat.nonZeros() << "\n";+ int count = 0;+ for(int j=0; j<mat.outerSize(); ++j)+ for(typename SparseMatrixType::InnerIterator it(mat,j); it; ++it)+ {+ ++ count;+ internal::PutMatrixElt(it.value(), it.row()+1, it.col()+1, out);+ // out << it.row()+1 << " " << it.col()+1 << " " << it.value() << "\n";+ }+ out.close();+ return true;+}++template<typename VectorType>+bool saveMarketVector (const VectorType& vec, const std::string& filename)+{+ typedef typename VectorType::Scalar Scalar; + std::ofstream out(filename.c_str(),std::ios::out);+ if(!out)+ return false;+ + out.flags(std::ios_base::scientific);+ out.precision(64);+ if(internal::is_same<Scalar, std::complex<float> >::value || internal::is_same<Scalar, std::complex<double> >::value)+ out << "%%MatrixMarket matrix array complex general\n"; + else+ out << "%%MatrixMarket matrix array real general\n"; + out << vec.size() << " "<< 1 << "\n";+ for (int i=0; i < vec.size(); i++){+ internal::putVectorElt(vec(i), out); + }+ out.close();+ return true; +}++} // end namespace Eigen++#endif // EIGEN_SPARSE_MARKET_IO_H
+ eigen3/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h view
@@ -0,0 +1,232 @@++// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Desire NUENTSA WAKAM <desire.nuentsa_wakam@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_BROWSE_MATRICES_H+#define EIGEN_BROWSE_MATRICES_H++namespace Eigen {++enum {+ SPD = 0x100,+ NonSymmetric = 0x0+}; ++/** + * @brief Iterator to browse matrices from a specified folder+ * + * This is used to load all the matrices from a folder. + * The matrices should be in Matrix Market format+ * It is assumed that the matrices are named as matname.mtx+ * and matname_SPD.mtx if the matrix is Symmetric and positive definite (or Hermitian)+ * The right hand side vectors are loaded as well, if they exist.+ * They should be named as matname_b.mtx. + * Note that the right hand side for a SPD matrix is named as matname_SPD_b.mtx+ * + * Sometimes a reference solution is available. In this case, it should be named as matname_x.mtx+ * + * Sample code+ * \code+ * + * \endcode+ * + * \tparam Scalar The scalar type + */+template <typename Scalar>+class MatrixMarketIterator +{+ public:+ typedef Matrix<Scalar,Dynamic,1> VectorType; + typedef SparseMatrix<Scalar,ColMajor> MatrixType; + + public:+ MatrixMarketIterator(const std::string folder):m_sym(0),m_isvalid(false),m_matIsLoaded(false),m_hasRhs(false),m_hasrefX(false),m_folder(folder)+ {+ m_folder_id = opendir(folder.c_str());+ if (!m_folder_id){+ m_isvalid = false;+ std::cerr << "The provided Matrix folder could not be opened \n\n";+ abort();+ }+ Getnextvalidmatrix();+ }+ + ~MatrixMarketIterator()+ {+ if (m_folder_id) closedir(m_folder_id); + }+ + inline MatrixMarketIterator& operator++()+ {+ m_matIsLoaded = false;+ m_hasrefX = false;+ m_hasRhs = false;+ Getnextvalidmatrix();+ return *this;+ }+ inline operator bool() const { return m_isvalid;}+ + /** Return the sparse matrix corresponding to the current file */+ inline MatrixType& matrix() + { + // Read the matrix+ if (m_matIsLoaded) return m_mat;+ + std::string matrix_file = m_folder + "/" + m_matname + ".mtx";+ if ( !loadMarket(m_mat, matrix_file)) + {+ m_matIsLoaded = false;+ return m_mat;+ }+ m_matIsLoaded = true; + + if (m_sym != NonSymmetric) + { // Store the upper part of the matrix. It is needed by the solvers dealing with nonsymmetric matrices ??+ MatrixType B; + B = m_mat;+ m_mat = B.template selfadjointView<Lower>();+ }+ return m_mat; + }+ + /** Return the right hand side corresponding to the current matrix. + * If the rhs file is not provided, a random rhs is generated+ */+ inline VectorType& rhs() + { + // Get the right hand side+ if (m_hasRhs) return m_rhs;+ + std::string rhs_file;+ rhs_file = m_folder + "/" + m_matname + "_b.mtx"; // The pattern is matname_b.mtx+ m_hasRhs = Fileexists(rhs_file);+ if (m_hasRhs)+ {+ m_rhs.resize(m_mat.cols());+ m_hasRhs = loadMarketVector(m_rhs, rhs_file);+ }+ if (!m_hasRhs)+ {+ // Generate a random right hand side+ if (!m_matIsLoaded) this->matrix(); + m_refX.resize(m_mat.cols());+ m_refX.setRandom();+ m_rhs = m_mat * m_refX;+ m_hasrefX = true;+ m_hasRhs = true;+ }+ return m_rhs; + }+ + /** Return a reference solution+ * If it is not provided and if the right hand side is not available+ * then refX is randomly generated such that A*refX = b + * where A and b are the matrix and the rhs. + * Note that when a rhs is provided, refX is not available + */+ inline VectorType& refX() + { + // Check if a reference solution is provided+ if (m_hasrefX) return m_refX;+ + std::string lhs_file;+ lhs_file = m_folder + "/" + m_matname + "_x.mtx"; + m_hasrefX = Fileexists(lhs_file);+ if (m_hasrefX)+ {+ m_refX.resize(m_mat.cols());+ m_hasrefX = loadMarketVector(m_refX, lhs_file);+ }+ return m_refX; + }+ + inline std::string& matname() { return m_matname; }+ + inline int sym() { return m_sym; }+ + inline bool hasRhs() {return m_hasRhs; }+ inline bool hasrefX() {return m_hasrefX; }+ + protected:+ + inline bool Fileexists(std::string file)+ {+ std::ifstream file_id(file.c_str());+ if (!file_id.good() ) + {+ return false;+ }+ else + {+ file_id.close();+ return true;+ }+ }+ + void Getnextvalidmatrix( )+ {+ m_isvalid = false;+ // Here, we return with the next valid matrix in the folder+ while ( (m_curs_id = readdir(m_folder_id)) != NULL) {+ m_isvalid = false;+ std::string curfile;+ curfile = m_folder + "/" + m_curs_id->d_name;+ // Discard if it is a folder+ if (m_curs_id->d_type == DT_DIR) continue; //FIXME This may not be available on non BSD systems+// struct stat st_buf; +// stat (curfile.c_str(), &st_buf);+// if (S_ISDIR(st_buf.st_mode)) continue;+ + // Determine from the header if it is a matrix or a right hand side + bool isvector,iscomplex=false;+ if(!getMarketHeader(curfile,m_sym,iscomplex,isvector)) continue;+ if(isvector) continue;+ if (!iscomplex)+ {+ if(internal::is_same<Scalar, std::complex<float> >::value || internal::is_same<Scalar, std::complex<double> >::value)+ continue; + }+ if (iscomplex)+ {+ if(internal::is_same<Scalar, float>::value || internal::is_same<Scalar, double>::value)+ continue; + }+ + + // Get the matrix name+ std::string filename = m_curs_id->d_name;+ m_matname = filename.substr(0, filename.length()-4); + + // Find if the matrix is SPD + size_t found = m_matname.find("SPD");+ if( (found!=std::string::npos) && (m_sym != NonSymmetric) )+ m_sym = SPD;+ + m_isvalid = true;+ break; + }+ }+ int m_sym; // Symmetry of the matrix+ MatrixType m_mat; // Current matrix + VectorType m_rhs; // Current vector+ VectorType m_refX; // The reference solution, if exists+ std::string m_matname; // Matrix Name+ bool m_isvalid; + bool m_matIsLoaded; // Determine if the matrix has already been loaded from the file+ bool m_hasRhs; // The right hand side exists+ bool m_hasrefX; // A reference solution is provided+ std::string m_folder;+ DIR * m_folder_id;+ struct dirent *m_curs_id; + +};++} // end namespace Eigen++#endif
+ eigen3/unsupported/Eigen/src/SparseExtra/RandomSetter.h view
@@ -0,0 +1,327 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_RANDOMSETTER_H+#define EIGEN_RANDOMSETTER_H++namespace Eigen { ++/** Represents a std::map+ *+ * \see RandomSetter+ */+template<typename Scalar> struct StdMapTraits+{+ typedef int KeyType;+ typedef std::map<KeyType,Scalar> Type;+ enum {+ IsSorted = 1+ };++ static void setInvalidKey(Type&, const KeyType&) {}+};++#ifdef EIGEN_UNORDERED_MAP_SUPPORT+/** Represents a std::unordered_map+ *+ * To use it you need to both define EIGEN_UNORDERED_MAP_SUPPORT and include the unordered_map header file+ * yourself making sure that unordered_map is defined in the std namespace.+ *+ * For instance, with current version of gcc you can either enable C++0x standard (-std=c++0x) or do:+ * \code+ * #include <tr1/unordered_map>+ * #define EIGEN_UNORDERED_MAP_SUPPORT+ * namespace std {+ * using std::tr1::unordered_map;+ * }+ * \endcode+ *+ * \see RandomSetter+ */+template<typename Scalar> struct StdUnorderedMapTraits+{+ typedef int KeyType;+ typedef std::unordered_map<KeyType,Scalar> Type;+ enum {+ IsSorted = 0+ };++ static void setInvalidKey(Type&, const KeyType&) {}+};+#endif // EIGEN_UNORDERED_MAP_SUPPORT++#ifdef _DENSE_HASH_MAP_H_+/** Represents a google::dense_hash_map+ *+ * \see RandomSetter+ */+template<typename Scalar> struct GoogleDenseHashMapTraits+{+ typedef int KeyType;+ typedef google::dense_hash_map<KeyType,Scalar> Type;+ enum {+ IsSorted = 0+ };++ static void setInvalidKey(Type& map, const KeyType& k)+ { map.set_empty_key(k); }+};+#endif++#ifdef _SPARSE_HASH_MAP_H_+/** Represents a google::sparse_hash_map+ *+ * \see RandomSetter+ */+template<typename Scalar> struct GoogleSparseHashMapTraits+{+ typedef int KeyType;+ typedef google::sparse_hash_map<KeyType,Scalar> Type;+ enum {+ IsSorted = 0+ };++ static void setInvalidKey(Type&, const KeyType&) {}+};+#endif++/** \class RandomSetter+ *+ * \brief The RandomSetter is a wrapper object allowing to set/update a sparse matrix with random access+ *+ * \param SparseMatrixType the type of the sparse matrix we are updating+ * \param MapTraits a traits class representing the map implementation used for the temporary sparse storage.+ * Its default value depends on the system.+ * \param OuterPacketBits defines the number of rows (or columns) manage by a single map object+ * as a power of two exponent.+ *+ * This class temporarily represents a sparse matrix object using a generic map implementation allowing for+ * efficient random access. The conversion from the compressed representation to a hash_map object is performed+ * in the RandomSetter constructor, while the sparse matrix is updated back at destruction time. This strategy+ * suggest the use of nested blocks as in this example:+ *+ * \code+ * SparseMatrix<double> m(rows,cols);+ * {+ * RandomSetter<SparseMatrix<double> > w(m);+ * // don't use m but w instead with read/write random access to the coefficients:+ * for(;;)+ * w(rand(),rand()) = rand;+ * }+ * // when w is deleted, the data are copied back to m+ * // and m is ready to use.+ * \endcode+ *+ * Since hash_map objects are not fully sorted, representing a full matrix as a single hash_map would+ * involve a big and costly sort to update the compressed matrix back. To overcome this issue, a RandomSetter+ * use multiple hash_map, each representing 2^OuterPacketBits columns or rows according to the storage order.+ * To reach optimal performance, this value should be adjusted according to the average number of nonzeros+ * per rows/columns.+ *+ * The possible values for the template parameter MapTraits are:+ * - \b StdMapTraits: corresponds to std::map. (does not perform very well)+ * - \b GnuHashMapTraits: corresponds to __gnu_cxx::hash_map (available only with GCC)+ * - \b GoogleDenseHashMapTraits: corresponds to google::dense_hash_map (best efficiency, reasonable memory consumption)+ * - \b GoogleSparseHashMapTraits: corresponds to google::sparse_hash_map (best memory consumption, relatively good performance)+ *+ * The default map implementation depends on the availability, and the preferred order is:+ * GoogleSparseHashMapTraits, GnuHashMapTraits, and finally StdMapTraits.+ *+ * For performance and memory consumption reasons it is highly recommended to use one of+ * the Google's hash_map implementation. To enable the support for them, you have two options:+ * - \#include <google/dense_hash_map> yourself \b before Eigen/Sparse header+ * - define EIGEN_GOOGLEHASH_SUPPORT+ * In the later case the inclusion of <google/dense_hash_map> is made for you.+ *+ * \see http://code.google.com/p/google-sparsehash/+ */+template<typename SparseMatrixType,+ template <typename T> class MapTraits =+#if defined _DENSE_HASH_MAP_H_+ GoogleDenseHashMapTraits+#elif defined _HASH_MAP+ GnuHashMapTraits+#else+ StdMapTraits+#endif+ ,int OuterPacketBits = 6>+class RandomSetter+{+ typedef typename SparseMatrixType::Scalar Scalar;+ typedef typename SparseMatrixType::Index Index;++ struct ScalarWrapper+ {+ ScalarWrapper() : value(0) {}+ Scalar value;+ };+ typedef typename MapTraits<ScalarWrapper>::KeyType KeyType;+ typedef typename MapTraits<ScalarWrapper>::Type HashMapType;+ static const int OuterPacketMask = (1 << OuterPacketBits) - 1;+ enum {+ SwapStorage = 1 - MapTraits<ScalarWrapper>::IsSorted,+ TargetRowMajor = (SparseMatrixType::Flags & RowMajorBit) ? 1 : 0,+ SetterRowMajor = SwapStorage ? 1-TargetRowMajor : TargetRowMajor+ };++ public:++ /** Constructs a random setter object from the sparse matrix \a target+ *+ * Note that the initial value of \a target are imported. If you want to re-set+ * a sparse matrix from scratch, then you must set it to zero first using the+ * setZero() function.+ */+ inline RandomSetter(SparseMatrixType& target)+ : mp_target(&target)+ {+ const Index outerSize = SwapStorage ? target.innerSize() : target.outerSize();+ const Index innerSize = SwapStorage ? target.outerSize() : target.innerSize();+ m_outerPackets = outerSize >> OuterPacketBits;+ if (outerSize&OuterPacketMask)+ m_outerPackets += 1;+ m_hashmaps = new HashMapType[m_outerPackets];+ // compute number of bits needed to store inner indices+ Index aux = innerSize - 1;+ m_keyBitsOffset = 0;+ while (aux)+ {+ ++m_keyBitsOffset;+ aux = aux >> 1;+ }+ KeyType ik = (1<<(OuterPacketBits+m_keyBitsOffset));+ for (Index k=0; k<m_outerPackets; ++k)+ MapTraits<ScalarWrapper>::setInvalidKey(m_hashmaps[k],ik);++ // insert current coeffs+ for (Index j=0; j<mp_target->outerSize(); ++j)+ for (typename SparseMatrixType::InnerIterator it(*mp_target,j); it; ++it)+ (*this)(TargetRowMajor?j:it.index(), TargetRowMajor?it.index():j) = it.value();+ }++ /** Destructor updating back the sparse matrix target */+ ~RandomSetter()+ {+ KeyType keyBitsMask = (1<<m_keyBitsOffset)-1;+ if (!SwapStorage) // also means the map is sorted+ {+ mp_target->setZero();+ mp_target->makeCompressed();+ mp_target->reserve(nonZeros());+ Index prevOuter = -1;+ for (Index k=0; k<m_outerPackets; ++k)+ {+ const Index outerOffset = (1<<OuterPacketBits) * k;+ typename HashMapType::iterator end = m_hashmaps[k].end();+ for (typename HashMapType::iterator it = m_hashmaps[k].begin(); it!=end; ++it)+ {+ const Index outer = (it->first >> m_keyBitsOffset) + outerOffset;+ const Index inner = it->first & keyBitsMask;+ if (prevOuter!=outer)+ {+ for (Index j=prevOuter+1;j<=outer;++j)+ mp_target->startVec(j);+ prevOuter = outer;+ }+ mp_target->insertBackByOuterInner(outer, inner) = it->second.value;+ }+ }+ mp_target->finalize();+ }+ else+ {+ VectorXi positions(mp_target->outerSize());+ positions.setZero();+ // pass 1+ for (Index k=0; k<m_outerPackets; ++k)+ {+ typename HashMapType::iterator end = m_hashmaps[k].end();+ for (typename HashMapType::iterator it = m_hashmaps[k].begin(); it!=end; ++it)+ {+ const Index outer = it->first & keyBitsMask;+ ++positions[outer];+ }+ }+ // prefix sum+ Index count = 0;+ for (Index j=0; j<mp_target->outerSize(); ++j)+ {+ Index tmp = positions[j];+ mp_target->outerIndexPtr()[j] = count;+ positions[j] = count;+ count += tmp;+ }+ mp_target->makeCompressed();+ mp_target->outerIndexPtr()[mp_target->outerSize()] = count;+ mp_target->resizeNonZeros(count);+ // pass 2+ for (Index k=0; k<m_outerPackets; ++k)+ {+ const Index outerOffset = (1<<OuterPacketBits) * k;+ typename HashMapType::iterator end = m_hashmaps[k].end();+ for (typename HashMapType::iterator it = m_hashmaps[k].begin(); it!=end; ++it)+ {+ const Index inner = (it->first >> m_keyBitsOffset) + outerOffset;+ const Index outer = it->first & keyBitsMask;+ // sorted insertion+ // Note that we have to deal with at most 2^OuterPacketBits unsorted coefficients,+ // moreover those 2^OuterPacketBits coeffs are likely to be sparse, an so only a+ // small fraction of them have to be sorted, whence the following simple procedure:+ Index posStart = mp_target->outerIndexPtr()[outer];+ Index i = (positions[outer]++) - 1;+ while ( (i >= posStart) && (mp_target->innerIndexPtr()[i] > inner) )+ {+ mp_target->valuePtr()[i+1] = mp_target->valuePtr()[i];+ mp_target->innerIndexPtr()[i+1] = mp_target->innerIndexPtr()[i];+ --i;+ }+ mp_target->innerIndexPtr()[i+1] = inner;+ mp_target->valuePtr()[i+1] = it->second.value;+ }+ }+ }+ delete[] m_hashmaps;+ }++ /** \returns a reference to the coefficient at given coordinates \a row, \a col */+ Scalar& operator() (Index row, Index col)+ {+ const Index outer = SetterRowMajor ? row : col;+ const Index inner = SetterRowMajor ? col : row;+ const Index outerMajor = outer >> OuterPacketBits; // index of the packet/map+ const Index outerMinor = outer & OuterPacketMask; // index of the inner vector in the packet+ const KeyType key = (KeyType(outerMinor)<<m_keyBitsOffset) | inner;+ return m_hashmaps[outerMajor][key].value;+ }++ /** \returns the number of non zero coefficients+ *+ * \note According to the underlying map/hash_map implementation,+ * this function might be quite expensive.+ */+ Index nonZeros() const+ {+ Index nz = 0;+ for (Index k=0; k<m_outerPackets; ++k)+ nz += static_cast<Index>(m_hashmaps[k].size());+ return nz;+ }+++ protected:++ HashMapType* m_hashmaps;+ SparseMatrixType* mp_target;+ Index m_outerPackets;+ unsigned char m_keyBitsOffset;+};++} // end namespace Eigen++#endif // EIGEN_RANDOMSETTER_H
+ eigen3/unsupported/Eigen/src/Splines/CMakeLists.txt view
@@ -0,0 +1,6 @@+FILE(GLOB Eigen_Splines_SRCS "*.h")++INSTALL(FILES+ ${Eigen_Splines_SRCS}+ DESTINATION ${INCLUDE_INSTALL_DIR}/unsupported/Eigen/src/Splines COMPONENT Devel+ )
+ eigen3/unsupported/Eigen/src/Splines/Spline.h view
@@ -0,0 +1,474 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 20010-2011 Hauke Heibel <hauke.heibel@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_SPLINE_H+#define EIGEN_SPLINE_H++#include "SplineFwd.h"++namespace Eigen+{+ /**+ * \ingroup Splines_Module+ * \class Spline+ * \brief A class representing multi-dimensional spline curves.+ *+ * The class represents B-splines with non-uniform knot vectors. Each control+ * point of the B-spline is associated with a basis function+ * \f{align*}+ * C(u) & = \sum_{i=0}^{n}N_{i,p}(u)P_i+ * \f}+ *+ * \tparam _Scalar The underlying data type (typically float or double)+ * \tparam _Dim The curve dimension (e.g. 2 or 3)+ * \tparam _Degree Per default set to Dynamic; could be set to the actual desired+ * degree for optimization purposes (would result in stack allocation+ * of several temporary variables).+ **/+ template <typename _Scalar, int _Dim, int _Degree>+ class Spline+ {+ public:+ typedef _Scalar Scalar; /*!< The spline curve's scalar type. */+ enum { Dimension = _Dim /*!< The spline curve's dimension. */ };+ enum { Degree = _Degree /*!< The spline curve's degree. */ };++ /** \brief The point type the spline is representing. */+ typedef typename SplineTraits<Spline>::PointType PointType;+ + /** \brief The data type used to store knot vectors. */+ typedef typename SplineTraits<Spline>::KnotVectorType KnotVectorType;+ + /** \brief The data type used to store non-zero basis functions. */+ typedef typename SplineTraits<Spline>::BasisVectorType BasisVectorType;+ + /** \brief The data type representing the spline's control points. */+ typedef typename SplineTraits<Spline>::ControlPointVectorType ControlPointVectorType;+ + /**+ * \brief Creates a (constant) zero spline.+ * For Splines with dynamic degree, the resulting degree will be 0.+ **/+ Spline() + : m_knots(1, (Degree==Dynamic ? 2 : 2*Degree+2))+ , m_ctrls(ControlPointVectorType::Zero(2,(Degree==Dynamic ? 1 : Degree+1))) + {+ // in theory this code can go to the initializer list but it will get pretty+ // much unreadable ...+ enum { MinDegree = (Degree==Dynamic ? 0 : Degree) };+ m_knots.template segment<MinDegree+1>(0) = Array<Scalar,1,MinDegree+1>::Zero();+ m_knots.template segment<MinDegree+1>(MinDegree+1) = Array<Scalar,1,MinDegree+1>::Ones();+ }++ /**+ * \brief Creates a spline from a knot vector and control points.+ * \param knots The spline's knot vector.+ * \param ctrls The spline's control point vector.+ **/+ template <typename OtherVectorType, typename OtherArrayType>+ Spline(const OtherVectorType& knots, const OtherArrayType& ctrls) : m_knots(knots), m_ctrls(ctrls) {}++ /**+ * \brief Copy constructor for splines.+ * \param spline The input spline.+ **/+ template <int OtherDegree>+ Spline(const Spline<Scalar, Dimension, OtherDegree>& spline) : + m_knots(spline.knots()), m_ctrls(spline.ctrls()) {}++ /**+ * \brief Returns the knots of the underlying spline.+ **/+ const KnotVectorType& knots() const { return m_knots; }+ + /**+ * \brief Returns the knots of the underlying spline.+ **/ + const ControlPointVectorType& ctrls() const { return m_ctrls; }++ /**+ * \brief Returns the spline value at a given site \f$u\f$.+ *+ * The function returns+ * \f{align*}+ * C(u) & = \sum_{i=0}^{n}N_{i,p}P_i+ * \f}+ *+ * \param u Parameter \f$u \in [0;1]\f$ at which the spline is evaluated.+ * \return The spline value at the given location \f$u\f$.+ **/+ PointType operator()(Scalar u) const;++ /**+ * \brief Evaluation of spline derivatives of up-to given order.+ *+ * The function returns+ * \f{align*}+ * \frac{d^i}{du^i}C(u) & = \sum_{i=0}^{n} \frac{d^i}{du^i} N_{i,p}(u)P_i+ * \f}+ * for i ranging between 0 and order.+ *+ * \param u Parameter \f$u \in [0;1]\f$ at which the spline derivative is evaluated.+ * \param order The order up to which the derivatives are computed.+ **/+ typename SplineTraits<Spline>::DerivativeType+ derivatives(Scalar u, DenseIndex order) const;++ /**+ * \copydoc Spline::derivatives+ * Using the template version of this function is more efficieent since+ * temporary objects are allocated on the stack whenever this is possible.+ **/ + template <int DerivativeOrder>+ typename SplineTraits<Spline,DerivativeOrder>::DerivativeType+ derivatives(Scalar u, DenseIndex order = DerivativeOrder) const;++ /**+ * \brief Computes the non-zero basis functions at the given site.+ *+ * Splines have local support and a point from their image is defined+ * by exactly \f$p+1\f$ control points \f$P_i\f$ where \f$p\f$ is the+ * spline degree.+ *+ * This function computes the \f$p+1\f$ non-zero basis function values+ * for a given parameter value \f$u\f$. It returns+ * \f{align*}{+ * N_{i,p}(u), \hdots, N_{i+p+1,p}(u)+ * \f}+ *+ * \param u Parameter \f$u \in [0;1]\f$ at which the non-zero basis functions + * are computed.+ **/+ typename SplineTraits<Spline>::BasisVectorType+ basisFunctions(Scalar u) const;++ /**+ * \brief Computes the non-zero spline basis function derivatives up to given order.+ *+ * The function computes+ * \f{align*}{+ * \frac{d^i}{du^i} N_{i,p}(u), \hdots, \frac{d^i}{du^i} N_{i+p+1,p}(u)+ * \f}+ * with i ranging from 0 up to the specified order.+ *+ * \param u Parameter \f$u \in [0;1]\f$ at which the non-zero basis function+ * derivatives are computed.+ * \param order The order up to which the basis function derivatives are computes.+ **/+ typename SplineTraits<Spline>::BasisDerivativeType+ basisFunctionDerivatives(Scalar u, DenseIndex order) const;++ /**+ * \copydoc Spline::basisFunctionDerivatives+ * Using the template version of this function is more efficieent since+ * temporary objects are allocated on the stack whenever this is possible.+ **/ + template <int DerivativeOrder>+ typename SplineTraits<Spline,DerivativeOrder>::BasisDerivativeType+ basisFunctionDerivatives(Scalar u, DenseIndex order = DerivativeOrder) const;++ /**+ * \brief Returns the spline degree.+ **/ + DenseIndex degree() const;++ /** + * \brief Returns the span within the knot vector in which u is falling.+ * \param u The site for which the span is determined.+ **/+ DenseIndex span(Scalar u) const;++ /**+ * \brief Computes the spang within the provided knot vector in which u is falling.+ **/+ static DenseIndex Span(typename SplineTraits<Spline>::Scalar u, DenseIndex degree, const typename SplineTraits<Spline>::KnotVectorType& knots);+ + /**+ * \brief Returns the spline's non-zero basis functions.+ *+ * The function computes and returns+ * \f{align*}{+ * N_{i,p}(u), \hdots, N_{i+p+1,p}(u)+ * \f}+ *+ * \param u The site at which the basis functions are computed.+ * \param degree The degree of the underlying spline.+ * \param knots The underlying spline's knot vector.+ **/+ static BasisVectorType BasisFunctions(Scalar u, DenseIndex degree, const KnotVectorType& knots);+++ private:+ KnotVectorType m_knots; /*!< Knot vector. */+ ControlPointVectorType m_ctrls; /*!< Control points. */+ };++ template <typename _Scalar, int _Dim, int _Degree>+ DenseIndex Spline<_Scalar, _Dim, _Degree>::Span(+ typename SplineTraits< Spline<_Scalar, _Dim, _Degree> >::Scalar u,+ DenseIndex degree,+ const typename SplineTraits< Spline<_Scalar, _Dim, _Degree> >::KnotVectorType& knots)+ {+ // Piegl & Tiller, "The NURBS Book", A2.1 (p. 68)+ if (u <= knots(0)) return degree;+ const Scalar* pos = std::upper_bound(knots.data()+degree-1, knots.data()+knots.size()-degree-1, u);+ return static_cast<DenseIndex>( std::distance(knots.data(), pos) - 1 );+ }++ template <typename _Scalar, int _Dim, int _Degree>+ typename Spline<_Scalar, _Dim, _Degree>::BasisVectorType+ Spline<_Scalar, _Dim, _Degree>::BasisFunctions(+ typename Spline<_Scalar, _Dim, _Degree>::Scalar u,+ DenseIndex degree,+ const typename Spline<_Scalar, _Dim, _Degree>::KnotVectorType& knots)+ {+ typedef typename Spline<_Scalar, _Dim, _Degree>::BasisVectorType BasisVectorType;++ const DenseIndex p = degree;+ const DenseIndex i = Spline::Span(u, degree, knots);++ const KnotVectorType& U = knots;++ BasisVectorType left(p+1); left(0) = Scalar(0);+ BasisVectorType right(p+1); right(0) = Scalar(0); ++ VectorBlock<BasisVectorType,Degree>(left,1,p) = u - VectorBlock<const KnotVectorType,Degree>(U,i+1-p,p).reverse();+ VectorBlock<BasisVectorType,Degree>(right,1,p) = VectorBlock<const KnotVectorType,Degree>(U,i+1,p) - u;++ BasisVectorType N(1,p+1);+ N(0) = Scalar(1);+ for (DenseIndex j=1; j<=p; ++j)+ {+ Scalar saved = Scalar(0);+ for (DenseIndex r=0; r<j; r++)+ {+ const Scalar tmp = N(r)/(right(r+1)+left(j-r));+ N[r] = saved + right(r+1)*tmp;+ saved = left(j-r)*tmp;+ }+ N(j) = saved;+ }+ return N;+ }++ template <typename _Scalar, int _Dim, int _Degree>+ DenseIndex Spline<_Scalar, _Dim, _Degree>::degree() const+ {+ if (_Degree == Dynamic)+ return m_knots.size() - m_ctrls.cols() - 1;+ else+ return _Degree;+ }++ template <typename _Scalar, int _Dim, int _Degree>+ DenseIndex Spline<_Scalar, _Dim, _Degree>::span(Scalar u) const+ {+ return Spline::Span(u, degree(), knots());+ }++ template <typename _Scalar, int _Dim, int _Degree>+ typename Spline<_Scalar, _Dim, _Degree>::PointType Spline<_Scalar, _Dim, _Degree>::operator()(Scalar u) const+ {+ enum { Order = SplineTraits<Spline>::OrderAtCompileTime };++ const DenseIndex span = this->span(u);+ const DenseIndex p = degree();+ const BasisVectorType basis_funcs = basisFunctions(u);++ const Replicate<BasisVectorType,Dimension,1> ctrl_weights(basis_funcs);+ const Block<const ControlPointVectorType,Dimension,Order> ctrl_pts(ctrls(),0,span-p,Dimension,p+1);+ return (ctrl_weights * ctrl_pts).rowwise().sum();+ }++ /* --------------------------------------------------------------------------------------------- */++ template <typename SplineType, typename DerivativeType>+ void derivativesImpl(const SplineType& spline, typename SplineType::Scalar u, DenseIndex order, DerivativeType& der)+ { + enum { Dimension = SplineTraits<SplineType>::Dimension };+ enum { Order = SplineTraits<SplineType>::OrderAtCompileTime };+ enum { DerivativeOrder = DerivativeType::ColsAtCompileTime };++ typedef typename SplineTraits<SplineType>::ControlPointVectorType ControlPointVectorType;+ typedef typename SplineTraits<SplineType,DerivativeOrder>::BasisDerivativeType BasisDerivativeType;+ typedef typename BasisDerivativeType::ConstRowXpr BasisDerivativeRowXpr; ++ const DenseIndex p = spline.degree();+ const DenseIndex span = spline.span(u);++ const DenseIndex n = (std::min)(p, order);++ der.resize(Dimension,n+1);++ // Retrieve the basis function derivatives up to the desired order... + const BasisDerivativeType basis_func_ders = spline.template basisFunctionDerivatives<DerivativeOrder>(u, n+1);++ // ... and perform the linear combinations of the control points.+ for (DenseIndex der_order=0; der_order<n+1; ++der_order)+ {+ const Replicate<BasisDerivativeRowXpr,Dimension,1> ctrl_weights( basis_func_ders.row(der_order) );+ const Block<const ControlPointVectorType,Dimension,Order> ctrl_pts(spline.ctrls(),0,span-p,Dimension,p+1);+ der.col(der_order) = (ctrl_weights * ctrl_pts).rowwise().sum();+ }+ }++ template <typename _Scalar, int _Dim, int _Degree>+ typename SplineTraits< Spline<_Scalar, _Dim, _Degree> >::DerivativeType+ Spline<_Scalar, _Dim, _Degree>::derivatives(Scalar u, DenseIndex order) const+ {+ typename SplineTraits< Spline >::DerivativeType res;+ derivativesImpl(*this, u, order, res);+ return res;+ }++ template <typename _Scalar, int _Dim, int _Degree>+ template <int DerivativeOrder>+ typename SplineTraits< Spline<_Scalar, _Dim, _Degree>, DerivativeOrder >::DerivativeType+ Spline<_Scalar, _Dim, _Degree>::derivatives(Scalar u, DenseIndex order) const+ {+ typename SplineTraits< Spline, DerivativeOrder >::DerivativeType res;+ derivativesImpl(*this, u, order, res);+ return res;+ }++ template <typename _Scalar, int _Dim, int _Degree>+ typename SplineTraits< Spline<_Scalar, _Dim, _Degree> >::BasisVectorType+ Spline<_Scalar, _Dim, _Degree>::basisFunctions(Scalar u) const+ {+ return Spline::BasisFunctions(u, degree(), knots());+ }++ /* --------------------------------------------------------------------------------------------- */++ template <typename SplineType, typename DerivativeType>+ void basisFunctionDerivativesImpl(const SplineType& spline, typename SplineType::Scalar u, DenseIndex order, DerivativeType& N_)+ {+ enum { Order = SplineTraits<SplineType>::OrderAtCompileTime };++ typedef typename SplineTraits<SplineType>::Scalar Scalar;+ typedef typename SplineTraits<SplineType>::BasisVectorType BasisVectorType;+ typedef typename SplineTraits<SplineType>::KnotVectorType KnotVectorType;++ const KnotVectorType& U = spline.knots();++ const DenseIndex p = spline.degree();+ const DenseIndex span = spline.span(u);++ const DenseIndex n = (std::min)(p, order);++ N_.resize(n+1, p+1);++ BasisVectorType left = BasisVectorType::Zero(p+1);+ BasisVectorType right = BasisVectorType::Zero(p+1);++ Matrix<Scalar,Order,Order> ndu(p+1,p+1);++ double saved, temp;++ ndu(0,0) = 1.0;++ DenseIndex j;+ for (j=1; j<=p; ++j)+ {+ left[j] = u-U[span+1-j];+ right[j] = U[span+j]-u;+ saved = 0.0;++ for (DenseIndex r=0; r<j; ++r)+ {+ /* Lower triangle */+ ndu(j,r) = right[r+1]+left[j-r];+ temp = ndu(r,j-1)/ndu(j,r);+ /* Upper triangle */+ ndu(r,j) = static_cast<Scalar>(saved+right[r+1] * temp);+ saved = left[j-r] * temp;+ }++ ndu(j,j) = static_cast<Scalar>(saved);+ }++ for (j = p; j>=0; --j) + N_(0,j) = ndu(j,p);++ // Compute the derivatives+ DerivativeType a(n+1,p+1);+ DenseIndex r=0;+ for (; r<=p; ++r)+ {+ DenseIndex s1,s2;+ s1 = 0; s2 = 1; // alternate rows in array a+ a(0,0) = 1.0;++ // Compute the k-th derivative+ for (DenseIndex k=1; k<=static_cast<DenseIndex>(n); ++k)+ {+ double d = 0.0;+ DenseIndex rk,pk,j1,j2;+ rk = r-k; pk = p-k;++ if (r>=k)+ {+ a(s2,0) = a(s1,0)/ndu(pk+1,rk);+ d = a(s2,0)*ndu(rk,pk);+ }++ if (rk>=-1) j1 = 1;+ else j1 = -rk;++ if (r-1 <= pk) j2 = k-1;+ else j2 = p-r;++ for (j=j1; j<=j2; ++j)+ {+ a(s2,j) = (a(s1,j)-a(s1,j-1))/ndu(pk+1,rk+j);+ d += a(s2,j)*ndu(rk+j,pk);+ }++ if (r<=pk)+ {+ a(s2,k) = -a(s1,k-1)/ndu(pk+1,r);+ d += a(s2,k)*ndu(r,pk);+ }++ N_(k,r) = static_cast<Scalar>(d);+ j = s1; s1 = s2; s2 = j; // Switch rows+ }+ }++ /* Multiply through by the correct factors */+ /* (Eq. [2.9]) */+ r = p;+ for (DenseIndex k=1; k<=static_cast<DenseIndex>(n); ++k)+ {+ for (DenseIndex j=p; j>=0; --j) N_(k,j) *= r;+ r *= p-k;+ }+ }++ template <typename _Scalar, int _Dim, int _Degree>+ typename SplineTraits< Spline<_Scalar, _Dim, _Degree> >::BasisDerivativeType+ Spline<_Scalar, _Dim, _Degree>::basisFunctionDerivatives(Scalar u, DenseIndex order) const+ {+ typename SplineTraits< Spline >::BasisDerivativeType der;+ basisFunctionDerivativesImpl(*this, u, order, der);+ return der;+ }++ template <typename _Scalar, int _Dim, int _Degree>+ template <int DerivativeOrder>+ typename SplineTraits< Spline<_Scalar, _Dim, _Degree>, DerivativeOrder >::BasisDerivativeType+ Spline<_Scalar, _Dim, _Degree>::basisFunctionDerivatives(Scalar u, DenseIndex order) const+ {+ typename SplineTraits< Spline, DerivativeOrder >::BasisDerivativeType der;+ basisFunctionDerivativesImpl(*this, u, order, der);+ return der;+ }+}++#endif // EIGEN_SPLINE_H
+ eigen3/unsupported/Eigen/src/Splines/SplineFitting.h view
@@ -0,0 +1,156 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 20010-2011 Hauke Heibel <hauke.heibel@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_SPLINE_FITTING_H+#define EIGEN_SPLINE_FITTING_H++#include <numeric>++#include "SplineFwd.h"++#include <Eigen/QR>++namespace Eigen+{+ /**+ * \brief Computes knot averages.+ * \ingroup Splines_Module+ *+ * The knots are computed as+ * \f{align*}+ * u_0 & = \hdots = u_p = 0 \\+ * u_{m-p} & = \hdots = u_{m} = 1 \\+ * u_{j+p} & = \frac{1}{p}\sum_{i=j}^{j+p-1}\bar{u}_i \quad\quad j=1,\hdots,n-p+ * \f}+ * where \f$p\f$ is the degree and \f$m+1\f$ the number knots+ * of the desired interpolating spline.+ *+ * \param[in] parameters The input parameters. During interpolation one for each data point.+ * \param[in] degree The spline degree which is used during the interpolation.+ * \param[out] knots The output knot vector.+ *+ * \sa Les Piegl and Wayne Tiller, The NURBS book (2nd ed.), 1997, 9.2.1 Global Curve Interpolation to Point Data+ **/+ template <typename KnotVectorType>+ void KnotAveraging(const KnotVectorType& parameters, DenseIndex degree, KnotVectorType& knots)+ {+ knots.resize(parameters.size()+degree+1); ++ for (DenseIndex j=1; j<parameters.size()-degree; ++j)+ knots(j+degree) = parameters.segment(j,degree).mean();++ knots.segment(0,degree+1) = KnotVectorType::Zero(degree+1);+ knots.segment(knots.size()-degree-1,degree+1) = KnotVectorType::Ones(degree+1);+ }++ /**+ * \brief Computes chord length parameters which are required for spline interpolation.+ * \ingroup Splines_Module+ *+ * \param[in] pts The data points to which a spline should be fit.+ * \param[out] chord_lengths The resulting chord lenggth vector.+ *+ * \sa Les Piegl and Wayne Tiller, The NURBS book (2nd ed.), 1997, 9.2.1 Global Curve Interpolation to Point Data+ **/ + template <typename PointArrayType, typename KnotVectorType>+ void ChordLengths(const PointArrayType& pts, KnotVectorType& chord_lengths)+ {+ typedef typename KnotVectorType::Scalar Scalar;++ const DenseIndex n = pts.cols();++ // 1. compute the column-wise norms+ chord_lengths.resize(pts.cols());+ chord_lengths[0] = 0;+ chord_lengths.rightCols(n-1) = (pts.array().leftCols(n-1) - pts.array().rightCols(n-1)).matrix().colwise().norm();++ // 2. compute the partial sums+ std::partial_sum(chord_lengths.data(), chord_lengths.data()+n, chord_lengths.data());++ // 3. normalize the data+ chord_lengths /= chord_lengths(n-1);+ chord_lengths(n-1) = Scalar(1);+ }++ /**+ * \brief Spline fitting methods.+ * \ingroup Splines_Module+ **/ + template <typename SplineType>+ struct SplineFitting+ {+ typedef typename SplineType::KnotVectorType KnotVectorType;++ /**+ * \brief Fits an interpolating Spline to the given data points.+ *+ * \param pts The points for which an interpolating spline will be computed.+ * \param degree The degree of the interpolating spline.+ *+ * \returns A spline interpolating the initially provided points.+ **/+ template <typename PointArrayType>+ static SplineType Interpolate(const PointArrayType& pts, DenseIndex degree);++ /**+ * \brief Fits an interpolating Spline to the given data points.+ *+ * \param pts The points for which an interpolating spline will be computed.+ * \param degree The degree of the interpolating spline.+ * \param knot_parameters The knot parameters for the interpolation.+ *+ * \returns A spline interpolating the initially provided points.+ **/+ template <typename PointArrayType>+ static SplineType Interpolate(const PointArrayType& pts, DenseIndex degree, const KnotVectorType& knot_parameters);+ };++ template <typename SplineType>+ template <typename PointArrayType>+ SplineType SplineFitting<SplineType>::Interpolate(const PointArrayType& pts, DenseIndex degree, const KnotVectorType& knot_parameters)+ {+ typedef typename SplineType::KnotVectorType::Scalar Scalar; + typedef typename SplineType::ControlPointVectorType ControlPointVectorType; ++ typedef Matrix<Scalar,Dynamic,Dynamic> MatrixType;++ KnotVectorType knots;+ KnotAveraging(knot_parameters, degree, knots);++ DenseIndex n = pts.cols();+ MatrixType A = MatrixType::Zero(n,n);+ for (DenseIndex i=1; i<n-1; ++i)+ {+ const DenseIndex span = SplineType::Span(knot_parameters[i], degree, knots);++ // The segment call should somehow be told the spline order at compile time.+ A.row(i).segment(span-degree, degree+1) = SplineType::BasisFunctions(knot_parameters[i], degree, knots);+ }+ A(0,0) = 1.0;+ A(n-1,n-1) = 1.0;++ HouseholderQR<MatrixType> qr(A);++ // Here, we are creating a temporary due to an Eigen issue.+ ControlPointVectorType ctrls = qr.solve(MatrixType(pts.transpose())).transpose();++ return SplineType(knots, ctrls);+ }++ template <typename SplineType>+ template <typename PointArrayType>+ SplineType SplineFitting<SplineType>::Interpolate(const PointArrayType& pts, DenseIndex degree)+ {+ KnotVectorType chord_lengths; // knot parameters+ ChordLengths(pts, chord_lengths);+ return Interpolate(pts, degree, chord_lengths);+ }+}++#endif // EIGEN_SPLINE_FITTING_H
+ eigen3/unsupported/Eigen/src/Splines/SplineFwd.h view
@@ -0,0 +1,86 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 20010-2011 Hauke Heibel <hauke.heibel@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#ifndef EIGEN_SPLINES_FWD_H+#define EIGEN_SPLINES_FWD_H++#include <Eigen/Core>++namespace Eigen+{+ template <typename Scalar, int Dim, int Degree = Dynamic> class Spline;++ template < typename SplineType, int DerivativeOrder = Dynamic > struct SplineTraits {};++ /**+ * \ingroup Splines_Module+ * \brief Compile-time attributes of the Spline class for Dynamic degree.+ **/+ template <typename _Scalar, int _Dim, int _Degree>+ struct SplineTraits< Spline<_Scalar, _Dim, _Degree>, Dynamic >+ {+ typedef _Scalar Scalar; /*!< The spline curve's scalar type. */+ enum { Dimension = _Dim /*!< The spline curve's dimension. */ };+ enum { Degree = _Degree /*!< The spline curve's degree. */ };++ enum { OrderAtCompileTime = _Degree==Dynamic ? Dynamic : _Degree+1 /*!< The spline curve's order at compile-time. */ };+ enum { NumOfDerivativesAtCompileTime = OrderAtCompileTime /*!< The number of derivatives defined for the current spline. */ };++ /** \brief The data type used to store non-zero basis functions. */+ typedef Array<Scalar,1,OrderAtCompileTime> BasisVectorType;++ /** \brief The data type used to store the values of the basis function derivatives. */+ typedef Array<Scalar,Dynamic,Dynamic,RowMajor,NumOfDerivativesAtCompileTime,OrderAtCompileTime> BasisDerivativeType;+ + /** \brief The data type used to store the spline's derivative values. */+ typedef Array<Scalar,Dimension,Dynamic,ColMajor,Dimension,NumOfDerivativesAtCompileTime> DerivativeType;++ /** \brief The point type the spline is representing. */+ typedef Array<Scalar,Dimension,1> PointType;+ + /** \brief The data type used to store knot vectors. */+ typedef Array<Scalar,1,Dynamic> KnotVectorType;+ + /** \brief The data type representing the spline's control points. */+ typedef Array<Scalar,Dimension,Dynamic> ControlPointVectorType;+ };++ /**+ * \ingroup Splines_Module+ * \brief Compile-time attributes of the Spline class for fixed degree.+ *+ * The traits class inherits all attributes from the SplineTraits of Dynamic degree.+ **/+ template < typename _Scalar, int _Dim, int _Degree, int _DerivativeOrder >+ struct SplineTraits< Spline<_Scalar, _Dim, _Degree>, _DerivativeOrder > : public SplineTraits< Spline<_Scalar, _Dim, _Degree> >+ {+ enum { OrderAtCompileTime = _Degree==Dynamic ? Dynamic : _Degree+1 /*!< The spline curve's order at compile-time. */ };+ enum { NumOfDerivativesAtCompileTime = _DerivativeOrder==Dynamic ? Dynamic : _DerivativeOrder+1 /*!< The number of derivatives defined for the current spline. */ };++ /** \brief The data type used to store the values of the basis function derivatives. */+ typedef Array<_Scalar,Dynamic,Dynamic,RowMajor,NumOfDerivativesAtCompileTime,OrderAtCompileTime> BasisDerivativeType;+ + /** \brief The data type used to store the spline's derivative values. */ + typedef Array<_Scalar,_Dim,Dynamic,ColMajor,_Dim,NumOfDerivativesAtCompileTime> DerivativeType;+ };++ /** \brief 2D float B-spline with dynamic degree. */+ typedef Spline<float,2> Spline2f;+ + /** \brief 3D float B-spline with dynamic degree. */+ typedef Spline<float,3> Spline3f;++ /** \brief 2D double B-spline with dynamic degree. */+ typedef Spline<double,2> Spline2d;+ + /** \brief 3D double B-spline with dynamic degree. */+ typedef Spline<double,3> Spline3d;+}++#endif // EIGEN_SPLINES_FWD_H
+ eigen3/unsupported/README.txt view
@@ -0,0 +1,50 @@+This directory contains contributions from various users.+They are provided "as is", without any support. Nevertheless,+most of them are subject to be included in Eigen in the future.++In order to use an unsupported module you have to do either:++ - add the path_to_eigen/unsupported directory to your include path and do:+ #include <Eigen/ModuleHeader>++ - or directly do:+ #include <unsupported/Eigen/ModuleHeader>+++If you are interested in contributing to one of them, or have other stuff+you would like to share, feel free to contact us:+http://eigen.tuxfamily.org/index.php?title=Main_Page#Mailing_list++Any kind of contributions are much appreciated, even very preliminary ones.+However, it:+ - must rely on Eigen,+ - must be highly related to math,+ - should have some general purpose in the sense that it could+ potentially become an offical Eigen module (or be merged into another one).++In doubt feel free to contact us. For instance, if your addons is very too specific+but it shows an interesting way of using Eigen, then it could be a nice demo.+++This directory is organized as follow:++unsupported/Eigen/ModuleHeader1+unsupported/Eigen/ModuleHeader2+unsupported/Eigen/...+unsupported/Eigen/src/Module1/SourceFile1.h+unsupported/Eigen/src/Module1/SourceFile2.h+unsupported/Eigen/src/Module1/...+unsupported/Eigen/src/Module2/SourceFile1.h+unsupported/Eigen/src/Module2/SourceFile2.h+unsupported/Eigen/src/Module2/...+unsupported/Eigen/src/...+unsupported/doc/snippets/.cpp <- code snippets for the doc+unsupported/doc/examples/.cpp <- examples for the doc+unsupported/doc/TutorialModule1.dox+unsupported/doc/TutorialModule2.dox+unsupported/doc/...+unsupported/test/.cpp <- unit test files++The documentation is generated at the same time than the main Eigen documentation.+The .html files are generated in: build_dir/doc/html/unsupported/+
+ eigen3/unsupported/bench/bench_svd.cpp view
@@ -0,0 +1,123 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2013 Gauthier Brun <brun.gauthier@gmail.com>+// Copyright (C) 2013 Nicolas Carre <nicolas.carre@ensimag.fr>+// Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>+// Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/++// Bench to compare the efficiency of SVD algorithms++#include <iostream>+#include <bench/BenchTimer.h>+#include <unsupported/Eigen/SVD>+++using namespace Eigen;+using namespace std;++// number of computations of each algorithm before the print of the time+#ifndef REPEAT+#define REPEAT 10+#endif++// number of tests of the same type+#ifndef NUMBER_SAMPLE+#define NUMBER_SAMPLE 2+#endif++template<typename MatrixType>+void bench_svd(const MatrixType& a = MatrixType())+{+ MatrixType m = MatrixType::Random(a.rows(), a.cols());+ BenchTimer timerJacobi;+ BenchTimer timerBDC;+ timerJacobi.reset();+ timerBDC.reset();++ cout << " Only compute Singular Values" <<endl;+ for (int k=1; k<=NUMBER_SAMPLE; ++k)+ {+ timerBDC.start();+ for (int i=0; i<REPEAT; ++i) + {+ BDCSVD<MatrixType> bdc_matrix(m);+ }+ timerBDC.stop();+ + timerJacobi.start();+ for (int i=0; i<REPEAT; ++i) + {+ JacobiSVD<MatrixType> jacobi_matrix(m);+ }+ timerJacobi.stop();+++ cout << "Sample " << k << " : " << REPEAT << " computations : Jacobi : " << fixed << timerJacobi.value() << "s ";+ cout << " || " << " BDC : " << timerBDC.value() << "s " <<endl <<endl;+ + if (timerBDC.value() >= timerJacobi.value()) + cout << "KO : BDC is " << timerJacobi.value() / timerBDC.value() << " times faster than Jacobi" <<endl;+ else + cout << "OK : BDC is " << timerJacobi.value() / timerBDC.value() << " times faster than Jacobi" <<endl;+ + }+ cout << " =================" <<endl;+ std::cout<< std::endl;+ timerJacobi.reset();+ timerBDC.reset();+ cout << " Computes rotaion matrix" <<endl;+ for (int k=1; k<=NUMBER_SAMPLE; ++k)+ {+ timerBDC.start();+ for (int i=0; i<REPEAT; ++i) + {+ BDCSVD<MatrixType> bdc_matrix(m, ComputeFullU|ComputeFullV);+ }+ timerBDC.stop();+ + timerJacobi.start();+ for (int i=0; i<REPEAT; ++i) + {+ JacobiSVD<MatrixType> jacobi_matrix(m, ComputeFullU|ComputeFullV);+ }+ timerJacobi.stop();+++ cout << "Sample " << k << " : " << REPEAT << " computations : Jacobi : " << fixed << timerJacobi.value() << "s ";+ cout << " || " << " BDC : " << timerBDC.value() << "s " <<endl <<endl;+ + if (timerBDC.value() >= timerJacobi.value()) + cout << "KO : BDC is " << timerJacobi.value() / timerBDC.value() << " times faster than Jacobi" <<endl;+ else + cout << "OK : BDC is " << timerJacobi.value() / timerBDC.value() << " times faster than Jacobi" <<endl;+ + }+ std::cout<< std::endl;+}++++int main(int argc, char* argv[])+{+ std::cout<< std::endl;++ std::cout<<"On a (Dynamic, Dynamic) (6, 6) Matrix" <<std::endl;+ bench_svd<Matrix<double,Dynamic,Dynamic> >(Matrix<double,Dynamic,Dynamic>(6, 6));+ + std::cout<<"On a (Dynamic, Dynamic) (32, 32) Matrix" <<std::endl;+ bench_svd<Matrix<double,Dynamic,Dynamic> >(Matrix<double,Dynamic,Dynamic>(32, 32));++ //std::cout<<"On a (Dynamic, Dynamic) (128, 128) Matrix" <<std::endl;+ //bench_svd<Matrix<double,Dynamic,Dynamic> >(Matrix<double,Dynamic,Dynamic>(128, 128));++ std::cout<<"On a (Dynamic, Dynamic) (160, 160) Matrix" <<std::endl;+ bench_svd<Matrix<double,Dynamic,Dynamic> >(Matrix<double,Dynamic,Dynamic>(160, 160));+ + std::cout<< "--------------------------------------------------------------------"<< std::endl;+ +}
+ eigen3/unsupported/doc/CMakeLists.txt view
@@ -0,0 +1,4 @@+set_directory_properties(PROPERTIES EXCLUDE_FROM_ALL TRUE)++add_subdirectory(examples)+add_subdirectory(snippets)
+ eigen3/unsupported/doc/Overview.dox view
@@ -0,0 +1,25 @@+namespace Eigen {++/** \mainpage Eigen's unsupported modules++This is the API documentation for Eigen's unsupported modules.++These modules are contributions from various users. They are provided "as is", without any support.++Click on the \e Modules tab at the top of this page to get a list of all unsupported modules.++Don't miss the <a href="..//index.html">official Eigen documentation</a>.++*/++/*++\defgroup Unsupported_modules Unsupported modules++The unsupported modules are contributions from various users. They are+provided "as is", without any support. Nevertheless, some of them are+subject to be included in Eigen in the future.++*/++}
+ eigen3/unsupported/doc/eigendoxy_layout.xml.in view
@@ -0,0 +1,177 @@+<?xml version="1.0"?>+<doxygenlayout version="1.0">+ <!-- Navigation index tabs for HTML output -->+ <navindex>+ <tab type="user" url="index.html" title="Overview" />+ <tab type="modules" visible="yes" title="Unsupported Modules" intro=""/>+<!-- <tab type="mainpage" visible="yes" title=""/> -->+ <tab type="classlist" visible="yes" title="" intro=""/>+<!-- <tab type="classmembers" visible="yes" title="" intro=""/> -->+ </navindex>++ <!-- Layout definition for a class page -->+ <class>+ <briefdescription visible="no"/>+ <includes visible="$SHOW_INCLUDE_FILES"/>+ <detaileddescription title=""/>+ <inheritancegraph visible="$CLASS_GRAPH"/>+ <collaborationgraph visible="$COLLABORATION_GRAPH"/>+ <allmemberslink visible="yes"/>+ <memberdecl>+ <nestedclasses visible="yes" title=""/>+ <publictypes title=""/>+ <publicslots title=""/>+ <signals title=""/>+ <publicmethods title=""/>+ <publicstaticmethods title=""/>+ <publicattributes title=""/>+ <publicstaticattributes title=""/>+ <protectedtypes title=""/>+ <protectedslots title=""/>+ <protectedmethods title=""/>+ <protectedstaticmethods title=""/>+ <protectedattributes title=""/>+ <protectedstaticattributes title=""/>+ <packagetypes title=""/>+ <packagemethods title=""/>+ <packagestaticmethods title=""/>+ <packageattributes title=""/>+ <packagestaticattributes title=""/>+ <properties title=""/>+ <events title=""/>+ <privatetypes title=""/>+ <privateslots title=""/>+ <privatemethods title=""/>+ <privatestaticmethods title=""/>+ <privateattributes title=""/>+ <privatestaticattributes title=""/>+ <friends title=""/>+ <related title="" subtitle=""/>+ <membergroups visible="yes"/>+ </memberdecl>+ + <memberdef>+ <inlineclasses title=""/>+ <typedefs title=""/>+ <enums title=""/>+ <constructors title=""/>+ <functions title=""/>+ <related title=""/>+ <variables title=""/>+ <properties title=""/>+ <events title=""/>+ </memberdef>+ <usedfiles visible="$SHOW_USED_FILES"/>+ <authorsection visible="yes"/>+ </class>++ <!-- Layout definition for a namespace page -->+ <namespace>+ <briefdescription visible="yes"/>+ <memberdecl>+ <nestednamespaces visible="yes" title=""/>+ <classes visible="yes" title=""/>+ <typedefs title=""/>+ <enums title=""/>+ <functions title=""/>+ <variables title=""/>+ <membergroups visible="yes"/>+ </memberdecl>+ <detaileddescription title=""/>+ <memberdef>+ <inlineclasses title=""/>+ <typedefs title=""/>+ <enums title=""/>+ <functions title=""/>+ <variables title=""/>+ </memberdef>+ <authorsection visible="yes"/>+ </namespace>++ <!-- Layout definition for a file page -->+ <file>+ <briefdescription visible="yes"/>+ <includes visible="$SHOW_INCLUDE_FILES"/>+ <includegraph visible="$INCLUDE_GRAPH"/>+ <includedbygraph visible="$INCLUDED_BY_GRAPH"/>+ <sourcelink visible="yes"/>+ <memberdecl>+ <classes visible="yes" title=""/>+ <namespaces visible="yes" title=""/>+ <defines title=""/>+ <typedefs title=""/>+ <enums title=""/>+ <functions title=""/>+ <variables title=""/>+ <membergroups visible="yes"/>+ </memberdecl>+ <detaileddescription title=""/>+ <memberdef>+ <inlineclasses title=""/>+ <defines title=""/>+ <typedefs title=""/>+ <enums title=""/>+ <functions title=""/>+ <variables title=""/>+ </memberdef>+ <authorsection/>+ </file>++ <!-- Layout definition for a group page -->+ <group>+ <briefdescription visible="no"/>+ <detaileddescription title=""/>+ <groupgraph visible="$GROUP_GRAPHS"/>+ <memberdecl>+ <nestedgroups visible="yes" title=""/>+ <dirs visible="yes" title=""/>+ <files visible="yes" title=""/>+ <namespaces visible="yes" title=""/>+ <classes visible="yes" title=""/>+ <defines title=""/>+ <typedefs title=""/>+ <enums title=""/>+ <enumvalues title=""/>+ <functions title=""/>+ <variables title=""/>+ <signals title=""/>+ <publicslots title=""/>+ <protectedslots title=""/>+ <privateslots title=""/>+ <events title=""/>+ <properties title=""/>+ <friends title=""/>+ <membergroups visible="yes"/>+ </memberdecl>+ + <memberdef>+ <pagedocs/>+ <inlineclasses title=""/>+ <defines title=""/>+ <typedefs title=""/>+ <enums title=""/>+ <enumvalues title=""/>+ <functions title=""/>+ <variables title=""/>+ <signals title=""/>+ <publicslots title=""/>+ <protectedslots title=""/>+ <privateslots title=""/>+ <events title=""/>+ <properties title=""/>+ <friends title=""/>+ </memberdef>+ <authorsection visible="yes"/>+ </group>++ <!-- Layout definition for a directory page -->+ <directory>+ <briefdescription visible="yes"/>+ <directorygraph visible="yes"/>+ <memberdecl>+ <dirs visible="yes"/>+ <files visible="yes"/>+ </memberdecl>+ <detaileddescription title=""/>+ </directory>+</doxygenlayout>
+ eigen3/unsupported/doc/examples/BVH_Example.cpp view
@@ -0,0 +1,52 @@+#include <Eigen/StdVector>+#include <unsupported/Eigen/BVH>+#include <iostream>++using namespace Eigen;+typedef AlignedBox<double, 2> Box2d;++namespace Eigen {+ namespace internal {+ Box2d bounding_box(const Vector2d &v) { return Box2d(v, v); } //compute the bounding box of a single point+ }+}++struct PointPointMinimizer //how to compute squared distances between points and rectangles+{+ PointPointMinimizer() : calls(0) {}+ typedef double Scalar;++ double minimumOnVolumeVolume(const Box2d &r1, const Box2d &r2) { ++calls; return r1.squaredExteriorDistance(r2); }+ double minimumOnVolumeObject(const Box2d &r, const Vector2d &v) { ++calls; return r.squaredExteriorDistance(v); }+ double minimumOnObjectVolume(const Vector2d &v, const Box2d &r) { ++calls; return r.squaredExteriorDistance(v); }+ double minimumOnObjectObject(const Vector2d &v1, const Vector2d &v2) { ++calls; return (v1 - v2).squaredNorm(); }++ int calls;+};++int main()+{+ typedef std::vector<Vector2d, aligned_allocator<Vector2d> > StdVectorOfVector2d;+ StdVectorOfVector2d redPoints, bluePoints;+ for(int i = 0; i < 100; ++i) { //initialize random set of red points and blue points+ redPoints.push_back(Vector2d::Random());+ bluePoints.push_back(Vector2d::Random());+ }++ PointPointMinimizer minimizer;+ double minDistSq = std::numeric_limits<double>::max();++ //brute force to find closest red-blue pair+ for(int i = 0; i < (int)redPoints.size(); ++i)+ for(int j = 0; j < (int)bluePoints.size(); ++j)+ minDistSq = std::min(minDistSq, minimizer.minimumOnObjectObject(redPoints[i], bluePoints[j]));+ std::cout << "Brute force distance = " << sqrt(minDistSq) << ", calls = " << minimizer.calls << std::endl;++ //using BVH to find closest red-blue pair+ minimizer.calls = 0;+ KdBVH<double, 2, Vector2d> redTree(redPoints.begin(), redPoints.end()), blueTree(bluePoints.begin(), bluePoints.end()); //construct the trees+ minDistSq = BVMinimize(redTree, blueTree, minimizer); //actual BVH minimization call+ std::cout << "BVH distance = " << sqrt(minDistSq) << ", calls = " << minimizer.calls << std::endl;++ return 0;+}
+ eigen3/unsupported/doc/examples/CMakeLists.txt view
@@ -0,0 +1,20 @@+FILE(GLOB examples_SRCS "*.cpp")++ADD_CUSTOM_TARGET(unsupported_examples)++INCLUDE_DIRECTORIES(../../../unsupported ../../../unsupported/test)++FOREACH(example_src ${examples_SRCS})+ GET_FILENAME_COMPONENT(example ${example_src} NAME_WE)+ ADD_EXECUTABLE(example_${example} ${example_src})+ if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)+ target_link_libraries(example_${example} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})+ endif()+ ADD_CUSTOM_COMMAND(+ TARGET example_${example}+ POST_BUILD+ COMMAND example_${example}+ ARGS >${CMAKE_CURRENT_BINARY_DIR}/${example}.out+ )+ ADD_DEPENDENCIES(unsupported_examples example_${example})+ENDFOREACH(example_src)
+ eigen3/unsupported/doc/examples/FFT.cpp view
@@ -0,0 +1,118 @@+// To use the simple FFT implementation+// g++ -o demofft -I.. -Wall -O3 FFT.cpp ++// To use the FFTW implementation+// g++ -o demofft -I.. -DUSE_FFTW -Wall -O3 FFT.cpp -lfftw3 -lfftw3f -lfftw3l++#ifdef USE_FFTW+#include <fftw3.h>+#endif++#include <vector>+#include <complex>+#include <algorithm>+#include <iterator>+#include <iostream>+#include <Eigen/Core>+#include <unsupported/Eigen/FFT>++using namespace std;+using namespace Eigen;++template <typename T>+T mag2(T a)+{+ return a*a;+}+template <typename T>+T mag2(std::complex<T> a)+{+ return norm(a);+}++template <typename T>+T mag2(const std::vector<T> & vec)+{+ T out=0;+ for (size_t k=0;k<vec.size();++k)+ out += mag2(vec[k]);+ return out;+}++template <typename T>+T mag2(const std::vector<std::complex<T> > & vec)+{+ T out=0;+ for (size_t k=0;k<vec.size();++k)+ out += mag2(vec[k]);+ return out;+}++template <typename T>+vector<T> operator-(const vector<T> & a,const vector<T> & b )+{+ vector<T> c(a);+ for (size_t k=0;k<b.size();++k) + c[k] -= b[k];+ return c;+}++template <typename T>+void RandomFill(std::vector<T> & vec)+{+ for (size_t k=0;k<vec.size();++k)+ vec[k] = T( rand() )/T(RAND_MAX) - .5;+}++template <typename T>+void RandomFill(std::vector<std::complex<T> > & vec)+{+ for (size_t k=0;k<vec.size();++k)+ vec[k] = std::complex<T> ( T( rand() )/T(RAND_MAX) - .5, T( rand() )/T(RAND_MAX) - .5);+}++template <typename T_time,typename T_freq>+void fwd_inv(size_t nfft)+{+ typedef typename NumTraits<T_freq>::Real Scalar;+ vector<T_time> timebuf(nfft);+ RandomFill(timebuf);++ vector<T_freq> freqbuf;+ static FFT<Scalar> fft;+ fft.fwd(freqbuf,timebuf);++ vector<T_time> timebuf2;+ fft.inv(timebuf2,freqbuf);++ long double rmse = mag2(timebuf - timebuf2) / mag2(timebuf);+ cout << "roundtrip rmse: " << rmse << endl;+}++template <typename T_scalar>+void two_demos(int nfft)+{+ cout << " scalar ";+ fwd_inv<T_scalar,std::complex<T_scalar> >(nfft);+ cout << " complex ";+ fwd_inv<std::complex<T_scalar>,std::complex<T_scalar> >(nfft);+}++void demo_all_types(int nfft)+{+ cout << "nfft=" << nfft << endl;+ cout << " float" << endl;+ two_demos<float>(nfft);+ cout << " double" << endl;+ two_demos<double>(nfft);+ cout << " long double" << endl;+ two_demos<long double>(nfft);+}++int main()+{+ demo_all_types( 2*3*4*5*7 );+ demo_all_types( 2*9*16*25 );+ demo_all_types( 1024 );+ return 0;+}
+ eigen3/unsupported/doc/examples/MatrixExponential.cpp view
@@ -0,0 +1,16 @@+#include <unsupported/Eigen/MatrixFunctions>+#include <iostream>++using namespace Eigen;++int main()+{+ const double pi = std::acos(-1.0);++ MatrixXd A(3,3);+ A << 0, -pi/4, 0,+ pi/4, 0, 0,+ 0, 0, 0;+ std::cout << "The matrix A is:\n" << A << "\n\n";+ std::cout << "The matrix exponential of A is:\n" << A.exp() << "\n\n";+}
+ eigen3/unsupported/doc/examples/MatrixFunction.cpp view
@@ -0,0 +1,23 @@+#include <unsupported/Eigen/MatrixFunctions>+#include <iostream>++using namespace Eigen;++std::complex<double> expfn(std::complex<double> x, int)+{+ return std::exp(x);+}++int main()+{+ const double pi = std::acos(-1.0);++ MatrixXd A(3,3);+ A << 0, -pi/4, 0,+ pi/4, 0, 0,+ 0, 0, 0;++ std::cout << "The matrix A is:\n" << A << "\n\n";+ std::cout << "The matrix exponential of A is:\n" + << A.matrixFunction(expfn) << "\n\n";+}
+ eigen3/unsupported/doc/examples/MatrixLogarithm.cpp view
@@ -0,0 +1,15 @@+#include <unsupported/Eigen/MatrixFunctions>+#include <iostream>++using namespace Eigen;++int main()+{+ using std::sqrt;+ MatrixXd A(3,3);+ A << 0.5*sqrt(2), -0.5*sqrt(2), 0,+ 0.5*sqrt(2), 0.5*sqrt(2), 0,+ 0, 0, 1;+ std::cout << "The matrix A is:\n" << A << "\n\n";+ std::cout << "The matrix logarithm of A is:\n" << A.log() << "\n";+}
+ eigen3/unsupported/doc/examples/MatrixPower.cpp view
@@ -0,0 +1,16 @@+#include <unsupported/Eigen/MatrixFunctions>+#include <iostream>++using namespace Eigen;++int main()+{+ const double pi = std::acos(-1.0);+ Matrix3d A;+ A << cos(1), -sin(1), 0,+ sin(1), cos(1), 0,+ 0 , 0 , 1;+ std::cout << "The matrix A is:\n" << A << "\n\n"+ "The matrix power A^(pi/4) is:\n" << A.pow(pi/4) << std::endl;+ return 0;+}
+ eigen3/unsupported/doc/examples/MatrixPower_optimal.cpp view
@@ -0,0 +1,17 @@+#include <unsupported/Eigen/MatrixFunctions>+#include <iostream>++using namespace Eigen;++int main()+{+ Matrix4cd A = Matrix4cd::Random();+ MatrixPower<Matrix4cd> Apow(A);++ std::cout << "The matrix A is:\n" << A << "\n\n"+ "A^3.1 is:\n" << Apow(3.1) << "\n\n"+ "A^3.3 is:\n" << Apow(3.3) << "\n\n"+ "A^3.7 is:\n" << Apow(3.7) << "\n\n"+ "A^3.9 is:\n" << Apow(3.9) << std::endl;+ return 0;+}
+ eigen3/unsupported/doc/examples/MatrixSine.cpp view
@@ -0,0 +1,20 @@+#include <unsupported/Eigen/MatrixFunctions>+#include <iostream>++using namespace Eigen;++int main()+{+ MatrixXd A = MatrixXd::Random(3,3);+ std::cout << "A = \n" << A << "\n\n";++ MatrixXd sinA = A.sin();+ std::cout << "sin(A) = \n" << sinA << "\n\n";++ MatrixXd cosA = A.cos();+ std::cout << "cos(A) = \n" << cosA << "\n\n";+ + // The matrix functions satisfy sin^2(A) + cos^2(A) = I, + // like the scalar functions.+ std::cout << "sin^2(A) + cos^2(A) = \n" << sinA*sinA + cosA*cosA << "\n\n";+}
+ eigen3/unsupported/doc/examples/MatrixSinh.cpp view
@@ -0,0 +1,20 @@+#include <unsupported/Eigen/MatrixFunctions>+#include <iostream>++using namespace Eigen;++int main()+{+ MatrixXf A = MatrixXf::Random(3,3);+ std::cout << "A = \n" << A << "\n\n";++ MatrixXf sinhA = A.sinh();+ std::cout << "sinh(A) = \n" << sinhA << "\n\n";++ MatrixXf coshA = A.cosh();+ std::cout << "cosh(A) = \n" << coshA << "\n\n";+ + // The matrix functions satisfy cosh^2(A) - sinh^2(A) = I, + // like the scalar functions.+ std::cout << "cosh^2(A) - sinh^2(A) = \n" << coshA*coshA - sinhA*sinhA << "\n\n";+}
+ eigen3/unsupported/doc/examples/MatrixSquareRoot.cpp view
@@ -0,0 +1,16 @@+#include <unsupported/Eigen/MatrixFunctions>+#include <iostream>++using namespace Eigen;++int main()+{+ const double pi = std::acos(-1.0);++ MatrixXd A(2,2);+ A << cos(pi/3), -sin(pi/3), + sin(pi/3), cos(pi/3);+ std::cout << "The matrix A is:\n" << A << "\n\n";+ std::cout << "The matrix square root of A is:\n" << A.sqrt() << "\n\n";+ std::cout << "The square of the last matrix is:\n" << A.sqrt() * A.sqrt() << "\n";+}
+ eigen3/unsupported/doc/examples/PolynomialSolver1.cpp view
@@ -0,0 +1,53 @@+#include <unsupported/Eigen/Polynomials>+#include <vector>+#include <iostream>++using namespace Eigen;+using namespace std;++int main()+{+ typedef Matrix<double,5,1> Vector5d;++ Vector5d roots = Vector5d::Random();+ cout << "Roots: " << roots.transpose() << endl;+ Eigen::Matrix<double,6,1> polynomial;+ roots_to_monicPolynomial( roots, polynomial );++ PolynomialSolver<double,5> psolve( polynomial );+ cout << "Complex roots: " << psolve.roots().transpose() << endl;++ std::vector<double> realRoots;+ psolve.realRoots( realRoots );+ Map<Vector5d> mapRR( &realRoots[0] );+ cout << "Real roots: " << mapRR.transpose() << endl;++ cout << endl;+ cout << "Illustration of the convergence problem with the QR algorithm: " << endl;+ cout << "---------------------------------------------------------------" << endl;+ Eigen::Matrix<float,7,1> hardCase_polynomial;+ hardCase_polynomial <<+ -0.957, 0.9219, 0.3516, 0.9453, -0.4023, -0.5508, -0.03125;+ cout << "Hard case polynomial defined by floats: " << hardCase_polynomial.transpose() << endl;+ PolynomialSolver<float,6> psolvef( hardCase_polynomial );+ cout << "Complex roots: " << psolvef.roots().transpose() << endl;+ Eigen::Matrix<float,6,1> evals;+ for( int i=0; i<6; ++i ){ evals[i] = std::abs( poly_eval( hardCase_polynomial, psolvef.roots()[i] ) ); }+ cout << "Norms of the evaluations of the polynomial at the roots: " << evals.transpose() << endl << endl;++ cout << "Using double's almost always solves the problem for small degrees: " << endl;+ cout << "-------------------------------------------------------------------" << endl;+ PolynomialSolver<double,6> psolve6d( hardCase_polynomial.cast<double>() );+ cout << "Complex roots: " << psolve6d.roots().transpose() << endl;+ for( int i=0; i<6; ++i )+ {+ std::complex<float> castedRoot( psolve6d.roots()[i].real(), psolve6d.roots()[i].imag() );+ evals[i] = std::abs( poly_eval( hardCase_polynomial, castedRoot ) );+ }+ cout << "Norms of the evaluations of the polynomial at the roots: " << evals.transpose() << endl << endl;++ cout.precision(10);+ cout << "The last root in float then in double: " << psolvef.roots()[5] << "\t" << psolve6d.roots()[5] << endl;+ std::complex<float> castedRoot( psolve6d.roots()[5].real(), psolve6d.roots()[5].imag() );+ cout << "Norm of the difference: " << std::abs( psolvef.roots()[5] - castedRoot ) << endl;+}
+ eigen3/unsupported/doc/examples/PolynomialUtils1.cpp view
@@ -0,0 +1,20 @@+#include <unsupported/Eigen/Polynomials>+#include <iostream>++using namespace Eigen;+using namespace std;++int main()+{+ Vector4d roots = Vector4d::Random();+ cout << "Roots: " << roots.transpose() << endl;+ Eigen::Matrix<double,5,1> polynomial;+ roots_to_monicPolynomial( roots, polynomial );+ cout << "Polynomial: ";+ for( int i=0; i<4; ++i ){ cout << polynomial[i] << ".x^" << i << "+ "; }+ cout << polynomial[4] << ".x^4" << endl;+ Vector4d evaluation;+ for( int i=0; i<4; ++i ){+ evaluation[i] = poly_eval( polynomial, roots[i] ); }+ cout << "Evaluation of the polynomial at the roots: " << evaluation.transpose();+}
+ eigen3/unsupported/doc/snippets/CMakeLists.txt view
@@ -0,0 +1,26 @@+FILE(GLOB snippets_SRCS "*.cpp")++ADD_CUSTOM_TARGET(unsupported_snippets)++FOREACH(snippet_src ${snippets_SRCS})+ GET_FILENAME_COMPONENT(snippet ${snippet_src} NAME_WE)+ SET(compile_snippet_target compile_${snippet})+ SET(compile_snippet_src ${compile_snippet_target}.cpp)+ FILE(READ ${snippet_src} snippet_source_code)+ CONFIGURE_FILE(${PROJECT_SOURCE_DIR}/doc/snippets/compile_snippet.cpp.in+ ${CMAKE_CURRENT_BINARY_DIR}/${compile_snippet_src})+ ADD_EXECUTABLE(${compile_snippet_target}+ ${CMAKE_CURRENT_BINARY_DIR}/${compile_snippet_src})+ if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)+ target_link_libraries(${compile_snippet_target} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})+ endif()+ ADD_CUSTOM_COMMAND(+ TARGET ${compile_snippet_target}+ POST_BUILD+ COMMAND ${compile_snippet_target}+ ARGS >${CMAKE_CURRENT_BINARY_DIR}/${snippet}.out+ )+ ADD_DEPENDENCIES(unsupported_snippets ${compile_snippet_target})+ set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${compile_snippet_src}+ PROPERTIES OBJECT_DEPENDS ${snippet_src})+ENDFOREACH(snippet_src)
+ eigen3/unsupported/test/BVH.cpp view
@@ -0,0 +1,222 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Ilya Baran <ibaran@mit.edu>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/StdVector>+#include <Eigen/Geometry>+#include <unsupported/Eigen/BVH>++namespace Eigen {++template<typename Scalar, int Dim> AlignedBox<Scalar, Dim> bounding_box(const Matrix<Scalar, Dim, 1> &v) { return AlignedBox<Scalar, Dim>(v); }++}+++template<int Dim>+struct Ball+{+EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(double, Dim)++ typedef Matrix<double, Dim, 1> VectorType;++ Ball() {}+ Ball(const VectorType &c, double r) : center(c), radius(r) {}++ VectorType center;+ double radius;+};+template<int Dim> AlignedBox<double, Dim> bounding_box(const Ball<Dim> &b)+{ return AlignedBox<double, Dim>(b.center.array() - b.radius, b.center.array() + b.radius); }++inline double SQR(double x) { return x * x; }++template<int Dim>+struct BallPointStuff //this class provides functions to be both an intersector and a minimizer, both for a ball and a point and for two trees+{+ typedef double Scalar;+ typedef Matrix<double, Dim, 1> VectorType;+ typedef Ball<Dim> BallType;+ typedef AlignedBox<double, Dim> BoxType;++ BallPointStuff() : calls(0), count(0) {}+ BallPointStuff(const VectorType &inP) : p(inP), calls(0), count(0) {}+++ bool intersectVolume(const BoxType &r) { ++calls; return r.contains(p); }+ bool intersectObject(const BallType &b) {+ ++calls;+ if((b.center - p).squaredNorm() < SQR(b.radius))+ ++count;+ return false; //continue+ }++ bool intersectVolumeVolume(const BoxType &r1, const BoxType &r2) { ++calls; return !(r1.intersection(r2)).isNull(); }+ bool intersectVolumeObject(const BoxType &r, const BallType &b) { ++calls; return r.squaredExteriorDistance(b.center) < SQR(b.radius); }+ bool intersectObjectVolume(const BallType &b, const BoxType &r) { ++calls; return r.squaredExteriorDistance(b.center) < SQR(b.radius); }+ bool intersectObjectObject(const BallType &b1, const BallType &b2){+ ++calls;+ if((b1.center - b2.center).norm() < b1.radius + b2.radius)+ ++count;+ return false;+ }+ bool intersectVolumeObject(const BoxType &r, const VectorType &v) { ++calls; return r.contains(v); }+ bool intersectObjectObject(const BallType &b, const VectorType &v){+ ++calls;+ if((b.center - v).squaredNorm() < SQR(b.radius))+ ++count;+ return false;+ }++ double minimumOnVolume(const BoxType &r) { ++calls; return r.squaredExteriorDistance(p); }+ double minimumOnObject(const BallType &b) { ++calls; return (std::max)(0., (b.center - p).squaredNorm() - SQR(b.radius)); }+ double minimumOnVolumeVolume(const BoxType &r1, const BoxType &r2) { ++calls; return r1.squaredExteriorDistance(r2); }+ double minimumOnVolumeObject(const BoxType &r, const BallType &b) { ++calls; return SQR((std::max)(0., r.exteriorDistance(b.center) - b.radius)); }+ double minimumOnObjectVolume(const BallType &b, const BoxType &r) { ++calls; return SQR((std::max)(0., r.exteriorDistance(b.center) - b.radius)); }+ double minimumOnObjectObject(const BallType &b1, const BallType &b2){ ++calls; return SQR((std::max)(0., (b1.center - b2.center).norm() - b1.radius - b2.radius)); }+ double minimumOnVolumeObject(const BoxType &r, const VectorType &v) { ++calls; return r.squaredExteriorDistance(v); }+ double minimumOnObjectObject(const BallType &b, const VectorType &v){ ++calls; return SQR((std::max)(0., (b.center - v).norm() - b.radius)); }++ VectorType p;+ int calls;+ int count;+};+++template<int Dim>+struct TreeTest+{+ typedef Matrix<double, Dim, 1> VectorType;+ typedef std::vector<VectorType, aligned_allocator<VectorType> > VectorTypeList;+ typedef Ball<Dim> BallType;+ typedef std::vector<BallType, aligned_allocator<BallType> > BallTypeList;+ typedef AlignedBox<double, Dim> BoxType;++ void testIntersect1()+ {+ BallTypeList b;+ for(int i = 0; i < 500; ++i) {+ b.push_back(BallType(VectorType::Random(), 0.5 * internal::random(0., 1.)));+ }+ KdBVH<double, Dim, BallType> tree(b.begin(), b.end());++ VectorType pt = VectorType::Random();+ BallPointStuff<Dim> i1(pt), i2(pt);++ for(int i = 0; i < (int)b.size(); ++i)+ i1.intersectObject(b[i]);++ BVIntersect(tree, i2);++ VERIFY(i1.count == i2.count);+ }++ void testMinimize1()+ {+ BallTypeList b;+ for(int i = 0; i < 500; ++i) {+ b.push_back(BallType(VectorType::Random(), 0.01 * internal::random(0., 1.)));+ }+ KdBVH<double, Dim, BallType> tree(b.begin(), b.end());++ VectorType pt = VectorType::Random();+ BallPointStuff<Dim> i1(pt), i2(pt);++ double m1 = (std::numeric_limits<double>::max)(), m2 = m1;++ for(int i = 0; i < (int)b.size(); ++i)+ m1 = (std::min)(m1, i1.minimumOnObject(b[i]));++ m2 = BVMinimize(tree, i2);++ VERIFY_IS_APPROX(m1, m2);+ }++ void testIntersect2()+ {+ BallTypeList b;+ VectorTypeList v;++ for(int i = 0; i < 50; ++i) {+ b.push_back(BallType(VectorType::Random(), 0.5 * internal::random(0., 1.)));+ for(int j = 0; j < 3; ++j)+ v.push_back(VectorType::Random());+ }++ KdBVH<double, Dim, BallType> tree(b.begin(), b.end());+ KdBVH<double, Dim, VectorType> vTree(v.begin(), v.end());++ BallPointStuff<Dim> i1, i2;++ for(int i = 0; i < (int)b.size(); ++i)+ for(int j = 0; j < (int)v.size(); ++j)+ i1.intersectObjectObject(b[i], v[j]);++ BVIntersect(tree, vTree, i2);++ VERIFY(i1.count == i2.count);+ }++ void testMinimize2()+ {+ BallTypeList b;+ VectorTypeList v;++ for(int i = 0; i < 50; ++i) {+ b.push_back(BallType(VectorType::Random(), 1e-7 + 1e-6 * internal::random(0., 1.)));+ for(int j = 0; j < 3; ++j)+ v.push_back(VectorType::Random());+ }++ KdBVH<double, Dim, BallType> tree(b.begin(), b.end());+ KdBVH<double, Dim, VectorType> vTree(v.begin(), v.end());++ BallPointStuff<Dim> i1, i2;++ double m1 = (std::numeric_limits<double>::max)(), m2 = m1;++ for(int i = 0; i < (int)b.size(); ++i)+ for(int j = 0; j < (int)v.size(); ++j)+ m1 = (std::min)(m1, i1.minimumOnObjectObject(b[i], v[j]));++ m2 = BVMinimize(tree, vTree, i2);++ VERIFY_IS_APPROX(m1, m2);+ }+};+++void test_BVH()+{+ for(int i = 0; i < g_repeat; i++) {+#ifdef EIGEN_TEST_PART_1+ TreeTest<2> test2;+ CALL_SUBTEST(test2.testIntersect1());+ CALL_SUBTEST(test2.testMinimize1());+ CALL_SUBTEST(test2.testIntersect2());+ CALL_SUBTEST(test2.testMinimize2());+#endif++#ifdef EIGEN_TEST_PART_2+ TreeTest<3> test3;+ CALL_SUBTEST(test3.testIntersect1());+ CALL_SUBTEST(test3.testMinimize1());+ CALL_SUBTEST(test3.testIntersect2());+ CALL_SUBTEST(test3.testMinimize2());+#endif++#ifdef EIGEN_TEST_PART_3+ TreeTest<4> test4;+ CALL_SUBTEST(test4.testIntersect1());+ CALL_SUBTEST(test4.testMinimize1());+ CALL_SUBTEST(test4.testIntersect2());+ CALL_SUBTEST(test4.testMinimize2());+#endif+ }+}
+ eigen3/unsupported/test/CMakeLists.txt view
@@ -0,0 +1,90 @@++set_property(GLOBAL PROPERTY EIGEN_CURRENT_SUBPROJECT "Unsupported")+add_custom_target(BuildUnsupported)++include_directories(../../test ../../unsupported ../../Eigen + ${CMAKE_CURRENT_BINARY_DIR}/../../test)++find_package(GoogleHash)+if(GOOGLEHASH_FOUND)+ add_definitions("-DEIGEN_GOOGLEHASH_SUPPORT")+ include_directories(${GOOGLEHASH_INCLUDES})+ ei_add_property(EIGEN_TESTED_BACKENDS "GoogleHash, ")+else(GOOGLEHASH_FOUND)+ ei_add_property(EIGEN_MISSING_BACKENDS "GoogleHash, ")+endif(GOOGLEHASH_FOUND)++find_package(Adolc)+if(ADOLC_FOUND)+ include_directories(${ADOLC_INCLUDES})+ ei_add_property(EIGEN_TESTED_BACKENDS "Adolc, ")+ ei_add_test(forward_adolc "" ${ADOLC_LIBRARIES})+else(ADOLC_FOUND)+ ei_add_property(EIGEN_MISSING_BACKENDS "Adolc, ")+endif(ADOLC_FOUND)++# this test seems to never have been successful on x87, so is considered to contain a FP-related bug.+# see thread: "non-linear optimization test summary"+ei_add_test(NonLinearOptimization)++ei_add_test(NumericalDiff)+ei_add_test(autodiff)+ei_add_test(BVH)+ei_add_test(matrix_exponential)+ei_add_test(matrix_function)+ei_add_test(matrix_power)+ei_add_test(matrix_square_root)+ei_add_test(alignedvector3)+ei_add_test(FFT)++find_package(MPFR 2.3.0)+find_package(GMP)+if(MPFR_FOUND)+ include_directories(${MPFR_INCLUDES} ./mpreal)+ ei_add_property(EIGEN_TESTED_BACKENDS "MPFR C++, ")+ set(EIGEN_MPFR_TEST_LIBRARIES ${MPFR_LIBRARIES} ${GMP_LIBRARIES})+ ei_add_test(mpreal_support "" "${EIGEN_MPFR_TEST_LIBRARIES}" )+else()+ ei_add_property(EIGEN_MISSING_BACKENDS "MPFR C++, ")+endif()++ei_add_test(sparse_extra "" "")++find_package(FFTW)+if(FFTW_FOUND)+ ei_add_property(EIGEN_TESTED_BACKENDS "fftw, ")+ include_directories( ${FFTW_INCLUDES} )+ if(FFTWL_LIB)+ ei_add_test(FFTW "-DEIGEN_FFTW_DEFAULT -DEIGEN_HAS_FFTWL" "${FFTW_LIBRARIES}" )+ else()+ ei_add_test(FFTW "-DEIGEN_FFTW_DEFAULT" "${FFTW_LIBRARIES}" )+ endif()+else()+ ei_add_property(EIGEN_MISSING_BACKENDS "fftw, ")+endif()++option(EIGEN_TEST_NO_OPENGL "Disable OpenGL support in unit tests" OFF)+if(NOT EIGEN_TEST_NO_OPENGL)+ find_package(OpenGL)+ find_package(GLUT)+ find_package(GLEW)+ if(OPENGL_FOUND AND GLUT_FOUND AND GLEW_FOUND)+ include_directories(${OPENGL_INCLUDE_DIR} ${GLUT_INCLUDE_DIR} ${GLEW_INCLUDE_DIRS})+ ei_add_property(EIGEN_TESTED_BACKENDS "OpenGL, ")+ set(EIGEN_GL_LIB ${GLUT_LIBRARIES} ${GLEW_LIBRARIES} ${OPENGL_LIBRARIES})+ ei_add_test(openglsupport "" "${EIGEN_GL_LIB}" )+ else()+ ei_add_property(EIGEN_MISSING_BACKENDS "OpenGL, ")+ endif()+else()+ ei_add_property(EIGEN_MISSING_BACKENDS "OpenGL, ")+endif()++ei_add_test(polynomialsolver)+ei_add_test(polynomialutils)+ei_add_test(kronecker_product)+ei_add_test(splines)+ei_add_test(gmres)+ei_add_test(minres)+ei_add_test(levenberg_marquardt)+ei_add_test(bdcsvd)
+ eigen3/unsupported/test/FFT.cpp view
@@ -0,0 +1,2 @@+#define test_FFTW test_FFT+#include "FFTW.cpp"
+ eigen3/unsupported/test/FFTW.cpp view
@@ -0,0 +1,262 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Mark Borgerding mark a borgerding net+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <unsupported/Eigen/FFT>++template <typename T> +std::complex<T> RandomCpx() { return std::complex<T>( (T)(rand()/(T)RAND_MAX - .5), (T)(rand()/(T)RAND_MAX - .5) ); }++using namespace std;+using namespace Eigen;+++template < typename T>+complex<long double> promote(complex<T> x) { return complex<long double>(x.real(),x.imag()); }++complex<long double> promote(float x) { return complex<long double>( x); }+complex<long double> promote(double x) { return complex<long double>( x); }+complex<long double> promote(long double x) { return complex<long double>( x); }+ ++ template <typename VT1,typename VT2>+ long double fft_rmse( const VT1 & fftbuf,const VT2 & timebuf)+ {+ long double totalpower=0;+ long double difpower=0;+ long double pi = acos((long double)-1 );+ for (size_t k0=0;k0<(size_t)fftbuf.size();++k0) {+ complex<long double> acc = 0;+ long double phinc = -2.*k0* pi / timebuf.size();+ for (size_t k1=0;k1<(size_t)timebuf.size();++k1) {+ acc += promote( timebuf[k1] ) * exp( complex<long double>(0,k1*phinc) );+ }+ totalpower += numext::abs2(acc);+ complex<long double> x = promote(fftbuf[k0]); + complex<long double> dif = acc - x;+ difpower += numext::abs2(dif);+ //cerr << k0 << "\t" << acc << "\t" << x << "\t" << sqrt(numext::abs2(dif)) << endl;+ }+ cerr << "rmse:" << sqrt(difpower/totalpower) << endl;+ return sqrt(difpower/totalpower);+ }++ template <typename VT1,typename VT2>+ long double dif_rmse( const VT1 buf1,const VT2 buf2)+ {+ long double totalpower=0;+ long double difpower=0;+ size_t n = (min)( buf1.size(),buf2.size() );+ for (size_t k=0;k<n;++k) {+ totalpower += (numext::abs2( buf1[k] ) + numext::abs2(buf2[k]) )/2.;+ difpower += numext::abs2(buf1[k] - buf2[k]);+ }+ return sqrt(difpower/totalpower);+ }++enum { StdVectorContainer, EigenVectorContainer };++template<int Container, typename Scalar> struct VectorType;++template<typename Scalar> struct VectorType<StdVectorContainer,Scalar>+{+ typedef vector<Scalar> type;+};++template<typename Scalar> struct VectorType<EigenVectorContainer,Scalar>+{+ typedef Matrix<Scalar,Dynamic,1> type;+};++template <int Container, typename T>+void test_scalar_generic(int nfft)+{+ typedef typename FFT<T>::Complex Complex;+ typedef typename FFT<T>::Scalar Scalar;+ typedef typename VectorType<Container,Scalar>::type ScalarVector;+ typedef typename VectorType<Container,Complex>::type ComplexVector;++ FFT<T> fft;+ ScalarVector tbuf(nfft);+ ComplexVector freqBuf;+ for (int k=0;k<nfft;++k)+ tbuf[k]= (T)( rand()/(double)RAND_MAX - .5);++ // make sure it DOESN'T give the right full spectrum answer+ // if we've asked for half-spectrum+ fft.SetFlag(fft.HalfSpectrum );+ fft.fwd( freqBuf,tbuf);+ VERIFY((size_t)freqBuf.size() == (size_t)( (nfft>>1)+1) );+ VERIFY( fft_rmse(freqBuf,tbuf) < test_precision<T>() );// gross check++ fft.ClearFlag(fft.HalfSpectrum );+ fft.fwd( freqBuf,tbuf);+ VERIFY( (size_t)freqBuf.size() == (size_t)nfft);+ VERIFY( fft_rmse(freqBuf,tbuf) < test_precision<T>() );// gross check++ if (nfft&1)+ return; // odd FFTs get the wrong size inverse FFT++ ScalarVector tbuf2;+ fft.inv( tbuf2 , freqBuf);+ VERIFY( dif_rmse(tbuf,tbuf2) < test_precision<T>() );// gross check+++ // verify that the Unscaled flag takes effect+ ScalarVector tbuf3;+ fft.SetFlag(fft.Unscaled);++ fft.inv( tbuf3 , freqBuf);++ for (int k=0;k<nfft;++k)+ tbuf3[k] *= T(1./nfft);+++ //for (size_t i=0;i<(size_t) tbuf.size();++i)+ // cout << "freqBuf=" << freqBuf[i] << " in2=" << tbuf3[i] << " - in=" << tbuf[i] << " => " << (tbuf3[i] - tbuf[i] ) << endl;++ VERIFY( dif_rmse(tbuf,tbuf3) < test_precision<T>() );// gross check++ // verify that ClearFlag works+ fft.ClearFlag(fft.Unscaled);+ fft.inv( tbuf2 , freqBuf);+ VERIFY( dif_rmse(tbuf,tbuf2) < test_precision<T>() );// gross check+}++template <typename T>+void test_scalar(int nfft)+{+ test_scalar_generic<StdVectorContainer,T>(nfft);+ //test_scalar_generic<EigenVectorContainer,T>(nfft);+}+++template <int Container, typename T>+void test_complex_generic(int nfft)+{+ typedef typename FFT<T>::Complex Complex;+ typedef typename VectorType<Container,Complex>::type ComplexVector;++ FFT<T> fft;++ ComplexVector inbuf(nfft);+ ComplexVector outbuf;+ ComplexVector buf3;+ for (int k=0;k<nfft;++k)+ inbuf[k]= Complex( (T)(rand()/(double)RAND_MAX - .5), (T)(rand()/(double)RAND_MAX - .5) );+ fft.fwd( outbuf , inbuf);++ VERIFY( fft_rmse(outbuf,inbuf) < test_precision<T>() );// gross check+ fft.inv( buf3 , outbuf);++ VERIFY( dif_rmse(inbuf,buf3) < test_precision<T>() );// gross check++ // verify that the Unscaled flag takes effect+ ComplexVector buf4;+ fft.SetFlag(fft.Unscaled);+ fft.inv( buf4 , outbuf);+ for (int k=0;k<nfft;++k)+ buf4[k] *= T(1./nfft);+ VERIFY( dif_rmse(inbuf,buf4) < test_precision<T>() );// gross check++ // verify that ClearFlag works+ fft.ClearFlag(fft.Unscaled);+ fft.inv( buf3 , outbuf);+ VERIFY( dif_rmse(inbuf,buf3) < test_precision<T>() );// gross check+}++template <typename T>+void test_complex(int nfft)+{+ test_complex_generic<StdVectorContainer,T>(nfft);+ test_complex_generic<EigenVectorContainer,T>(nfft);+}+/*+template <typename T,int nrows,int ncols>+void test_complex2d()+{+ typedef typename Eigen::FFT<T>::Complex Complex;+ FFT<T> fft;+ Eigen::Matrix<Complex,nrows,ncols> src,src2,dst,dst2;++ src = Eigen::Matrix<Complex,nrows,ncols>::Random();+ //src = Eigen::Matrix<Complex,nrows,ncols>::Identity();++ for (int k=0;k<ncols;k++) {+ Eigen::Matrix<Complex,nrows,1> tmpOut;+ fft.fwd( tmpOut,src.col(k) );+ dst2.col(k) = tmpOut;+ }++ for (int k=0;k<nrows;k++) {+ Eigen::Matrix<Complex,1,ncols> tmpOut;+ fft.fwd( tmpOut, dst2.row(k) );+ dst2.row(k) = tmpOut;+ }++ fft.fwd2(dst.data(),src.data(),ncols,nrows);+ fft.inv2(src2.data(),dst.data(),ncols,nrows);+ VERIFY( (src-src2).norm() < test_precision<T>() );+ VERIFY( (dst-dst2).norm() < test_precision<T>() );+}+*/+++void test_return_by_value(int len)+{+ VectorXf in;+ VectorXf in1;+ in.setRandom( len );+ VectorXcf out1,out2;+ FFT<float> fft;++ fft.SetFlag(fft.HalfSpectrum );++ fft.fwd(out1,in);+ out2 = fft.fwd(in);+ VERIFY( (out1-out2).norm() < test_precision<float>() );+ in1 = fft.inv(out1);+ VERIFY( (in1-in).norm() < test_precision<float>() );+}++void test_FFTW()+{+ CALL_SUBTEST( test_return_by_value(32) );+ //CALL_SUBTEST( ( test_complex2d<float,4,8> () ) ); CALL_SUBTEST( ( test_complex2d<double,4,8> () ) );+ //CALL_SUBTEST( ( test_complex2d<long double,4,8> () ) );+ CALL_SUBTEST( test_complex<float>(32) ); CALL_SUBTEST( test_complex<double>(32) ); + CALL_SUBTEST( test_complex<float>(256) ); CALL_SUBTEST( test_complex<double>(256) ); + CALL_SUBTEST( test_complex<float>(3*8) ); CALL_SUBTEST( test_complex<double>(3*8) ); + CALL_SUBTEST( test_complex<float>(5*32) ); CALL_SUBTEST( test_complex<double>(5*32) ); + CALL_SUBTEST( test_complex<float>(2*3*4) ); CALL_SUBTEST( test_complex<double>(2*3*4) ); + CALL_SUBTEST( test_complex<float>(2*3*4*5) ); CALL_SUBTEST( test_complex<double>(2*3*4*5) ); + CALL_SUBTEST( test_complex<float>(2*3*4*5*7) ); CALL_SUBTEST( test_complex<double>(2*3*4*5*7) ); ++ CALL_SUBTEST( test_scalar<float>(32) ); CALL_SUBTEST( test_scalar<double>(32) ); + CALL_SUBTEST( test_scalar<float>(45) ); CALL_SUBTEST( test_scalar<double>(45) ); + CALL_SUBTEST( test_scalar<float>(50) ); CALL_SUBTEST( test_scalar<double>(50) ); + CALL_SUBTEST( test_scalar<float>(256) ); CALL_SUBTEST( test_scalar<double>(256) ); + CALL_SUBTEST( test_scalar<float>(2*3*4*5*7) ); CALL_SUBTEST( test_scalar<double>(2*3*4*5*7) ); + + #ifdef EIGEN_HAS_FFTWL+ CALL_SUBTEST( test_complex<long double>(32) );+ CALL_SUBTEST( test_complex<long double>(256) );+ CALL_SUBTEST( test_complex<long double>(3*8) );+ CALL_SUBTEST( test_complex<long double>(5*32) );+ CALL_SUBTEST( test_complex<long double>(2*3*4) );+ CALL_SUBTEST( test_complex<long double>(2*3*4*5) );+ CALL_SUBTEST( test_complex<long double>(2*3*4*5*7) );+ + CALL_SUBTEST( test_scalar<long double>(32) );+ CALL_SUBTEST( test_scalar<long double>(45) );+ CALL_SUBTEST( test_scalar<long double>(50) );+ CALL_SUBTEST( test_scalar<long double>(256) );+ CALL_SUBTEST( test_scalar<long double>(2*3*4*5*7) );+ #endif+}
+ eigen3/unsupported/test/NonLinearOptimization.cpp view
@@ -0,0 +1,1870 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>++#include <stdio.h>++#include "main.h"+#include <unsupported/Eigen/NonLinearOptimization>++// This disables some useless Warnings on MSVC.+// It is intended to be done for this test only.+#include <Eigen/src/Core/util/DisableStupidWarnings.h>++using std::sqrt;++int fcn_chkder(const VectorXd &x, VectorXd &fvec, MatrixXd &fjac, int iflag)+{+ /* subroutine fcn for chkder example. */++ int i;+ assert(15 == fvec.size());+ assert(3 == x.size());+ double tmp1, tmp2, tmp3, tmp4;+ static const double y[15]={1.4e-1, 1.8e-1, 2.2e-1, 2.5e-1, 2.9e-1, 3.2e-1, 3.5e-1,+ 3.9e-1, 3.7e-1, 5.8e-1, 7.3e-1, 9.6e-1, 1.34, 2.1, 4.39};+++ if (iflag == 0)+ return 0;++ if (iflag != 2)+ for (i=0; i<15; i++) {+ tmp1 = i+1;+ tmp2 = 16-i-1;+ tmp3 = tmp1;+ if (i >= 8) tmp3 = tmp2;+ fvec[i] = y[i] - (x[0] + tmp1/(x[1]*tmp2 + x[2]*tmp3));+ }+ else {+ for (i = 0; i < 15; i++) {+ tmp1 = i+1;+ tmp2 = 16-i-1;++ /* error introduced into next statement for illustration. */+ /* corrected statement should read tmp3 = tmp1 . */++ tmp3 = tmp2;+ if (i >= 8) tmp3 = tmp2;+ tmp4 = (x[1]*tmp2 + x[2]*tmp3); tmp4=tmp4*tmp4;+ fjac(i,0) = -1.;+ fjac(i,1) = tmp1*tmp2/tmp4;+ fjac(i,2) = tmp1*tmp3/tmp4;+ }+ }+ return 0;+}+++void testChkder()+{+ const int m=15, n=3;+ VectorXd x(n), fvec(m), xp, fvecp(m), err;+ MatrixXd fjac(m,n);+ VectorXi ipvt;++ /* the following values should be suitable for */+ /* checking the jacobian matrix. */+ x << 9.2e-1, 1.3e-1, 5.4e-1;++ internal::chkder(x, fvec, fjac, xp, fvecp, 1, err);+ fcn_chkder(x, fvec, fjac, 1);+ fcn_chkder(x, fvec, fjac, 2);+ fcn_chkder(xp, fvecp, fjac, 1);+ internal::chkder(x, fvec, fjac, xp, fvecp, 2, err);++ fvecp -= fvec;++ // check those+ VectorXd fvec_ref(m), fvecp_ref(m), err_ref(m);+ fvec_ref <<+ -1.181606, -1.429655, -1.606344,+ -1.745269, -1.840654, -1.921586,+ -1.984141, -2.022537, -2.468977,+ -2.827562, -3.473582, -4.437612,+ -6.047662, -9.267761, -18.91806;+ fvecp_ref <<+ -7.724666e-09, -3.432406e-09, -2.034843e-10,+ 2.313685e-09, 4.331078e-09, 5.984096e-09,+ 7.363281e-09, 8.53147e-09, 1.488591e-08,+ 2.33585e-08, 3.522012e-08, 5.301255e-08,+ 8.26666e-08, 1.419747e-07, 3.19899e-07;+ err_ref <<+ 0.1141397, 0.09943516, 0.09674474,+ 0.09980447, 0.1073116, 0.1220445,+ 0.1526814, 1, 1,+ 1, 1, 1,+ 1, 1, 1;++ VERIFY_IS_APPROX(fvec, fvec_ref);+ VERIFY_IS_APPROX(fvecp, fvecp_ref);+ VERIFY_IS_APPROX(err, err_ref);+}++// Generic functor+template<typename _Scalar, int NX=Dynamic, int NY=Dynamic>+struct Functor+{+ typedef _Scalar Scalar;+ enum {+ InputsAtCompileTime = NX,+ ValuesAtCompileTime = NY+ };+ typedef Matrix<Scalar,InputsAtCompileTime,1> InputType;+ typedef Matrix<Scalar,ValuesAtCompileTime,1> ValueType;+ typedef Matrix<Scalar,ValuesAtCompileTime,InputsAtCompileTime> JacobianType;++ const int m_inputs, m_values;++ Functor() : m_inputs(InputsAtCompileTime), m_values(ValuesAtCompileTime) {}+ Functor(int inputs, int values) : m_inputs(inputs), m_values(values) {}++ int inputs() const { return m_inputs; }+ int values() const { return m_values; }++ // you should define that in the subclass :+// void operator() (const InputType& x, ValueType* v, JacobianType* _j=0) const;+};++struct lmder_functor : Functor<double>+{+ lmder_functor(void): Functor<double>(3,15) {}+ int operator()(const VectorXd &x, VectorXd &fvec) const+ {+ double tmp1, tmp2, tmp3;+ static const double y[15] = {1.4e-1, 1.8e-1, 2.2e-1, 2.5e-1, 2.9e-1, 3.2e-1, 3.5e-1,+ 3.9e-1, 3.7e-1, 5.8e-1, 7.3e-1, 9.6e-1, 1.34, 2.1, 4.39};++ for (int i = 0; i < values(); i++)+ {+ tmp1 = i+1;+ tmp2 = 16 - i - 1;+ tmp3 = (i>=8)? tmp2 : tmp1;+ fvec[i] = y[i] - (x[0] + tmp1/(x[1]*tmp2 + x[2]*tmp3));+ }+ return 0;+ }++ int df(const VectorXd &x, MatrixXd &fjac) const+ {+ double tmp1, tmp2, tmp3, tmp4;+ for (int i = 0; i < values(); i++)+ {+ tmp1 = i+1;+ tmp2 = 16 - i - 1;+ tmp3 = (i>=8)? tmp2 : tmp1;+ tmp4 = (x[1]*tmp2 + x[2]*tmp3); tmp4 = tmp4*tmp4;+ fjac(i,0) = -1;+ fjac(i,1) = tmp1*tmp2/tmp4;+ fjac(i,2) = tmp1*tmp3/tmp4;+ }+ return 0;+ }+};++void testLmder1()+{+ int n=3, info;++ VectorXd x;++ /* the following starting values provide a rough fit. */+ x.setConstant(n, 1.);++ // do the computation+ lmder_functor functor;+ LevenbergMarquardt<lmder_functor> lm(functor);+ info = lm.lmder1(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 6);+ VERIFY_IS_EQUAL(lm.njev, 5);++ // check norm+ VERIFY_IS_APPROX(lm.fvec.blueNorm(), 0.09063596);++ // check x+ VectorXd x_ref(n);+ x_ref << 0.08241058, 1.133037, 2.343695;+ VERIFY_IS_APPROX(x, x_ref);+}++void testLmder()+{+ const int m=15, n=3;+ int info;+ double fnorm, covfac;+ VectorXd x;++ /* the following starting values provide a rough fit. */+ x.setConstant(n, 1.);++ // do the computation+ lmder_functor functor;+ LevenbergMarquardt<lmder_functor> lm(functor);+ info = lm.minimize(x);++ // check return values+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 6);+ VERIFY_IS_EQUAL(lm.njev, 5);++ // check norm+ fnorm = lm.fvec.blueNorm();+ VERIFY_IS_APPROX(fnorm, 0.09063596);++ // check x+ VectorXd x_ref(n);+ x_ref << 0.08241058, 1.133037, 2.343695;+ VERIFY_IS_APPROX(x, x_ref);++ // check covariance+ covfac = fnorm*fnorm/(m-n);+ internal::covar(lm.fjac, lm.permutation.indices()); // TODO : move this as a function of lm++ MatrixXd cov_ref(n,n);+ cov_ref <<+ 0.0001531202, 0.002869941, -0.002656662,+ 0.002869941, 0.09480935, -0.09098995,+ -0.002656662, -0.09098995, 0.08778727;++// std::cout << fjac*covfac << std::endl;++ MatrixXd cov;+ cov = covfac*lm.fjac.topLeftCorner<n,n>();+ VERIFY_IS_APPROX( cov, cov_ref);+ // TODO: why isn't this allowed ? :+ // VERIFY_IS_APPROX( covfac*fjac.topLeftCorner<n,n>() , cov_ref);+}++struct hybrj_functor : Functor<double>+{+ hybrj_functor(void) : Functor<double>(9,9) {}++ int operator()(const VectorXd &x, VectorXd &fvec)+ {+ double temp, temp1, temp2;+ const int n = x.size();+ assert(fvec.size()==n);+ for (int k = 0; k < n; k++)+ {+ temp = (3. - 2.*x[k])*x[k];+ temp1 = 0.;+ if (k) temp1 = x[k-1];+ temp2 = 0.;+ if (k != n-1) temp2 = x[k+1];+ fvec[k] = temp - temp1 - 2.*temp2 + 1.;+ }+ return 0;+ }+ int df(const VectorXd &x, MatrixXd &fjac)+ {+ const int n = x.size();+ assert(fjac.rows()==n);+ assert(fjac.cols()==n);+ for (int k = 0; k < n; k++)+ {+ for (int j = 0; j < n; j++)+ fjac(k,j) = 0.;+ fjac(k,k) = 3.- 4.*x[k];+ if (k) fjac(k,k-1) = -1.;+ if (k != n-1) fjac(k,k+1) = -2.;+ }+ return 0;+ }+};+++void testHybrj1()+{+ const int n=9;+ int info;+ VectorXd x(n);++ /* the following starting values provide a rough fit. */+ x.setConstant(n, -1.);++ // do the computation+ hybrj_functor functor;+ HybridNonLinearSolver<hybrj_functor> solver(functor);+ info = solver.hybrj1(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(solver.nfev, 11);+ VERIFY_IS_EQUAL(solver.njev, 1);++ // check norm+ VERIFY_IS_APPROX(solver.fvec.blueNorm(), 1.192636e-08);+++// check x+ VectorXd x_ref(n);+ x_ref <<+ -0.5706545, -0.6816283, -0.7017325,+ -0.7042129, -0.701369, -0.6918656,+ -0.665792, -0.5960342, -0.4164121;+ VERIFY_IS_APPROX(x, x_ref);+}++void testHybrj()+{+ const int n=9;+ int info;+ VectorXd x(n);++ /* the following starting values provide a rough fit. */+ x.setConstant(n, -1.);+++ // do the computation+ hybrj_functor functor;+ HybridNonLinearSolver<hybrj_functor> solver(functor);+ solver.diag.setConstant(n, 1.);+ solver.useExternalScaling = true;+ info = solver.solve(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(solver.nfev, 11);+ VERIFY_IS_EQUAL(solver.njev, 1);++ // check norm+ VERIFY_IS_APPROX(solver.fvec.blueNorm(), 1.192636e-08);+++// check x+ VectorXd x_ref(n);+ x_ref <<+ -0.5706545, -0.6816283, -0.7017325,+ -0.7042129, -0.701369, -0.6918656,+ -0.665792, -0.5960342, -0.4164121;+ VERIFY_IS_APPROX(x, x_ref);++}++struct hybrd_functor : Functor<double>+{+ hybrd_functor(void) : Functor<double>(9,9) {}+ int operator()(const VectorXd &x, VectorXd &fvec) const+ {+ double temp, temp1, temp2;+ const int n = x.size();++ assert(fvec.size()==n);+ for (int k=0; k < n; k++)+ {+ temp = (3. - 2.*x[k])*x[k];+ temp1 = 0.;+ if (k) temp1 = x[k-1];+ temp2 = 0.;+ if (k != n-1) temp2 = x[k+1];+ fvec[k] = temp - temp1 - 2.*temp2 + 1.;+ }+ return 0;+ }+};++void testHybrd1()+{+ int n=9, info;+ VectorXd x(n);++ /* the following starting values provide a rough solution. */+ x.setConstant(n, -1.);++ // do the computation+ hybrd_functor functor;+ HybridNonLinearSolver<hybrd_functor> solver(functor);+ info = solver.hybrd1(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(solver.nfev, 20);++ // check norm+ VERIFY_IS_APPROX(solver.fvec.blueNorm(), 1.192636e-08);++ // check x+ VectorXd x_ref(n);+ x_ref << -0.5706545, -0.6816283, -0.7017325, -0.7042129, -0.701369, -0.6918656, -0.665792, -0.5960342, -0.4164121;+ VERIFY_IS_APPROX(x, x_ref);+}++void testHybrd()+{+ const int n=9;+ int info;+ VectorXd x;++ /* the following starting values provide a rough fit. */+ x.setConstant(n, -1.);++ // do the computation+ hybrd_functor functor;+ HybridNonLinearSolver<hybrd_functor> solver(functor);+ solver.parameters.nb_of_subdiagonals = 1;+ solver.parameters.nb_of_superdiagonals = 1;+ solver.diag.setConstant(n, 1.);+ solver.useExternalScaling = true;+ info = solver.solveNumericalDiff(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(solver.nfev, 14);++ // check norm+ VERIFY_IS_APPROX(solver.fvec.blueNorm(), 1.192636e-08);++ // check x+ VectorXd x_ref(n);+ x_ref <<+ -0.5706545, -0.6816283, -0.7017325,+ -0.7042129, -0.701369, -0.6918656,+ -0.665792, -0.5960342, -0.4164121;+ VERIFY_IS_APPROX(x, x_ref);+}++struct lmstr_functor : Functor<double>+{+ lmstr_functor(void) : Functor<double>(3,15) {}+ int operator()(const VectorXd &x, VectorXd &fvec)+ {+ /* subroutine fcn for lmstr1 example. */+ double tmp1, tmp2, tmp3;+ static const double y[15]={1.4e-1, 1.8e-1, 2.2e-1, 2.5e-1, 2.9e-1, 3.2e-1, 3.5e-1,+ 3.9e-1, 3.7e-1, 5.8e-1, 7.3e-1, 9.6e-1, 1.34, 2.1, 4.39};++ assert(15==fvec.size());+ assert(3==x.size());++ for (int i=0; i<15; i++)+ {+ tmp1 = i+1;+ tmp2 = 16 - i - 1;+ tmp3 = (i>=8)? tmp2 : tmp1;+ fvec[i] = y[i] - (x[0] + tmp1/(x[1]*tmp2 + x[2]*tmp3));+ }+ return 0;+ }+ int df(const VectorXd &x, VectorXd &jac_row, VectorXd::Index rownb)+ {+ assert(x.size()==3);+ assert(jac_row.size()==x.size());+ double tmp1, tmp2, tmp3, tmp4;++ int i = rownb-2;+ tmp1 = i+1;+ tmp2 = 16 - i - 1;+ tmp3 = (i>=8)? tmp2 : tmp1;+ tmp4 = (x[1]*tmp2 + x[2]*tmp3); tmp4 = tmp4*tmp4;+ jac_row[0] = -1;+ jac_row[1] = tmp1*tmp2/tmp4;+ jac_row[2] = tmp1*tmp3/tmp4;+ return 0;+ }+};++void testLmstr1()+{+ const int n=3;+ int info;++ VectorXd x(n);++ /* the following starting values provide a rough fit. */+ x.setConstant(n, 1.);++ // do the computation+ lmstr_functor functor;+ LevenbergMarquardt<lmstr_functor> lm(functor);+ info = lm.lmstr1(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 6);+ VERIFY_IS_EQUAL(lm.njev, 5);++ // check norm+ VERIFY_IS_APPROX(lm.fvec.blueNorm(), 0.09063596);++ // check x+ VectorXd x_ref(n);+ x_ref << 0.08241058, 1.133037, 2.343695 ;+ VERIFY_IS_APPROX(x, x_ref);+}++void testLmstr()+{+ const int n=3;+ int info;+ double fnorm;+ VectorXd x(n);++ /* the following starting values provide a rough fit. */+ x.setConstant(n, 1.);++ // do the computation+ lmstr_functor functor;+ LevenbergMarquardt<lmstr_functor> lm(functor);+ info = lm.minimizeOptimumStorage(x);++ // check return values+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 6);+ VERIFY_IS_EQUAL(lm.njev, 5);++ // check norm+ fnorm = lm.fvec.blueNorm();+ VERIFY_IS_APPROX(fnorm, 0.09063596);++ // check x+ VectorXd x_ref(n);+ x_ref << 0.08241058, 1.133037, 2.343695;+ VERIFY_IS_APPROX(x, x_ref);++}++struct lmdif_functor : Functor<double>+{+ lmdif_functor(void) : Functor<double>(3,15) {}+ int operator()(const VectorXd &x, VectorXd &fvec) const+ {+ int i;+ double tmp1,tmp2,tmp3;+ static const double y[15]={1.4e-1,1.8e-1,2.2e-1,2.5e-1,2.9e-1,3.2e-1,3.5e-1,3.9e-1,+ 3.7e-1,5.8e-1,7.3e-1,9.6e-1,1.34e0,2.1e0,4.39e0};++ assert(x.size()==3);+ assert(fvec.size()==15);+ for (i=0; i<15; i++)+ {+ tmp1 = i+1;+ tmp2 = 15 - i;+ tmp3 = tmp1;++ if (i >= 8) tmp3 = tmp2;+ fvec[i] = y[i] - (x[0] + tmp1/(x[1]*tmp2 + x[2]*tmp3));+ }+ return 0;+ }+};++void testLmdif1()+{+ const int n=3;+ int info;++ VectorXd x(n), fvec(15);++ /* the following starting values provide a rough fit. */+ x.setConstant(n, 1.);++ // do the computation+ lmdif_functor functor;+ DenseIndex nfev;+ info = LevenbergMarquardt<lmdif_functor>::lmdif1(functor, x, &nfev);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(nfev, 26);++ // check norm+ functor(x, fvec);+ VERIFY_IS_APPROX(fvec.blueNorm(), 0.09063596);++ // check x+ VectorXd x_ref(n);+ x_ref << 0.0824106, 1.1330366, 2.3436947;+ VERIFY_IS_APPROX(x, x_ref);++}++void testLmdif()+{+ const int m=15, n=3;+ int info;+ double fnorm, covfac;+ VectorXd x(n);++ /* the following starting values provide a rough fit. */+ x.setConstant(n, 1.);++ // do the computation+ lmdif_functor functor;+ NumericalDiff<lmdif_functor> numDiff(functor);+ LevenbergMarquardt<NumericalDiff<lmdif_functor> > lm(numDiff);+ info = lm.minimize(x);++ // check return values+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 26);++ // check norm+ fnorm = lm.fvec.blueNorm();+ VERIFY_IS_APPROX(fnorm, 0.09063596);++ // check x+ VectorXd x_ref(n);+ x_ref << 0.08241058, 1.133037, 2.343695;+ VERIFY_IS_APPROX(x, x_ref);++ // check covariance+ covfac = fnorm*fnorm/(m-n);+ internal::covar(lm.fjac, lm.permutation.indices()); // TODO : move this as a function of lm++ MatrixXd cov_ref(n,n);+ cov_ref <<+ 0.0001531202, 0.002869942, -0.002656662,+ 0.002869942, 0.09480937, -0.09098997,+ -0.002656662, -0.09098997, 0.08778729;++// std::cout << fjac*covfac << std::endl;++ MatrixXd cov;+ cov = covfac*lm.fjac.topLeftCorner<n,n>();+ VERIFY_IS_APPROX( cov, cov_ref);+ // TODO: why isn't this allowed ? :+ // VERIFY_IS_APPROX( covfac*fjac.topLeftCorner<n,n>() , cov_ref);+}++struct chwirut2_functor : Functor<double>+{+ chwirut2_functor(void) : Functor<double>(3,54) {}+ static const double m_x[54];+ static const double m_y[54];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ int i;++ assert(b.size()==3);+ assert(fvec.size()==54);+ for(i=0; i<54; i++) {+ double x = m_x[i];+ fvec[i] = exp(-b[0]*x)/(b[1]+b[2]*x) - m_y[i];+ }+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==3);+ assert(fjac.rows()==54);+ assert(fjac.cols()==3);+ for(int i=0; i<54; i++) {+ double x = m_x[i];+ double factor = 1./(b[1]+b[2]*x);+ double e = exp(-b[0]*x);+ fjac(i,0) = -x*e*factor;+ fjac(i,1) = -e*factor*factor;+ fjac(i,2) = -x*e*factor*factor;+ }+ return 0;+ }+};+const double chwirut2_functor::m_x[54] = { 0.500E0, 1.000E0, 1.750E0, 3.750E0, 5.750E0, 0.875E0, 2.250E0, 3.250E0, 5.250E0, 0.750E0, 1.750E0, 2.750E0, 4.750E0, 0.625E0, 1.250E0, 2.250E0, 4.250E0, .500E0, 3.000E0, .750E0, 3.000E0, 1.500E0, 6.000E0, 3.000E0, 6.000E0, 1.500E0, 3.000E0, .500E0, 2.000E0, 4.000E0, .750E0, 2.000E0, 5.000E0, .750E0, 2.250E0, 3.750E0, 5.750E0, 3.000E0, .750E0, 2.500E0, 4.000E0, .750E0, 2.500E0, 4.000E0, .750E0, 2.500E0, 4.000E0, .500E0, 6.000E0, 3.000E0, .500E0, 2.750E0, .500E0, 1.750E0};+const double chwirut2_functor::m_y[54] = { 92.9000E0 ,57.1000E0 ,31.0500E0 ,11.5875E0 ,8.0250E0 ,63.6000E0 ,21.4000E0 ,14.2500E0 ,8.4750E0 ,63.8000E0 ,26.8000E0 ,16.4625E0 ,7.1250E0 ,67.3000E0 ,41.0000E0 ,21.1500E0 ,8.1750E0 ,81.5000E0 ,13.1200E0 ,59.9000E0 ,14.6200E0 ,32.9000E0 ,5.4400E0 ,12.5600E0 ,5.4400E0 ,32.0000E0 ,13.9500E0 ,75.8000E0 ,20.0000E0 ,10.4200E0 ,59.5000E0 ,21.6700E0 ,8.5500E0 ,62.0000E0 ,20.2000E0 ,7.7600E0 ,3.7500E0 ,11.8100E0 ,54.7000E0 ,23.7000E0 ,11.5500E0 ,61.3000E0 ,17.7000E0 ,8.7400E0 ,59.2000E0 ,16.3000E0 ,8.6200E0 ,81.0000E0 ,4.8700E0 ,14.6200E0 ,81.7000E0 ,17.1700E0 ,81.3000E0 ,28.9000E0 };++// http://www.itl.nist.gov/div898/strd/nls/data/chwirut2.shtml+void testNistChwirut2(void)+{+ const int n=3;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 0.1, 0.01, 0.02;+ // do the computation+ chwirut2_functor functor;+ LevenbergMarquardt<chwirut2_functor> lm(functor);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 10);+ VERIFY_IS_EQUAL(lm.njev, 8);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.1304802941E+02);+ // check x+ VERIFY_IS_APPROX(x[0], 1.6657666537E-01);+ VERIFY_IS_APPROX(x[1], 5.1653291286E-03);+ VERIFY_IS_APPROX(x[2], 1.2150007096E-02);++ /*+ * Second try+ */+ x<< 0.15, 0.008, 0.010;+ // do the computation+ lm.resetParameters();+ lm.parameters.ftol = 1.E6*NumTraits<double>::epsilon();+ lm.parameters.xtol = 1.E6*NumTraits<double>::epsilon();+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 7);+ VERIFY_IS_EQUAL(lm.njev, 6);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.1304802941E+02);+ // check x+ VERIFY_IS_APPROX(x[0], 1.6657666537E-01);+ VERIFY_IS_APPROX(x[1], 5.1653291286E-03);+ VERIFY_IS_APPROX(x[2], 1.2150007096E-02);+}+++struct misra1a_functor : Functor<double>+{+ misra1a_functor(void) : Functor<double>(2,14) {}+ static const double m_x[14];+ static const double m_y[14];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==2);+ assert(fvec.size()==14);+ for(int i=0; i<14; i++) {+ fvec[i] = b[0]*(1.-exp(-b[1]*m_x[i])) - m_y[i] ;+ }+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==2);+ assert(fjac.rows()==14);+ assert(fjac.cols()==2);+ for(int i=0; i<14; i++) {+ fjac(i,0) = (1.-exp(-b[1]*m_x[i]));+ fjac(i,1) = (b[0]*m_x[i]*exp(-b[1]*m_x[i]));+ }+ return 0;+ }+};+const double misra1a_functor::m_x[14] = { 77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0};+const double misra1a_functor::m_y[14] = { 10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0};++// http://www.itl.nist.gov/div898/strd/nls/data/misra1a.shtml+void testNistMisra1a(void)+{+ const int n=2;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 500., 0.0001;+ // do the computation+ misra1a_functor functor;+ LevenbergMarquardt<misra1a_functor> lm(functor);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 19);+ VERIFY_IS_EQUAL(lm.njev, 15);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.2455138894E-01);+ // check x+ VERIFY_IS_APPROX(x[0], 2.3894212918E+02);+ VERIFY_IS_APPROX(x[1], 5.5015643181E-04);++ /*+ * Second try+ */+ x<< 250., 0.0005;+ // do the computation+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 5);+ VERIFY_IS_EQUAL(lm.njev, 4);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.2455138894E-01);+ // check x+ VERIFY_IS_APPROX(x[0], 2.3894212918E+02);+ VERIFY_IS_APPROX(x[1], 5.5015643181E-04);+}++struct hahn1_functor : Functor<double>+{+ hahn1_functor(void) : Functor<double>(7,236) {}+ static const double m_x[236];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ static const double m_y[236] = { .591E0 , 1.547E0 , 2.902E0 , 2.894E0 , 4.703E0 , 6.307E0 , 7.03E0 , 7.898E0 , 9.470E0 , 9.484E0 , 10.072E0 , 10.163E0 , 11.615E0 , 12.005E0 , 12.478E0 , 12.982E0 , 12.970E0 , 13.926E0 , 14.452E0 , 14.404E0 , 15.190E0 , 15.550E0 , 15.528E0 , 15.499E0 , 16.131E0 , 16.438E0 , 16.387E0 , 16.549E0 , 16.872E0 , 16.830E0 , 16.926E0 , 16.907E0 , 16.966E0 , 17.060E0 , 17.122E0 , 17.311E0 , 17.355E0 , 17.668E0 , 17.767E0 , 17.803E0 , 17.765E0 , 17.768E0 , 17.736E0 , 17.858E0 , 17.877E0 , 17.912E0 , 18.046E0 , 18.085E0 , 18.291E0 , 18.357E0 , 18.426E0 , 18.584E0 , 18.610E0 , 18.870E0 , 18.795E0 , 19.111E0 , .367E0 , .796E0 , 0.892E0 , 1.903E0 , 2.150E0 , 3.697E0 , 5.870E0 , 6.421E0 , 7.422E0 , 9.944E0 , 11.023E0 , 11.87E0 , 12.786E0 , 14.067E0 , 13.974E0 , 14.462E0 , 14.464E0 , 15.381E0 , 15.483E0 , 15.59E0 , 16.075E0 , 16.347E0 , 16.181E0 , 16.915E0 , 17.003E0 , 16.978E0 , 17.756E0 , 17.808E0 , 17.868E0 , 18.481E0 , 18.486E0 , 19.090E0 , 16.062E0 , 16.337E0 , 16.345E0 ,+ 16.388E0 , 17.159E0 , 17.116E0 , 17.164E0 , 17.123E0 , 17.979E0 , 17.974E0 , 18.007E0 , 17.993E0 , 18.523E0 , 18.669E0 , 18.617E0 , 19.371E0 , 19.330E0 , 0.080E0 , 0.248E0 , 1.089E0 , 1.418E0 , 2.278E0 , 3.624E0 , 4.574E0 , 5.556E0 , 7.267E0 , 7.695E0 , 9.136E0 , 9.959E0 , 9.957E0 , 11.600E0 , 13.138E0 , 13.564E0 , 13.871E0 , 13.994E0 , 14.947E0 , 15.473E0 , 15.379E0 , 15.455E0 , 15.908E0 , 16.114E0 , 17.071E0 , 17.135E0 , 17.282E0 , 17.368E0 , 17.483E0 , 17.764E0 , 18.185E0 , 18.271E0 , 18.236E0 , 18.237E0 , 18.523E0 , 18.627E0 , 18.665E0 , 19.086E0 , 0.214E0 , 0.943E0 , 1.429E0 , 2.241E0 , 2.951E0 , 3.782E0 , 4.757E0 , 5.602E0 , 7.169E0 , 8.920E0 , 10.055E0 , 12.035E0 , 12.861E0 , 13.436E0 , 14.167E0 , 14.755E0 , 15.168E0 , 15.651E0 , 15.746E0 , 16.216E0 , 16.445E0 , 16.965E0 , 17.121E0 , 17.206E0 , 17.250E0 , 17.339E0 , 17.793E0 , 18.123E0 , 18.49E0 , 18.566E0 , 18.645E0 , 18.706E0 , 18.924E0 , 19.1E0 , 0.375E0 , 0.471E0 , 1.504E0 , 2.204E0 , 2.813E0 , 4.765E0 , 9.835E0 , 10.040E0 , 11.946E0 , 12.596E0 , +13.303E0 , 13.922E0 , 14.440E0 , 14.951E0 , 15.627E0 , 15.639E0 , 15.814E0 , 16.315E0 , 16.334E0 , 16.430E0 , 16.423E0 , 17.024E0 , 17.009E0 , 17.165E0 , 17.134E0 , 17.349E0 , 17.576E0 , 17.848E0 , 18.090E0 , 18.276E0 , 18.404E0 , 18.519E0 , 19.133E0 , 19.074E0 , 19.239E0 , 19.280E0 , 19.101E0 , 19.398E0 , 19.252E0 , 19.89E0 , 20.007E0 , 19.929E0 , 19.268E0 , 19.324E0 , 20.049E0 , 20.107E0 , 20.062E0 , 20.065E0 , 19.286E0 , 19.972E0 , 20.088E0 , 20.743E0 , 20.83E0 , 20.935E0 , 21.035E0 , 20.93E0 , 21.074E0 , 21.085E0 , 20.935E0 };++ // int called=0; printf("call hahn1_functor with iflag=%d, called=%d\n", iflag, called); if (iflag==1) called++;++ assert(b.size()==7);+ assert(fvec.size()==236);+ for(int i=0; i<236; i++) {+ double x=m_x[i], xx=x*x, xxx=xx*x;+ fvec[i] = (b[0]+b[1]*x+b[2]*xx+b[3]*xxx) / (1.+b[4]*x+b[5]*xx+b[6]*xxx) - m_y[i];+ }+ return 0;+ }++ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==7);+ assert(fjac.rows()==236);+ assert(fjac.cols()==7);+ for(int i=0; i<236; i++) {+ double x=m_x[i], xx=x*x, xxx=xx*x;+ double fact = 1./(1.+b[4]*x+b[5]*xx+b[6]*xxx);+ fjac(i,0) = 1.*fact;+ fjac(i,1) = x*fact;+ fjac(i,2) = xx*fact;+ fjac(i,3) = xxx*fact;+ fact = - (b[0]+b[1]*x+b[2]*xx+b[3]*xxx) * fact * fact;+ fjac(i,4) = x*fact;+ fjac(i,5) = xx*fact;+ fjac(i,6) = xxx*fact;+ }+ return 0;+ }+};+const double hahn1_functor::m_x[236] = { 24.41E0 , 34.82E0 , 44.09E0 , 45.07E0 , 54.98E0 , 65.51E0 , 70.53E0 , 75.70E0 , 89.57E0 , 91.14E0 , 96.40E0 , 97.19E0 , 114.26E0 , 120.25E0 , 127.08E0 , 133.55E0 , 133.61E0 , 158.67E0 , 172.74E0 , 171.31E0 , 202.14E0 , 220.55E0 , 221.05E0 , 221.39E0 , 250.99E0 , 268.99E0 , 271.80E0 , 271.97E0 , 321.31E0 , 321.69E0 , 330.14E0 , 333.03E0 , 333.47E0 , 340.77E0 , 345.65E0 , 373.11E0 , 373.79E0 , 411.82E0 , 419.51E0 , 421.59E0 , 422.02E0 , 422.47E0 , 422.61E0 , 441.75E0 , 447.41E0 , 448.7E0 , 472.89E0 , 476.69E0 , 522.47E0 , 522.62E0 , 524.43E0 , 546.75E0 , 549.53E0 , 575.29E0 , 576.00E0 , 625.55E0 , 20.15E0 , 28.78E0 , 29.57E0 , 37.41E0 , 39.12E0 , 50.24E0 , 61.38E0 , 66.25E0 , 73.42E0 , 95.52E0 , 107.32E0 , 122.04E0 , 134.03E0 , 163.19E0 , 163.48E0 , 175.70E0 , 179.86E0 , 211.27E0 , 217.78E0 , 219.14E0 , 262.52E0 , 268.01E0 , 268.62E0 , 336.25E0 , 337.23E0 , 339.33E0 , 427.38E0 , 428.58E0 , 432.68E0 , 528.99E0 , 531.08E0 , 628.34E0 , 253.24E0 , 273.13E0 , 273.66E0 ,+282.10E0 , 346.62E0 , 347.19E0 , 348.78E0 , 351.18E0 , 450.10E0 , 450.35E0 , 451.92E0 , 455.56E0 , 552.22E0 , 553.56E0 , 555.74E0 , 652.59E0 , 656.20E0 , 14.13E0 , 20.41E0 , 31.30E0 , 33.84E0 , 39.70E0 , 48.83E0 , 54.50E0 , 60.41E0 , 72.77E0 , 75.25E0 , 86.84E0 , 94.88E0 , 96.40E0 , 117.37E0 , 139.08E0 , 147.73E0 , 158.63E0 , 161.84E0 , 192.11E0 , 206.76E0 , 209.07E0 , 213.32E0 , 226.44E0 , 237.12E0 , 330.90E0 , 358.72E0 , 370.77E0 , 372.72E0 , 396.24E0 , 416.59E0 , 484.02E0 , 495.47E0 , 514.78E0 , 515.65E0 , 519.47E0 , 544.47E0 , 560.11E0 , 620.77E0 , 18.97E0 , 28.93E0 , 33.91E0 , 40.03E0 , 44.66E0 , 49.87E0 , 55.16E0 , 60.90E0 , 72.08E0 , 85.15E0 , 97.06E0 , 119.63E0 , 133.27E0 , 143.84E0 , 161.91E0 , 180.67E0 , 198.44E0 , 226.86E0 , 229.65E0 , 258.27E0 , 273.77E0 , 339.15E0 , 350.13E0 , 362.75E0 , 371.03E0 , 393.32E0 , 448.53E0 , 473.78E0 , 511.12E0 , 524.70E0 , 548.75E0 , 551.64E0 , 574.02E0 , 623.86E0 , 21.46E0 , 24.33E0 , 33.43E0 , 39.22E0 , 44.18E0 , 55.02E0 , 94.33E0 , 96.44E0 , 118.82E0 , 128.48E0 ,+141.94E0 , 156.92E0 , 171.65E0 , 190.00E0 , 223.26E0 , 223.88E0 , 231.50E0 , 265.05E0 , 269.44E0 , 271.78E0 , 273.46E0 , 334.61E0 , 339.79E0 , 349.52E0 , 358.18E0 , 377.98E0 , 394.77E0 , 429.66E0 , 468.22E0 , 487.27E0 , 519.54E0 , 523.03E0 , 612.99E0 , 638.59E0 , 641.36E0 , 622.05E0 , 631.50E0 , 663.97E0 , 646.9E0 , 748.29E0 , 749.21E0 , 750.14E0 , 647.04E0 , 646.89E0 , 746.9E0 , 748.43E0 , 747.35E0 , 749.27E0 , 647.61E0 , 747.78E0 , 750.51E0 , 851.37E0 , 845.97E0 , 847.54E0 , 849.93E0 , 851.61E0 , 849.75E0 , 850.98E0 , 848.23E0};++// http://www.itl.nist.gov/div898/strd/nls/data/hahn1.shtml+void testNistHahn1(void)+{+ const int n=7;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 10., -1., .05, -.00001, -.05, .001, -.000001;+ // do the computation+ hahn1_functor functor;+ LevenbergMarquardt<hahn1_functor> lm(functor);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 11);+ VERIFY_IS_EQUAL(lm.njev, 10);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.5324382854E+00);+ // check x+ VERIFY_IS_APPROX(x[0], 1.0776351733E+00);+ VERIFY_IS_APPROX(x[1],-1.2269296921E-01);+ VERIFY_IS_APPROX(x[2], 4.0863750610E-03);+ VERIFY_IS_APPROX(x[3],-1.426264e-06); // shoulde be : -1.4262662514E-06+ VERIFY_IS_APPROX(x[4],-5.7609940901E-03);+ VERIFY_IS_APPROX(x[5], 2.4053735503E-04);+ VERIFY_IS_APPROX(x[6],-1.2314450199E-07);++ /*+ * Second try+ */+ x<< .1, -.1, .005, -.000001, -.005, .0001, -.0000001;+ // do the computation+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 11);+ VERIFY_IS_EQUAL(lm.njev, 10);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.5324382854E+00);+ // check x+ VERIFY_IS_APPROX(x[0], 1.077640); // should be : 1.0776351733E+00+ VERIFY_IS_APPROX(x[1], -0.1226933); // should be : -1.2269296921E-01+ VERIFY_IS_APPROX(x[2], 0.004086383); // should be : 4.0863750610E-03+ VERIFY_IS_APPROX(x[3], -1.426277e-06); // shoulde be : -1.4262662514E-06+ VERIFY_IS_APPROX(x[4],-5.7609940901E-03);+ VERIFY_IS_APPROX(x[5], 0.00024053772); // should be : 2.4053735503E-04+ VERIFY_IS_APPROX(x[6], -1.231450e-07); // should be : -1.2314450199E-07++}++struct misra1d_functor : Functor<double>+{+ misra1d_functor(void) : Functor<double>(2,14) {}+ static const double x[14];+ static const double y[14];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==2);+ assert(fvec.size()==14);+ for(int i=0; i<14; i++) {+ fvec[i] = b[0]*b[1]*x[i]/(1.+b[1]*x[i]) - y[i];+ }+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==2);+ assert(fjac.rows()==14);+ assert(fjac.cols()==2);+ for(int i=0; i<14; i++) {+ double den = 1.+b[1]*x[i];+ fjac(i,0) = b[1]*x[i] / den;+ fjac(i,1) = b[0]*x[i]*(den-b[1]*x[i])/den/den;+ }+ return 0;+ }+};+const double misra1d_functor::x[14] = { 77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0};+const double misra1d_functor::y[14] = { 10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0};++// http://www.itl.nist.gov/div898/strd/nls/data/misra1d.shtml+void testNistMisra1d(void)+{+ const int n=2;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 500., 0.0001;+ // do the computation+ misra1d_functor functor;+ LevenbergMarquardt<misra1d_functor> lm(functor);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 3);+ VERIFY_IS_EQUAL(lm.nfev, 9);+ VERIFY_IS_EQUAL(lm.njev, 7);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.6419295283E-02);+ // check x+ VERIFY_IS_APPROX(x[0], 4.3736970754E+02);+ VERIFY_IS_APPROX(x[1], 3.0227324449E-04);++ /*+ * Second try+ */+ x<< 450., 0.0003;+ // do the computation+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 4);+ VERIFY_IS_EQUAL(lm.njev, 3);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.6419295283E-02);+ // check x+ VERIFY_IS_APPROX(x[0], 4.3736970754E+02);+ VERIFY_IS_APPROX(x[1], 3.0227324449E-04);+}+++struct lanczos1_functor : Functor<double>+{+ lanczos1_functor(void) : Functor<double>(6,24) {}+ static const double x[24];+ static const double y[24];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==6);+ assert(fvec.size()==24);+ for(int i=0; i<24; i++)+ fvec[i] = b[0]*exp(-b[1]*x[i]) + b[2]*exp(-b[3]*x[i]) + b[4]*exp(-b[5]*x[i]) - y[i];+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==6);+ assert(fjac.rows()==24);+ assert(fjac.cols()==6);+ for(int i=0; i<24; i++) {+ fjac(i,0) = exp(-b[1]*x[i]);+ fjac(i,1) = -b[0]*x[i]*exp(-b[1]*x[i]);+ fjac(i,2) = exp(-b[3]*x[i]);+ fjac(i,3) = -b[2]*x[i]*exp(-b[3]*x[i]);+ fjac(i,4) = exp(-b[5]*x[i]);+ fjac(i,5) = -b[4]*x[i]*exp(-b[5]*x[i]);+ }+ return 0;+ }+};+const double lanczos1_functor::x[24] = { 0.000000000000E+00, 5.000000000000E-02, 1.000000000000E-01, 1.500000000000E-01, 2.000000000000E-01, 2.500000000000E-01, 3.000000000000E-01, 3.500000000000E-01, 4.000000000000E-01, 4.500000000000E-01, 5.000000000000E-01, 5.500000000000E-01, 6.000000000000E-01, 6.500000000000E-01, 7.000000000000E-01, 7.500000000000E-01, 8.000000000000E-01, 8.500000000000E-01, 9.000000000000E-01, 9.500000000000E-01, 1.000000000000E+00, 1.050000000000E+00, 1.100000000000E+00, 1.150000000000E+00 };+const double lanczos1_functor::y[24] = { 2.513400000000E+00 ,2.044333373291E+00 ,1.668404436564E+00 ,1.366418021208E+00 ,1.123232487372E+00 ,9.268897180037E-01 ,7.679338563728E-01 ,6.388775523106E-01 ,5.337835317402E-01 ,4.479363617347E-01 ,3.775847884350E-01 ,3.197393199326E-01 ,2.720130773746E-01 ,2.324965529032E-01 ,1.996589546065E-01 ,1.722704126914E-01 ,1.493405660168E-01 ,1.300700206922E-01 ,1.138119324644E-01 ,1.000415587559E-01 ,8.833209084540E-02 ,7.833544019350E-02 ,6.976693743449E-02 ,6.239312536719E-02 };++// http://www.itl.nist.gov/div898/strd/nls/data/lanczos1.shtml+void testNistLanczos1(void)+{+ const int n=6;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 1.2, 0.3, 5.6, 5.5, 6.5, 7.6;+ // do the computation+ lanczos1_functor functor;+ LevenbergMarquardt<lanczos1_functor> lm(functor);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 2);+ VERIFY_IS_EQUAL(lm.nfev, 79);+ VERIFY_IS_EQUAL(lm.njev, 72);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.430899764097e-25); // should be 1.4307867721E-25, but nist results are on 128-bit floats+ // check x+ VERIFY_IS_APPROX(x[0], 9.5100000027E-02);+ VERIFY_IS_APPROX(x[1], 1.0000000001E+00);+ VERIFY_IS_APPROX(x[2], 8.6070000013E-01);+ VERIFY_IS_APPROX(x[3], 3.0000000002E+00);+ VERIFY_IS_APPROX(x[4], 1.5575999998E+00);+ VERIFY_IS_APPROX(x[5], 5.0000000001E+00);++ /*+ * Second try+ */+ x<< 0.5, 0.7, 3.6, 4.2, 4., 6.3;+ // do the computation+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 2);+ VERIFY_IS_EQUAL(lm.nfev, 9);+ VERIFY_IS_EQUAL(lm.njev, 8);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.428595533845e-25); // should be 1.4307867721E-25, but nist results are on 128-bit floats+ // check x+ VERIFY_IS_APPROX(x[0], 9.5100000027E-02);+ VERIFY_IS_APPROX(x[1], 1.0000000001E+00);+ VERIFY_IS_APPROX(x[2], 8.6070000013E-01);+ VERIFY_IS_APPROX(x[3], 3.0000000002E+00);+ VERIFY_IS_APPROX(x[4], 1.5575999998E+00);+ VERIFY_IS_APPROX(x[5], 5.0000000001E+00);++}++struct rat42_functor : Functor<double>+{+ rat42_functor(void) : Functor<double>(3,9) {}+ static const double x[9];+ static const double y[9];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==3);+ assert(fvec.size()==9);+ for(int i=0; i<9; i++) {+ fvec[i] = b[0] / (1.+exp(b[1]-b[2]*x[i])) - y[i];+ }+ return 0;+ }++ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==3);+ assert(fjac.rows()==9);+ assert(fjac.cols()==3);+ for(int i=0; i<9; i++) {+ double e = exp(b[1]-b[2]*x[i]);+ fjac(i,0) = 1./(1.+e);+ fjac(i,1) = -b[0]*e/(1.+e)/(1.+e);+ fjac(i,2) = +b[0]*e*x[i]/(1.+e)/(1.+e);+ }+ return 0;+ }+};+const double rat42_functor::x[9] = { 9.000E0, 14.000E0, 21.000E0, 28.000E0, 42.000E0, 57.000E0, 63.000E0, 70.000E0, 79.000E0 };+const double rat42_functor::y[9] = { 8.930E0 ,10.800E0 ,18.590E0 ,22.330E0 ,39.350E0 ,56.110E0 ,61.730E0 ,64.620E0 ,67.080E0 };++// http://www.itl.nist.gov/div898/strd/nls/data/ratkowsky2.shtml+void testNistRat42(void)+{+ const int n=3;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 100., 1., 0.1;+ // do the computation+ rat42_functor functor;+ LevenbergMarquardt<rat42_functor> lm(functor);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 10);+ VERIFY_IS_EQUAL(lm.njev, 8);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8.0565229338E+00);+ // check x+ VERIFY_IS_APPROX(x[0], 7.2462237576E+01);+ VERIFY_IS_APPROX(x[1], 2.6180768402E+00);+ VERIFY_IS_APPROX(x[2], 6.7359200066E-02);++ /*+ * Second try+ */+ x<< 75., 2.5, 0.07;+ // do the computation+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 6);+ VERIFY_IS_EQUAL(lm.njev, 5);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8.0565229338E+00);+ // check x+ VERIFY_IS_APPROX(x[0], 7.2462237576E+01);+ VERIFY_IS_APPROX(x[1], 2.6180768402E+00);+ VERIFY_IS_APPROX(x[2], 6.7359200066E-02);+}++struct MGH10_functor : Functor<double>+{+ MGH10_functor(void) : Functor<double>(3,16) {}+ static const double x[16];+ static const double y[16];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==3);+ assert(fvec.size()==16);+ for(int i=0; i<16; i++)+ fvec[i] = b[0] * exp(b[1]/(x[i]+b[2])) - y[i];+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==3);+ assert(fjac.rows()==16);+ assert(fjac.cols()==3);+ for(int i=0; i<16; i++) {+ double factor = 1./(x[i]+b[2]);+ double e = exp(b[1]*factor);+ fjac(i,0) = e;+ fjac(i,1) = b[0]*factor*e;+ fjac(i,2) = -b[1]*b[0]*factor*factor*e;+ }+ return 0;+ }+};+const double MGH10_functor::x[16] = { 5.000000E+01, 5.500000E+01, 6.000000E+01, 6.500000E+01, 7.000000E+01, 7.500000E+01, 8.000000E+01, 8.500000E+01, 9.000000E+01, 9.500000E+01, 1.000000E+02, 1.050000E+02, 1.100000E+02, 1.150000E+02, 1.200000E+02, 1.250000E+02 };+const double MGH10_functor::y[16] = { 3.478000E+04, 2.861000E+04, 2.365000E+04, 1.963000E+04, 1.637000E+04, 1.372000E+04, 1.154000E+04, 9.744000E+03, 8.261000E+03, 7.030000E+03, 6.005000E+03, 5.147000E+03, 4.427000E+03, 3.820000E+03, 3.307000E+03, 2.872000E+03 };++// http://www.itl.nist.gov/div898/strd/nls/data/mgh10.shtml+void testNistMGH10(void)+{+ const int n=3;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 2., 400000., 25000.;+ // do the computation+ MGH10_functor functor;+ LevenbergMarquardt<MGH10_functor> lm(functor);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 2); + VERIFY_IS_EQUAL(lm.nfev, 284 ); + VERIFY_IS_EQUAL(lm.njev, 249 ); + // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8.7945855171E+01);+ // check x+ VERIFY_IS_APPROX(x[0], 5.6096364710E-03);+ VERIFY_IS_APPROX(x[1], 6.1813463463E+03);+ VERIFY_IS_APPROX(x[2], 3.4522363462E+02);++ /*+ * Second try+ */+ x<< 0.02, 4000., 250.;+ // do the computation+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 3);+ VERIFY_IS_EQUAL(lm.nfev, 126);+ VERIFY_IS_EQUAL(lm.njev, 116);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8.7945855171E+01);+ // check x+ VERIFY_IS_APPROX(x[0], 5.6096364710E-03);+ VERIFY_IS_APPROX(x[1], 6.1813463463E+03);+ VERIFY_IS_APPROX(x[2], 3.4522363462E+02);+}+++struct BoxBOD_functor : Functor<double>+{+ BoxBOD_functor(void) : Functor<double>(2,6) {}+ static const double x[6];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ static const double y[6] = { 109., 149., 149., 191., 213., 224. };+ assert(b.size()==2);+ assert(fvec.size()==6);+ for(int i=0; i<6; i++)+ fvec[i] = b[0]*(1.-exp(-b[1]*x[i])) - y[i];+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==2);+ assert(fjac.rows()==6);+ assert(fjac.cols()==2);+ for(int i=0; i<6; i++) {+ double e = exp(-b[1]*x[i]);+ fjac(i,0) = 1.-e;+ fjac(i,1) = b[0]*x[i]*e;+ }+ return 0;+ }+};+const double BoxBOD_functor::x[6] = { 1., 2., 3., 5., 7., 10. };++// http://www.itl.nist.gov/div898/strd/nls/data/boxbod.shtml+void testNistBoxBOD(void)+{+ const int n=2;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 1., 1.;+ // do the computation+ BoxBOD_functor functor;+ LevenbergMarquardt<BoxBOD_functor> lm(functor);+ lm.parameters.ftol = 1.E6*NumTraits<double>::epsilon();+ lm.parameters.xtol = 1.E6*NumTraits<double>::epsilon();+ lm.parameters.factor = 10.;+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 31);+ VERIFY_IS_EQUAL(lm.njev, 25);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.1680088766E+03);+ // check x+ VERIFY_IS_APPROX(x[0], 2.1380940889E+02);+ VERIFY_IS_APPROX(x[1], 5.4723748542E-01);++ /*+ * Second try+ */+ x<< 100., 0.75;+ // do the computation+ lm.resetParameters();+ lm.parameters.ftol = NumTraits<double>::epsilon();+ lm.parameters.xtol = NumTraits<double>::epsilon();+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1); + VERIFY_IS_EQUAL(lm.nfev, 15 ); + VERIFY_IS_EQUAL(lm.njev, 14 ); + // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.1680088766E+03);+ // check x+ VERIFY_IS_APPROX(x[0], 2.1380940889E+02);+ VERIFY_IS_APPROX(x[1], 5.4723748542E-01);+}++struct MGH17_functor : Functor<double>+{+ MGH17_functor(void) : Functor<double>(5,33) {}+ static const double x[33];+ static const double y[33];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==5);+ assert(fvec.size()==33);+ for(int i=0; i<33; i++)+ fvec[i] = b[0] + b[1]*exp(-b[3]*x[i]) + b[2]*exp(-b[4]*x[i]) - y[i];+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==5);+ assert(fjac.rows()==33);+ assert(fjac.cols()==5);+ for(int i=0; i<33; i++) {+ fjac(i,0) = 1.;+ fjac(i,1) = exp(-b[3]*x[i]);+ fjac(i,2) = exp(-b[4]*x[i]);+ fjac(i,3) = -x[i]*b[1]*exp(-b[3]*x[i]);+ fjac(i,4) = -x[i]*b[2]*exp(-b[4]*x[i]);+ }+ return 0;+ }+};+const double MGH17_functor::x[33] = { 0.000000E+00, 1.000000E+01, 2.000000E+01, 3.000000E+01, 4.000000E+01, 5.000000E+01, 6.000000E+01, 7.000000E+01, 8.000000E+01, 9.000000E+01, 1.000000E+02, 1.100000E+02, 1.200000E+02, 1.300000E+02, 1.400000E+02, 1.500000E+02, 1.600000E+02, 1.700000E+02, 1.800000E+02, 1.900000E+02, 2.000000E+02, 2.100000E+02, 2.200000E+02, 2.300000E+02, 2.400000E+02, 2.500000E+02, 2.600000E+02, 2.700000E+02, 2.800000E+02, 2.900000E+02, 3.000000E+02, 3.100000E+02, 3.200000E+02 };+const double MGH17_functor::y[33] = { 8.440000E-01, 9.080000E-01, 9.320000E-01, 9.360000E-01, 9.250000E-01, 9.080000E-01, 8.810000E-01, 8.500000E-01, 8.180000E-01, 7.840000E-01, 7.510000E-01, 7.180000E-01, 6.850000E-01, 6.580000E-01, 6.280000E-01, 6.030000E-01, 5.800000E-01, 5.580000E-01, 5.380000E-01, 5.220000E-01, 5.060000E-01, 4.900000E-01, 4.780000E-01, 4.670000E-01, 4.570000E-01, 4.480000E-01, 4.380000E-01, 4.310000E-01, 4.240000E-01, 4.200000E-01, 4.140000E-01, 4.110000E-01, 4.060000E-01 };++// http://www.itl.nist.gov/div898/strd/nls/data/mgh17.shtml+void testNistMGH17(void)+{+ const int n=5;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 50., 150., -100., 1., 2.;+ // do the computation+ MGH17_functor functor;+ LevenbergMarquardt<MGH17_functor> lm(functor);+ lm.parameters.ftol = NumTraits<double>::epsilon();+ lm.parameters.xtol = NumTraits<double>::epsilon();+ lm.parameters.maxfev = 1000;+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 2); + VERIFY_IS_EQUAL(lm.nfev, 602 ); + VERIFY_IS_EQUAL(lm.njev, 545 ); + // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.4648946975E-05);+ // check x+ VERIFY_IS_APPROX(x[0], 3.7541005211E-01);+ VERIFY_IS_APPROX(x[1], 1.9358469127E+00);+ VERIFY_IS_APPROX(x[2], -1.4646871366E+00);+ VERIFY_IS_APPROX(x[3], 1.2867534640E-02);+ VERIFY_IS_APPROX(x[4], 2.2122699662E-02);++ /*+ * Second try+ */+ x<< 0.5 ,1.5 ,-1 ,0.01 ,0.02;+ // do the computation+ lm.resetParameters();+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 18);+ VERIFY_IS_EQUAL(lm.njev, 15);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.4648946975E-05);+ // check x+ VERIFY_IS_APPROX(x[0], 3.7541005211E-01);+ VERIFY_IS_APPROX(x[1], 1.9358469127E+00);+ VERIFY_IS_APPROX(x[2], -1.4646871366E+00);+ VERIFY_IS_APPROX(x[3], 1.2867534640E-02);+ VERIFY_IS_APPROX(x[4], 2.2122699662E-02);+}++struct MGH09_functor : Functor<double>+{+ MGH09_functor(void) : Functor<double>(4,11) {}+ static const double _x[11];+ static const double y[11];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==4);+ assert(fvec.size()==11);+ for(int i=0; i<11; i++) {+ double x = _x[i], xx=x*x;+ fvec[i] = b[0]*(xx+x*b[1])/(xx+x*b[2]+b[3]) - y[i];+ }+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==4);+ assert(fjac.rows()==11);+ assert(fjac.cols()==4);+ for(int i=0; i<11; i++) {+ double x = _x[i], xx=x*x;+ double factor = 1./(xx+x*b[2]+b[3]);+ fjac(i,0) = (xx+x*b[1]) * factor;+ fjac(i,1) = b[0]*x* factor;+ fjac(i,2) = - b[0]*(xx+x*b[1]) * x * factor * factor;+ fjac(i,3) = - b[0]*(xx+x*b[1]) * factor * factor;+ }+ return 0;+ }+};+const double MGH09_functor::_x[11] = { 4., 2., 1., 5.E-1 , 2.5E-01, 1.670000E-01, 1.250000E-01, 1.E-01, 8.330000E-02, 7.140000E-02, 6.250000E-02 };+const double MGH09_functor::y[11] = { 1.957000E-01, 1.947000E-01, 1.735000E-01, 1.600000E-01, 8.440000E-02, 6.270000E-02, 4.560000E-02, 3.420000E-02, 3.230000E-02, 2.350000E-02, 2.460000E-02 };++// http://www.itl.nist.gov/div898/strd/nls/data/mgh09.shtml+void testNistMGH09(void)+{+ const int n=4;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 25., 39, 41.5, 39.;+ // do the computation+ MGH09_functor functor;+ LevenbergMarquardt<MGH09_functor> lm(functor);+ lm.parameters.maxfev = 1000;+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1); + VERIFY_IS_EQUAL(lm.nfev, 490 ); + VERIFY_IS_EQUAL(lm.njev, 376 ); + // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 3.0750560385E-04);+ // check x+ VERIFY_IS_APPROX(x[0], 0.1928077089); // should be 1.9280693458E-01+ VERIFY_IS_APPROX(x[1], 0.19126423573); // should be 1.9128232873E-01+ VERIFY_IS_APPROX(x[2], 0.12305309914); // should be 1.2305650693E-01+ VERIFY_IS_APPROX(x[3], 0.13605395375); // should be 1.3606233068E-01++ /*+ * Second try+ */+ x<< 0.25, 0.39, 0.415, 0.39;+ // do the computation+ lm.resetParameters();+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 18);+ VERIFY_IS_EQUAL(lm.njev, 16);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 3.0750560385E-04);+ // check x+ VERIFY_IS_APPROX(x[0], 0.19280781); // should be 1.9280693458E-01+ VERIFY_IS_APPROX(x[1], 0.19126265); // should be 1.9128232873E-01+ VERIFY_IS_APPROX(x[2], 0.12305280); // should be 1.2305650693E-01+ VERIFY_IS_APPROX(x[3], 0.13605322); // should be 1.3606233068E-01+}++++struct Bennett5_functor : Functor<double>+{+ Bennett5_functor(void) : Functor<double>(3,154) {}+ static const double x[154];+ static const double y[154];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==3);+ assert(fvec.size()==154);+ for(int i=0; i<154; i++)+ fvec[i] = b[0]* pow(b[1]+x[i],-1./b[2]) - y[i];+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==3);+ assert(fjac.rows()==154);+ assert(fjac.cols()==3);+ for(int i=0; i<154; i++) {+ double e = pow(b[1]+x[i],-1./b[2]);+ fjac(i,0) = e;+ fjac(i,1) = - b[0]*e/b[2]/(b[1]+x[i]);+ fjac(i,2) = b[0]*e*log(b[1]+x[i])/b[2]/b[2];+ }+ return 0;+ }+};+const double Bennett5_functor::x[154] = { 7.447168E0, 8.102586E0, 8.452547E0, 8.711278E0, 8.916774E0, 9.087155E0, 9.232590E0, 9.359535E0, 9.472166E0, 9.573384E0, 9.665293E0, 9.749461E0, 9.827092E0, 9.899128E0, 9.966321E0, 10.029280E0, 10.088510E0, 10.144430E0, 10.197380E0, 10.247670E0, 10.295560E0, 10.341250E0, 10.384950E0, 10.426820E0, 10.467000E0, 10.505640E0, 10.542830E0, 10.578690E0, 10.613310E0, 10.646780E0, 10.679150E0, 10.710520E0, 10.740920E0, 10.770440E0, 10.799100E0, 10.826970E0, 10.854080E0, 10.880470E0, 10.906190E0, 10.931260E0, 10.955720E0, 10.979590E0, 11.002910E0, 11.025700E0, 11.047980E0, 11.069770E0, 11.091100E0, 11.111980E0, 11.132440E0, 11.152480E0, 11.172130E0, 11.191410E0, 11.210310E0, 11.228870E0, 11.247090E0, 11.264980E0, 11.282560E0, 11.299840E0, 11.316820E0, 11.333520E0, 11.349940E0, 11.366100E0, 11.382000E0, 11.397660E0, 11.413070E0, 11.428240E0, 11.443200E0, 11.457930E0, 11.472440E0, 11.486750E0, 11.500860E0, 11.514770E0, 11.528490E0, 11.542020E0, 11.555380E0, 11.568550E0,+11.581560E0, 11.594420E0, 11.607121E0, 11.619640E0, 11.632000E0, 11.644210E0, 11.656280E0, 11.668200E0, 11.679980E0, 11.691620E0, 11.703130E0, 11.714510E0, 11.725760E0, 11.736880E0, 11.747890E0, 11.758780E0, 11.769550E0, 11.780200E0, 11.790730E0, 11.801160E0, 11.811480E0, 11.821700E0, 11.831810E0, 11.841820E0, 11.851730E0, 11.861550E0, 11.871270E0, 11.880890E0, 11.890420E0, 11.899870E0, 11.909220E0, 11.918490E0, 11.927680E0, 11.936780E0, 11.945790E0, 11.954730E0, 11.963590E0, 11.972370E0, 11.981070E0, 11.989700E0, 11.998260E0, 12.006740E0, 12.015150E0, 12.023490E0, 12.031760E0, 12.039970E0, 12.048100E0, 12.056170E0, 12.064180E0, 12.072120E0, 12.080010E0, 12.087820E0, 12.095580E0, 12.103280E0, 12.110920E0, 12.118500E0, 12.126030E0, 12.133500E0, 12.140910E0, 12.148270E0, 12.155570E0, 12.162830E0, 12.170030E0, 12.177170E0, 12.184270E0, 12.191320E0, 12.198320E0, 12.205270E0, 12.212170E0, 12.219030E0, 12.225840E0, 12.232600E0, 12.239320E0, 12.245990E0, 12.252620E0, 12.259200E0, 12.265750E0, 12.272240E0 };+const double Bennett5_functor::y[154] = { -34.834702E0 ,-34.393200E0 ,-34.152901E0 ,-33.979099E0 ,-33.845901E0 ,-33.732899E0 ,-33.640301E0 ,-33.559200E0 ,-33.486801E0 ,-33.423100E0 ,-33.365101E0 ,-33.313000E0 ,-33.260899E0 ,-33.217400E0 ,-33.176899E0 ,-33.139198E0 ,-33.101601E0 ,-33.066799E0 ,-33.035000E0 ,-33.003101E0 ,-32.971298E0 ,-32.942299E0 ,-32.916302E0 ,-32.890202E0 ,-32.864101E0 ,-32.841000E0 ,-32.817799E0 ,-32.797501E0 ,-32.774300E0 ,-32.757000E0 ,-32.733799E0 ,-32.716400E0 ,-32.699100E0 ,-32.678799E0 ,-32.661400E0 ,-32.644001E0 ,-32.626701E0 ,-32.612202E0 ,-32.597698E0 ,-32.583199E0 ,-32.568699E0 ,-32.554298E0 ,-32.539799E0 ,-32.525299E0 ,-32.510799E0 ,-32.499199E0 ,-32.487598E0 ,-32.473202E0 ,-32.461601E0 ,-32.435501E0 ,-32.435501E0 ,-32.426800E0 ,-32.412300E0 ,-32.400799E0 ,-32.392101E0 ,-32.380501E0 ,-32.366001E0 ,-32.357300E0 ,-32.348598E0 ,-32.339901E0 ,-32.328400E0 ,-32.319698E0 ,-32.311001E0 ,-32.299400E0 ,-32.290699E0 ,-32.282001E0 ,-32.273300E0 ,-32.264599E0 ,-32.256001E0 ,-32.247299E0+,-32.238602E0 ,-32.229900E0 ,-32.224098E0 ,-32.215401E0 ,-32.203800E0 ,-32.198002E0 ,-32.189400E0 ,-32.183601E0 ,-32.174900E0 ,-32.169102E0 ,-32.163300E0 ,-32.154598E0 ,-32.145901E0 ,-32.140099E0 ,-32.131401E0 ,-32.125599E0 ,-32.119801E0 ,-32.111198E0 ,-32.105400E0 ,-32.096699E0 ,-32.090900E0 ,-32.088001E0 ,-32.079300E0 ,-32.073502E0 ,-32.067699E0 ,-32.061901E0 ,-32.056099E0 ,-32.050301E0 ,-32.044498E0 ,-32.038799E0 ,-32.033001E0 ,-32.027199E0 ,-32.024300E0 ,-32.018501E0 ,-32.012699E0 ,-32.004002E0 ,-32.001099E0 ,-31.995300E0 ,-31.989500E0 ,-31.983700E0 ,-31.977900E0 ,-31.972099E0 ,-31.969299E0 ,-31.963501E0 ,-31.957701E0 ,-31.951900E0 ,-31.946100E0 ,-31.940300E0 ,-31.937401E0 ,-31.931601E0 ,-31.925800E0 ,-31.922899E0 ,-31.917101E0 ,-31.911301E0 ,-31.908400E0 ,-31.902599E0 ,-31.896900E0 ,-31.893999E0 ,-31.888201E0 ,-31.885300E0 ,-31.882401E0 ,-31.876600E0 ,-31.873699E0 ,-31.867901E0 ,-31.862101E0 ,-31.859200E0 ,-31.856300E0 ,-31.850500E0 ,-31.844700E0 ,-31.841801E0 ,-31.838900E0 ,-31.833099E0 ,-31.830200E0 ,+-31.827299E0 ,-31.821600E0 ,-31.818701E0 ,-31.812901E0 ,-31.809999E0 ,-31.807100E0 ,-31.801300E0 ,-31.798401E0 ,-31.795500E0 ,-31.789700E0 ,-31.786800E0 };++// http://www.itl.nist.gov/div898/strd/nls/data/bennett5.shtml+void testNistBennett5(void)+{+ const int n=3;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< -2000., 50., 0.8;+ // do the computation+ Bennett5_functor functor;+ LevenbergMarquardt<Bennett5_functor> lm(functor);+ lm.parameters.maxfev = 1000;+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 758);+ VERIFY_IS_EQUAL(lm.njev, 744);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.2404744073E-04);+ // check x+ VERIFY_IS_APPROX(x[0], -2.5235058043E+03);+ VERIFY_IS_APPROX(x[1], 4.6736564644E+01);+ VERIFY_IS_APPROX(x[2], 9.3218483193E-01);+ /*+ * Second try+ */+ x<< -1500., 45., 0.85;+ // do the computation+ lm.resetParameters();+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 203);+ VERIFY_IS_EQUAL(lm.njev, 192);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.2404744073E-04);+ // check x+ VERIFY_IS_APPROX(x[0], -2523.3007865); // should be -2.5235058043E+03+ VERIFY_IS_APPROX(x[1], 46.735705771); // should be 4.6736564644E+01);+ VERIFY_IS_APPROX(x[2], 0.93219881891); // should be 9.3218483193E-01);+}++struct thurber_functor : Functor<double>+{+ thurber_functor(void) : Functor<double>(7,37) {}+ static const double _x[37];+ static const double _y[37];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ // int called=0; printf("call hahn1_functor with iflag=%d, called=%d\n", iflag, called); if (iflag==1) called++;+ assert(b.size()==7);+ assert(fvec.size()==37);+ for(int i=0; i<37; i++) {+ double x=_x[i], xx=x*x, xxx=xx*x;+ fvec[i] = (b[0]+b[1]*x+b[2]*xx+b[3]*xxx) / (1.+b[4]*x+b[5]*xx+b[6]*xxx) - _y[i];+ }+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==7);+ assert(fjac.rows()==37);+ assert(fjac.cols()==7);+ for(int i=0; i<37; i++) {+ double x=_x[i], xx=x*x, xxx=xx*x;+ double fact = 1./(1.+b[4]*x+b[5]*xx+b[6]*xxx);+ fjac(i,0) = 1.*fact;+ fjac(i,1) = x*fact;+ fjac(i,2) = xx*fact;+ fjac(i,3) = xxx*fact;+ fact = - (b[0]+b[1]*x+b[2]*xx+b[3]*xxx) * fact * fact;+ fjac(i,4) = x*fact;+ fjac(i,5) = xx*fact;+ fjac(i,6) = xxx*fact;+ }+ return 0;+ }+};+const double thurber_functor::_x[37] = { -3.067E0, -2.981E0, -2.921E0, -2.912E0, -2.840E0, -2.797E0, -2.702E0, -2.699E0, -2.633E0, -2.481E0, -2.363E0, -2.322E0, -1.501E0, -1.460E0, -1.274E0, -1.212E0, -1.100E0, -1.046E0, -0.915E0, -0.714E0, -0.566E0, -0.545E0, -0.400E0, -0.309E0, -0.109E0, -0.103E0, 0.010E0, 0.119E0, 0.377E0, 0.790E0, 0.963E0, 1.006E0, 1.115E0, 1.572E0, 1.841E0, 2.047E0, 2.200E0 };+const double thurber_functor::_y[37] = { 80.574E0, 84.248E0, 87.264E0, 87.195E0, 89.076E0, 89.608E0, 89.868E0, 90.101E0, 92.405E0, 95.854E0, 100.696E0, 101.060E0, 401.672E0, 390.724E0, 567.534E0, 635.316E0, 733.054E0, 759.087E0, 894.206E0, 990.785E0, 1090.109E0, 1080.914E0, 1122.643E0, 1178.351E0, 1260.531E0, 1273.514E0, 1288.339E0, 1327.543E0, 1353.863E0, 1414.509E0, 1425.208E0, 1421.384E0, 1442.962E0, 1464.350E0, 1468.705E0, 1447.894E0, 1457.628E0};++// http://www.itl.nist.gov/div898/strd/nls/data/thurber.shtml+void testNistThurber(void)+{+ const int n=7;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 1000 ,1000 ,400 ,40 ,0.7,0.3,0.0 ;+ // do the computation+ thurber_functor functor;+ LevenbergMarquardt<thurber_functor> lm(functor);+ lm.parameters.ftol = 1.E4*NumTraits<double>::epsilon();+ lm.parameters.xtol = 1.E4*NumTraits<double>::epsilon();+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 39);+ VERIFY_IS_EQUAL(lm.njev, 36);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.6427082397E+03);+ // check x+ VERIFY_IS_APPROX(x[0], 1.2881396800E+03);+ VERIFY_IS_APPROX(x[1], 1.4910792535E+03);+ VERIFY_IS_APPROX(x[2], 5.8323836877E+02);+ VERIFY_IS_APPROX(x[3], 7.5416644291E+01);+ VERIFY_IS_APPROX(x[4], 9.6629502864E-01);+ VERIFY_IS_APPROX(x[5], 3.9797285797E-01);+ VERIFY_IS_APPROX(x[6], 4.9727297349E-02);++ /*+ * Second try+ */+ x<< 1300 ,1500 ,500 ,75 ,1 ,0.4 ,0.05 ;+ // do the computation+ lm.resetParameters();+ lm.parameters.ftol = 1.E4*NumTraits<double>::epsilon();+ lm.parameters.xtol = 1.E4*NumTraits<double>::epsilon();+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 29);+ VERIFY_IS_EQUAL(lm.njev, 28);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 5.6427082397E+03);+ // check x+ VERIFY_IS_APPROX(x[0], 1.2881396800E+03);+ VERIFY_IS_APPROX(x[1], 1.4910792535E+03);+ VERIFY_IS_APPROX(x[2], 5.8323836877E+02);+ VERIFY_IS_APPROX(x[3], 7.5416644291E+01);+ VERIFY_IS_APPROX(x[4], 9.6629502864E-01);+ VERIFY_IS_APPROX(x[5], 3.9797285797E-01);+ VERIFY_IS_APPROX(x[6], 4.9727297349E-02);+}++struct rat43_functor : Functor<double>+{+ rat43_functor(void) : Functor<double>(4,15) {}+ static const double x[15];+ static const double y[15];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==4);+ assert(fvec.size()==15);+ for(int i=0; i<15; i++)+ fvec[i] = b[0] * pow(1.+exp(b[1]-b[2]*x[i]),-1./b[3]) - y[i];+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==4);+ assert(fjac.rows()==15);+ assert(fjac.cols()==4);+ for(int i=0; i<15; i++) {+ double e = exp(b[1]-b[2]*x[i]);+ double power = -1./b[3];+ fjac(i,0) = pow(1.+e, power);+ fjac(i,1) = power*b[0]*e*pow(1.+e, power-1.);+ fjac(i,2) = -power*b[0]*e*x[i]*pow(1.+e, power-1.);+ fjac(i,3) = b[0]*power*power*log(1.+e)*pow(1.+e, power);+ }+ return 0;+ }+};+const double rat43_functor::x[15] = { 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15. };+const double rat43_functor::y[15] = { 16.08, 33.83, 65.80, 97.20, 191.55, 326.20, 386.87, 520.53, 590.03, 651.92, 724.93, 699.56, 689.96, 637.56, 717.41 };++// http://www.itl.nist.gov/div898/strd/nls/data/ratkowsky3.shtml+void testNistRat43(void)+{+ const int n=4;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 100., 10., 1., 1.;+ // do the computation+ rat43_functor functor;+ LevenbergMarquardt<rat43_functor> lm(functor);+ lm.parameters.ftol = 1.E6*NumTraits<double>::epsilon();+ lm.parameters.xtol = 1.E6*NumTraits<double>::epsilon();+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 27);+ VERIFY_IS_EQUAL(lm.njev, 20);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8.7864049080E+03);+ // check x+ VERIFY_IS_APPROX(x[0], 6.9964151270E+02);+ VERIFY_IS_APPROX(x[1], 5.2771253025E+00);+ VERIFY_IS_APPROX(x[2], 7.5962938329E-01);+ VERIFY_IS_APPROX(x[3], 1.2792483859E+00);++ /*+ * Second try+ */+ x<< 700., 5., 0.75, 1.3;+ // do the computation+ lm.resetParameters();+ lm.parameters.ftol = 1.E5*NumTraits<double>::epsilon();+ lm.parameters.xtol = 1.E5*NumTraits<double>::epsilon();+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 9);+ VERIFY_IS_EQUAL(lm.njev, 8);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 8.7864049080E+03);+ // check x+ VERIFY_IS_APPROX(x[0], 6.9964151270E+02);+ VERIFY_IS_APPROX(x[1], 5.2771253025E+00);+ VERIFY_IS_APPROX(x[2], 7.5962938329E-01);+ VERIFY_IS_APPROX(x[3], 1.2792483859E+00);+}++++struct eckerle4_functor : Functor<double>+{+ eckerle4_functor(void) : Functor<double>(3,35) {}+ static const double x[35];+ static const double y[35];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==3);+ assert(fvec.size()==35);+ for(int i=0; i<35; i++)+ fvec[i] = b[0]/b[1] * exp(-0.5*(x[i]-b[2])*(x[i]-b[2])/(b[1]*b[1])) - y[i];+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==3);+ assert(fjac.rows()==35);+ assert(fjac.cols()==3);+ for(int i=0; i<35; i++) {+ double b12 = b[1]*b[1];+ double e = exp(-0.5*(x[i]-b[2])*(x[i]-b[2])/b12);+ fjac(i,0) = e / b[1];+ fjac(i,1) = ((x[i]-b[2])*(x[i]-b[2])/b12-1.) * b[0]*e/b12;+ fjac(i,2) = (x[i]-b[2])*e*b[0]/b[1]/b12;+ }+ return 0;+ }+};+const double eckerle4_functor::x[35] = { 400.0, 405.0, 410.0, 415.0, 420.0, 425.0, 430.0, 435.0, 436.5, 438.0, 439.5, 441.0, 442.5, 444.0, 445.5, 447.0, 448.5, 450.0, 451.5, 453.0, 454.5, 456.0, 457.5, 459.0, 460.5, 462.0, 463.5, 465.0, 470.0, 475.0, 480.0, 485.0, 490.0, 495.0, 500.0};+const double eckerle4_functor::y[35] = { 0.0001575, 0.0001699, 0.0002350, 0.0003102, 0.0004917, 0.0008710, 0.0017418, 0.0046400, 0.0065895, 0.0097302, 0.0149002, 0.0237310, 0.0401683, 0.0712559, 0.1264458, 0.2073413, 0.2902366, 0.3445623, 0.3698049, 0.3668534, 0.3106727, 0.2078154, 0.1164354, 0.0616764, 0.0337200, 0.0194023, 0.0117831, 0.0074357, 0.0022732, 0.0008800, 0.0004579, 0.0002345, 0.0001586, 0.0001143, 0.0000710 };++// http://www.itl.nist.gov/div898/strd/nls/data/eckerle4.shtml+void testNistEckerle4(void)+{+ const int n=3;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 1., 10., 500.;+ // do the computation+ eckerle4_functor functor;+ LevenbergMarquardt<eckerle4_functor> lm(functor);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 18);+ VERIFY_IS_EQUAL(lm.njev, 15);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.4635887487E-03);+ // check x+ VERIFY_IS_APPROX(x[0], 1.5543827178);+ VERIFY_IS_APPROX(x[1], 4.0888321754);+ VERIFY_IS_APPROX(x[2], 4.5154121844E+02);++ /*+ * Second try+ */+ x<< 1.5, 5., 450.;+ // do the computation+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev, 7);+ VERIFY_IS_EQUAL(lm.njev, 6);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec.squaredNorm(), 1.4635887487E-03);+ // check x+ VERIFY_IS_APPROX(x[0], 1.5543827178);+ VERIFY_IS_APPROX(x[1], 4.0888321754);+ VERIFY_IS_APPROX(x[2], 4.5154121844E+02);+}++void test_NonLinearOptimization()+{+ // Tests using the examples provided by (c)minpack+ CALL_SUBTEST/*_1*/(testChkder());+ CALL_SUBTEST/*_1*/(testLmder1());+ CALL_SUBTEST/*_1*/(testLmder());+ CALL_SUBTEST/*_2*/(testHybrj1());+ CALL_SUBTEST/*_2*/(testHybrj());+ CALL_SUBTEST/*_2*/(testHybrd1());+ CALL_SUBTEST/*_2*/(testHybrd());+ CALL_SUBTEST/*_3*/(testLmstr1());+ CALL_SUBTEST/*_3*/(testLmstr());+ CALL_SUBTEST/*_3*/(testLmdif1());+ CALL_SUBTEST/*_3*/(testLmdif());++ // NIST tests, level of difficulty = "Lower"+ CALL_SUBTEST/*_4*/(testNistMisra1a());+ CALL_SUBTEST/*_4*/(testNistChwirut2());++ // NIST tests, level of difficulty = "Average"+ CALL_SUBTEST/*_5*/(testNistHahn1());+ CALL_SUBTEST/*_6*/(testNistMisra1d());+// CALL_SUBTEST/*_7*/(testNistMGH17());+// CALL_SUBTEST/*_8*/(testNistLanczos1());++// // NIST tests, level of difficulty = "Higher"+ CALL_SUBTEST/*_9*/(testNistRat42());+// CALL_SUBTEST/*_10*/(testNistMGH10());+ CALL_SUBTEST/*_11*/(testNistBoxBOD());+// CALL_SUBTEST/*_12*/(testNistMGH09());+ CALL_SUBTEST/*_13*/(testNistBennett5());+ CALL_SUBTEST/*_14*/(testNistThurber());+ CALL_SUBTEST/*_15*/(testNistRat43());+ CALL_SUBTEST/*_16*/(testNistEckerle4());+}++/*+ * Can be useful for debugging...+ printf("info, nfev : %d, %d\n", info, lm.nfev);+ printf("info, nfev, njev : %d, %d, %d\n", info, solver.nfev, solver.njev);+ printf("info, nfev : %d, %d\n", info, solver.nfev);+ printf("x[0] : %.32g\n", x[0]);+ printf("x[1] : %.32g\n", x[1]);+ printf("x[2] : %.32g\n", x[2]);+ printf("x[3] : %.32g\n", x[3]);+ printf("fvec.blueNorm() : %.32g\n", solver.fvec.blueNorm());+ printf("fvec.blueNorm() : %.32g\n", lm.fvec.blueNorm());++ printf("info, nfev, njev : %d, %d, %d\n", info, lm.nfev, lm.njev);+ printf("fvec.squaredNorm() : %.13g\n", lm.fvec.squaredNorm());+ std::cout << x << std::endl;+ std::cout.precision(9);+ std::cout << x[0] << std::endl;+ std::cout << x[1] << std::endl;+ std::cout << x[2] << std::endl;+ std::cout << x[3] << std::endl;+*/+
+ eigen3/unsupported/test/NumericalDiff.cpp view
@@ -0,0 +1,114 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>++#include <stdio.h>++#include "main.h"+#include <unsupported/Eigen/NumericalDiff>+ +// Generic functor+template<typename _Scalar, int NX=Dynamic, int NY=Dynamic>+struct Functor+{+ typedef _Scalar Scalar;+ enum {+ InputsAtCompileTime = NX,+ ValuesAtCompileTime = NY+ };+ typedef Matrix<Scalar,InputsAtCompileTime,1> InputType;+ typedef Matrix<Scalar,ValuesAtCompileTime,1> ValueType;+ typedef Matrix<Scalar,ValuesAtCompileTime,InputsAtCompileTime> JacobianType;+ + int m_inputs, m_values;+ + Functor() : m_inputs(InputsAtCompileTime), m_values(ValuesAtCompileTime) {}+ Functor(int inputs, int values) : m_inputs(inputs), m_values(values) {}+ + int inputs() const { return m_inputs; }+ int values() const { return m_values; }++};++struct my_functor : Functor<double>+{+ my_functor(void): Functor<double>(3,15) {}+ int operator()(const VectorXd &x, VectorXd &fvec) const+ {+ double tmp1, tmp2, tmp3;+ double y[15] = {1.4e-1, 1.8e-1, 2.2e-1, 2.5e-1, 2.9e-1, 3.2e-1, 3.5e-1,+ 3.9e-1, 3.7e-1, 5.8e-1, 7.3e-1, 9.6e-1, 1.34, 2.1, 4.39};++ for (int i = 0; i < values(); i++)+ {+ tmp1 = i+1;+ tmp2 = 16 - i - 1;+ tmp3 = (i>=8)? tmp2 : tmp1;+ fvec[i] = y[i] - (x[0] + tmp1/(x[1]*tmp2 + x[2]*tmp3));+ }+ return 0;+ }++ int actual_df(const VectorXd &x, MatrixXd &fjac) const+ {+ double tmp1, tmp2, tmp3, tmp4;+ for (int i = 0; i < values(); i++)+ {+ tmp1 = i+1;+ tmp2 = 16 - i - 1;+ tmp3 = (i>=8)? tmp2 : tmp1;+ tmp4 = (x[1]*tmp2 + x[2]*tmp3); tmp4 = tmp4*tmp4;+ fjac(i,0) = -1;+ fjac(i,1) = tmp1*tmp2/tmp4;+ fjac(i,2) = tmp1*tmp3/tmp4;+ }+ return 0;+ }+};++void test_forward()+{+ VectorXd x(3);+ MatrixXd jac(15,3);+ MatrixXd actual_jac(15,3);+ my_functor functor;++ x << 0.082, 1.13, 2.35;++ // real one + functor.actual_df(x, actual_jac);+// std::cout << actual_jac << std::endl << std::endl;++ // using NumericalDiff+ NumericalDiff<my_functor> numDiff(functor);+ numDiff.df(x, jac);+// std::cout << jac << std::endl;++ VERIFY_IS_APPROX(jac, actual_jac);+}++void test_central()+{+ VectorXd x(3);+ MatrixXd jac(15,3);+ MatrixXd actual_jac(15,3);+ my_functor functor;++ x << 0.082, 1.13, 2.35;++ // real one + functor.actual_df(x, actual_jac);++ // using NumericalDiff+ NumericalDiff<my_functor,Central> numDiff(functor);+ numDiff.df(x, jac);++ VERIFY_IS_APPROX(jac, actual_jac);+}++void test_NumericalDiff()+{+ CALL_SUBTEST(test_forward());+ CALL_SUBTEST(test_central());+}
+ eigen3/unsupported/test/alignedvector3.cpp view
@@ -0,0 +1,59 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <unsupported/Eigen/AlignedVector3>++template<typename Scalar>+void alignedvector3()+{+ Scalar s1 = internal::random<Scalar>();+ Scalar s2 = internal::random<Scalar>();+ typedef Matrix<Scalar,3,1> RefType;+ typedef Matrix<Scalar,3,3> Mat33;+ typedef AlignedVector3<Scalar> FastType;+ RefType r1(RefType::Random()), r2(RefType::Random()), r3(RefType::Random()),+ r4(RefType::Random()), r5(RefType::Random()), r6(RefType::Random());+ FastType f1(r1), f2(r2), f3(r3), f4(r4), f5(r5), f6(r6);+ Mat33 m1(Mat33::Random());+ + VERIFY_IS_APPROX(f1,r1);+ VERIFY_IS_APPROX(f4,r4);++ VERIFY_IS_APPROX(f4+f1,r4+r1);+ VERIFY_IS_APPROX(f4-f1,r4-r1);+ VERIFY_IS_APPROX(f4+f1-f2,r4+r1-r2);+ VERIFY_IS_APPROX(f4+=f3,r4+=r3);+ VERIFY_IS_APPROX(f4-=f5,r4-=r5);+ VERIFY_IS_APPROX(f4-=f5+f1,r4-=r5+r1);+ VERIFY_IS_APPROX(f5+f1-s1*f2,r5+r1-s1*r2);+ VERIFY_IS_APPROX(f5+f1/s2-s1*f2,r5+r1/s2-s1*r2);+ + VERIFY_IS_APPROX(m1*f4,m1*r4);+ VERIFY_IS_APPROX(f4.transpose()*m1,r4.transpose()*m1);+ + VERIFY_IS_APPROX(f2.dot(f3),r2.dot(r3));+ VERIFY_IS_APPROX(f2.cross(f3),r2.cross(r3));+ VERIFY_IS_APPROX(f2.norm(),r2.norm());++ VERIFY_IS_APPROX(f2.normalized(),r2.normalized());++ VERIFY_IS_APPROX((f2+f1).normalized(),(r2+r1).normalized());+ + f2.normalize();+ r2.normalize();+ VERIFY_IS_APPROX(f2,r2);+}++void test_alignedvector3()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST( alignedvector3<float>() );+ }+}
+ eigen3/unsupported/test/autodiff.cpp view
@@ -0,0 +1,173 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <unsupported/Eigen/AutoDiff>++template<typename Scalar>+EIGEN_DONT_INLINE Scalar foo(const Scalar& x, const Scalar& y)+{+ using namespace std;+// return x+std::sin(y);+ EIGEN_ASM_COMMENT("mybegin");+ return static_cast<Scalar>(x*2 - pow(x,2) + 2*sqrt(y*y) - 4 * sin(x) + 2 * cos(y) - exp(-0.5*x*x));+ //return x+2*y*x;//x*2 -std::pow(x,2);//(2*y/x);// - y*2;+ EIGEN_ASM_COMMENT("myend");+}++template<typename Vector>+EIGEN_DONT_INLINE typename Vector::Scalar foo(const Vector& p)+{+ typedef typename Vector::Scalar Scalar;+ return (p-Vector(Scalar(-1),Scalar(1.))).norm() + (p.array() * p.array()).sum() + p.dot(p);+}++template<typename _Scalar, int NX=Dynamic, int NY=Dynamic>+struct TestFunc1+{+ typedef _Scalar Scalar;+ enum {+ InputsAtCompileTime = NX,+ ValuesAtCompileTime = NY+ };+ typedef Matrix<Scalar,InputsAtCompileTime,1> InputType;+ typedef Matrix<Scalar,ValuesAtCompileTime,1> ValueType;+ typedef Matrix<Scalar,ValuesAtCompileTime,InputsAtCompileTime> JacobianType;++ int m_inputs, m_values;++ TestFunc1() : m_inputs(InputsAtCompileTime), m_values(ValuesAtCompileTime) {}+ TestFunc1(int inputs, int values) : m_inputs(inputs), m_values(values) {}++ int inputs() const { return m_inputs; }+ int values() const { return m_values; }++ template<typename T>+ void operator() (const Matrix<T,InputsAtCompileTime,1>& x, Matrix<T,ValuesAtCompileTime,1>* _v) const+ {+ Matrix<T,ValuesAtCompileTime,1>& v = *_v;++ v[0] = 2 * x[0] * x[0] + x[0] * x[1];+ v[1] = 3 * x[1] * x[0] + 0.5 * x[1] * x[1];+ if(inputs()>2)+ {+ v[0] += 0.5 * x[2];+ v[1] += x[2];+ }+ if(values()>2)+ {+ v[2] = 3 * x[1] * x[0] * x[0];+ }+ if (inputs()>2 && values()>2)+ v[2] *= x[2];+ }++ void operator() (const InputType& x, ValueType* v, JacobianType* _j) const+ {+ (*this)(x, v);++ if(_j)+ {+ JacobianType& j = *_j;++ j(0,0) = 4 * x[0] + x[1];+ j(1,0) = 3 * x[1];++ j(0,1) = x[0];+ j(1,1) = 3 * x[0] + 2 * 0.5 * x[1];++ if (inputs()>2)+ {+ j(0,2) = 0.5;+ j(1,2) = 1;+ }+ if(values()>2)+ {+ j(2,0) = 3 * x[1] * 2 * x[0];+ j(2,1) = 3 * x[0] * x[0];+ }+ if (inputs()>2 && values()>2)+ {+ j(2,0) *= x[2];+ j(2,1) *= x[2];++ j(2,2) = 3 * x[1] * x[0] * x[0];+ j(2,2) = 3 * x[1] * x[0] * x[0];+ }+ }+ }+};++template<typename Func> void forward_jacobian(const Func& f)+{+ typename Func::InputType x = Func::InputType::Random(f.inputs());+ typename Func::ValueType y(f.values()), yref(f.values());+ typename Func::JacobianType j(f.values(),f.inputs()), jref(f.values(),f.inputs());++ jref.setZero();+ yref.setZero();+ f(x,&yref,&jref);+// std::cerr << y.transpose() << "\n\n";;+// std::cerr << j << "\n\n";;++ j.setZero();+ y.setZero();+ AutoDiffJacobian<Func> autoj(f);+ autoj(x, &y, &j);+// std::cerr << y.transpose() << "\n\n";;+// std::cerr << j << "\n\n";;++ VERIFY_IS_APPROX(y, yref);+ VERIFY_IS_APPROX(j, jref);+}+++// TODO also check actual derivatives!+void test_autodiff_scalar()+{+ Vector2f p = Vector2f::Random();+ typedef AutoDiffScalar<Vector2f> AD;+ AD ax(p.x(),Vector2f::UnitX());+ AD ay(p.y(),Vector2f::UnitY());+ AD res = foo<AD>(ax,ay);+ VERIFY_IS_APPROX(res.value(), foo(p.x(),p.y()));+}++// TODO also check actual derivatives!+void test_autodiff_vector()+{+ Vector2f p = Vector2f::Random();+ typedef AutoDiffScalar<Vector2f> AD;+ typedef Matrix<AD,2,1> VectorAD;+ VectorAD ap = p.cast<AD>();+ ap.x().derivatives() = Vector2f::UnitX();+ ap.y().derivatives() = Vector2f::UnitY();+ + AD res = foo<VectorAD>(ap);+ VERIFY_IS_APPROX(res.value(), foo(p));+}++void test_autodiff_jacobian()+{+ CALL_SUBTEST(( forward_jacobian(TestFunc1<double,2,2>()) ));+ CALL_SUBTEST(( forward_jacobian(TestFunc1<double,2,3>()) ));+ CALL_SUBTEST(( forward_jacobian(TestFunc1<double,3,2>()) ));+ CALL_SUBTEST(( forward_jacobian(TestFunc1<double,3,3>()) ));+ CALL_SUBTEST(( forward_jacobian(TestFunc1<double>(3,3)) ));+}++void test_autodiff()+{+ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1( test_autodiff_scalar() );+ CALL_SUBTEST_2( test_autodiff_vector() );+ CALL_SUBTEST_3( test_autodiff_jacobian() );+ }+}+
+ eigen3/unsupported/test/bdcsvd.cpp view
@@ -0,0 +1,213 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2013 Gauthier Brun <brun.gauthier@gmail.com>+// Copyright (C) 2013 Nicolas Carre <nicolas.carre@ensimag.fr>+// Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>+// Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/++#include "svd_common.h"+#include <iostream>+#include <Eigen/LU>++// check if "svd" is the good image of "m" +template<typename MatrixType>+void bdcsvd_check_full(const MatrixType& m, const BDCSVD<MatrixType>& svd)+{+ svd_check_full< MatrixType, BDCSVD< MatrixType > >(m, svd);+}++// Compare to a reference value+template<typename MatrixType>+void bdcsvd_compare_to_full(const MatrixType& m,+ unsigned int computationOptions,+ const BDCSVD<MatrixType>& referenceSvd)+{+ svd_compare_to_full< MatrixType, BDCSVD< MatrixType > >(m, computationOptions, referenceSvd);+} // end bdcsvd_compare_to_full+++template<typename MatrixType>+void bdcsvd_solve(const MatrixType& m, unsigned int computationOptions)+{+ svd_solve< MatrixType, BDCSVD< MatrixType > >(m, computationOptions);+} // end template bdcsvd_solve+++// test the computations options+template<typename MatrixType>+void bdcsvd_test_all_computation_options(const MatrixType& m)+{+ BDCSVD<MatrixType> fullSvd(m, ComputeFullU|ComputeFullV);+ svd_test_computation_options_1< MatrixType, BDCSVD< MatrixType > >(m, fullSvd); + svd_test_computation_options_2< MatrixType, BDCSVD< MatrixType > >(m, fullSvd); +} // end bdcsvd_test_all_computation_options+++// Call a test with all the computations options+template<typename MatrixType>+void bdcsvd(const MatrixType& a = MatrixType(), bool pickrandom = true)+{+ MatrixType m = pickrandom ? MatrixType::Random(a.rows(), a.cols()) : a;+ bdcsvd_test_all_computation_options<MatrixType>(m);+} // end template bdcsvd+++// verify assert+template<typename MatrixType> +void bdcsvd_verify_assert(const MatrixType& m)+{+ svd_verify_assert< MatrixType, BDCSVD< MatrixType > >(m);+}// end template bdcsvd_verify_assert+++// test weird values+template<typename MatrixType>+void bdcsvd_inf_nan()+{+ svd_inf_nan< MatrixType, BDCSVD< MatrixType > >();+}// end template bdcsvd_inf_nan++++void bdcsvd_preallocate()+{+ svd_preallocate< BDCSVD< MatrixXf > >();+} // end bdcsvd_preallocate+++// compare the Singular values returned with Jacobi and Bdc+template<typename MatrixType> +void compare_bdc_jacobi(const MatrixType& a = MatrixType(), unsigned int computationOptions = 0)+{+ std::cout << "debut compare" << std::endl;+ MatrixType m = MatrixType::Random(a.rows(), a.cols());+ BDCSVD<MatrixType> bdc_svd(m);+ JacobiSVD<MatrixType> jacobi_svd(m);+ VERIFY_IS_APPROX(bdc_svd.singularValues(), jacobi_svd.singularValues());+ if(computationOptions & ComputeFullU)+ VERIFY_IS_APPROX(bdc_svd.matrixU(), jacobi_svd.matrixU());+ if(computationOptions & ComputeThinU)+ VERIFY_IS_APPROX(bdc_svd.matrixU(), jacobi_svd.matrixU());+ if(computationOptions & ComputeFullV)+ VERIFY_IS_APPROX(bdc_svd.matrixV(), jacobi_svd.matrixV());+ if(computationOptions & ComputeThinV)+ VERIFY_IS_APPROX(bdc_svd.matrixV(), jacobi_svd.matrixV());+ std::cout << "fin compare" << std::endl;+} // end template compare_bdc_jacobi+++// call the tests+void test_bdcsvd()+{+ // test of Dynamic defined Matrix (42, 42) of float + CALL_SUBTEST_11(( bdcsvd_verify_assert<Matrix<float,Dynamic,Dynamic> >+ (Matrix<float,Dynamic,Dynamic>(42,42)) ));+ CALL_SUBTEST_11(( compare_bdc_jacobi<Matrix<float,Dynamic,Dynamic> >+ (Matrix<float,Dynamic,Dynamic>(42,42), 0) ));+ CALL_SUBTEST_11(( bdcsvd<Matrix<float,Dynamic,Dynamic> >+ (Matrix<float,Dynamic,Dynamic>(42,42)) ));++ // test of Dynamic defined Matrix (50, 50) of double + CALL_SUBTEST_13(( bdcsvd_verify_assert<Matrix<double,Dynamic,Dynamic> >+ (Matrix<double,Dynamic,Dynamic>(50,50)) ));+ CALL_SUBTEST_13(( compare_bdc_jacobi<Matrix<double,Dynamic,Dynamic> >+ (Matrix<double,Dynamic,Dynamic>(50,50), 0) ));+ CALL_SUBTEST_13(( bdcsvd<Matrix<double,Dynamic,Dynamic> >+ (Matrix<double,Dynamic,Dynamic>(50, 50)) )); ++ // test of Dynamic defined Matrix (22, 22) of complex double+ CALL_SUBTEST_14(( bdcsvd_verify_assert<Matrix<std::complex<double>,Dynamic,Dynamic> >+ (Matrix<std::complex<double>,Dynamic,Dynamic>(22,22)) ));+ CALL_SUBTEST_14(( compare_bdc_jacobi<Matrix<std::complex<double>,Dynamic,Dynamic> >+ (Matrix<std::complex<double>, Dynamic, Dynamic> (22,22), 0) ));+ CALL_SUBTEST_14(( bdcsvd<Matrix<std::complex<double>,Dynamic,Dynamic> >+ (Matrix<std::complex<double>,Dynamic,Dynamic>(22, 22)) )); ++ // test of Dynamic defined Matrix (10, 10) of int+ //CALL_SUBTEST_15(( bdcsvd_verify_assert<Matrix<int,Dynamic,Dynamic> >+ // (Matrix<int,Dynamic,Dynamic>(10,10)) )); + //CALL_SUBTEST_15(( compare_bdc_jacobi<Matrix<int,Dynamic,Dynamic> >+ // (Matrix<int,Dynamic,Dynamic>(10,10), 0) ));+ //CALL_SUBTEST_15(( bdcsvd<Matrix<int,Dynamic,Dynamic> >+ // (Matrix<int,Dynamic,Dynamic>(10, 10)) )); + ++ // test of Dynamic defined Matrix (8, 6) of double + + CALL_SUBTEST_16(( bdcsvd_verify_assert<Matrix<double,Dynamic,Dynamic> >+ (Matrix<double,Dynamic,Dynamic>(8,6)) ));+ CALL_SUBTEST_16(( compare_bdc_jacobi<Matrix<double,Dynamic,Dynamic> >+ (Matrix<double,Dynamic,Dynamic>(8, 6), 0) )); + CALL_SUBTEST_16(( bdcsvd<Matrix<double,Dynamic,Dynamic> >+ (Matrix<double,Dynamic,Dynamic>(8, 6)) ));+++ + // test of Dynamic defined Matrix (36, 12) of float+ CALL_SUBTEST_17(( compare_bdc_jacobi<Matrix<float,Dynamic,Dynamic> >+ (Matrix<float,Dynamic,Dynamic>(36, 12), 0) )); + CALL_SUBTEST_17(( bdcsvd<Matrix<float,Dynamic,Dynamic> >+ (Matrix<float,Dynamic,Dynamic>(36, 12)) )); ++ // test of Dynamic defined Matrix (5, 8) of double + CALL_SUBTEST_18(( compare_bdc_jacobi<Matrix<double,Dynamic,Dynamic> >+ (Matrix<double,Dynamic,Dynamic>(5, 8), 0) )); + CALL_SUBTEST_18(( bdcsvd<Matrix<double,Dynamic,Dynamic> >+ (Matrix<double,Dynamic,Dynamic>(5, 8)) )); +++ // non regression tests+ CALL_SUBTEST_3(( bdcsvd_verify_assert(Matrix3f()) ));+ CALL_SUBTEST_4(( bdcsvd_verify_assert(Matrix4d()) ));+ CALL_SUBTEST_7(( bdcsvd_verify_assert(MatrixXf(10,12)) ));+ CALL_SUBTEST_8(( bdcsvd_verify_assert(MatrixXcd(7,5)) ));++ // SUBTESTS 1 and 2 on specifics matrix+ for(int i = 0; i < g_repeat; i++) {+ Matrix2cd m;+ m << 0, 1,+ 0, 1;+ CALL_SUBTEST_1(( bdcsvd(m, false) ));+ m << 1, 0,+ 1, 0;+ CALL_SUBTEST_1(( bdcsvd(m, false) ));++ Matrix2d n;+ n << 0, 0,+ 0, 0;+ CALL_SUBTEST_2(( bdcsvd(n, false) ));+ n << 0, 0,+ 0, 1;+ CALL_SUBTEST_2(( bdcsvd(n, false) ));+ + // Statics matrix don't work with BDSVD yet+ // bdc algo on a random 3x3 float matrix+ // CALL_SUBTEST_3(( bdcsvd<Matrix3f>() ));+ // bdc algo on a random 4x4 double matrix+ // CALL_SUBTEST_4(( bdcsvd<Matrix4d>() ));+ // bdc algo on a random 3x5 float matrix+ // CALL_SUBTEST_5(( bdcsvd<Matrix<float,3,5> >() ));++ int r = internal::random<int>(1, 30),+ c = internal::random<int>(1, 30);+ CALL_SUBTEST_7(( bdcsvd<MatrixXf>(MatrixXf(r,c)) ));+ CALL_SUBTEST_8(( bdcsvd<MatrixXcd>(MatrixXcd(r,c)) ));+ (void) r;+ (void) c;++ // Test on inf/nan matrix+ CALL_SUBTEST_7( bdcsvd_inf_nan<MatrixXf>() );+ }++ CALL_SUBTEST_7(( bdcsvd<MatrixXf>(MatrixXf(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2))) ));+ CALL_SUBTEST_8(( bdcsvd<MatrixXcd>(MatrixXcd(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/3), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/3))) ));++ // Test problem size constructors+ CALL_SUBTEST_7( BDCSVD<MatrixXf>(10,10) );++} // end test_bdcsvd
+ eigen3/unsupported/test/dgmres.cpp view
@@ -0,0 +1,31 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>+// Copyright (C) 2012 desire Nuentsa <desire.nuentsa_wakam@inria.fr+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "../../test/sparse_solver.h"+#include <Eigen/src/IterativeSolvers/DGMRES.h>++template<typename T> void test_dgmres_T()+{+ DGMRES<SparseMatrix<T>, DiagonalPreconditioner<T> > dgmres_colmajor_diag;+ DGMRES<SparseMatrix<T>, IdentityPreconditioner > dgmres_colmajor_I;+ DGMRES<SparseMatrix<T>, IncompleteLUT<T> > dgmres_colmajor_ilut;+ //GMRES<SparseMatrix<T>, SSORPreconditioner<T> > dgmres_colmajor_ssor;++ CALL_SUBTEST( check_sparse_square_solving(dgmres_colmajor_diag) );+// CALL_SUBTEST( check_sparse_square_solving(dgmres_colmajor_I) );+ CALL_SUBTEST( check_sparse_square_solving(dgmres_colmajor_ilut) );+ //CALL_SUBTEST( check_sparse_square_solving(dgmres_colmajor_ssor) );+}++void test_dgmres()+{+ CALL_SUBTEST_1(test_dgmres_T<double>());+ CALL_SUBTEST_2(test_dgmres_T<std::complex<double> >());+}
+ eigen3/unsupported/test/forward_adolc.cpp view
@@ -0,0 +1,143 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <Eigen/Dense>++#define NUMBER_DIRECTIONS 16+#include <unsupported/Eigen/AdolcForward>++int adtl::ADOLC_numDir;++template<typename Vector>+EIGEN_DONT_INLINE typename Vector::Scalar foo(const Vector& p)+{+ typedef typename Vector::Scalar Scalar;+ return (p-Vector(Scalar(-1),Scalar(1.))).norm() + (p.array().sqrt().abs() * p.array().sin()).sum() + p.dot(p);+}++template<typename _Scalar, int NX=Dynamic, int NY=Dynamic>+struct TestFunc1+{+ typedef _Scalar Scalar;+ enum {+ InputsAtCompileTime = NX,+ ValuesAtCompileTime = NY+ };+ typedef Matrix<Scalar,InputsAtCompileTime,1> InputType;+ typedef Matrix<Scalar,ValuesAtCompileTime,1> ValueType;+ typedef Matrix<Scalar,ValuesAtCompileTime,InputsAtCompileTime> JacobianType;++ int m_inputs, m_values;++ TestFunc1() : m_inputs(InputsAtCompileTime), m_values(ValuesAtCompileTime) {}+ TestFunc1(int inputs, int values) : m_inputs(inputs), m_values(values) {}++ int inputs() const { return m_inputs; }+ int values() const { return m_values; }++ template<typename T>+ void operator() (const Matrix<T,InputsAtCompileTime,1>& x, Matrix<T,ValuesAtCompileTime,1>* _v) const+ {+ Matrix<T,ValuesAtCompileTime,1>& v = *_v;++ v[0] = 2 * x[0] * x[0] + x[0] * x[1];+ v[1] = 3 * x[1] * x[0] + 0.5 * x[1] * x[1];+ if(inputs()>2)+ {+ v[0] += 0.5 * x[2];+ v[1] += x[2];+ }+ if(values()>2)+ {+ v[2] = 3 * x[1] * x[0] * x[0];+ }+ if (inputs()>2 && values()>2)+ v[2] *= x[2];+ }++ void operator() (const InputType& x, ValueType* v, JacobianType* _j) const+ {+ (*this)(x, v);++ if(_j)+ {+ JacobianType& j = *_j;++ j(0,0) = 4 * x[0] + x[1];+ j(1,0) = 3 * x[1];++ j(0,1) = x[0];+ j(1,1) = 3 * x[0] + 2 * 0.5 * x[1];++ if (inputs()>2)+ {+ j(0,2) = 0.5;+ j(1,2) = 1;+ }+ if(values()>2)+ {+ j(2,0) = 3 * x[1] * 2 * x[0];+ j(2,1) = 3 * x[0] * x[0];+ }+ if (inputs()>2 && values()>2)+ {+ j(2,0) *= x[2];+ j(2,1) *= x[2];++ j(2,2) = 3 * x[1] * x[0] * x[0];+ j(2,2) = 3 * x[1] * x[0] * x[0];+ }+ }+ }+};++template<typename Func> void adolc_forward_jacobian(const Func& f)+{+ typename Func::InputType x = Func::InputType::Random(f.inputs());+ typename Func::ValueType y(f.values()), yref(f.values());+ typename Func::JacobianType j(f.values(),f.inputs()), jref(f.values(),f.inputs());++ jref.setZero();+ yref.setZero();+ f(x,&yref,&jref);+// std::cerr << y.transpose() << "\n\n";;+// std::cerr << j << "\n\n";;++ j.setZero();+ y.setZero();+ AdolcForwardJacobian<Func> autoj(f);+ autoj(x, &y, &j);+// std::cerr << y.transpose() << "\n\n";;+// std::cerr << j << "\n\n";;++ VERIFY_IS_APPROX(y, yref);+ VERIFY_IS_APPROX(j, jref);+}++void test_forward_adolc()+{+ adtl::ADOLC_numDir = NUMBER_DIRECTIONS;++ for(int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST(( adolc_forward_jacobian(TestFunc1<double,2,2>()) ));+ CALL_SUBTEST(( adolc_forward_jacobian(TestFunc1<double,2,3>()) ));+ CALL_SUBTEST(( adolc_forward_jacobian(TestFunc1<double,3,2>()) ));+ CALL_SUBTEST(( adolc_forward_jacobian(TestFunc1<double,3,3>()) ));+ CALL_SUBTEST(( adolc_forward_jacobian(TestFunc1<double>(3,3)) ));+ }++ {+ // simple instanciation tests+ Matrix<adtl::adouble,2,1> x;+ foo(x);+ Matrix<adtl::adouble,Dynamic,Dynamic> A(4,4);;+ A.selfadjointView<Lower>().eigenvalues();+ }+}
+ eigen3/unsupported/test/gmres.cpp view
@@ -0,0 +1,31 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>+// Copyright (C) 2012 Kolja Brix <brix@igpm.rwth-aaachen.de>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "../../test/sparse_solver.h"+#include <Eigen/IterativeSolvers>++template<typename T> void test_gmres_T()+{+ GMRES<SparseMatrix<T>, DiagonalPreconditioner<T> > gmres_colmajor_diag;+ GMRES<SparseMatrix<T>, IdentityPreconditioner > gmres_colmajor_I;+ GMRES<SparseMatrix<T>, IncompleteLUT<T> > gmres_colmajor_ilut;+ //GMRES<SparseMatrix<T>, SSORPreconditioner<T> > gmres_colmajor_ssor;++ CALL_SUBTEST( check_sparse_square_solving(gmres_colmajor_diag) );+// CALL_SUBTEST( check_sparse_square_solving(gmres_colmajor_I) );+ CALL_SUBTEST( check_sparse_square_solving(gmres_colmajor_ilut) );+ //CALL_SUBTEST( check_sparse_square_solving(gmres_colmajor_ssor) );+}++void test_gmres()+{+ CALL_SUBTEST_1(test_gmres_T<double>());+ CALL_SUBTEST_2(test_gmres_T<std::complex<double> >());+}
+ eigen3/unsupported/test/jacobisvd.cpp view
@@ -0,0 +1,198 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "svd_common.h"++template<typename MatrixType, int QRPreconditioner>+void jacobisvd_check_full(const MatrixType& m, const JacobiSVD<MatrixType, QRPreconditioner>& svd)+{+ svd_check_full<MatrixType, JacobiSVD<MatrixType, QRPreconditioner > >(m, svd);+}++template<typename MatrixType, int QRPreconditioner>+void jacobisvd_compare_to_full(const MatrixType& m,+ unsigned int computationOptions,+ const JacobiSVD<MatrixType, QRPreconditioner>& referenceSvd)+{+ svd_compare_to_full<MatrixType, JacobiSVD<MatrixType, QRPreconditioner> >(m, computationOptions, referenceSvd);+}+++template<typename MatrixType, int QRPreconditioner>+void jacobisvd_solve(const MatrixType& m, unsigned int computationOptions)+{+ svd_solve< MatrixType, JacobiSVD< MatrixType, QRPreconditioner > >(m, computationOptions);+}++++template<typename MatrixType, int QRPreconditioner>+void jacobisvd_test_all_computation_options(const MatrixType& m)+{+ + if (QRPreconditioner == NoQRPreconditioner && m.rows() != m.cols())+ return;++ JacobiSVD< MatrixType, QRPreconditioner > fullSvd(m, ComputeFullU|ComputeFullV);+ svd_test_computation_options_1< MatrixType, JacobiSVD< MatrixType, QRPreconditioner > >(m, fullSvd);++ if(QRPreconditioner == FullPivHouseholderQRPreconditioner)+ return;+ svd_test_computation_options_2< MatrixType, JacobiSVD< MatrixType, QRPreconditioner > >(m, fullSvd);++}++template<typename MatrixType>+void jacobisvd(const MatrixType& a = MatrixType(), bool pickrandom = true)+{+ MatrixType m = pickrandom ? MatrixType::Random(a.rows(), a.cols()) : a;++ jacobisvd_test_all_computation_options<MatrixType, FullPivHouseholderQRPreconditioner>(m);+ jacobisvd_test_all_computation_options<MatrixType, ColPivHouseholderQRPreconditioner>(m);+ jacobisvd_test_all_computation_options<MatrixType, HouseholderQRPreconditioner>(m);+ jacobisvd_test_all_computation_options<MatrixType, NoQRPreconditioner>(m);+}+++template<typename MatrixType> +void jacobisvd_verify_assert(const MatrixType& m)+{+ + svd_verify_assert<MatrixType, JacobiSVD< MatrixType > >(m);++ typedef typename MatrixType::Index Index;+ Index rows = m.rows();+ Index cols = m.cols();++ enum {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,+ ColsAtCompileTime = MatrixType::ColsAtCompileTime+ };++ MatrixType a = MatrixType::Zero(rows, cols);+ a.setZero();++ if (ColsAtCompileTime == Dynamic)+ {+ JacobiSVD<MatrixType, FullPivHouseholderQRPreconditioner> svd_fullqr;+ VERIFY_RAISES_ASSERT(svd_fullqr.compute(a, ComputeFullU|ComputeThinV))+ VERIFY_RAISES_ASSERT(svd_fullqr.compute(a, ComputeThinU|ComputeThinV))+ VERIFY_RAISES_ASSERT(svd_fullqr.compute(a, ComputeThinU|ComputeFullV))+ }+}++template<typename MatrixType>+void jacobisvd_method()+{+ enum { Size = MatrixType::RowsAtCompileTime };+ typedef typename MatrixType::RealScalar RealScalar;+ typedef Matrix<RealScalar, Size, 1> RealVecType;+ MatrixType m = MatrixType::Identity();+ VERIFY_IS_APPROX(m.jacobiSvd().singularValues(), RealVecType::Ones());+ VERIFY_RAISES_ASSERT(m.jacobiSvd().matrixU());+ VERIFY_RAISES_ASSERT(m.jacobiSvd().matrixV());+ VERIFY_IS_APPROX(m.jacobiSvd(ComputeFullU|ComputeFullV).solve(m), m);+}++++template<typename MatrixType>+void jacobisvd_inf_nan()+{+ svd_inf_nan<MatrixType, JacobiSVD< MatrixType > >();+}+++// Regression test for bug 286: JacobiSVD loops indefinitely with some+// matrices containing denormal numbers.+void jacobisvd_bug286()+{+#if defined __INTEL_COMPILER+// shut up warning #239: floating point underflow+#pragma warning push+#pragma warning disable 239+#endif+ Matrix2d M;+ M << -7.90884e-313, -4.94e-324,+ 0, 5.60844e-313;+#if defined __INTEL_COMPILER+#pragma warning pop+#endif+ JacobiSVD<Matrix2d> svd;+ svd.compute(M); // just check we don't loop indefinitely+}+++void jacobisvd_preallocate()+{+ svd_preallocate< JacobiSVD <MatrixXf> >();+}++void test_jacobisvd()+{+ CALL_SUBTEST_11(( jacobisvd<Matrix<double,Dynamic,Dynamic> >+ (Matrix<double,Dynamic,Dynamic>(16, 6)) ));++ CALL_SUBTEST_3(( jacobisvd_verify_assert(Matrix3f()) ));+ CALL_SUBTEST_4(( jacobisvd_verify_assert(Matrix4d()) ));+ CALL_SUBTEST_7(( jacobisvd_verify_assert(MatrixXf(10,12)) ));+ CALL_SUBTEST_8(( jacobisvd_verify_assert(MatrixXcd(7,5)) ));++ for(int i = 0; i < g_repeat; i++) {+ Matrix2cd m;+ m << 0, 1,+ 0, 1;+ CALL_SUBTEST_1(( jacobisvd(m, false) ));+ m << 1, 0,+ 1, 0;+ CALL_SUBTEST_1(( jacobisvd(m, false) ));++ Matrix2d n;+ n << 0, 0,+ 0, 0;+ CALL_SUBTEST_2(( jacobisvd(n, false) ));+ n << 0, 0,+ 0, 1;+ CALL_SUBTEST_2(( jacobisvd(n, false) ));+ + CALL_SUBTEST_3(( jacobisvd<Matrix3f>() ));+ CALL_SUBTEST_4(( jacobisvd<Matrix4d>() ));+ CALL_SUBTEST_5(( jacobisvd<Matrix<float,3,5> >() ));+ CALL_SUBTEST_6(( jacobisvd<Matrix<double,Dynamic,2> >(Matrix<double,Dynamic,2>(10,2)) ));++ int r = internal::random<int>(1, 30),+ c = internal::random<int>(1, 30);+ CALL_SUBTEST_7(( jacobisvd<MatrixXf>(MatrixXf(r,c)) ));+ CALL_SUBTEST_8(( jacobisvd<MatrixXcd>(MatrixXcd(r,c)) ));+ (void) r;+ (void) c;++ // Test on inf/nan matrix+ CALL_SUBTEST_7( jacobisvd_inf_nan<MatrixXf>() );+ }++ CALL_SUBTEST_7(( jacobisvd<MatrixXf>(MatrixXf(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/2))) ));+ CALL_SUBTEST_8(( jacobisvd<MatrixXcd>(MatrixXcd(internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/3), internal::random<int>(EIGEN_TEST_MAX_SIZE/4, EIGEN_TEST_MAX_SIZE/3))) ));+++ // test matrixbase method+ CALL_SUBTEST_1(( jacobisvd_method<Matrix2cd>() ));+ CALL_SUBTEST_3(( jacobisvd_method<Matrix3f>() ));+++ // Test problem size constructors+ CALL_SUBTEST_7( JacobiSVD<MatrixXf>(10,10) );++ // Check that preallocation avoids subsequent mallocs+ CALL_SUBTEST_9( jacobisvd_preallocate() );++ // Regression check for bug 286+ CALL_SUBTEST_2( jacobisvd_bug286() );+}
+ eigen3/unsupported/test/kronecker_product.cpp view
@@ -0,0 +1,181 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Kolja Brix <brix@igpm.rwth-aachen.de>+// Copyright (C) 2011 Andreas Platen <andiplaten@gmx.de>+// Copyright (C) 2012 Chen-Pang He <jdh8@ms63.hinet.net>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.+++#include "sparse.h"+#include <Eigen/SparseExtra>+#include <Eigen/KroneckerProduct>+++template<typename MatrixType>+void check_dimension(const MatrixType& ab, const int rows, const int cols)+{+ VERIFY_IS_EQUAL(ab.rows(), rows);+ VERIFY_IS_EQUAL(ab.cols(), cols);+}+++template<typename MatrixType>+void check_kronecker_product(const MatrixType& ab)+{+ VERIFY_IS_EQUAL(ab.rows(), 6);+ VERIFY_IS_EQUAL(ab.cols(), 6);+ VERIFY_IS_EQUAL(ab.nonZeros(), 36);+ VERIFY_IS_APPROX(ab.coeff(0,0), -0.4017367630386106);+ VERIFY_IS_APPROX(ab.coeff(0,1), 0.1056863433932735);+ VERIFY_IS_APPROX(ab.coeff(0,2), -0.7255206194554212);+ VERIFY_IS_APPROX(ab.coeff(0,3), 0.1908653336744706);+ VERIFY_IS_APPROX(ab.coeff(0,4), 0.350864567234111);+ VERIFY_IS_APPROX(ab.coeff(0,5), -0.0923032108308013);+ VERIFY_IS_APPROX(ab.coeff(1,0), 0.415417514804677);+ VERIFY_IS_APPROX(ab.coeff(1,1), -0.2369227701722048);+ VERIFY_IS_APPROX(ab.coeff(1,2), 0.7502275131458511);+ VERIFY_IS_APPROX(ab.coeff(1,3), -0.4278731019742696);+ VERIFY_IS_APPROX(ab.coeff(1,4), -0.3628129162264507);+ VERIFY_IS_APPROX(ab.coeff(1,5), 0.2069210808481275);+ VERIFY_IS_APPROX(ab.coeff(2,0), 0.05465890160863986);+ VERIFY_IS_APPROX(ab.coeff(2,1), -0.2634092511419858);+ VERIFY_IS_APPROX(ab.coeff(2,2), 0.09871180285793758);+ VERIFY_IS_APPROX(ab.coeff(2,3), -0.4757066334017702);+ VERIFY_IS_APPROX(ab.coeff(2,4), -0.04773740823058334);+ VERIFY_IS_APPROX(ab.coeff(2,5), 0.2300535609645254);+ VERIFY_IS_APPROX(ab.coeff(3,0), -0.8172945853260133);+ VERIFY_IS_APPROX(ab.coeff(3,1), 0.2150086428359221);+ VERIFY_IS_APPROX(ab.coeff(3,2), 0.5825113847292743);+ VERIFY_IS_APPROX(ab.coeff(3,3), -0.1532433770097174);+ VERIFY_IS_APPROX(ab.coeff(3,4), -0.329383387282399);+ VERIFY_IS_APPROX(ab.coeff(3,5), 0.08665207912033064);+ VERIFY_IS_APPROX(ab.coeff(4,0), 0.8451267514863225);+ VERIFY_IS_APPROX(ab.coeff(4,1), -0.481996458918977);+ VERIFY_IS_APPROX(ab.coeff(4,2), -0.6023482390791535);+ VERIFY_IS_APPROX(ab.coeff(4,3), 0.3435339347164565);+ VERIFY_IS_APPROX(ab.coeff(4,4), 0.3406002157428891);+ VERIFY_IS_APPROX(ab.coeff(4,5), -0.1942526344200915);+ VERIFY_IS_APPROX(ab.coeff(5,0), 0.1111982482925399);+ VERIFY_IS_APPROX(ab.coeff(5,1), -0.5358806424754169);+ VERIFY_IS_APPROX(ab.coeff(5,2), -0.07925446559335647);+ VERIFY_IS_APPROX(ab.coeff(5,3), 0.3819388757769038);+ VERIFY_IS_APPROX(ab.coeff(5,4), 0.04481475387219876);+ VERIFY_IS_APPROX(ab.coeff(5,5), -0.2159688616158057);+}+++template<typename MatrixType>+void check_sparse_kronecker_product(const MatrixType& ab)+{+ VERIFY_IS_EQUAL(ab.rows(), 12);+ VERIFY_IS_EQUAL(ab.cols(), 10);+ VERIFY_IS_EQUAL(ab.nonZeros(), 3*2);+ VERIFY_IS_APPROX(ab.coeff(3,0), -0.04);+ VERIFY_IS_APPROX(ab.coeff(5,1), 0.05);+ VERIFY_IS_APPROX(ab.coeff(0,6), -0.08);+ VERIFY_IS_APPROX(ab.coeff(2,7), 0.10);+ VERIFY_IS_APPROX(ab.coeff(6,8), 0.12);+ VERIFY_IS_APPROX(ab.coeff(8,9), -0.15);+}+++void test_kronecker_product()+{+ // DM = dense matrix; SM = sparse matrix++ Matrix<double, 2, 3> DM_a;+ SparseMatrix<double> SM_a(2,3);+ SM_a.insert(0,0) = DM_a.coeffRef(0,0) = -0.4461540300782201;+ SM_a.insert(0,1) = DM_a.coeffRef(0,1) = -0.8057364375283049;+ SM_a.insert(0,2) = DM_a.coeffRef(0,2) = 0.3896572459516341;+ SM_a.insert(1,0) = DM_a.coeffRef(1,0) = -0.9076572187376921;+ SM_a.insert(1,1) = DM_a.coeffRef(1,1) = 0.6469156566545853;+ SM_a.insert(1,2) = DM_a.coeffRef(1,2) = -0.3658010398782789;+ + MatrixXd DM_b(3,2);+ SparseMatrix<double> SM_b(3,2);+ SM_b.insert(0,0) = DM_b.coeffRef(0,0) = 0.9004440976767099;+ SM_b.insert(0,1) = DM_b.coeffRef(0,1) = -0.2368830858139832;+ SM_b.insert(1,0) = DM_b.coeffRef(1,0) = -0.9311078389941825;+ SM_b.insert(1,1) = DM_b.coeffRef(1,1) = 0.5310335762980047;+ SM_b.insert(2,0) = DM_b.coeffRef(2,0) = -0.1225112806872035;+ SM_b.insert(2,1) = DM_b.coeffRef(2,1) = 0.5903998022741264;++ SparseMatrix<double,RowMajor> SM_row_a(SM_a), SM_row_b(SM_b);++ // test kroneckerProduct(DM_block,DM,DM_fixedSize)+ Matrix<double, 6, 6> DM_fix_ab = kroneckerProduct(DM_a.topLeftCorner<2,3>(),DM_b);++ CALL_SUBTEST(check_kronecker_product(DM_fix_ab));++ for(int i=0;i<DM_fix_ab.rows();++i)+ for(int j=0;j<DM_fix_ab.cols();++j)+ VERIFY_IS_APPROX(kroneckerProduct(DM_a,DM_b).coeff(i,j), DM_fix_ab(i,j));++ // test kroneckerProduct(DM,DM,DM_block)+ MatrixXd DM_block_ab(10,15);+ DM_block_ab.block<6,6>(2,5) = kroneckerProduct(DM_a,DM_b);+ CALL_SUBTEST(check_kronecker_product(DM_block_ab.block<6,6>(2,5)));++ // test kroneckerProduct(DM,DM,DM)+ MatrixXd DM_ab = kroneckerProduct(DM_a,DM_b);+ CALL_SUBTEST(check_kronecker_product(DM_ab));++ // test kroneckerProduct(SM,DM,SM)+ SparseMatrix<double> SM_ab = kroneckerProduct(SM_a,DM_b);+ CALL_SUBTEST(check_kronecker_product(SM_ab));+ SparseMatrix<double,RowMajor> SM_ab2 = kroneckerProduct(SM_a,DM_b);+ CALL_SUBTEST(check_kronecker_product(SM_ab2));++ // test kroneckerProduct(DM,SM,SM)+ SM_ab.setZero();+ SM_ab.insert(0,0)=37.0;+ SM_ab = kroneckerProduct(DM_a,SM_b);+ CALL_SUBTEST(check_kronecker_product(SM_ab));+ SM_ab2.setZero();+ SM_ab2.insert(0,0)=37.0;+ SM_ab2 = kroneckerProduct(DM_a,SM_b);+ CALL_SUBTEST(check_kronecker_product(SM_ab2));++ // test kroneckerProduct(SM,SM,SM)+ SM_ab.resize(2,33);+ SM_ab.insert(0,0)=37.0;+ SM_ab = kroneckerProduct(SM_a,SM_b);+ CALL_SUBTEST(check_kronecker_product(SM_ab));+ SM_ab2.resize(5,11);+ SM_ab2.insert(0,0)=37.0;+ SM_ab2 = kroneckerProduct(SM_a,SM_b);+ CALL_SUBTEST(check_kronecker_product(SM_ab2));++ // test kroneckerProduct(SM,SM,SM) with sparse pattern+ SM_a.resize(4,5);+ SM_b.resize(3,2);+ SM_a.resizeNonZeros(0);+ SM_b.resizeNonZeros(0);+ SM_a.insert(1,0) = -0.1;+ SM_a.insert(0,3) = -0.2;+ SM_a.insert(2,4) = 0.3;+ SM_a.finalize();+ + SM_b.insert(0,0) = 0.4;+ SM_b.insert(2,1) = -0.5;+ SM_b.finalize();+ SM_ab.resize(1,1);+ SM_ab.insert(0,0)=37.0;+ SM_ab = kroneckerProduct(SM_a,SM_b);+ CALL_SUBTEST(check_sparse_kronecker_product(SM_ab));++ // test dimension of result of kroneckerProduct(DM,DM,DM)+ MatrixXd DM_a2(2,1);+ MatrixXd DM_b2(5,4);+ MatrixXd DM_ab2 = kroneckerProduct(DM_a2,DM_b2);+ CALL_SUBTEST(check_dimension(DM_ab2,2*5,1*4));+ DM_a2.resize(10,9);+ DM_b2.resize(4,8);+ DM_ab2 = kroneckerProduct(DM_a2,DM_b2);+ CALL_SUBTEST(check_dimension(DM_ab2,10*4,9*8));+}
+ eigen3/unsupported/test/levenberg_marquardt.cpp view
@@ -0,0 +1,1448 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>+// Copyright (C) 2012 desire Nuentsa <desire.nuentsa_wakam@inria.fr+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.+++#include <stdio.h>++#include "main.h"+#include <unsupported/Eigen/LevenbergMarquardt>++// This disables some useless Warnings on MSVC.+// It is intended to be done for this test only.+#include <Eigen/src/Core/util/DisableStupidWarnings.h>++using std::sqrt;++struct lmder_functor : DenseFunctor<double>+{+ lmder_functor(void): DenseFunctor<double>(3,15) {}+ int operator()(const VectorXd &x, VectorXd &fvec) const+ {+ double tmp1, tmp2, tmp3;+ static const double y[15] = {1.4e-1, 1.8e-1, 2.2e-1, 2.5e-1, 2.9e-1, 3.2e-1, 3.5e-1,+ 3.9e-1, 3.7e-1, 5.8e-1, 7.3e-1, 9.6e-1, 1.34, 2.1, 4.39};++ for (int i = 0; i < values(); i++)+ {+ tmp1 = i+1;+ tmp2 = 16 - i - 1;+ tmp3 = (i>=8)? tmp2 : tmp1;+ fvec[i] = y[i] - (x[0] + tmp1/(x[1]*tmp2 + x[2]*tmp3));+ }+ return 0;+ }++ int df(const VectorXd &x, MatrixXd &fjac) const+ {+ double tmp1, tmp2, tmp3, tmp4;+ for (int i = 0; i < values(); i++)+ {+ tmp1 = i+1;+ tmp2 = 16 - i - 1;+ tmp3 = (i>=8)? tmp2 : tmp1;+ tmp4 = (x[1]*tmp2 + x[2]*tmp3); tmp4 = tmp4*tmp4;+ fjac(i,0) = -1;+ fjac(i,1) = tmp1*tmp2/tmp4;+ fjac(i,2) = tmp1*tmp3/tmp4;+ }+ return 0;+ }+};++void testLmder1()+{+ int n=3, info;++ VectorXd x;++ /* the following starting values provide a rough fit. */+ x.setConstant(n, 1.);++ // do the computation+ lmder_functor functor;+ LevenbergMarquardt<lmder_functor> lm(functor);+ info = lm.lmder1(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 6);+ VERIFY_IS_EQUAL(lm.njev(), 5);++ // check norm+ VERIFY_IS_APPROX(lm.fvec().blueNorm(), 0.09063596);++ // check x+ VectorXd x_ref(n);+ x_ref << 0.08241058, 1.133037, 2.343695;+ VERIFY_IS_APPROX(x, x_ref);+}++void testLmder()+{+ const int m=15, n=3;+ int info;+ double fnorm, covfac;+ VectorXd x;++ /* the following starting values provide a rough fit. */+ x.setConstant(n, 1.);++ // do the computation+ lmder_functor functor;+ LevenbergMarquardt<lmder_functor> lm(functor);+ info = lm.minimize(x);++ // check return values+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 6);+ VERIFY_IS_EQUAL(lm.njev(), 5);++ // check norm+ fnorm = lm.fvec().blueNorm();+ VERIFY_IS_APPROX(fnorm, 0.09063596);++ // check x+ VectorXd x_ref(n);+ x_ref << 0.08241058, 1.133037, 2.343695;+ VERIFY_IS_APPROX(x, x_ref);++ // check covariance+ covfac = fnorm*fnorm/(m-n);+ internal::covar(lm.matrixR(), lm.permutation().indices()); // TODO : move this as a function of lm++ MatrixXd cov_ref(n,n);+ cov_ref <<+ 0.0001531202, 0.002869941, -0.002656662,+ 0.002869941, 0.09480935, -0.09098995,+ -0.002656662, -0.09098995, 0.08778727;++// std::cout << fjac*covfac << std::endl;++ MatrixXd cov;+ cov = covfac*lm.matrixR().topLeftCorner<n,n>();+ VERIFY_IS_APPROX( cov, cov_ref);+ // TODO: why isn't this allowed ? :+ // VERIFY_IS_APPROX( covfac*fjac.topLeftCorner<n,n>() , cov_ref);+}++struct lmdif_functor : DenseFunctor<double>+{+ lmdif_functor(void) : DenseFunctor<double>(3,15) {}+ int operator()(const VectorXd &x, VectorXd &fvec) const+ {+ int i;+ double tmp1,tmp2,tmp3;+ static const double y[15]={1.4e-1,1.8e-1,2.2e-1,2.5e-1,2.9e-1,3.2e-1,3.5e-1,3.9e-1,+ 3.7e-1,5.8e-1,7.3e-1,9.6e-1,1.34e0,2.1e0,4.39e0};++ assert(x.size()==3);+ assert(fvec.size()==15);+ for (i=0; i<15; i++)+ {+ tmp1 = i+1;+ tmp2 = 15 - i;+ tmp3 = tmp1;++ if (i >= 8) tmp3 = tmp2;+ fvec[i] = y[i] - (x[0] + tmp1/(x[1]*tmp2 + x[2]*tmp3));+ }+ return 0;+ }+};++void testLmdif1()+{+ const int n=3;+ int info;++ VectorXd x(n), fvec(15);++ /* the following starting values provide a rough fit. */+ x.setConstant(n, 1.);++ // do the computation+ lmdif_functor functor;+ DenseIndex nfev;+ info = LevenbergMarquardt<lmdif_functor>::lmdif1(functor, x, &nfev);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+// VERIFY_IS_EQUAL(nfev, 26);++ // check norm+ functor(x, fvec);+ VERIFY_IS_APPROX(fvec.blueNorm(), 0.09063596);++ // check x+ VectorXd x_ref(n);+ x_ref << 0.0824106, 1.1330366, 2.3436947;+ VERIFY_IS_APPROX(x, x_ref);++}++void testLmdif()+{+ const int m=15, n=3;+ int info;+ double fnorm, covfac;+ VectorXd x(n);++ /* the following starting values provide a rough fit. */+ x.setConstant(n, 1.);++ // do the computation+ lmdif_functor functor;+ NumericalDiff<lmdif_functor> numDiff(functor);+ LevenbergMarquardt<NumericalDiff<lmdif_functor> > lm(numDiff);+ info = lm.minimize(x);++ // check return values+ VERIFY_IS_EQUAL(info, 1);+// VERIFY_IS_EQUAL(lm.nfev(), 26);++ // check norm+ fnorm = lm.fvec().blueNorm();+ VERIFY_IS_APPROX(fnorm, 0.09063596);++ // check x+ VectorXd x_ref(n);+ x_ref << 0.08241058, 1.133037, 2.343695;+ VERIFY_IS_APPROX(x, x_ref);++ // check covariance+ covfac = fnorm*fnorm/(m-n);+ internal::covar(lm.matrixR(), lm.permutation().indices()); // TODO : move this as a function of lm++ MatrixXd cov_ref(n,n);+ cov_ref <<+ 0.0001531202, 0.002869942, -0.002656662,+ 0.002869942, 0.09480937, -0.09098997,+ -0.002656662, -0.09098997, 0.08778729;++// std::cout << fjac*covfac << std::endl;++ MatrixXd cov;+ cov = covfac*lm.matrixR().topLeftCorner<n,n>();+ VERIFY_IS_APPROX( cov, cov_ref);+ // TODO: why isn't this allowed ? :+ // VERIFY_IS_APPROX( covfac*fjac.topLeftCorner<n,n>() , cov_ref);+}++struct chwirut2_functor : DenseFunctor<double>+{+ chwirut2_functor(void) : DenseFunctor<double>(3,54) {}+ static const double m_x[54];+ static const double m_y[54];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ int i;++ assert(b.size()==3);+ assert(fvec.size()==54);+ for(i=0; i<54; i++) {+ double x = m_x[i];+ fvec[i] = exp(-b[0]*x)/(b[1]+b[2]*x) - m_y[i];+ }+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==3);+ assert(fjac.rows()==54);+ assert(fjac.cols()==3);+ for(int i=0; i<54; i++) {+ double x = m_x[i];+ double factor = 1./(b[1]+b[2]*x);+ double e = exp(-b[0]*x);+ fjac(i,0) = -x*e*factor;+ fjac(i,1) = -e*factor*factor;+ fjac(i,2) = -x*e*factor*factor;+ }+ return 0;+ }+};+const double chwirut2_functor::m_x[54] = { 0.500E0, 1.000E0, 1.750E0, 3.750E0, 5.750E0, 0.875E0, 2.250E0, 3.250E0, 5.250E0, 0.750E0, 1.750E0, 2.750E0, 4.750E0, 0.625E0, 1.250E0, 2.250E0, 4.250E0, .500E0, 3.000E0, .750E0, 3.000E0, 1.500E0, 6.000E0, 3.000E0, 6.000E0, 1.500E0, 3.000E0, .500E0, 2.000E0, 4.000E0, .750E0, 2.000E0, 5.000E0, .750E0, 2.250E0, 3.750E0, 5.750E0, 3.000E0, .750E0, 2.500E0, 4.000E0, .750E0, 2.500E0, 4.000E0, .750E0, 2.500E0, 4.000E0, .500E0, 6.000E0, 3.000E0, .500E0, 2.750E0, .500E0, 1.750E0};+const double chwirut2_functor::m_y[54] = { 92.9000E0 ,57.1000E0 ,31.0500E0 ,11.5875E0 ,8.0250E0 ,63.6000E0 ,21.4000E0 ,14.2500E0 ,8.4750E0 ,63.8000E0 ,26.8000E0 ,16.4625E0 ,7.1250E0 ,67.3000E0 ,41.0000E0 ,21.1500E0 ,8.1750E0 ,81.5000E0 ,13.1200E0 ,59.9000E0 ,14.6200E0 ,32.9000E0 ,5.4400E0 ,12.5600E0 ,5.4400E0 ,32.0000E0 ,13.9500E0 ,75.8000E0 ,20.0000E0 ,10.4200E0 ,59.5000E0 ,21.6700E0 ,8.5500E0 ,62.0000E0 ,20.2000E0 ,7.7600E0 ,3.7500E0 ,11.8100E0 ,54.7000E0 ,23.7000E0 ,11.5500E0 ,61.3000E0 ,17.7000E0 ,8.7400E0 ,59.2000E0 ,16.3000E0 ,8.6200E0 ,81.0000E0 ,4.8700E0 ,14.6200E0 ,81.7000E0 ,17.1700E0 ,81.3000E0 ,28.9000E0 };++// http://www.itl.nist.gov/div898/strd/nls/data/chwirut2.shtml+void testNistChwirut2(void)+{+ const int n=3;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 0.1, 0.01, 0.02;+ // do the computation+ chwirut2_functor functor;+ LevenbergMarquardt<chwirut2_functor> lm(functor);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+// VERIFY_IS_EQUAL(lm.nfev(), 10);+ VERIFY_IS_EQUAL(lm.njev(), 8);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 5.1304802941E+02);+ // check x+ VERIFY_IS_APPROX(x[0], 1.6657666537E-01);+ VERIFY_IS_APPROX(x[1], 5.1653291286E-03);+ VERIFY_IS_APPROX(x[2], 1.2150007096E-02);++ /*+ * Second try+ */+ x<< 0.15, 0.008, 0.010;+ // do the computation+ lm.resetParameters();+ lm.setFtol(1.E6*NumTraits<double>::epsilon());+ lm.setXtol(1.E6*NumTraits<double>::epsilon());+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+// VERIFY_IS_EQUAL(lm.nfev(), 7);+ VERIFY_IS_EQUAL(lm.njev(), 6);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 5.1304802941E+02);+ // check x+ VERIFY_IS_APPROX(x[0], 1.6657666537E-01);+ VERIFY_IS_APPROX(x[1], 5.1653291286E-03);+ VERIFY_IS_APPROX(x[2], 1.2150007096E-02);+}+++struct misra1a_functor : DenseFunctor<double>+{+ misra1a_functor(void) : DenseFunctor<double>(2,14) {}+ static const double m_x[14];+ static const double m_y[14];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==2);+ assert(fvec.size()==14);+ for(int i=0; i<14; i++) {+ fvec[i] = b[0]*(1.-exp(-b[1]*m_x[i])) - m_y[i] ;+ }+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==2);+ assert(fjac.rows()==14);+ assert(fjac.cols()==2);+ for(int i=0; i<14; i++) {+ fjac(i,0) = (1.-exp(-b[1]*m_x[i]));+ fjac(i,1) = (b[0]*m_x[i]*exp(-b[1]*m_x[i]));+ }+ return 0;+ }+};+const double misra1a_functor::m_x[14] = { 77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0};+const double misra1a_functor::m_y[14] = { 10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0};++// http://www.itl.nist.gov/div898/strd/nls/data/misra1a.shtml+void testNistMisra1a(void)+{+ const int n=2;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 500., 0.0001;+ // do the computation+ misra1a_functor functor;+ LevenbergMarquardt<misra1a_functor> lm(functor);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 19);+ VERIFY_IS_EQUAL(lm.njev(), 15);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 1.2455138894E-01);+ // check x+ VERIFY_IS_APPROX(x[0], 2.3894212918E+02);+ VERIFY_IS_APPROX(x[1], 5.5015643181E-04);++ /*+ * Second try+ */+ x<< 250., 0.0005;+ // do the computation+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 5);+ VERIFY_IS_EQUAL(lm.njev(), 4);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 1.2455138894E-01);+ // check x+ VERIFY_IS_APPROX(x[0], 2.3894212918E+02);+ VERIFY_IS_APPROX(x[1], 5.5015643181E-04);+}++struct hahn1_functor : DenseFunctor<double>+{+ hahn1_functor(void) : DenseFunctor<double>(7,236) {}+ static const double m_x[236];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ static const double m_y[236] = { .591E0 , 1.547E0 , 2.902E0 , 2.894E0 , 4.703E0 , 6.307E0 , 7.03E0 , 7.898E0 , 9.470E0 , 9.484E0 , 10.072E0 , 10.163E0 , 11.615E0 , 12.005E0 , 12.478E0 , 12.982E0 , 12.970E0 , 13.926E0 , 14.452E0 , 14.404E0 , 15.190E0 , 15.550E0 , 15.528E0 , 15.499E0 , 16.131E0 , 16.438E0 , 16.387E0 , 16.549E0 , 16.872E0 , 16.830E0 , 16.926E0 , 16.907E0 , 16.966E0 , 17.060E0 , 17.122E0 , 17.311E0 , 17.355E0 , 17.668E0 , 17.767E0 , 17.803E0 , 17.765E0 , 17.768E0 , 17.736E0 , 17.858E0 , 17.877E0 , 17.912E0 , 18.046E0 , 18.085E0 , 18.291E0 , 18.357E0 , 18.426E0 , 18.584E0 , 18.610E0 , 18.870E0 , 18.795E0 , 19.111E0 , .367E0 , .796E0 , 0.892E0 , 1.903E0 , 2.150E0 , 3.697E0 , 5.870E0 , 6.421E0 , 7.422E0 , 9.944E0 , 11.023E0 , 11.87E0 , 12.786E0 , 14.067E0 , 13.974E0 , 14.462E0 , 14.464E0 , 15.381E0 , 15.483E0 , 15.59E0 , 16.075E0 , 16.347E0 , 16.181E0 , 16.915E0 , 17.003E0 , 16.978E0 , 17.756E0 , 17.808E0 , 17.868E0 , 18.481E0 , 18.486E0 , 19.090E0 , 16.062E0 , 16.337E0 , 16.345E0 ,+ 16.388E0 , 17.159E0 , 17.116E0 , 17.164E0 , 17.123E0 , 17.979E0 , 17.974E0 , 18.007E0 , 17.993E0 , 18.523E0 , 18.669E0 , 18.617E0 , 19.371E0 , 19.330E0 , 0.080E0 , 0.248E0 , 1.089E0 , 1.418E0 , 2.278E0 , 3.624E0 , 4.574E0 , 5.556E0 , 7.267E0 , 7.695E0 , 9.136E0 , 9.959E0 , 9.957E0 , 11.600E0 , 13.138E0 , 13.564E0 , 13.871E0 , 13.994E0 , 14.947E0 , 15.473E0 , 15.379E0 , 15.455E0 , 15.908E0 , 16.114E0 , 17.071E0 , 17.135E0 , 17.282E0 , 17.368E0 , 17.483E0 , 17.764E0 , 18.185E0 , 18.271E0 , 18.236E0 , 18.237E0 , 18.523E0 , 18.627E0 , 18.665E0 , 19.086E0 , 0.214E0 , 0.943E0 , 1.429E0 , 2.241E0 , 2.951E0 , 3.782E0 , 4.757E0 , 5.602E0 , 7.169E0 , 8.920E0 , 10.055E0 , 12.035E0 , 12.861E0 , 13.436E0 , 14.167E0 , 14.755E0 , 15.168E0 , 15.651E0 , 15.746E0 , 16.216E0 , 16.445E0 , 16.965E0 , 17.121E0 , 17.206E0 , 17.250E0 , 17.339E0 , 17.793E0 , 18.123E0 , 18.49E0 , 18.566E0 , 18.645E0 , 18.706E0 , 18.924E0 , 19.1E0 , 0.375E0 , 0.471E0 , 1.504E0 , 2.204E0 , 2.813E0 , 4.765E0 , 9.835E0 , 10.040E0 , 11.946E0 , +12.596E0 , +13.303E0 , 13.922E0 , 14.440E0 , 14.951E0 , 15.627E0 , 15.639E0 , 15.814E0 , 16.315E0 , 16.334E0 , 16.430E0 , 16.423E0 , 17.024E0 , 17.009E0 , 17.165E0 , 17.134E0 , 17.349E0 , 17.576E0 , 17.848E0 , 18.090E0 , 18.276E0 , 18.404E0 , 18.519E0 , 19.133E0 , 19.074E0 , 19.239E0 , 19.280E0 , 19.101E0 , 19.398E0 , 19.252E0 , 19.89E0 , 20.007E0 , 19.929E0 , 19.268E0 , 19.324E0 , 20.049E0 , 20.107E0 , 20.062E0 , 20.065E0 , 19.286E0 , 19.972E0 , 20.088E0 , 20.743E0 , 20.83E0 , 20.935E0 , 21.035E0 , 20.93E0 , 21.074E0 , 21.085E0 , 20.935E0 };++ // int called=0; printf("call hahn1_functor with iflag=%d, called=%d\n", iflag, called); if (iflag==1) called++;++ assert(b.size()==7);+ assert(fvec.size()==236);+ for(int i=0; i<236; i++) {+ double x=m_x[i], xx=x*x, xxx=xx*x;+ fvec[i] = (b[0]+b[1]*x+b[2]*xx+b[3]*xxx) / (1.+b[4]*x+b[5]*xx+b[6]*xxx) - m_y[i];+ }+ return 0;+ }++ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==7);+ assert(fjac.rows()==236);+ assert(fjac.cols()==7);+ for(int i=0; i<236; i++) {+ double x=m_x[i], xx=x*x, xxx=xx*x;+ double fact = 1./(1.+b[4]*x+b[5]*xx+b[6]*xxx);+ fjac(i,0) = 1.*fact;+ fjac(i,1) = x*fact;+ fjac(i,2) = xx*fact;+ fjac(i,3) = xxx*fact;+ fact = - (b[0]+b[1]*x+b[2]*xx+b[3]*xxx) * fact * fact;+ fjac(i,4) = x*fact;+ fjac(i,5) = xx*fact;+ fjac(i,6) = xxx*fact;+ }+ return 0;+ }+};+const double hahn1_functor::m_x[236] = { 24.41E0 , 34.82E0 , 44.09E0 , 45.07E0 , 54.98E0 , 65.51E0 , 70.53E0 , 75.70E0 , 89.57E0 , 91.14E0 , 96.40E0 , 97.19E0 , 114.26E0 , 120.25E0 , 127.08E0 , 133.55E0 , 133.61E0 , 158.67E0 , 172.74E0 , 171.31E0 , 202.14E0 , 220.55E0 , 221.05E0 , 221.39E0 , 250.99E0 , 268.99E0 , 271.80E0 , 271.97E0 , 321.31E0 , 321.69E0 , 330.14E0 , 333.03E0 , 333.47E0 , 340.77E0 , 345.65E0 , 373.11E0 , 373.79E0 , 411.82E0 , 419.51E0 , 421.59E0 , 422.02E0 , 422.47E0 , 422.61E0 , 441.75E0 , 447.41E0 , 448.7E0 , 472.89E0 , 476.69E0 , 522.47E0 , 522.62E0 , 524.43E0 , 546.75E0 , 549.53E0 , 575.29E0 , 576.00E0 , 625.55E0 , 20.15E0 , 28.78E0 , 29.57E0 , 37.41E0 , 39.12E0 , 50.24E0 , 61.38E0 , 66.25E0 , 73.42E0 , 95.52E0 , 107.32E0 , 122.04E0 , 134.03E0 , 163.19E0 , 163.48E0 , 175.70E0 , 179.86E0 , 211.27E0 , 217.78E0 , 219.14E0 , 262.52E0 , 268.01E0 , 268.62E0 , 336.25E0 , 337.23E0 , 339.33E0 , 427.38E0 , 428.58E0 , 432.68E0 , 528.99E0 , 531.08E0 , 628.34E0 , 253.24E0 , 273.13E0 , 273.66E0 ,+282.10E0 , 346.62E0 , 347.19E0 , 348.78E0 , 351.18E0 , 450.10E0 , 450.35E0 , 451.92E0 , 455.56E0 , 552.22E0 , 553.56E0 , 555.74E0 , 652.59E0 , 656.20E0 , 14.13E0 , 20.41E0 , 31.30E0 , 33.84E0 , 39.70E0 , 48.83E0 , 54.50E0 , 60.41E0 , 72.77E0 , 75.25E0 , 86.84E0 , 94.88E0 , 96.40E0 , 117.37E0 , 139.08E0 , 147.73E0 , 158.63E0 , 161.84E0 , 192.11E0 , 206.76E0 , 209.07E0 , 213.32E0 , 226.44E0 , 237.12E0 , 330.90E0 , 358.72E0 , 370.77E0 , 372.72E0 , 396.24E0 , 416.59E0 , 484.02E0 , 495.47E0 , 514.78E0 , 515.65E0 , 519.47E0 , 544.47E0 , 560.11E0 , 620.77E0 , 18.97E0 , 28.93E0 , 33.91E0 , 40.03E0 , 44.66E0 , 49.87E0 , 55.16E0 , 60.90E0 , 72.08E0 , 85.15E0 , 97.06E0 , 119.63E0 , 133.27E0 , 143.84E0 , 161.91E0 , 180.67E0 , 198.44E0 , 226.86E0 , 229.65E0 , 258.27E0 , 273.77E0 , 339.15E0 , 350.13E0 , 362.75E0 , 371.03E0 , 393.32E0 , 448.53E0 , 473.78E0 , 511.12E0 , 524.70E0 , 548.75E0 , 551.64E0 , 574.02E0 , 623.86E0 , 21.46E0 , 24.33E0 , 33.43E0 , 39.22E0 , 44.18E0 , 55.02E0 , 94.33E0 , 96.44E0 , 118.82E0 , 128.48E0 ,+141.94E0 , 156.92E0 , 171.65E0 , 190.00E0 , 223.26E0 , 223.88E0 , 231.50E0 , 265.05E0 , 269.44E0 , 271.78E0 , 273.46E0 , 334.61E0 , 339.79E0 , 349.52E0 , 358.18E0 , 377.98E0 , 394.77E0 , 429.66E0 , 468.22E0 , 487.27E0 , 519.54E0 , 523.03E0 , 612.99E0 , 638.59E0 , 641.36E0 , 622.05E0 , 631.50E0 , 663.97E0 , 646.9E0 , 748.29E0 , 749.21E0 , 750.14E0 , 647.04E0 , 646.89E0 , 746.9E0 , 748.43E0 , 747.35E0 , 749.27E0 , 647.61E0 , 747.78E0 , 750.51E0 , 851.37E0 , 845.97E0 , 847.54E0 , 849.93E0 , 851.61E0 , 849.75E0 , 850.98E0 , 848.23E0};++// http://www.itl.nist.gov/div898/strd/nls/data/hahn1.shtml+void testNistHahn1(void)+{+ const int n=7;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 10., -1., .05, -.00001, -.05, .001, -.000001;+ // do the computation+ hahn1_functor functor;+ LevenbergMarquardt<hahn1_functor> lm(functor);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 11);+ VERIFY_IS_EQUAL(lm.njev(), 10);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 1.5324382854E+00);+ // check x+ VERIFY_IS_APPROX(x[0], 1.0776351733E+00);+ VERIFY_IS_APPROX(x[1],-1.2269296921E-01);+ VERIFY_IS_APPROX(x[2], 4.0863750610E-03);+ VERIFY_IS_APPROX(x[3],-1.426264e-06); // shoulde be : -1.4262662514E-06+ VERIFY_IS_APPROX(x[4],-5.7609940901E-03);+ VERIFY_IS_APPROX(x[5], 2.4053735503E-04);+ VERIFY_IS_APPROX(x[6],-1.2314450199E-07);++ /*+ * Second try+ */+ x<< .1, -.1, .005, -.000001, -.005, .0001, -.0000001;+ // do the computation+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+// VERIFY_IS_EQUAL(lm.nfev(), 11);+ VERIFY_IS_EQUAL(lm.njev(), 10);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 1.5324382854E+00);+ // check x+ VERIFY_IS_APPROX(x[0], 1.077640); // should be : 1.0776351733E+00+ VERIFY_IS_APPROX(x[1], -0.1226933); // should be : -1.2269296921E-01+ VERIFY_IS_APPROX(x[2], 0.004086383); // should be : 4.0863750610E-03+ VERIFY_IS_APPROX(x[3], -1.426277e-06); // shoulde be : -1.4262662514E-06+ VERIFY_IS_APPROX(x[4],-5.7609940901E-03);+ VERIFY_IS_APPROX(x[5], 0.00024053772); // should be : 2.4053735503E-04+ VERIFY_IS_APPROX(x[6], -1.231450e-07); // should be : -1.2314450199E-07++}++struct misra1d_functor : DenseFunctor<double>+{+ misra1d_functor(void) : DenseFunctor<double>(2,14) {}+ static const double x[14];+ static const double y[14];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==2);+ assert(fvec.size()==14);+ for(int i=0; i<14; i++) {+ fvec[i] = b[0]*b[1]*x[i]/(1.+b[1]*x[i]) - y[i];+ }+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==2);+ assert(fjac.rows()==14);+ assert(fjac.cols()==2);+ for(int i=0; i<14; i++) {+ double den = 1.+b[1]*x[i];+ fjac(i,0) = b[1]*x[i] / den;+ fjac(i,1) = b[0]*x[i]*(den-b[1]*x[i])/den/den;+ }+ return 0;+ }+};+const double misra1d_functor::x[14] = { 77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0};+const double misra1d_functor::y[14] = { 10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0};++// http://www.itl.nist.gov/div898/strd/nls/data/misra1d.shtml+void testNistMisra1d(void)+{+ const int n=2;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 500., 0.0001;+ // do the computation+ misra1d_functor functor;+ LevenbergMarquardt<misra1d_functor> lm(functor);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 9);+ VERIFY_IS_EQUAL(lm.njev(), 7);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 5.6419295283E-02);+ // check x+ VERIFY_IS_APPROX(x[0], 4.3736970754E+02);+ VERIFY_IS_APPROX(x[1], 3.0227324449E-04);++ /*+ * Second try+ */+ x<< 450., 0.0003;+ // do the computation+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 4);+ VERIFY_IS_EQUAL(lm.njev(), 3);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 5.6419295283E-02);+ // check x+ VERIFY_IS_APPROX(x[0], 4.3736970754E+02);+ VERIFY_IS_APPROX(x[1], 3.0227324449E-04);+}+++struct lanczos1_functor : DenseFunctor<double>+{+ lanczos1_functor(void) : DenseFunctor<double>(6,24) {}+ static const double x[24];+ static const double y[24];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==6);+ assert(fvec.size()==24);+ for(int i=0; i<24; i++)+ fvec[i] = b[0]*exp(-b[1]*x[i]) + b[2]*exp(-b[3]*x[i]) + b[4]*exp(-b[5]*x[i]) - y[i];+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==6);+ assert(fjac.rows()==24);+ assert(fjac.cols()==6);+ for(int i=0; i<24; i++) {+ fjac(i,0) = exp(-b[1]*x[i]);+ fjac(i,1) = -b[0]*x[i]*exp(-b[1]*x[i]);+ fjac(i,2) = exp(-b[3]*x[i]);+ fjac(i,3) = -b[2]*x[i]*exp(-b[3]*x[i]);+ fjac(i,4) = exp(-b[5]*x[i]);+ fjac(i,5) = -b[4]*x[i]*exp(-b[5]*x[i]);+ }+ return 0;+ }+};+const double lanczos1_functor::x[24] = { 0.000000000000E+00, 5.000000000000E-02, 1.000000000000E-01, 1.500000000000E-01, 2.000000000000E-01, 2.500000000000E-01, 3.000000000000E-01, 3.500000000000E-01, 4.000000000000E-01, 4.500000000000E-01, 5.000000000000E-01, 5.500000000000E-01, 6.000000000000E-01, 6.500000000000E-01, 7.000000000000E-01, 7.500000000000E-01, 8.000000000000E-01, 8.500000000000E-01, 9.000000000000E-01, 9.500000000000E-01, 1.000000000000E+00, 1.050000000000E+00, 1.100000000000E+00, 1.150000000000E+00 };+const double lanczos1_functor::y[24] = { 2.513400000000E+00 ,2.044333373291E+00 ,1.668404436564E+00 ,1.366418021208E+00 ,1.123232487372E+00 ,9.268897180037E-01 ,7.679338563728E-01 ,6.388775523106E-01 ,5.337835317402E-01 ,4.479363617347E-01 ,3.775847884350E-01 ,3.197393199326E-01 ,2.720130773746E-01 ,2.324965529032E-01 ,1.996589546065E-01 ,1.722704126914E-01 ,1.493405660168E-01 ,1.300700206922E-01 ,1.138119324644E-01 ,1.000415587559E-01 ,8.833209084540E-02 ,7.833544019350E-02 ,6.976693743449E-02 ,6.239312536719E-02 };++// http://www.itl.nist.gov/div898/strd/nls/data/lanczos1.shtml+void testNistLanczos1(void)+{+ const int n=6;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 1.2, 0.3, 5.6, 5.5, 6.5, 7.6;+ // do the computation+ lanczos1_functor functor;+ LevenbergMarquardt<lanczos1_functor> lm(functor);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 2);+ VERIFY_IS_EQUAL(lm.nfev(), 79);+ VERIFY_IS_EQUAL(lm.njev(), 72);+ // check norm^2+// VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 1.430899764097e-25); // should be 1.4307867721E-25, but nist results are on 128-bit floats+ // check x+ VERIFY_IS_APPROX(x[0], 9.5100000027E-02);+ VERIFY_IS_APPROX(x[1], 1.0000000001E+00);+ VERIFY_IS_APPROX(x[2], 8.6070000013E-01);+ VERIFY_IS_APPROX(x[3], 3.0000000002E+00);+ VERIFY_IS_APPROX(x[4], 1.5575999998E+00);+ VERIFY_IS_APPROX(x[5], 5.0000000001E+00);++ /*+ * Second try+ */+ x<< 0.5, 0.7, 3.6, 4.2, 4., 6.3;+ // do the computation+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 2);+ VERIFY_IS_EQUAL(lm.nfev(), 9);+ VERIFY_IS_EQUAL(lm.njev(), 8);+ // check norm^2+// VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 1.428595533845e-25); // should be 1.4307867721E-25, but nist results are on 128-bit floats+ // check x+ VERIFY_IS_APPROX(x[0], 9.5100000027E-02);+ VERIFY_IS_APPROX(x[1], 1.0000000001E+00);+ VERIFY_IS_APPROX(x[2], 8.6070000013E-01);+ VERIFY_IS_APPROX(x[3], 3.0000000002E+00);+ VERIFY_IS_APPROX(x[4], 1.5575999998E+00);+ VERIFY_IS_APPROX(x[5], 5.0000000001E+00);++}++struct rat42_functor : DenseFunctor<double>+{+ rat42_functor(void) : DenseFunctor<double>(3,9) {}+ static const double x[9];+ static const double y[9];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==3);+ assert(fvec.size()==9);+ for(int i=0; i<9; i++) {+ fvec[i] = b[0] / (1.+exp(b[1]-b[2]*x[i])) - y[i];+ }+ return 0;+ }++ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==3);+ assert(fjac.rows()==9);+ assert(fjac.cols()==3);+ for(int i=0; i<9; i++) {+ double e = exp(b[1]-b[2]*x[i]);+ fjac(i,0) = 1./(1.+e);+ fjac(i,1) = -b[0]*e/(1.+e)/(1.+e);+ fjac(i,2) = +b[0]*e*x[i]/(1.+e)/(1.+e);+ }+ return 0;+ }+};+const double rat42_functor::x[9] = { 9.000E0, 14.000E0, 21.000E0, 28.000E0, 42.000E0, 57.000E0, 63.000E0, 70.000E0, 79.000E0 };+const double rat42_functor::y[9] = { 8.930E0 ,10.800E0 ,18.590E0 ,22.330E0 ,39.350E0 ,56.110E0 ,61.730E0 ,64.620E0 ,67.080E0 };++// http://www.itl.nist.gov/div898/strd/nls/data/ratkowsky2.shtml+void testNistRat42(void)+{+ const int n=3;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 100., 1., 0.1;+ // do the computation+ rat42_functor functor;+ LevenbergMarquardt<rat42_functor> lm(functor);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 10);+ VERIFY_IS_EQUAL(lm.njev(), 8);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 8.0565229338E+00);+ // check x+ VERIFY_IS_APPROX(x[0], 7.2462237576E+01);+ VERIFY_IS_APPROX(x[1], 2.6180768402E+00);+ VERIFY_IS_APPROX(x[2], 6.7359200066E-02);++ /*+ * Second try+ */+ x<< 75., 2.5, 0.07;+ // do the computation+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 6);+ VERIFY_IS_EQUAL(lm.njev(), 5);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 8.0565229338E+00);+ // check x+ VERIFY_IS_APPROX(x[0], 7.2462237576E+01);+ VERIFY_IS_APPROX(x[1], 2.6180768402E+00);+ VERIFY_IS_APPROX(x[2], 6.7359200066E-02);+}++struct MGH10_functor : DenseFunctor<double>+{+ MGH10_functor(void) : DenseFunctor<double>(3,16) {}+ static const double x[16];+ static const double y[16];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==3);+ assert(fvec.size()==16);+ for(int i=0; i<16; i++)+ fvec[i] = b[0] * exp(b[1]/(x[i]+b[2])) - y[i];+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==3);+ assert(fjac.rows()==16);+ assert(fjac.cols()==3);+ for(int i=0; i<16; i++) {+ double factor = 1./(x[i]+b[2]);+ double e = exp(b[1]*factor);+ fjac(i,0) = e;+ fjac(i,1) = b[0]*factor*e;+ fjac(i,2) = -b[1]*b[0]*factor*factor*e;+ }+ return 0;+ }+};+const double MGH10_functor::x[16] = { 5.000000E+01, 5.500000E+01, 6.000000E+01, 6.500000E+01, 7.000000E+01, 7.500000E+01, 8.000000E+01, 8.500000E+01, 9.000000E+01, 9.500000E+01, 1.000000E+02, 1.050000E+02, 1.100000E+02, 1.150000E+02, 1.200000E+02, 1.250000E+02 };+const double MGH10_functor::y[16] = { 3.478000E+04, 2.861000E+04, 2.365000E+04, 1.963000E+04, 1.637000E+04, 1.372000E+04, 1.154000E+04, 9.744000E+03, 8.261000E+03, 7.030000E+03, 6.005000E+03, 5.147000E+03, 4.427000E+03, 3.820000E+03, 3.307000E+03, 2.872000E+03 };++// http://www.itl.nist.gov/div898/strd/nls/data/mgh10.shtml+void testNistMGH10(void)+{+ const int n=3;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 2., 400000., 25000.;+ // do the computation+ MGH10_functor functor;+ LevenbergMarquardt<MGH10_functor> lm(functor);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1); + VERIFY_IS_EQUAL(lm.nfev(), 284 ); + VERIFY_IS_EQUAL(lm.njev(), 249 ); + // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 8.7945855171E+01);+ // check x+ VERIFY_IS_APPROX(x[0], 5.6096364710E-03);+ VERIFY_IS_APPROX(x[1], 6.1813463463E+03);+ VERIFY_IS_APPROX(x[2], 3.4522363462E+02);++ /*+ * Second try+ */+ x<< 0.02, 4000., 250.;+ // do the computation+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 126);+ VERIFY_IS_EQUAL(lm.njev(), 116);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 8.7945855171E+01);+ // check x+ VERIFY_IS_APPROX(x[0], 5.6096364710E-03);+ VERIFY_IS_APPROX(x[1], 6.1813463463E+03);+ VERIFY_IS_APPROX(x[2], 3.4522363462E+02);+}+++struct BoxBOD_functor : DenseFunctor<double>+{+ BoxBOD_functor(void) : DenseFunctor<double>(2,6) {}+ static const double x[6];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ static const double y[6] = { 109., 149., 149., 191., 213., 224. };+ assert(b.size()==2);+ assert(fvec.size()==6);+ for(int i=0; i<6; i++)+ fvec[i] = b[0]*(1.-exp(-b[1]*x[i])) - y[i];+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==2);+ assert(fjac.rows()==6);+ assert(fjac.cols()==2);+ for(int i=0; i<6; i++) {+ double e = exp(-b[1]*x[i]);+ fjac(i,0) = 1.-e;+ fjac(i,1) = b[0]*x[i]*e;+ }+ return 0;+ }+};+const double BoxBOD_functor::x[6] = { 1., 2., 3., 5., 7., 10. };++// http://www.itl.nist.gov/div898/strd/nls/data/boxbod.shtml+void testNistBoxBOD(void)+{+ const int n=2;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 1., 1.;+ // do the computation+ BoxBOD_functor functor;+ LevenbergMarquardt<BoxBOD_functor> lm(functor);+ lm.setFtol(1.E6*NumTraits<double>::epsilon());+ lm.setXtol(1.E6*NumTraits<double>::epsilon());+ lm.setFactor(10);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 31);+ VERIFY_IS_EQUAL(lm.njev(), 25);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 1.1680088766E+03);+ // check x+ VERIFY_IS_APPROX(x[0], 2.1380940889E+02);+ VERIFY_IS_APPROX(x[1], 5.4723748542E-01);++ /*+ * Second try+ */+ x<< 100., 0.75;+ // do the computation+ lm.resetParameters();+ lm.setFtol(NumTraits<double>::epsilon());+ lm.setXtol( NumTraits<double>::epsilon());+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1); + VERIFY_IS_EQUAL(lm.nfev(), 15 ); + VERIFY_IS_EQUAL(lm.njev(), 14 ); + // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 1.1680088766E+03);+ // check x+ VERIFY_IS_APPROX(x[0], 2.1380940889E+02);+ VERIFY_IS_APPROX(x[1], 5.4723748542E-01);+}++struct MGH17_functor : DenseFunctor<double>+{+ MGH17_functor(void) : DenseFunctor<double>(5,33) {}+ static const double x[33];+ static const double y[33];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==5);+ assert(fvec.size()==33);+ for(int i=0; i<33; i++)+ fvec[i] = b[0] + b[1]*exp(-b[3]*x[i]) + b[2]*exp(-b[4]*x[i]) - y[i];+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==5);+ assert(fjac.rows()==33);+ assert(fjac.cols()==5);+ for(int i=0; i<33; i++) {+ fjac(i,0) = 1.;+ fjac(i,1) = exp(-b[3]*x[i]);+ fjac(i,2) = exp(-b[4]*x[i]);+ fjac(i,3) = -x[i]*b[1]*exp(-b[3]*x[i]);+ fjac(i,4) = -x[i]*b[2]*exp(-b[4]*x[i]);+ }+ return 0;+ }+};+const double MGH17_functor::x[33] = { 0.000000E+00, 1.000000E+01, 2.000000E+01, 3.000000E+01, 4.000000E+01, 5.000000E+01, 6.000000E+01, 7.000000E+01, 8.000000E+01, 9.000000E+01, 1.000000E+02, 1.100000E+02, 1.200000E+02, 1.300000E+02, 1.400000E+02, 1.500000E+02, 1.600000E+02, 1.700000E+02, 1.800000E+02, 1.900000E+02, 2.000000E+02, 2.100000E+02, 2.200000E+02, 2.300000E+02, 2.400000E+02, 2.500000E+02, 2.600000E+02, 2.700000E+02, 2.800000E+02, 2.900000E+02, 3.000000E+02, 3.100000E+02, 3.200000E+02 };+const double MGH17_functor::y[33] = { 8.440000E-01, 9.080000E-01, 9.320000E-01, 9.360000E-01, 9.250000E-01, 9.080000E-01, 8.810000E-01, 8.500000E-01, 8.180000E-01, 7.840000E-01, 7.510000E-01, 7.180000E-01, 6.850000E-01, 6.580000E-01, 6.280000E-01, 6.030000E-01, 5.800000E-01, 5.580000E-01, 5.380000E-01, 5.220000E-01, 5.060000E-01, 4.900000E-01, 4.780000E-01, 4.670000E-01, 4.570000E-01, 4.480000E-01, 4.380000E-01, 4.310000E-01, 4.240000E-01, 4.200000E-01, 4.140000E-01, 4.110000E-01, 4.060000E-01 };++// http://www.itl.nist.gov/div898/strd/nls/data/mgh17.shtml+void testNistMGH17(void)+{+ const int n=5;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 50., 150., -100., 1., 2.;+ // do the computation+ MGH17_functor functor;+ LevenbergMarquardt<MGH17_functor> lm(functor);+ lm.setFtol(NumTraits<double>::epsilon());+ lm.setXtol(NumTraits<double>::epsilon());+ lm.setMaxfev(1000);+ info = lm.minimize(x);++ // check return value+// VERIFY_IS_EQUAL(info, 2); //FIXME Use (lm.info() == Success)+// VERIFY_IS_EQUAL(lm.nfev(), 602 ); + VERIFY_IS_EQUAL(lm.njev(), 545 ); + // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 5.4648946975E-05);+ // check x+ VERIFY_IS_APPROX(x[0], 3.7541005211E-01);+ VERIFY_IS_APPROX(x[1], 1.9358469127E+00);+ VERIFY_IS_APPROX(x[2], -1.4646871366E+00);+ VERIFY_IS_APPROX(x[3], 1.2867534640E-02);+ VERIFY_IS_APPROX(x[4], 2.2122699662E-02);++ /*+ * Second try+ */+ x<< 0.5 ,1.5 ,-1 ,0.01 ,0.02;+ // do the computation+ lm.resetParameters();+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 18);+ VERIFY_IS_EQUAL(lm.njev(), 15);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 5.4648946975E-05);+ // check x+ VERIFY_IS_APPROX(x[0], 3.7541005211E-01);+ VERIFY_IS_APPROX(x[1], 1.9358469127E+00);+ VERIFY_IS_APPROX(x[2], -1.4646871366E+00);+ VERIFY_IS_APPROX(x[3], 1.2867534640E-02);+ VERIFY_IS_APPROX(x[4], 2.2122699662E-02);+}++struct MGH09_functor : DenseFunctor<double>+{+ MGH09_functor(void) : DenseFunctor<double>(4,11) {}+ static const double _x[11];+ static const double y[11];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==4);+ assert(fvec.size()==11);+ for(int i=0; i<11; i++) {+ double x = _x[i], xx=x*x;+ fvec[i] = b[0]*(xx+x*b[1])/(xx+x*b[2]+b[3]) - y[i];+ }+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==4);+ assert(fjac.rows()==11);+ assert(fjac.cols()==4);+ for(int i=0; i<11; i++) {+ double x = _x[i], xx=x*x;+ double factor = 1./(xx+x*b[2]+b[3]);+ fjac(i,0) = (xx+x*b[1]) * factor;+ fjac(i,1) = b[0]*x* factor;+ fjac(i,2) = - b[0]*(xx+x*b[1]) * x * factor * factor;+ fjac(i,3) = - b[0]*(xx+x*b[1]) * factor * factor;+ }+ return 0;+ }+};+const double MGH09_functor::_x[11] = { 4., 2., 1., 5.E-1 , 2.5E-01, 1.670000E-01, 1.250000E-01, 1.E-01, 8.330000E-02, 7.140000E-02, 6.250000E-02 };+const double MGH09_functor::y[11] = { 1.957000E-01, 1.947000E-01, 1.735000E-01, 1.600000E-01, 8.440000E-02, 6.270000E-02, 4.560000E-02, 3.420000E-02, 3.230000E-02, 2.350000E-02, 2.460000E-02 };++// http://www.itl.nist.gov/div898/strd/nls/data/mgh09.shtml+void testNistMGH09(void)+{+ const int n=4;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 25., 39, 41.5, 39.;+ // do the computation+ MGH09_functor functor;+ LevenbergMarquardt<MGH09_functor> lm(functor);+ lm.setMaxfev(1000);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1); + VERIFY_IS_EQUAL(lm.nfev(), 490 ); + VERIFY_IS_EQUAL(lm.njev(), 376 ); + // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 3.0750560385E-04);+ // check x+ VERIFY_IS_APPROX(x[0], 0.1928077089); // should be 1.9280693458E-01+ VERIFY_IS_APPROX(x[1], 0.19126423573); // should be 1.9128232873E-01+ VERIFY_IS_APPROX(x[2], 0.12305309914); // should be 1.2305650693E-01+ VERIFY_IS_APPROX(x[3], 0.13605395375); // should be 1.3606233068E-01++ /*+ * Second try+ */+ x<< 0.25, 0.39, 0.415, 0.39;+ // do the computation+ lm.resetParameters();+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 18);+ VERIFY_IS_EQUAL(lm.njev(), 16);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 3.0750560385E-04);+ // check x+ VERIFY_IS_APPROX(x[0], 0.19280781); // should be 1.9280693458E-01+ VERIFY_IS_APPROX(x[1], 0.19126265); // should be 1.9128232873E-01+ VERIFY_IS_APPROX(x[2], 0.12305280); // should be 1.2305650693E-01+ VERIFY_IS_APPROX(x[3], 0.13605322); // should be 1.3606233068E-01+}++++struct Bennett5_functor : DenseFunctor<double>+{+ Bennett5_functor(void) : DenseFunctor<double>(3,154) {}+ static const double x[154];+ static const double y[154];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==3);+ assert(fvec.size()==154);+ for(int i=0; i<154; i++)+ fvec[i] = b[0]* pow(b[1]+x[i],-1./b[2]) - y[i];+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==3);+ assert(fjac.rows()==154);+ assert(fjac.cols()==3);+ for(int i=0; i<154; i++) {+ double e = pow(b[1]+x[i],-1./b[2]);+ fjac(i,0) = e;+ fjac(i,1) = - b[0]*e/b[2]/(b[1]+x[i]);+ fjac(i,2) = b[0]*e*log(b[1]+x[i])/b[2]/b[2];+ }+ return 0;+ }+};+const double Bennett5_functor::x[154] = { 7.447168E0, 8.102586E0, 8.452547E0, 8.711278E0, 8.916774E0, 9.087155E0, 9.232590E0, 9.359535E0, 9.472166E0, 9.573384E0, 9.665293E0, 9.749461E0, 9.827092E0, 9.899128E0, 9.966321E0, 10.029280E0, 10.088510E0, 10.144430E0, 10.197380E0, 10.247670E0, 10.295560E0, 10.341250E0, 10.384950E0, 10.426820E0, 10.467000E0, 10.505640E0, 10.542830E0, 10.578690E0, 10.613310E0, 10.646780E0, 10.679150E0, 10.710520E0, 10.740920E0, 10.770440E0, 10.799100E0, 10.826970E0, 10.854080E0, 10.880470E0, 10.906190E0, 10.931260E0, 10.955720E0, 10.979590E0, 11.002910E0, 11.025700E0, 11.047980E0, 11.069770E0, 11.091100E0, 11.111980E0, 11.132440E0, 11.152480E0, 11.172130E0, 11.191410E0, 11.210310E0, 11.228870E0, 11.247090E0, 11.264980E0, 11.282560E0, 11.299840E0, 11.316820E0, 11.333520E0, 11.349940E0, 11.366100E0, 11.382000E0, 11.397660E0, 11.413070E0, 11.428240E0, 11.443200E0, 11.457930E0, 11.472440E0, 11.486750E0, 11.500860E0, 11.514770E0, 11.528490E0, 11.542020E0, 11.555380E0, 11.568550E0,+11.581560E0, 11.594420E0, 11.607121E0, 11.619640E0, 11.632000E0, 11.644210E0, 11.656280E0, 11.668200E0, 11.679980E0, 11.691620E0, 11.703130E0, 11.714510E0, 11.725760E0, 11.736880E0, 11.747890E0, 11.758780E0, 11.769550E0, 11.780200E0, 11.790730E0, 11.801160E0, 11.811480E0, 11.821700E0, 11.831810E0, 11.841820E0, 11.851730E0, 11.861550E0, 11.871270E0, 11.880890E0, 11.890420E0, 11.899870E0, 11.909220E0, 11.918490E0, 11.927680E0, 11.936780E0, 11.945790E0, 11.954730E0, 11.963590E0, 11.972370E0, 11.981070E0, 11.989700E0, 11.998260E0, 12.006740E0, 12.015150E0, 12.023490E0, 12.031760E0, 12.039970E0, 12.048100E0, 12.056170E0, 12.064180E0, 12.072120E0, 12.080010E0, 12.087820E0, 12.095580E0, 12.103280E0, 12.110920E0, 12.118500E0, 12.126030E0, 12.133500E0, 12.140910E0, 12.148270E0, 12.155570E0, 12.162830E0, 12.170030E0, 12.177170E0, 12.184270E0, 12.191320E0, 12.198320E0, 12.205270E0, 12.212170E0, 12.219030E0, 12.225840E0, 12.232600E0, 12.239320E0, 12.245990E0, 12.252620E0, 12.259200E0, 12.265750E0, 12.272240E0 };+const double Bennett5_functor::y[154] = { -34.834702E0 ,-34.393200E0 ,-34.152901E0 ,-33.979099E0 ,-33.845901E0 ,-33.732899E0 ,-33.640301E0 ,-33.559200E0 ,-33.486801E0 ,-33.423100E0 ,-33.365101E0 ,-33.313000E0 ,-33.260899E0 ,-33.217400E0 ,-33.176899E0 ,-33.139198E0 ,-33.101601E0 ,-33.066799E0 ,-33.035000E0 ,-33.003101E0 ,-32.971298E0 ,-32.942299E0 ,-32.916302E0 ,-32.890202E0 ,-32.864101E0 ,-32.841000E0 ,-32.817799E0 ,-32.797501E0 ,-32.774300E0 ,-32.757000E0 ,-32.733799E0 ,-32.716400E0 ,-32.699100E0 ,-32.678799E0 ,-32.661400E0 ,-32.644001E0 ,-32.626701E0 ,-32.612202E0 ,-32.597698E0 ,-32.583199E0 ,-32.568699E0 ,-32.554298E0 ,-32.539799E0 ,-32.525299E0 ,-32.510799E0 ,-32.499199E0 ,-32.487598E0 ,-32.473202E0 ,-32.461601E0 ,-32.435501E0 ,-32.435501E0 ,-32.426800E0 ,-32.412300E0 ,-32.400799E0 ,-32.392101E0 ,-32.380501E0 ,-32.366001E0 ,-32.357300E0 ,-32.348598E0 ,-32.339901E0 ,-32.328400E0 ,-32.319698E0 ,-32.311001E0 ,-32.299400E0 ,-32.290699E0 ,-32.282001E0 ,-32.273300E0 ,-32.264599E0 ,-32.256001E0 ,-32.247299E0+,-32.238602E0 ,-32.229900E0 ,-32.224098E0 ,-32.215401E0 ,-32.203800E0 ,-32.198002E0 ,-32.189400E0 ,-32.183601E0 ,-32.174900E0 ,-32.169102E0 ,-32.163300E0 ,-32.154598E0 ,-32.145901E0 ,-32.140099E0 ,-32.131401E0 ,-32.125599E0 ,-32.119801E0 ,-32.111198E0 ,-32.105400E0 ,-32.096699E0 ,-32.090900E0 ,-32.088001E0 ,-32.079300E0 ,-32.073502E0 ,-32.067699E0 ,-32.061901E0 ,-32.056099E0 ,-32.050301E0 ,-32.044498E0 ,-32.038799E0 ,-32.033001E0 ,-32.027199E0 ,-32.024300E0 ,-32.018501E0 ,-32.012699E0 ,-32.004002E0 ,-32.001099E0 ,-31.995300E0 ,-31.989500E0 ,-31.983700E0 ,-31.977900E0 ,-31.972099E0 ,-31.969299E0 ,-31.963501E0 ,-31.957701E0 ,-31.951900E0 ,-31.946100E0 ,-31.940300E0 ,-31.937401E0 ,-31.931601E0 ,-31.925800E0 ,-31.922899E0 ,-31.917101E0 ,-31.911301E0 ,-31.908400E0 ,-31.902599E0 ,-31.896900E0 ,-31.893999E0 ,-31.888201E0 ,-31.885300E0 ,-31.882401E0 ,-31.876600E0 ,-31.873699E0 ,-31.867901E0 ,-31.862101E0 ,-31.859200E0 ,-31.856300E0 ,-31.850500E0 ,-31.844700E0 ,-31.841801E0 ,-31.838900E0 ,-31.833099E0 ,-31.830200E0 ,+-31.827299E0 ,-31.821600E0 ,-31.818701E0 ,-31.812901E0 ,-31.809999E0 ,-31.807100E0 ,-31.801300E0 ,-31.798401E0 ,-31.795500E0 ,-31.789700E0 ,-31.786800E0 };++// http://www.itl.nist.gov/div898/strd/nls/data/bennett5.shtml+void testNistBennett5(void)+{+ const int n=3;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< -2000., 50., 0.8;+ // do the computation+ Bennett5_functor functor;+ LevenbergMarquardt<Bennett5_functor> lm(functor);+ lm.setMaxfev(1000);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 758);+ VERIFY_IS_EQUAL(lm.njev(), 744);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 5.2404744073E-04);+ // check x+ VERIFY_IS_APPROX(x[0], -2.5235058043E+03);+ VERIFY_IS_APPROX(x[1], 4.6736564644E+01);+ VERIFY_IS_APPROX(x[2], 9.3218483193E-01);+ /*+ * Second try+ */+ x<< -1500., 45., 0.85;+ // do the computation+ lm.resetParameters();+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 203);+ VERIFY_IS_EQUAL(lm.njev(), 192);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 5.2404744073E-04);+ // check x+ VERIFY_IS_APPROX(x[0], -2523.3007865); // should be -2.5235058043E+03+ VERIFY_IS_APPROX(x[1], 46.735705771); // should be 4.6736564644E+01);+ VERIFY_IS_APPROX(x[2], 0.93219881891); // should be 9.3218483193E-01);+}++struct thurber_functor : DenseFunctor<double>+{+ thurber_functor(void) : DenseFunctor<double>(7,37) {}+ static const double _x[37];+ static const double _y[37];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ // int called=0; printf("call hahn1_functor with iflag=%d, called=%d\n", iflag, called); if (iflag==1) called++;+ assert(b.size()==7);+ assert(fvec.size()==37);+ for(int i=0; i<37; i++) {+ double x=_x[i], xx=x*x, xxx=xx*x;+ fvec[i] = (b[0]+b[1]*x+b[2]*xx+b[3]*xxx) / (1.+b[4]*x+b[5]*xx+b[6]*xxx) - _y[i];+ }+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==7);+ assert(fjac.rows()==37);+ assert(fjac.cols()==7);+ for(int i=0; i<37; i++) {+ double x=_x[i], xx=x*x, xxx=xx*x;+ double fact = 1./(1.+b[4]*x+b[5]*xx+b[6]*xxx);+ fjac(i,0) = 1.*fact;+ fjac(i,1) = x*fact;+ fjac(i,2) = xx*fact;+ fjac(i,3) = xxx*fact;+ fact = - (b[0]+b[1]*x+b[2]*xx+b[3]*xxx) * fact * fact;+ fjac(i,4) = x*fact;+ fjac(i,5) = xx*fact;+ fjac(i,6) = xxx*fact;+ }+ return 0;+ }+};+const double thurber_functor::_x[37] = { -3.067E0, -2.981E0, -2.921E0, -2.912E0, -2.840E0, -2.797E0, -2.702E0, -2.699E0, -2.633E0, -2.481E0, -2.363E0, -2.322E0, -1.501E0, -1.460E0, -1.274E0, -1.212E0, -1.100E0, -1.046E0, -0.915E0, -0.714E0, -0.566E0, -0.545E0, -0.400E0, -0.309E0, -0.109E0, -0.103E0, 0.010E0, 0.119E0, 0.377E0, 0.790E0, 0.963E0, 1.006E0, 1.115E0, 1.572E0, 1.841E0, 2.047E0, 2.200E0 };+const double thurber_functor::_y[37] = { 80.574E0, 84.248E0, 87.264E0, 87.195E0, 89.076E0, 89.608E0, 89.868E0, 90.101E0, 92.405E0, 95.854E0, 100.696E0, 101.060E0, 401.672E0, 390.724E0, 567.534E0, 635.316E0, 733.054E0, 759.087E0, 894.206E0, 990.785E0, 1090.109E0, 1080.914E0, 1122.643E0, 1178.351E0, 1260.531E0, 1273.514E0, 1288.339E0, 1327.543E0, 1353.863E0, 1414.509E0, 1425.208E0, 1421.384E0, 1442.962E0, 1464.350E0, 1468.705E0, 1447.894E0, 1457.628E0};++// http://www.itl.nist.gov/div898/strd/nls/data/thurber.shtml+void testNistThurber(void)+{+ const int n=7;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 1000 ,1000 ,400 ,40 ,0.7,0.3,0.0 ;+ // do the computation+ thurber_functor functor;+ LevenbergMarquardt<thurber_functor> lm(functor);+ lm.setFtol(1.E4*NumTraits<double>::epsilon());+ lm.setXtol(1.E4*NumTraits<double>::epsilon());+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 39);+ VERIFY_IS_EQUAL(lm.njev(), 36);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 5.6427082397E+03);+ // check x+ VERIFY_IS_APPROX(x[0], 1.2881396800E+03);+ VERIFY_IS_APPROX(x[1], 1.4910792535E+03);+ VERIFY_IS_APPROX(x[2], 5.8323836877E+02);+ VERIFY_IS_APPROX(x[3], 7.5416644291E+01);+ VERIFY_IS_APPROX(x[4], 9.6629502864E-01);+ VERIFY_IS_APPROX(x[5], 3.9797285797E-01);+ VERIFY_IS_APPROX(x[6], 4.9727297349E-02);++ /*+ * Second try+ */+ x<< 1300 ,1500 ,500 ,75 ,1 ,0.4 ,0.05 ;+ // do the computation+ lm.resetParameters();+ lm.setFtol(1.E4*NumTraits<double>::epsilon());+ lm.setXtol(1.E4*NumTraits<double>::epsilon());+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 29);+ VERIFY_IS_EQUAL(lm.njev(), 28);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 5.6427082397E+03);+ // check x+ VERIFY_IS_APPROX(x[0], 1.2881396800E+03);+ VERIFY_IS_APPROX(x[1], 1.4910792535E+03);+ VERIFY_IS_APPROX(x[2], 5.8323836877E+02);+ VERIFY_IS_APPROX(x[3], 7.5416644291E+01);+ VERIFY_IS_APPROX(x[4], 9.6629502864E-01);+ VERIFY_IS_APPROX(x[5], 3.9797285797E-01);+ VERIFY_IS_APPROX(x[6], 4.9727297349E-02);+}++struct rat43_functor : DenseFunctor<double>+{+ rat43_functor(void) : DenseFunctor<double>(4,15) {}+ static const double x[15];+ static const double y[15];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==4);+ assert(fvec.size()==15);+ for(int i=0; i<15; i++)+ fvec[i] = b[0] * pow(1.+exp(b[1]-b[2]*x[i]),-1./b[3]) - y[i];+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==4);+ assert(fjac.rows()==15);+ assert(fjac.cols()==4);+ for(int i=0; i<15; i++) {+ double e = exp(b[1]-b[2]*x[i]);+ double power = -1./b[3];+ fjac(i,0) = pow(1.+e, power);+ fjac(i,1) = power*b[0]*e*pow(1.+e, power-1.);+ fjac(i,2) = -power*b[0]*e*x[i]*pow(1.+e, power-1.);+ fjac(i,3) = b[0]*power*power*log(1.+e)*pow(1.+e, power);+ }+ return 0;+ }+};+const double rat43_functor::x[15] = { 1., 2., 3., 4., 5., 6., 7., 8., 9., 10., 11., 12., 13., 14., 15. };+const double rat43_functor::y[15] = { 16.08, 33.83, 65.80, 97.20, 191.55, 326.20, 386.87, 520.53, 590.03, 651.92, 724.93, 699.56, 689.96, 637.56, 717.41 };++// http://www.itl.nist.gov/div898/strd/nls/data/ratkowsky3.shtml+void testNistRat43(void)+{+ const int n=4;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 100., 10., 1., 1.;+ // do the computation+ rat43_functor functor;+ LevenbergMarquardt<rat43_functor> lm(functor);+ lm.setFtol(1.E6*NumTraits<double>::epsilon());+ lm.setXtol(1.E6*NumTraits<double>::epsilon());+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 27);+ VERIFY_IS_EQUAL(lm.njev(), 20);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 8.7864049080E+03);+ // check x+ VERIFY_IS_APPROX(x[0], 6.9964151270E+02);+ VERIFY_IS_APPROX(x[1], 5.2771253025E+00);+ VERIFY_IS_APPROX(x[2], 7.5962938329E-01);+ VERIFY_IS_APPROX(x[3], 1.2792483859E+00);++ /*+ * Second try+ */+ x<< 700., 5., 0.75, 1.3;+ // do the computation+ lm.resetParameters();+ lm.setFtol(1.E5*NumTraits<double>::epsilon());+ lm.setXtol(1.E5*NumTraits<double>::epsilon());+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 9);+ VERIFY_IS_EQUAL(lm.njev(), 8);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 8.7864049080E+03);+ // check x+ VERIFY_IS_APPROX(x[0], 6.9964151270E+02);+ VERIFY_IS_APPROX(x[1], 5.2771253025E+00);+ VERIFY_IS_APPROX(x[2], 7.5962938329E-01);+ VERIFY_IS_APPROX(x[3], 1.2792483859E+00);+}++++struct eckerle4_functor : DenseFunctor<double>+{+ eckerle4_functor(void) : DenseFunctor<double>(3,35) {}+ static const double x[35];+ static const double y[35];+ int operator()(const VectorXd &b, VectorXd &fvec)+ {+ assert(b.size()==3);+ assert(fvec.size()==35);+ for(int i=0; i<35; i++)+ fvec[i] = b[0]/b[1] * exp(-0.5*(x[i]-b[2])*(x[i]-b[2])/(b[1]*b[1])) - y[i];+ return 0;+ }+ int df(const VectorXd &b, MatrixXd &fjac)+ {+ assert(b.size()==3);+ assert(fjac.rows()==35);+ assert(fjac.cols()==3);+ for(int i=0; i<35; i++) {+ double b12 = b[1]*b[1];+ double e = exp(-0.5*(x[i]-b[2])*(x[i]-b[2])/b12);+ fjac(i,0) = e / b[1];+ fjac(i,1) = ((x[i]-b[2])*(x[i]-b[2])/b12-1.) * b[0]*e/b12;+ fjac(i,2) = (x[i]-b[2])*e*b[0]/b[1]/b12;+ }+ return 0;+ }+};+const double eckerle4_functor::x[35] = { 400.0, 405.0, 410.0, 415.0, 420.0, 425.0, 430.0, 435.0, 436.5, 438.0, 439.5, 441.0, 442.5, 444.0, 445.5, 447.0, 448.5, 450.0, 451.5, 453.0, 454.5, 456.0, 457.5, 459.0, 460.5, 462.0, 463.5, 465.0, 470.0, 475.0, 480.0, 485.0, 490.0, 495.0, 500.0};+const double eckerle4_functor::y[35] = { 0.0001575, 0.0001699, 0.0002350, 0.0003102, 0.0004917, 0.0008710, 0.0017418, 0.0046400, 0.0065895, 0.0097302, 0.0149002, 0.0237310, 0.0401683, 0.0712559, 0.1264458, 0.2073413, 0.2902366, 0.3445623, 0.3698049, 0.3668534, 0.3106727, 0.2078154, 0.1164354, 0.0616764, 0.0337200, 0.0194023, 0.0117831, 0.0074357, 0.0022732, 0.0008800, 0.0004579, 0.0002345, 0.0001586, 0.0001143, 0.0000710 };++// http://www.itl.nist.gov/div898/strd/nls/data/eckerle4.shtml+void testNistEckerle4(void)+{+ const int n=3;+ int info;++ VectorXd x(n);++ /*+ * First try+ */+ x<< 1., 10., 500.;+ // do the computation+ eckerle4_functor functor;+ LevenbergMarquardt<eckerle4_functor> lm(functor);+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 18);+ VERIFY_IS_EQUAL(lm.njev(), 15);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 1.4635887487E-03);+ // check x+ VERIFY_IS_APPROX(x[0], 1.5543827178);+ VERIFY_IS_APPROX(x[1], 4.0888321754);+ VERIFY_IS_APPROX(x[2], 4.5154121844E+02);++ /*+ * Second try+ */+ x<< 1.5, 5., 450.;+ // do the computation+ info = lm.minimize(x);++ // check return value+ VERIFY_IS_EQUAL(info, 1);+ VERIFY_IS_EQUAL(lm.nfev(), 7);+ VERIFY_IS_EQUAL(lm.njev(), 6);+ // check norm^2+ VERIFY_IS_APPROX(lm.fvec().squaredNorm(), 1.4635887487E-03);+ // check x+ VERIFY_IS_APPROX(x[0], 1.5543827178);+ VERIFY_IS_APPROX(x[1], 4.0888321754);+ VERIFY_IS_APPROX(x[2], 4.5154121844E+02);+}++void test_levenberg_marquardt()+{+ // Tests using the examples provided by (c)minpack+ CALL_SUBTEST(testLmder1());+ CALL_SUBTEST(testLmder());+ CALL_SUBTEST(testLmdif1());+// CALL_SUBTEST(testLmstr1());+// CALL_SUBTEST(testLmstr());+ CALL_SUBTEST(testLmdif());++ // NIST tests, level of difficulty = "Lower"+ CALL_SUBTEST(testNistMisra1a());+ CALL_SUBTEST(testNistChwirut2());++ // NIST tests, level of difficulty = "Average"+ CALL_SUBTEST(testNistHahn1());+ CALL_SUBTEST(testNistMisra1d());+ CALL_SUBTEST(testNistMGH17());+ CALL_SUBTEST(testNistLanczos1());++// // NIST tests, level of difficulty = "Higher"+ CALL_SUBTEST(testNistRat42());+ CALL_SUBTEST(testNistMGH10());+ CALL_SUBTEST(testNistBoxBOD());+// CALL_SUBTEST(testNistMGH09());+ CALL_SUBTEST(testNistBennett5());+ CALL_SUBTEST(testNistThurber());+ CALL_SUBTEST(testNistRat43());+ CALL_SUBTEST(testNistEckerle4());+}
+ eigen3/unsupported/test/matrix_exponential.cpp view
@@ -0,0 +1,141 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009 Jitse Niesen <jitse@maths.leeds.ac.uk>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "matrix_functions.h"++double binom(int n, int k)+{+ double res = 1;+ for (int i=0; i<k; i++)+ res = res * (n-k+i+1) / (i+1);+ return res;+}++template <typename T>+T expfn(T x, int)+{+ return std::exp(x);+}++template <typename T>+void test2dRotation(double tol)+{+ Matrix<T,2,2> A, B, C;+ T angle;++ A << 0, 1, -1, 0;+ for (int i=0; i<=20; i++)+ {+ angle = static_cast<T>(pow(10, i / 5. - 2));+ B << std::cos(angle), std::sin(angle), -std::sin(angle), std::cos(angle);++ C = (angle*A).matrixFunction(expfn);+ std::cout << "test2dRotation: i = " << i << " error funm = " << relerr(C, B);+ VERIFY(C.isApprox(B, static_cast<T>(tol)));++ C = (angle*A).exp();+ std::cout << " error expm = " << relerr(C, B) << "\n";+ VERIFY(C.isApprox(B, static_cast<T>(tol)));+ }+}++template <typename T>+void test2dHyperbolicRotation(double tol)+{+ Matrix<std::complex<T>,2,2> A, B, C;+ std::complex<T> imagUnit(0,1);+ T angle, ch, sh;++ for (int i=0; i<=20; i++)+ {+ angle = static_cast<T>((i-10) / 2.0);+ ch = std::cosh(angle);+ sh = std::sinh(angle);+ A << 0, angle*imagUnit, -angle*imagUnit, 0;+ B << ch, sh*imagUnit, -sh*imagUnit, ch;++ C = A.matrixFunction(expfn);+ std::cout << "test2dHyperbolicRotation: i = " << i << " error funm = " << relerr(C, B);+ VERIFY(C.isApprox(B, static_cast<T>(tol)));++ C = A.exp();+ std::cout << " error expm = " << relerr(C, B) << "\n";+ VERIFY(C.isApprox(B, static_cast<T>(tol)));+ }+}++template <typename T>+void testPascal(double tol)+{+ for (int size=1; size<20; size++)+ {+ Matrix<T,Dynamic,Dynamic> A(size,size), B(size,size), C(size,size);+ A.setZero();+ for (int i=0; i<size-1; i++)+ A(i+1,i) = static_cast<T>(i+1);+ B.setZero();+ for (int i=0; i<size; i++)+ for (int j=0; j<=i; j++)+ B(i,j) = static_cast<T>(binom(i,j));++ C = A.matrixFunction(expfn);+ std::cout << "testPascal: size = " << size << " error funm = " << relerr(C, B);+ VERIFY(C.isApprox(B, static_cast<T>(tol)));++ C = A.exp();+ std::cout << " error expm = " << relerr(C, B) << "\n";+ VERIFY(C.isApprox(B, static_cast<T>(tol)));+ }+}++template<typename MatrixType>+void randomTest(const MatrixType& m, double tol)+{+ /* this test covers the following files:+ Inverse.h+ */+ typename MatrixType::Index rows = m.rows();+ typename MatrixType::Index cols = m.cols();+ MatrixType m1(rows, cols), m2(rows, cols), identity = MatrixType::Identity(rows, cols);++ typedef typename NumTraits<typename internal::traits<MatrixType>::Scalar>::Real RealScalar;++ for(int i = 0; i < g_repeat; i++) {+ m1 = MatrixType::Random(rows, cols);++ m2 = m1.matrixFunction(expfn) * (-m1).matrixFunction(expfn);+ std::cout << "randomTest: error funm = " << relerr(identity, m2);+ VERIFY(identity.isApprox(m2, static_cast<RealScalar>(tol)));++ m2 = m1.exp() * (-m1).exp();+ std::cout << " error expm = " << relerr(identity, m2) << "\n";+ VERIFY(identity.isApprox(m2, static_cast<RealScalar>(tol)));+ }+}++void test_matrix_exponential()+{+ CALL_SUBTEST_2(test2dRotation<double>(1e-13));+ CALL_SUBTEST_1(test2dRotation<float>(2e-5)); // was 1e-5, relaxed for clang 2.8 / linux / x86-64+ CALL_SUBTEST_8(test2dRotation<long double>(1e-13)); + CALL_SUBTEST_2(test2dHyperbolicRotation<double>(1e-14));+ CALL_SUBTEST_1(test2dHyperbolicRotation<float>(1e-5));+ CALL_SUBTEST_8(test2dHyperbolicRotation<long double>(1e-14));+ CALL_SUBTEST_6(testPascal<float>(1e-6));+ CALL_SUBTEST_5(testPascal<double>(1e-15));+ CALL_SUBTEST_2(randomTest(Matrix2d(), 1e-13));+ CALL_SUBTEST_7(randomTest(Matrix<double,3,3,RowMajor>(), 1e-13));+ CALL_SUBTEST_3(randomTest(Matrix4cd(), 1e-13));+ CALL_SUBTEST_4(randomTest(MatrixXd(8,8), 1e-13));+ CALL_SUBTEST_1(randomTest(Matrix2f(), 1e-4));+ CALL_SUBTEST_5(randomTest(Matrix3cf(), 1e-4));+ CALL_SUBTEST_1(randomTest(Matrix4f(), 1e-4));+ CALL_SUBTEST_6(randomTest(MatrixXf(8,8), 1e-4));+ CALL_SUBTEST_9(randomTest(Matrix<long double,Dynamic,Dynamic>(7,7), 1e-13));+}
+ eigen3/unsupported/test/matrix_function.cpp view
@@ -0,0 +1,193 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010 Jitse Niesen <jitse@maths.leeds.ac.uk>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <unsupported/Eigen/MatrixFunctions>++// Variant of VERIFY_IS_APPROX which uses absolute error instead of+// relative error.+#define VERIFY_IS_APPROX_ABS(a, b) VERIFY(test_isApprox_abs(a, b))++template<typename Type1, typename Type2>+inline bool test_isApprox_abs(const Type1& a, const Type2& b)+{+ return ((a-b).array().abs() < test_precision<typename Type1::RealScalar>()).all();+}+++// Returns a matrix with eigenvalues clustered around 0, 1 and 2.+template<typename MatrixType>+MatrixType randomMatrixWithRealEivals(const typename MatrixType::Index size)+{+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::RealScalar RealScalar;+ MatrixType diag = MatrixType::Zero(size, size);+ for (Index i = 0; i < size; ++i) {+ diag(i, i) = Scalar(RealScalar(internal::random<int>(0,2)))+ + internal::random<Scalar>() * Scalar(RealScalar(0.01));+ }+ MatrixType A = MatrixType::Random(size, size);+ HouseholderQR<MatrixType> QRofA(A);+ return QRofA.householderQ().inverse() * diag * QRofA.householderQ();+}++template <typename MatrixType, int IsComplex = NumTraits<typename internal::traits<MatrixType>::Scalar>::IsComplex>+struct randomMatrixWithImagEivals+{+ // Returns a matrix with eigenvalues clustered around 0 and +/- i.+ static MatrixType run(const typename MatrixType::Index size);+};++// Partial specialization for real matrices+template<typename MatrixType>+struct randomMatrixWithImagEivals<MatrixType, 0>+{+ static MatrixType run(const typename MatrixType::Index size)+ {+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ MatrixType diag = MatrixType::Zero(size, size);+ Index i = 0;+ while (i < size) {+ Index randomInt = internal::random<Index>(-1, 1);+ if (randomInt == 0 || i == size-1) {+ diag(i, i) = internal::random<Scalar>() * Scalar(0.01);+ ++i;+ } else {+ Scalar alpha = Scalar(randomInt) + internal::random<Scalar>() * Scalar(0.01);+ diag(i, i+1) = alpha;+ diag(i+1, i) = -alpha;+ i += 2;+ }+ }+ MatrixType A = MatrixType::Random(size, size);+ HouseholderQR<MatrixType> QRofA(A);+ return QRofA.householderQ().inverse() * diag * QRofA.householderQ();+ }+};++// Partial specialization for complex matrices+template<typename MatrixType>+struct randomMatrixWithImagEivals<MatrixType, 1>+{+ static MatrixType run(const typename MatrixType::Index size)+ {+ typedef typename MatrixType::Index Index;+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::RealScalar RealScalar;+ const Scalar imagUnit(0, 1);+ MatrixType diag = MatrixType::Zero(size, size);+ for (Index i = 0; i < size; ++i) {+ diag(i, i) = Scalar(RealScalar(internal::random<Index>(-1, 1))) * imagUnit+ + internal::random<Scalar>() * Scalar(RealScalar(0.01));+ }+ MatrixType A = MatrixType::Random(size, size);+ HouseholderQR<MatrixType> QRofA(A);+ return QRofA.householderQ().inverse() * diag * QRofA.householderQ();+ }+};+++template<typename MatrixType>+void testMatrixExponential(const MatrixType& A)+{+ typedef typename internal::traits<MatrixType>::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef std::complex<RealScalar> ComplexScalar;++ VERIFY_IS_APPROX(A.exp(), A.matrixFunction(StdStemFunctions<ComplexScalar>::exp));+}++template<typename MatrixType>+void testMatrixLogarithm(const MatrixType& A)+{+ typedef typename internal::traits<MatrixType>::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;++ MatrixType scaledA;+ RealScalar maxImagPartOfSpectrum = A.eigenvalues().imag().cwiseAbs().maxCoeff();+ if (maxImagPartOfSpectrum >= 0.9 * M_PI)+ scaledA = A * 0.9 * M_PI / maxImagPartOfSpectrum;+ else+ scaledA = A;++ // identity X.exp().log() = X only holds if Im(lambda) < pi for all eigenvalues of X+ MatrixType expA = scaledA.exp();+ MatrixType logExpA = expA.log();+ VERIFY_IS_APPROX(logExpA, scaledA);+}++template<typename MatrixType>+void testHyperbolicFunctions(const MatrixType& A)+{+ // Need to use absolute error because of possible cancellation when+ // adding/subtracting expA and expmA.+ VERIFY_IS_APPROX_ABS(A.sinh(), (A.exp() - (-A).exp()) / 2);+ VERIFY_IS_APPROX_ABS(A.cosh(), (A.exp() + (-A).exp()) / 2);+}++template<typename MatrixType>+void testGonioFunctions(const MatrixType& A)+{+ typedef typename MatrixType::Scalar Scalar;+ typedef typename NumTraits<Scalar>::Real RealScalar;+ typedef std::complex<RealScalar> ComplexScalar;+ typedef Matrix<ComplexScalar, MatrixType::RowsAtCompileTime, + MatrixType::ColsAtCompileTime, MatrixType::Options> ComplexMatrix;++ ComplexScalar imagUnit(0,1);+ ComplexScalar two(2,0);++ ComplexMatrix Ac = A.template cast<ComplexScalar>();+ + ComplexMatrix exp_iA = (imagUnit * Ac).exp();+ ComplexMatrix exp_miA = (-imagUnit * Ac).exp();+ + ComplexMatrix sinAc = A.sin().template cast<ComplexScalar>();+ VERIFY_IS_APPROX_ABS(sinAc, (exp_iA - exp_miA) / (two*imagUnit));+ + ComplexMatrix cosAc = A.cos().template cast<ComplexScalar>();+ VERIFY_IS_APPROX_ABS(cosAc, (exp_iA + exp_miA) / 2);+}++template<typename MatrixType>+void testMatrix(const MatrixType& A)+{+ testMatrixExponential(A);+ testMatrixLogarithm(A);+ testHyperbolicFunctions(A);+ testGonioFunctions(A);+}++template<typename MatrixType>+void testMatrixType(const MatrixType& m)+{+ // Matrices with clustered eigenvalue lead to different code paths+ // in MatrixFunction.h and are thus useful for testing.+ typedef typename MatrixType::Index Index;++ const Index size = m.rows();+ for (int i = 0; i < g_repeat; i++) {+ testMatrix(MatrixType::Random(size, size).eval());+ testMatrix(randomMatrixWithRealEivals<MatrixType>(size));+ testMatrix(randomMatrixWithImagEivals<MatrixType>::run(size));+ }+}++void test_matrix_function()+{+ CALL_SUBTEST_1(testMatrixType(Matrix<float,1,1>()));+ CALL_SUBTEST_2(testMatrixType(Matrix3cf()));+ CALL_SUBTEST_3(testMatrixType(MatrixXf(8,8)));+ CALL_SUBTEST_4(testMatrixType(Matrix2d()));+ CALL_SUBTEST_5(testMatrixType(Matrix<double,5,5,RowMajor>()));+ CALL_SUBTEST_6(testMatrixType(Matrix4cd()));+ CALL_SUBTEST_7(testMatrixType(MatrixXd(13,13)));+}
+ eigen3/unsupported/test/matrix_functions.h view
@@ -0,0 +1,47 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2009-2011 Jitse Niesen <jitse@maths.leeds.ac.uk>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <unsupported/Eigen/MatrixFunctions>++template <typename MatrixType, int IsComplex = NumTraits<typename internal::traits<MatrixType>::Scalar>::IsComplex>+struct generateTestMatrix;++// for real matrices, make sure none of the eigenvalues are negative+template <typename MatrixType>+struct generateTestMatrix<MatrixType,0>+{+ static void run(MatrixType& result, typename MatrixType::Index size)+ {+ MatrixType mat = MatrixType::Random(size, size);+ EigenSolver<MatrixType> es(mat);+ typename EigenSolver<MatrixType>::EigenvalueType eivals = es.eigenvalues();+ for (typename MatrixType::Index i = 0; i < size; ++i) {+ if (eivals(i).imag() == 0 && eivals(i).real() < 0)+ eivals(i) = -eivals(i);+ }+ result = (es.eigenvectors() * eivals.asDiagonal() * es.eigenvectors().inverse()).real();+ }+};++// for complex matrices, any matrix is fine+template <typename MatrixType>+struct generateTestMatrix<MatrixType,1>+{+ static void run(MatrixType& result, typename MatrixType::Index size)+ {+ result = MatrixType::Random(size, size);+ }+};++template <typename Derived, typename OtherDerived>+double relerr(const MatrixBase<Derived>& A, const MatrixBase<OtherDerived>& B)+{+ return std::sqrt((A - B).cwiseAbs2().sum() / (std::min)(A.cwiseAbs2().sum(), B.cwiseAbs2().sum()));+}
+ eigen3/unsupported/test/matrix_power.cpp view
@@ -0,0 +1,133 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2012 Chen-Pang He <jdh8@ms63.hinet.net>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "matrix_functions.h"++template <typename MatrixType, int IsComplex = NumTraits<typename MatrixType::Scalar>::IsComplex>+struct generateTriangularMatrix;++// for real matrices, make sure none of the eigenvalues are negative+template <typename MatrixType>+struct generateTriangularMatrix<MatrixType,0>+{+ static void run(MatrixType& result, typename MatrixType::Index size)+ {+ result.resize(size, size);+ result.template triangularView<Upper>() = MatrixType::Random(size, size);+ for (typename MatrixType::Index i = 0; i < size; ++i)+ result.coeffRef(i,i) = std::abs(result.coeff(i,i));+ }+};++// for complex matrices, any matrix is fine+template <typename MatrixType>+struct generateTriangularMatrix<MatrixType,1>+{+ static void run(MatrixType& result, typename MatrixType::Index size)+ {+ result.resize(size, size);+ result.template triangularView<Upper>() = MatrixType::Random(size, size);+ }+};++template<typename T>+void test2dRotation(double tol)+{+ Matrix<T,2,2> A, B, C;+ T angle, c, s;++ A << 0, 1, -1, 0;+ MatrixPower<Matrix<T,2,2> > Apow(A);++ for (int i=0; i<=20; ++i) {+ angle = pow(10, (i-10) / 5.);+ c = std::cos(angle);+ s = std::sin(angle);+ B << c, s, -s, c;++ C = Apow(std::ldexp(angle,1) / M_PI);+ std::cout << "test2dRotation: i = " << i << " error powerm = " << relerr(C,B) << '\n';+ VERIFY(C.isApprox(B, static_cast<T>(tol)));+ }+}++template<typename T>+void test2dHyperbolicRotation(double tol)+{+ Matrix<std::complex<T>,2,2> A, B, C;+ T angle, ch = std::cosh((T)1);+ std::complex<T> ish(0, std::sinh((T)1));++ A << ch, ish, -ish, ch;+ MatrixPower<Matrix<std::complex<T>,2,2> > Apow(A);++ for (int i=0; i<=20; ++i) {+ angle = std::ldexp(static_cast<T>(i-10), -1);+ ch = std::cosh(angle);+ ish = std::complex<T>(0, std::sinh(angle));+ B << ch, ish, -ish, ch;++ C = Apow(angle);+ std::cout << "test2dHyperbolicRotation: i = " << i << " error powerm = " << relerr(C,B) << '\n';+ VERIFY(C.isApprox(B, static_cast<T>(tol)));+ }+}++template<typename MatrixType>+void testExponentLaws(const MatrixType& m, double tol)+{+ typedef typename MatrixType::RealScalar RealScalar;+ MatrixType m1, m2, m3, m4, m5;+ RealScalar x, y;++ for (int i=0; i < g_repeat; ++i) {+ generateTestMatrix<MatrixType>::run(m1, m.rows());+ MatrixPower<MatrixType> mpow(m1);++ x = internal::random<RealScalar>();+ y = internal::random<RealScalar>();+ m2 = mpow(x);+ m3 = mpow(y);++ m4 = mpow(x+y);+ m5.noalias() = m2 * m3;+ VERIFY(m4.isApprox(m5, static_cast<RealScalar>(tol)));++ m4 = mpow(x*y);+ m5 = m2.pow(y);+ VERIFY(m4.isApprox(m5, static_cast<RealScalar>(tol)));++ m4 = (std::abs(x) * m1).pow(y);+ m5 = std::pow(std::abs(x), y) * m3;+ VERIFY(m4.isApprox(m5, static_cast<RealScalar>(tol)));+ }+}++typedef Matrix<double,3,3,RowMajor> Matrix3dRowMajor;+typedef Matrix<long double,Dynamic,Dynamic> MatrixXe;+ +void test_matrix_power()+{+ CALL_SUBTEST_2(test2dRotation<double>(1e-13));+ CALL_SUBTEST_1(test2dRotation<float>(2e-5)); // was 1e-5, relaxed for clang 2.8 / linux / x86-64+ CALL_SUBTEST_9(test2dRotation<long double>(1e-13)); + CALL_SUBTEST_2(test2dHyperbolicRotation<double>(1e-14));+ CALL_SUBTEST_1(test2dHyperbolicRotation<float>(1e-5));+ CALL_SUBTEST_9(test2dHyperbolicRotation<long double>(1e-14));++ CALL_SUBTEST_2(testExponentLaws(Matrix2d(), 1e-13));+ CALL_SUBTEST_7(testExponentLaws(Matrix3dRowMajor(), 1e-13));+ CALL_SUBTEST_3(testExponentLaws(Matrix4cd(), 1e-13));+ CALL_SUBTEST_4(testExponentLaws(MatrixXd(8,8), 2e-12));+ CALL_SUBTEST_1(testExponentLaws(Matrix2f(), 1e-4));+ CALL_SUBTEST_5(testExponentLaws(Matrix3cf(), 1e-4));+ CALL_SUBTEST_8(testExponentLaws(Matrix4f(), 1e-4));+ CALL_SUBTEST_6(testExponentLaws(MatrixXf(2,2), 1e-3)); // see bug 614+ CALL_SUBTEST_9(testExponentLaws(MatrixXe(7,7), 1e-13));+}
+ eigen3/unsupported/test/matrix_square_root.cpp view
@@ -0,0 +1,31 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Jitse Niesen <jitse@maths.leeds.ac.uk>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "matrix_functions.h"++template<typename MatrixType>+void testMatrixSqrt(const MatrixType& m)+{+ MatrixType A;+ generateTestMatrix<MatrixType>::run(A, m.rows());+ MatrixType sqrtA = A.sqrt();+ VERIFY_IS_APPROX(sqrtA * sqrtA, A);+}++void test_matrix_square_root()+{+ for (int i = 0; i < g_repeat; i++) {+ CALL_SUBTEST_1(testMatrixSqrt(Matrix3cf()));+ CALL_SUBTEST_2(testMatrixSqrt(MatrixXcd(12,12)));+ CALL_SUBTEST_3(testMatrixSqrt(Matrix4f()));+ CALL_SUBTEST_4(testMatrixSqrt(Matrix<double,Dynamic,Dynamic,RowMajor>(9, 9)));+ CALL_SUBTEST_5(testMatrixSqrt(Matrix<float,1,1>()));+ CALL_SUBTEST_5(testMatrixSqrt(Matrix<std::complex<float>,1,1>()));+ }+}
+ eigen3/unsupported/test/minres.cpp view
@@ -0,0 +1,49 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2011 Gael Guennebaud <g.gael@free.fr>+// Copyright (C) 2012 Giacomo Po <gpo@ucla.edu>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.+#include <cmath>++#include "../../test/sparse_solver.h"+#include <Eigen/IterativeSolvers>++template<typename T> void test_minres_T()+{+ MINRES<SparseMatrix<T>, Lower|Upper, DiagonalPreconditioner<T> > minres_colmajor_diag;+ MINRES<SparseMatrix<T>, Lower, IdentityPreconditioner > minres_colmajor_lower_I;+ MINRES<SparseMatrix<T>, Upper, IdentityPreconditioner > minres_colmajor_upper_I;+// MINRES<SparseMatrix<T>, Lower, IncompleteLUT<T> > minres_colmajor_ilut;+ //minres<SparseMatrix<T>, SSORPreconditioner<T> > minres_colmajor_ssor;+++// CALL_SUBTEST( check_sparse_square_solving(minres_colmajor_diag) );+ // CALL_SUBTEST( check_sparse_square_solving(minres_colmajor_ilut) );+ //CALL_SUBTEST( check_sparse_square_solving(minres_colmajor_ssor) );++ // Diagonal preconditioner+ MINRES<SparseMatrix<T>, Lower, DiagonalPreconditioner<T> > minres_colmajor_lower_diag;+ MINRES<SparseMatrix<T>, Upper, DiagonalPreconditioner<T> > minres_colmajor_upper_diag;+ MINRES<SparseMatrix<T>, Upper|Lower, DiagonalPreconditioner<T> > minres_colmajor_uplo_diag;+ + // call tests for SPD matrix+ CALL_SUBTEST( check_sparse_spd_solving(minres_colmajor_lower_I) );+ CALL_SUBTEST( check_sparse_spd_solving(minres_colmajor_upper_I) );+ + CALL_SUBTEST( check_sparse_spd_solving(minres_colmajor_lower_diag) );+ CALL_SUBTEST( check_sparse_spd_solving(minres_colmajor_upper_diag) );+// CALL_SUBTEST( check_sparse_spd_solving(minres_colmajor_uplo_diag) );+ + // TO DO: symmetric semi-definite matrix+ // TO DO: symmetric indefinite matrix+}++void test_minres()+{+ CALL_SUBTEST_1(test_minres_T<double>());+// CALL_SUBTEST_2(test_minres_T<std::complex<double> >());+}
+ eigen3/unsupported/test/mpreal/mpreal.h view
@@ -0,0 +1,3074 @@+/* + MPFR C++: Multi-precision floating point number class for C++. + Based on MPFR library: http://mpfr.org + + Project homepage: http://www.holoborodko.com/pavel/mpfr + Contact e-mail: pavel@holoborodko.com + + Copyright (c) 2008-2014 Pavel Holoborodko + + Contributors: + Dmitriy Gubanov, Konstantin Holoborodko, Brian Gladman, + Helmut Jarausch, Fokko Beekhof, Ulrich Mutze, Heinz van Saanen, + Pere Constans, Peter van Hoof, Gael Guennebaud, Tsai Chia Cheng, + Alexei Zubanov, Jauhien Piatlicki, Victor Berger, John Westwood, + Petr Aleksandrov, Orion Poplawski, Charles Karney. + + Licensing: + (A) MPFR C++ is under GNU General Public License ("GPL"). + + (B) Non-free licenses may also be purchased from the author, for users who + do not want their programs protected by the GPL. + + The non-free licenses are for users that wish to use MPFR C++ in + their products but are unwilling to release their software + under the GPL (which would require them to release source code + and allow free redistribution). + + Such users can purchase an unlimited-use license from the author. + Contact us for more details. + + GNU General Public License ("GPL") copyright permissions statement: + ************************************************************************** + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef __MPREAL_H__ +#define __MPREAL_H__ + +#include <string> +#include <iostream> +#include <sstream> +#include <stdexcept> +#include <cfloat> +#include <cmath> +#include <cstring> +#include <limits> + +// Options +// FIXME HAVE_INT64_SUPPORT leads to clashes with long int and int64_t on some systems. +//#define MPREAL_HAVE_INT64_SUPPORT // Enable int64_t support if possible. Available only for MSVC 2010 & GCC. +#define MPREAL_HAVE_MSVC_DEBUGVIEW // Enable Debugger Visualizer for "Debug" builds in MSVC. +#define MPREAL_HAVE_DYNAMIC_STD_NUMERIC_LIMITS // Enable extended std::numeric_limits<mpfr::mpreal> specialization. + // Meaning that "digits", "round_style" and similar members are defined as functions, not constants. + // See std::numeric_limits<mpfr::mpreal> at the end of the file for more information. + +// Library version +#define MPREAL_VERSION_MAJOR 3 +#define MPREAL_VERSION_MINOR 5 +#define MPREAL_VERSION_PATCHLEVEL 9 +#define MPREAL_VERSION_STRING "3.5.9" + +// Detect compiler using signatures from http://predef.sourceforge.net/ +#if defined(__GNUC__) && defined(__INTEL_COMPILER) + #define IsInf(x) isinf(x) // Intel ICC compiler on Linux + +#elif defined(_MSC_VER) // Microsoft Visual C++ + #define IsInf(x) (!_finite(x)) + +#else + #define IsInf(x) std::isinf(x) // GNU C/C++ (and/or other compilers), just hope for C99 conformance +#endif + +// A Clang feature extension to determine compiler features. +#ifndef __has_feature + #define __has_feature(x) 0 +#endif + +// Detect support for r-value references (move semantic). Borrowed from Eigen. +#if (__has_feature(cxx_rvalue_references) || \ + defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \ + (defined(_MSC_VER) && _MSC_VER >= 1600)) + + #define MPREAL_HAVE_MOVE_SUPPORT + + // Use fields in mpfr_t structure to check if it was initialized / set dummy initialization + #define mpfr_is_initialized(x) (0 != (x)->_mpfr_d) + #define mpfr_set_uninitialized(x) ((x)->_mpfr_d = 0 ) +#endif + +// Detect support for explicit converters. +#if (__has_feature(cxx_explicit_conversions) || \ + defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \ + (defined(_MSC_VER) && _MSC_VER >= 1800)) + + #define MPREAL_HAVE_EXPLICIT_CONVERTERS +#endif + +// Detect available 64-bit capabilities +#if defined(MPREAL_HAVE_INT64_SUPPORT) + + #define MPFR_USE_INTMAX_T // Should be defined before mpfr.h + + #if defined(_MSC_VER) // MSVC + Windows + #if (_MSC_VER >= 1600) + #include <stdint.h> // <stdint.h> is available only in msvc2010! + + #else // MPFR relies on intmax_t which is available only in msvc2010 + #undef MPREAL_HAVE_INT64_SUPPORT // Besides, MPFR & MPIR have to be compiled with msvc2010 + #undef MPFR_USE_INTMAX_T // Since we cannot detect this, disable x64 by default + // Someone should change this manually if needed. + #endif + + #elif defined (__GNUC__) && defined(__linux__) + #if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(__ia64) || defined(__itanium__) || defined(_M_IA64) || defined (__PPC64__) + #undef MPREAL_HAVE_INT64_SUPPORT // Remove all shaman dances for x64 builds since + #undef MPFR_USE_INTMAX_T // GCC already supports x64 as of "long int" is 64-bit integer, nothing left to do + #else + #include <stdint.h> // use int64_t, uint64_t otherwise + #endif + + #else + #include <stdint.h> // rely on int64_t, uint64_t in all other cases, Mac OSX, etc. + #endif + +#endif + +#if defined(MPREAL_HAVE_MSVC_DEBUGVIEW) && defined(_MSC_VER) && defined(_DEBUG) + #define MPREAL_MSVC_DEBUGVIEW_CODE DebugView = toString(); + #define MPREAL_MSVC_DEBUGVIEW_DATA std::string DebugView; +#else + #define MPREAL_MSVC_DEBUGVIEW_CODE + #define MPREAL_MSVC_DEBUGVIEW_DATA +#endif + +#include <mpfr.h> + +#if (MPFR_VERSION < MPFR_VERSION_NUM(3,0,0)) + #include <cstdlib> // Needed for random() +#endif + +// Less important options +#define MPREAL_DOUBLE_BITS_OVERFLOW -1 // Triggers overflow exception during conversion to double if mpreal + // cannot fit in MPREAL_DOUBLE_BITS_OVERFLOW bits + // = -1 disables overflow checks (default) +#if defined(__GNUC__) + #define MPREAL_PERMISSIVE_EXPR __extension__ +#else + #define MPREAL_PERMISSIVE_EXPR +#endif + +namespace mpfr { + +class mpreal { +private: + mpfr_t mp; + +public: + + // Get default rounding mode & precision + inline static mp_rnd_t get_default_rnd() { return (mp_rnd_t)(mpfr_get_default_rounding_mode()); } + inline static mp_prec_t get_default_prec() { return mpfr_get_default_prec(); } + + // Constructors && type conversions + mpreal(); + mpreal(const mpreal& u); + mpreal(const mpf_t u); + mpreal(const mpz_t u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); + mpreal(const mpq_t u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); + mpreal(const double u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); + mpreal(const long double u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); + mpreal(const unsigned long int u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); + mpreal(const unsigned int u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); + mpreal(const long int u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); + mpreal(const int u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); + + // Construct mpreal from mpfr_t structure. + // shared = true allows to avoid deep copy, so that mpreal and 'u' share the same data & pointers. + mpreal(const mpfr_t u, bool shared = false); + +#if defined (MPREAL_HAVE_INT64_SUPPORT) + mpreal(const uint64_t u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); + mpreal(const int64_t u, mp_prec_t prec = mpreal::get_default_prec(), mp_rnd_t mode = mpreal::get_default_rnd()); +#endif + + mpreal(const char* s, mp_prec_t prec = mpreal::get_default_prec(), int base = 10, mp_rnd_t mode = mpreal::get_default_rnd()); + mpreal(const std::string& s, mp_prec_t prec = mpreal::get_default_prec(), int base = 10, mp_rnd_t mode = mpreal::get_default_rnd()); + + ~mpreal(); + +#ifdef MPREAL_HAVE_MOVE_SUPPORT + mpreal& operator=(mpreal&& v); + mpreal(mpreal&& u); +#endif + + // Operations + // = + // +, -, *, /, ++, --, <<, >> + // *=, +=, -=, /=, + // <, >, ==, <=, >= + + // = + mpreal& operator=(const mpreal& v); + mpreal& operator=(const mpf_t v); + mpreal& operator=(const mpz_t v); + mpreal& operator=(const mpq_t v); + mpreal& operator=(const long double v); + mpreal& operator=(const double v); + mpreal& operator=(const unsigned long int v); + mpreal& operator=(const unsigned int v); + mpreal& operator=(const long int v); + mpreal& operator=(const int v); + mpreal& operator=(const char* s); + mpreal& operator=(const std::string& s); + + // + + mpreal& operator+=(const mpreal& v); + mpreal& operator+=(const mpf_t v); + mpreal& operator+=(const mpz_t v); + mpreal& operator+=(const mpq_t v); + mpreal& operator+=(const long double u); + mpreal& operator+=(const double u); + mpreal& operator+=(const unsigned long int u); + mpreal& operator+=(const unsigned int u); + mpreal& operator+=(const long int u); + mpreal& operator+=(const int u); + +#if defined (MPREAL_HAVE_INT64_SUPPORT) + mpreal& operator+=(const int64_t u); + mpreal& operator+=(const uint64_t u); + mpreal& operator-=(const int64_t u); + mpreal& operator-=(const uint64_t u); + mpreal& operator*=(const int64_t u); + mpreal& operator*=(const uint64_t u); + mpreal& operator/=(const int64_t u); + mpreal& operator/=(const uint64_t u); +#endif + + const mpreal operator+() const; + mpreal& operator++ (); + const mpreal operator++ (int); + + // - + mpreal& operator-=(const mpreal& v); + mpreal& operator-=(const mpz_t v); + mpreal& operator-=(const mpq_t v); + mpreal& operator-=(const long double u); + mpreal& operator-=(const double u); + mpreal& operator-=(const unsigned long int u); + mpreal& operator-=(const unsigned int u); + mpreal& operator-=(const long int u); + mpreal& operator-=(const int u); + const mpreal operator-() const; + friend const mpreal operator-(const unsigned long int b, const mpreal& a); + friend const mpreal operator-(const unsigned int b, const mpreal& a); + friend const mpreal operator-(const long int b, const mpreal& a); + friend const mpreal operator-(const int b, const mpreal& a); + friend const mpreal operator-(const double b, const mpreal& a); + mpreal& operator-- (); + const mpreal operator-- (int); + + // * + mpreal& operator*=(const mpreal& v); + mpreal& operator*=(const mpz_t v); + mpreal& operator*=(const mpq_t v); + mpreal& operator*=(const long double v); + mpreal& operator*=(const double v); + mpreal& operator*=(const unsigned long int v); + mpreal& operator*=(const unsigned int v); + mpreal& operator*=(const long int v); + mpreal& operator*=(const int v); + + // / + mpreal& operator/=(const mpreal& v); + mpreal& operator/=(const mpz_t v); + mpreal& operator/=(const mpq_t v); + mpreal& operator/=(const long double v); + mpreal& operator/=(const double v); + mpreal& operator/=(const unsigned long int v); + mpreal& operator/=(const unsigned int v); + mpreal& operator/=(const long int v); + mpreal& operator/=(const int v); + friend const mpreal operator/(const unsigned long int b, const mpreal& a); + friend const mpreal operator/(const unsigned int b, const mpreal& a); + friend const mpreal operator/(const long int b, const mpreal& a); + friend const mpreal operator/(const int b, const mpreal& a); + friend const mpreal operator/(const double b, const mpreal& a); + + //<<= Fast Multiplication by 2^u + mpreal& operator<<=(const unsigned long int u); + mpreal& operator<<=(const unsigned int u); + mpreal& operator<<=(const long int u); + mpreal& operator<<=(const int u); + + //>>= Fast Division by 2^u + mpreal& operator>>=(const unsigned long int u); + mpreal& operator>>=(const unsigned int u); + mpreal& operator>>=(const long int u); + mpreal& operator>>=(const int u); + + // Boolean Operators + friend bool operator > (const mpreal& a, const mpreal& b); + friend bool operator >= (const mpreal& a, const mpreal& b); + friend bool operator < (const mpreal& a, const mpreal& b); + friend bool operator <= (const mpreal& a, const mpreal& b); + friend bool operator == (const mpreal& a, const mpreal& b); + friend bool operator != (const mpreal& a, const mpreal& b); + + // Optimized specializations for boolean operators + friend bool operator == (const mpreal& a, const unsigned long int b); + friend bool operator == (const mpreal& a, const unsigned int b); + friend bool operator == (const mpreal& a, const long int b); + friend bool operator == (const mpreal& a, const int b); + friend bool operator == (const mpreal& a, const long double b); + friend bool operator == (const mpreal& a, const double b); + + // Type Conversion operators + bool toBool (mp_rnd_t mode = GMP_RNDZ) const; + long toLong (mp_rnd_t mode = GMP_RNDZ) const; + unsigned long toULong (mp_rnd_t mode = GMP_RNDZ) const; + float toFloat (mp_rnd_t mode = GMP_RNDN) const; + double toDouble (mp_rnd_t mode = GMP_RNDN) const; + long double toLDouble (mp_rnd_t mode = GMP_RNDN) const; + +#if defined (MPREAL_HAVE_EXPLICIT_CONVERTERS) + explicit operator bool () const { return toBool(); } + explicit operator int () const { return toLong(); } + explicit operator long () const { return toLong(); } + explicit operator long long () const { return toLong(); } + explicit operator unsigned () const { return toULong(); } + explicit operator unsigned long () const { return toULong(); } + explicit operator unsigned long long () const { return toULong(); } + explicit operator float () const { return toFloat(); } + explicit operator double () const { return toDouble(); } + explicit operator long double () const { return toLDouble(); } +#endif + +#if defined (MPREAL_HAVE_INT64_SUPPORT) + int64_t toInt64 (mp_rnd_t mode = GMP_RNDZ) const; + uint64_t toUInt64 (mp_rnd_t mode = GMP_RNDZ) const; + + #if defined (MPREAL_HAVE_EXPLICIT_CONVERTERS) + explicit operator int64_t () const { return toInt64(); } + explicit operator uint64_t () const { return toUInt64(); } + #endif +#endif + + // Get raw pointers so that mpreal can be directly used in raw mpfr_* functions + ::mpfr_ptr mpfr_ptr(); + ::mpfr_srcptr mpfr_ptr() const; + ::mpfr_srcptr mpfr_srcptr() const; + + // Convert mpreal to string with n significant digits in base b + // n = -1 -> convert with the maximum available digits + std::string toString(int n = -1, int b = 10, mp_rnd_t mode = mpreal::get_default_rnd()) const; + +#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) + std::string toString(const std::string& format) const; +#endif + + std::ostream& output(std::ostream& os) const; + + // Math Functions + friend const mpreal sqr (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal sqrt(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal sqrt(const unsigned long int v, mp_rnd_t rnd_mode); + friend const mpreal cbrt(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal root(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode); + friend const mpreal pow (const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode); + friend const mpreal pow (const mpreal& a, const mpz_t b, mp_rnd_t rnd_mode); + friend const mpreal pow (const mpreal& a, const unsigned long int b, mp_rnd_t rnd_mode); + friend const mpreal pow (const mpreal& a, const long int b, mp_rnd_t rnd_mode); + friend const mpreal pow (const unsigned long int a, const mpreal& b, mp_rnd_t rnd_mode); + friend const mpreal pow (const unsigned long int a, const unsigned long int b, mp_rnd_t rnd_mode); + friend const mpreal fabs(const mpreal& v, mp_rnd_t rnd_mode); + + friend const mpreal abs(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal dim(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode); + friend inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode); + friend inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode); + friend inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode); + friend inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode); + friend int cmpabs(const mpreal& a,const mpreal& b); + + friend const mpreal log (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal log2 (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal log10(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal exp (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal exp2 (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal exp10(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal log1p(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal expm1(const mpreal& v, mp_rnd_t rnd_mode); + + friend const mpreal cos(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal sin(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal tan(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal sec(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal csc(const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal cot(const mpreal& v, mp_rnd_t rnd_mode); + friend int sin_cos(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode); + + friend const mpreal acos (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal asin (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal atan (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal atan2 (const mpreal& y, const mpreal& x, mp_rnd_t rnd_mode); + friend const mpreal acot (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal asec (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal acsc (const mpreal& v, mp_rnd_t rnd_mode); + + friend const mpreal cosh (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal sinh (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal tanh (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal sech (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal csch (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal coth (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal acosh (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal asinh (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal atanh (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal acoth (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal asech (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal acsch (const mpreal& v, mp_rnd_t rnd_mode); + + friend const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); + + friend const mpreal fac_ui (unsigned long int v, mp_prec_t prec, mp_rnd_t rnd_mode); + friend const mpreal eint (const mpreal& v, mp_rnd_t rnd_mode); + + friend const mpreal gamma (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal lngamma (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal lgamma (const mpreal& v, int *signp, mp_rnd_t rnd_mode); + friend const mpreal zeta (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal erf (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal erfc (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal besselj0 (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal besselj1 (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal besseljn (long n, const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal bessely0 (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal bessely1 (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal besselyn (long n, const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal fma (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode); + friend const mpreal fms (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode); + friend const mpreal agm (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode); + friend const mpreal sum (const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode); + friend int sgn(const mpreal& v); // returns -1 or +1 + +// MPFR 2.4.0 Specifics +#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) + friend int sinh_cosh (mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal li2 (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal fmod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); + friend const mpreal rec_sqrt (const mpreal& v, mp_rnd_t rnd_mode); + + // MATLAB's semantic equivalents + friend const mpreal rem (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); // Remainder after division + friend const mpreal mod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); // Modulus after division +#endif + +// MPFR 3.0.0 Specifics +#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) + friend const mpreal digamma (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal ai (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal urandom (gmp_randstate_t& state, mp_rnd_t rnd_mode); // use gmp_randinit_default() to init state, gmp_randclear() to clear + friend const mpreal grandom (gmp_randstate_t& state, mp_rnd_t rnd_mode); // use gmp_randinit_default() to init state, gmp_randclear() to clear + friend const mpreal grandom (unsigned int seed); +#endif + + // Uniformly distributed random number generation in [0,1] using + // Mersenne-Twister algorithm by default. + // Use parameter to setup seed, e.g.: random((unsigned)time(NULL)) + // Check urandom() for more precise control. + friend const mpreal random(unsigned int seed); + + // Exponent and mantissa manipulation + friend const mpreal frexp(const mpreal& v, mp_exp_t* exp); + friend const mpreal ldexp(const mpreal& v, mp_exp_t exp); + + // Splits mpreal value into fractional and integer parts. + // Returns fractional part and stores integer part in n. + friend const mpreal modf(const mpreal& v, mpreal& n); + + // Constants + // don't forget to call mpfr_free_cache() for every thread where you are using const-functions + friend const mpreal const_log2 (mp_prec_t prec, mp_rnd_t rnd_mode); + friend const mpreal const_pi (mp_prec_t prec, mp_rnd_t rnd_mode); + friend const mpreal const_euler (mp_prec_t prec, mp_rnd_t rnd_mode); + friend const mpreal const_catalan (mp_prec_t prec, mp_rnd_t rnd_mode); + + // returns +inf iff sign>=0 otherwise -inf + friend const mpreal const_infinity(int sign, mp_prec_t prec); + + // Output/ Input + friend std::ostream& operator<<(std::ostream& os, const mpreal& v); + friend std::istream& operator>>(std::istream& is, mpreal& v); + + // Integer Related Functions + friend const mpreal rint (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal ceil (const mpreal& v); + friend const mpreal floor(const mpreal& v); + friend const mpreal round(const mpreal& v); + friend const mpreal trunc(const mpreal& v); + friend const mpreal rint_ceil (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal rint_floor (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal rint_round (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal rint_trunc (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal frac (const mpreal& v, mp_rnd_t rnd_mode); + friend const mpreal remainder ( const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); + friend const mpreal remquo (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); + + // Miscellaneous Functions + friend const mpreal nexttoward (const mpreal& x, const mpreal& y); + friend const mpreal nextabove (const mpreal& x); + friend const mpreal nextbelow (const mpreal& x); + + // use gmp_randinit_default() to init state, gmp_randclear() to clear + friend const mpreal urandomb (gmp_randstate_t& state); + +// MPFR < 2.4.2 Specifics +#if (MPFR_VERSION <= MPFR_VERSION_NUM(2,4,2)) + friend const mpreal random2 (mp_size_t size, mp_exp_t exp); +#endif + + // Instance Checkers + friend bool isnan (const mpreal& v); + friend bool isinf (const mpreal& v); + friend bool isfinite (const mpreal& v); + + friend bool isnum (const mpreal& v); + friend bool iszero (const mpreal& v); + friend bool isint (const mpreal& v); + +#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) + friend bool isregular(const mpreal& v); +#endif + + // Set/Get instance properties + inline mp_prec_t get_prec() const; + inline void set_prec(mp_prec_t prec, mp_rnd_t rnd_mode = get_default_rnd()); // Change precision with rounding mode + + // Aliases for get_prec(), set_prec() - needed for compatibility with std::complex<mpreal> interface + inline mpreal& setPrecision(int Precision, mp_rnd_t RoundingMode = get_default_rnd()); + inline int getPrecision() const; + + // Set mpreal to +/- inf, NaN, +/-0 + mpreal& setInf (int Sign = +1); + mpreal& setNan (); + mpreal& setZero (int Sign = +1); + mpreal& setSign (int Sign, mp_rnd_t RoundingMode = get_default_rnd()); + + //Exponent + mp_exp_t get_exp(); + int set_exp(mp_exp_t e); + int check_range (int t, mp_rnd_t rnd_mode = get_default_rnd()); + int subnormalize (int t,mp_rnd_t rnd_mode = get_default_rnd()); + + // Inexact conversion from float + inline bool fits_in_bits(double x, int n); + + // Set/Get global properties + static void set_default_prec(mp_prec_t prec); + static void set_default_rnd(mp_rnd_t rnd_mode); + + static mp_exp_t get_emin (void); + static mp_exp_t get_emax (void); + static mp_exp_t get_emin_min (void); + static mp_exp_t get_emin_max (void); + static mp_exp_t get_emax_min (void); + static mp_exp_t get_emax_max (void); + static int set_emin (mp_exp_t exp); + static int set_emax (mp_exp_t exp); + + // Efficient swapping of two mpreal values - needed for std algorithms + friend void swap(mpreal& x, mpreal& y); + + friend const mpreal fmax(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); + friend const mpreal fmin(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode); + +private: + // Human friendly Debug Preview in Visual Studio. + // Put one of these lines: + // + // mpfr::mpreal=<DebugView> ; Show value only + // mpfr::mpreal=<DebugView>, <mp[0]._mpfr_prec,u>bits ; Show value & precision + // + // at the beginning of + // [Visual Studio Installation Folder]\Common7\Packages\Debugger\autoexp.dat + MPREAL_MSVC_DEBUGVIEW_DATA + + // "Smart" resources deallocation. Checks if instance initialized before deletion. + void clear(::mpfr_ptr); +}; + +////////////////////////////////////////////////////////////////////////// +// Exceptions +class conversion_overflow : public std::exception { +public: + std::string why() { return "inexact conversion from floating point"; } +}; + +////////////////////////////////////////////////////////////////////////// +// Constructors & converters +// Default constructor: creates mp number and initializes it to 0. +inline mpreal::mpreal() +{ + mpfr_init2 (mpfr_ptr(), mpreal::get_default_prec()); + mpfr_set_ui(mpfr_ptr(), 0, mpreal::get_default_rnd()); + + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +inline mpreal::mpreal(const mpreal& u) +{ + mpfr_init2(mpfr_ptr(),mpfr_get_prec(u.mpfr_srcptr())); + mpfr_set (mpfr_ptr(),u.mpfr_srcptr(),mpreal::get_default_rnd()); + + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +#ifdef MPREAL_HAVE_MOVE_SUPPORT +inline mpreal::mpreal(mpreal&& other) +{ + mpfr_set_uninitialized(mpfr_ptr()); // make sure "other" holds no pinter to actual data + mpfr_swap(mpfr_ptr(), other.mpfr_ptr()); + + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +inline mpreal& mpreal::operator=(mpreal&& other) +{ + mpfr_swap(mpfr_ptr(), other.mpfr_ptr()); + + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} +#endif + +inline mpreal::mpreal(const mpfr_t u, bool shared) +{ + if(shared) + { + std::memcpy(mpfr_ptr(), u, sizeof(mpfr_t)); + } + else + { + mpfr_init2(mpfr_ptr(), mpfr_get_prec(u)); + mpfr_set (mpfr_ptr(), u, mpreal::get_default_rnd()); + } + + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +inline mpreal::mpreal(const mpf_t u) +{ + mpfr_init2(mpfr_ptr(),(mp_prec_t) mpf_get_prec(u)); // (gmp: mp_bitcnt_t) unsigned long -> long (mpfr: mp_prec_t) + mpfr_set_f(mpfr_ptr(),u,mpreal::get_default_rnd()); + + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +inline mpreal::mpreal(const mpz_t u, mp_prec_t prec, mp_rnd_t mode) +{ + mpfr_init2(mpfr_ptr(), prec); + mpfr_set_z(mpfr_ptr(), u, mode); + + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +inline mpreal::mpreal(const mpq_t u, mp_prec_t prec, mp_rnd_t mode) +{ + mpfr_init2(mpfr_ptr(), prec); + mpfr_set_q(mpfr_ptr(), u, mode); + + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +inline mpreal::mpreal(const double u, mp_prec_t prec, mp_rnd_t mode) +{ + mpfr_init2(mpfr_ptr(), prec); + +#if (MPREAL_DOUBLE_BITS_OVERFLOW > -1) + if(fits_in_bits(u, MPREAL_DOUBLE_BITS_OVERFLOW)) + { + mpfr_set_d(mpfr_ptr(), u, mode); + }else + throw conversion_overflow(); +#else + mpfr_set_d(mpfr_ptr(), u, mode); +#endif + + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +inline mpreal::mpreal(const long double u, mp_prec_t prec, mp_rnd_t mode) +{ + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_ld(mpfr_ptr(), u, mode); + + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +inline mpreal::mpreal(const unsigned long int u, mp_prec_t prec, mp_rnd_t mode) +{ + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_ui(mpfr_ptr(), u, mode); + + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +inline mpreal::mpreal(const unsigned int u, mp_prec_t prec, mp_rnd_t mode) +{ + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_ui(mpfr_ptr(), u, mode); + + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +inline mpreal::mpreal(const long int u, mp_prec_t prec, mp_rnd_t mode) +{ + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_si(mpfr_ptr(), u, mode); + + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +inline mpreal::mpreal(const int u, mp_prec_t prec, mp_rnd_t mode) +{ + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_si(mpfr_ptr(), u, mode); + + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +#if defined (MPREAL_HAVE_INT64_SUPPORT) +inline mpreal::mpreal(const uint64_t u, mp_prec_t prec, mp_rnd_t mode) +{ + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_uj(mpfr_ptr(), u, mode); + + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +inline mpreal::mpreal(const int64_t u, mp_prec_t prec, mp_rnd_t mode) +{ + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_sj(mpfr_ptr(), u, mode); + + MPREAL_MSVC_DEBUGVIEW_CODE; +} +#endif + +inline mpreal::mpreal(const char* s, mp_prec_t prec, int base, mp_rnd_t mode) +{ + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_str(mpfr_ptr(), s, base, mode); + + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +inline mpreal::mpreal(const std::string& s, mp_prec_t prec, int base, mp_rnd_t mode) +{ + mpfr_init2 (mpfr_ptr(), prec); + mpfr_set_str(mpfr_ptr(), s.c_str(), base, mode); + + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +inline void mpreal::clear(::mpfr_ptr x) +{ +#ifdef MPREAL_HAVE_MOVE_SUPPORT + if(mpfr_is_initialized(x)) +#endif + mpfr_clear(x); +} + +inline mpreal::~mpreal() +{ + clear(mpfr_ptr()); +} + +// internal namespace needed for template magic +namespace internal{ + + // Use SFINAE to restrict arithmetic operations instantiation only for numeric types + // This is needed for smooth integration with libraries based on expression templates, like Eigen. + // TODO: Do the same for boolean operators. + template <typename ArgumentType> struct result_type {}; + + template <> struct result_type<mpreal> {typedef mpreal type;}; + template <> struct result_type<mpz_t> {typedef mpreal type;}; + template <> struct result_type<mpq_t> {typedef mpreal type;}; + template <> struct result_type<long double> {typedef mpreal type;}; + template <> struct result_type<double> {typedef mpreal type;}; + template <> struct result_type<unsigned long int> {typedef mpreal type;}; + template <> struct result_type<unsigned int> {typedef mpreal type;}; + template <> struct result_type<long int> {typedef mpreal type;}; + template <> struct result_type<int> {typedef mpreal type;}; + +#if defined (MPREAL_HAVE_INT64_SUPPORT) + template <> struct result_type<int64_t > {typedef mpreal type;}; + template <> struct result_type<uint64_t > {typedef mpreal type;}; +#endif +} + +// + Addition +template <typename Rhs> +inline const typename internal::result_type<Rhs>::type + operator+(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) += rhs; } + +template <typename Lhs> +inline const typename internal::result_type<Lhs>::type + operator+(const Lhs& lhs, const mpreal& rhs){ return mpreal(rhs) += lhs; } + +// - Subtraction +template <typename Rhs> +inline const typename internal::result_type<Rhs>::type + operator-(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) -= rhs; } + +template <typename Lhs> +inline const typename internal::result_type<Lhs>::type + operator-(const Lhs& lhs, const mpreal& rhs){ return mpreal(lhs) -= rhs; } + +// * Multiplication +template <typename Rhs> +inline const typename internal::result_type<Rhs>::type + operator*(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) *= rhs; } + +template <typename Lhs> +inline const typename internal::result_type<Lhs>::type + operator*(const Lhs& lhs, const mpreal& rhs){ return mpreal(rhs) *= lhs; } + +// / Division +template <typename Rhs> +inline const typename internal::result_type<Rhs>::type + operator/(const mpreal& lhs, const Rhs& rhs){ return mpreal(lhs) /= rhs; } + +template <typename Lhs> +inline const typename internal::result_type<Lhs>::type + operator/(const Lhs& lhs, const mpreal& rhs){ return mpreal(lhs) /= rhs; } + +////////////////////////////////////////////////////////////////////////// +// sqrt +const mpreal sqrt(const unsigned int v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal sqrt(const long int v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal sqrt(const int v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal sqrt(const long double v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal sqrt(const double v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + +// abs +inline const mpreal abs(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()); + +////////////////////////////////////////////////////////////////////////// +// pow +const mpreal pow(const mpreal& a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const mpreal& a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const mpreal& a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const mpreal& a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + +const mpreal pow(const unsigned int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const long int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const long double a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const double a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + +const mpreal pow(const unsigned long int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const unsigned long int a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const unsigned long int a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const unsigned long int a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const unsigned long int a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + +const mpreal pow(const unsigned int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const unsigned int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const unsigned int a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const unsigned int a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const unsigned int a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const unsigned int a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + +const mpreal pow(const long int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const long int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const long int a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const long int a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const long int a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const long int a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + +const mpreal pow(const int a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const int a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const int a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const int a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const int a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const int a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + +const mpreal pow(const long double a, const long double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const long double a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const long double a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const long double a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const long double a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + +const mpreal pow(const double a, const double b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const double a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const double a, const unsigned int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const double a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +const mpreal pow(const double a, const int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + +inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); +inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode = mpreal::get_default_rnd()); + +////////////////////////////////////////////////////////////////////////// +// Estimate machine epsilon for the given precision +// Returns smallest eps such that 1.0 + eps != 1.0 +inline mpreal machine_epsilon(mp_prec_t prec = mpreal::get_default_prec()); + +// Returns smallest eps such that x + eps != x (relative machine epsilon) +inline mpreal machine_epsilon(const mpreal& x); + +// Gives max & min values for the required precision, +// minval is 'safe' meaning 1 / minval does not overflow +// maxval is 'safe' meaning 1 / maxval does not underflow +inline mpreal minval(mp_prec_t prec = mpreal::get_default_prec()); +inline mpreal maxval(mp_prec_t prec = mpreal::get_default_prec()); + +// 'Dirty' equality check 1: |a-b| < min{|a|,|b|} * eps +inline bool isEqualFuzzy(const mpreal& a, const mpreal& b, const mpreal& eps); + +// 'Dirty' equality check 2: |a-b| < min{|a|,|b|} * eps( min{|a|,|b|} ) +inline bool isEqualFuzzy(const mpreal& a, const mpreal& b); + +// 'Bitwise' equality check +// maxUlps - a and b can be apart by maxUlps binary numbers. +inline bool isEqualUlps(const mpreal& a, const mpreal& b, int maxUlps); + +////////////////////////////////////////////////////////////////////////// +// Convert precision in 'bits' to decimal digits and vice versa. +// bits = ceil(digits*log[2](10)) +// digits = floor(bits*log[10](2)) + +inline mp_prec_t digits2bits(int d); +inline int bits2digits(mp_prec_t b); + +////////////////////////////////////////////////////////////////////////// +// min, max +const mpreal (max)(const mpreal& x, const mpreal& y); +const mpreal (min)(const mpreal& x, const mpreal& y); + +////////////////////////////////////////////////////////////////////////// +// Implementation +////////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////////// +// Operators - Assignment +inline mpreal& mpreal::operator=(const mpreal& v) +{ + if (this != &v) + { + mp_prec_t tp = mpfr_get_prec( mpfr_srcptr()); + mp_prec_t vp = mpfr_get_prec(v.mpfr_srcptr()); + + if(tp != vp){ + clear(mpfr_ptr()); + mpfr_init2(mpfr_ptr(), vp); + } + + mpfr_set(mpfr_ptr(), v.mpfr_srcptr(), mpreal::get_default_rnd()); + + MPREAL_MSVC_DEBUGVIEW_CODE; + } + return *this; +} + +inline mpreal& mpreal::operator=(const mpf_t v) +{ + mpfr_set_f(mpfr_ptr(), v, mpreal::get_default_rnd()); + + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator=(const mpz_t v) +{ + mpfr_set_z(mpfr_ptr(), v, mpreal::get_default_rnd()); + + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator=(const mpq_t v) +{ + mpfr_set_q(mpfr_ptr(), v, mpreal::get_default_rnd()); + + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator=(const long double v) +{ + mpfr_set_ld(mpfr_ptr(), v, mpreal::get_default_rnd()); + + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator=(const double v) +{ +#if (MPREAL_DOUBLE_BITS_OVERFLOW > -1) + if(fits_in_bits(v, MPREAL_DOUBLE_BITS_OVERFLOW)) + { + mpfr_set_d(mpfr_ptr(),v,mpreal::get_default_rnd()); + }else + throw conversion_overflow(); +#else + mpfr_set_d(mpfr_ptr(),v,mpreal::get_default_rnd()); +#endif + + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator=(const unsigned long int v) +{ + mpfr_set_ui(mpfr_ptr(), v, mpreal::get_default_rnd()); + + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator=(const unsigned int v) +{ + mpfr_set_ui(mpfr_ptr(), v, mpreal::get_default_rnd()); + + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator=(const long int v) +{ + mpfr_set_si(mpfr_ptr(), v, mpreal::get_default_rnd()); + + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator=(const int v) +{ + mpfr_set_si(mpfr_ptr(), v, mpreal::get_default_rnd()); + + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator=(const char* s) +{ + // Use other converters for more precise control on base & precision & rounding: + // + // mpreal(const char* s, mp_prec_t prec, int base, mp_rnd_t mode) + // mpreal(const std::string& s,mp_prec_t prec, int base, mp_rnd_t mode) + // + // Here we assume base = 10 and we use precision of target variable. + + mpfr_t t; + + mpfr_init2(t, mpfr_get_prec(mpfr_srcptr())); + + if(0 == mpfr_set_str(t, s, 10, mpreal::get_default_rnd())) + { + mpfr_set(mpfr_ptr(), t, mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + } + + clear(t); + return *this; +} + +inline mpreal& mpreal::operator=(const std::string& s) +{ + // Use other converters for more precise control on base & precision & rounding: + // + // mpreal(const char* s, mp_prec_t prec, int base, mp_rnd_t mode) + // mpreal(const std::string& s,mp_prec_t prec, int base, mp_rnd_t mode) + // + // Here we assume base = 10 and we use precision of target variable. + + mpfr_t t; + + mpfr_init2(t, mpfr_get_prec(mpfr_srcptr())); + + if(0 == mpfr_set_str(t, s.c_str(), 10, mpreal::get_default_rnd())) + { + mpfr_set(mpfr_ptr(), t, mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + } + + clear(t); + return *this; +} + + +////////////////////////////////////////////////////////////////////////// +// + Addition +inline mpreal& mpreal::operator+=(const mpreal& v) +{ + mpfr_add(mpfr_ptr(), mpfr_srcptr(), v.mpfr_srcptr(), mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator+=(const mpf_t u) +{ + *this += mpreal(u); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator+=(const mpz_t u) +{ + mpfr_add_z(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator+=(const mpq_t u) +{ + mpfr_add_q(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator+= (const long double u) +{ + *this += mpreal(u); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator+= (const double u) +{ +#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) + mpfr_add_d(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); +#else + *this += mpreal(u); +#endif + + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator+=(const unsigned long int u) +{ + mpfr_add_ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator+=(const unsigned int u) +{ + mpfr_add_ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator+=(const long int u) +{ + mpfr_add_si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator+=(const int u) +{ + mpfr_add_si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +#if defined (MPREAL_HAVE_INT64_SUPPORT) +inline mpreal& mpreal::operator+=(const int64_t u){ *this += mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } +inline mpreal& mpreal::operator+=(const uint64_t u){ *this += mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } +inline mpreal& mpreal::operator-=(const int64_t u){ *this -= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } +inline mpreal& mpreal::operator-=(const uint64_t u){ *this -= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } +inline mpreal& mpreal::operator*=(const int64_t u){ *this *= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } +inline mpreal& mpreal::operator*=(const uint64_t u){ *this *= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } +inline mpreal& mpreal::operator/=(const int64_t u){ *this /= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } +inline mpreal& mpreal::operator/=(const uint64_t u){ *this /= mpreal(u); MPREAL_MSVC_DEBUGVIEW_CODE; return *this; } +#endif + +inline const mpreal mpreal::operator+()const { return mpreal(*this); } + +inline const mpreal operator+(const mpreal& a, const mpreal& b) +{ + mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr()))); + mpfr_add(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd()); + return c; +} + +inline mpreal& mpreal::operator++() +{ + return *this += 1; +} + +inline const mpreal mpreal::operator++ (int) +{ + mpreal x(*this); + *this += 1; + return x; +} + +inline mpreal& mpreal::operator--() +{ + return *this -= 1; +} + +inline const mpreal mpreal::operator-- (int) +{ + mpreal x(*this); + *this -= 1; + return x; +} + +////////////////////////////////////////////////////////////////////////// +// - Subtraction +inline mpreal& mpreal::operator-=(const mpreal& v) +{ + mpfr_sub(mpfr_ptr(),mpfr_srcptr(),v.mpfr_srcptr(),mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator-=(const mpz_t v) +{ + mpfr_sub_z(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator-=(const mpq_t v) +{ + mpfr_sub_q(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator-=(const long double v) +{ + *this -= mpreal(v); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator-=(const double v) +{ +#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) + mpfr_sub_d(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); +#else + *this -= mpreal(v); +#endif + + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator-=(const unsigned long int v) +{ + mpfr_sub_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator-=(const unsigned int v) +{ + mpfr_sub_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator-=(const long int v) +{ + mpfr_sub_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator-=(const int v) +{ + mpfr_sub_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline const mpreal mpreal::operator-()const +{ + mpreal u(*this); + mpfr_neg(u.mpfr_ptr(),u.mpfr_srcptr(),mpreal::get_default_rnd()); + return u; +} + +inline const mpreal operator-(const mpreal& a, const mpreal& b) +{ + mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr()))); + mpfr_sub(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd()); + return c; +} + +inline const mpreal operator-(const double b, const mpreal& a) +{ +#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) + mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); + mpfr_d_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); + return x; +#else + mpreal x(b, mpfr_get_prec(a.mpfr_ptr())); + x -= a; + return x; +#endif +} + +inline const mpreal operator-(const unsigned long int b, const mpreal& a) +{ + mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); + mpfr_ui_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); + return x; +} + +inline const mpreal operator-(const unsigned int b, const mpreal& a) +{ + mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); + mpfr_ui_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); + return x; +} + +inline const mpreal operator-(const long int b, const mpreal& a) +{ + mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); + mpfr_si_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); + return x; +} + +inline const mpreal operator-(const int b, const mpreal& a) +{ + mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); + mpfr_si_sub(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); + return x; +} + +////////////////////////////////////////////////////////////////////////// +// * Multiplication +inline mpreal& mpreal::operator*= (const mpreal& v) +{ + mpfr_mul(mpfr_ptr(),mpfr_srcptr(),v.mpfr_srcptr(),mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator*=(const mpz_t v) +{ + mpfr_mul_z(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator*=(const mpq_t v) +{ + mpfr_mul_q(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator*=(const long double v) +{ + *this *= mpreal(v); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator*=(const double v) +{ +#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) + mpfr_mul_d(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); +#else + *this *= mpreal(v); +#endif + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator*=(const unsigned long int v) +{ + mpfr_mul_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator*=(const unsigned int v) +{ + mpfr_mul_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator*=(const long int v) +{ + mpfr_mul_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator*=(const int v) +{ + mpfr_mul_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline const mpreal operator*(const mpreal& a, const mpreal& b) +{ + mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_ptr()), mpfr_get_prec(b.mpfr_ptr()))); + mpfr_mul(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd()); + return c; +} + +////////////////////////////////////////////////////////////////////////// +// / Division +inline mpreal& mpreal::operator/=(const mpreal& v) +{ + mpfr_div(mpfr_ptr(),mpfr_srcptr(),v.mpfr_srcptr(),mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator/=(const mpz_t v) +{ + mpfr_div_z(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator/=(const mpq_t v) +{ + mpfr_div_q(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator/=(const long double v) +{ + *this /= mpreal(v); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator/=(const double v) +{ +#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) + mpfr_div_d(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); +#else + *this /= mpreal(v); +#endif + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator/=(const unsigned long int v) +{ + mpfr_div_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator/=(const unsigned int v) +{ + mpfr_div_ui(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator/=(const long int v) +{ + mpfr_div_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator/=(const int v) +{ + mpfr_div_si(mpfr_ptr(),mpfr_srcptr(),v,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline const mpreal operator/(const mpreal& a, const mpreal& b) +{ + mpreal c(0, (std::max)(mpfr_get_prec(a.mpfr_srcptr()), mpfr_get_prec(b.mpfr_srcptr()))); + mpfr_div(c.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), mpreal::get_default_rnd()); + return c; +} + +inline const mpreal operator/(const unsigned long int b, const mpreal& a) +{ + mpreal x(0, mpfr_get_prec(a.mpfr_srcptr())); + mpfr_ui_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); + return x; +} + +inline const mpreal operator/(const unsigned int b, const mpreal& a) +{ + mpreal x(0, mpfr_get_prec(a.mpfr_srcptr())); + mpfr_ui_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); + return x; +} + +inline const mpreal operator/(const long int b, const mpreal& a) +{ + mpreal x(0, mpfr_get_prec(a.mpfr_srcptr())); + mpfr_si_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); + return x; +} + +inline const mpreal operator/(const int b, const mpreal& a) +{ + mpreal x(0, mpfr_get_prec(a.mpfr_srcptr())); + mpfr_si_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); + return x; +} + +inline const mpreal operator/(const double b, const mpreal& a) +{ +#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) + mpreal x(0, mpfr_get_prec(a.mpfr_srcptr())); + mpfr_d_div(x.mpfr_ptr(), b, a.mpfr_srcptr(), mpreal::get_default_rnd()); + return x; +#else + mpreal x(0, mpfr_get_prec(a.mpfr_ptr())); + x /= a; + return x; +#endif +} + +////////////////////////////////////////////////////////////////////////// +// Shifts operators - Multiplication/Division by power of 2 +inline mpreal& mpreal::operator<<=(const unsigned long int u) +{ + mpfr_mul_2ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator<<=(const unsigned int u) +{ + mpfr_mul_2ui(mpfr_ptr(),mpfr_srcptr(),static_cast<unsigned long int>(u),mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator<<=(const long int u) +{ + mpfr_mul_2si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator<<=(const int u) +{ + mpfr_mul_2si(mpfr_ptr(),mpfr_srcptr(),static_cast<long int>(u),mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator>>=(const unsigned long int u) +{ + mpfr_div_2ui(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator>>=(const unsigned int u) +{ + mpfr_div_2ui(mpfr_ptr(),mpfr_srcptr(),static_cast<unsigned long int>(u),mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator>>=(const long int u) +{ + mpfr_div_2si(mpfr_ptr(),mpfr_srcptr(),u,mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::operator>>=(const int u) +{ + mpfr_div_2si(mpfr_ptr(),mpfr_srcptr(),static_cast<long int>(u),mpreal::get_default_rnd()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline const mpreal operator<<(const mpreal& v, const unsigned long int k) +{ + return mul_2ui(v,k); +} + +inline const mpreal operator<<(const mpreal& v, const unsigned int k) +{ + return mul_2ui(v,static_cast<unsigned long int>(k)); +} + +inline const mpreal operator<<(const mpreal& v, const long int k) +{ + return mul_2si(v,k); +} + +inline const mpreal operator<<(const mpreal& v, const int k) +{ + return mul_2si(v,static_cast<long int>(k)); +} + +inline const mpreal operator>>(const mpreal& v, const unsigned long int k) +{ + return div_2ui(v,k); +} + +inline const mpreal operator>>(const mpreal& v, const long int k) +{ + return div_2si(v,k); +} + +inline const mpreal operator>>(const mpreal& v, const unsigned int k) +{ + return div_2ui(v,static_cast<unsigned long int>(k)); +} + +inline const mpreal operator>>(const mpreal& v, const int k) +{ + return div_2si(v,static_cast<long int>(k)); +} + +// mul_2ui +inline const mpreal mul_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode) +{ + mpreal x(v); + mpfr_mul_2ui(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode); + return x; +} + +// mul_2si +inline const mpreal mul_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode) +{ + mpreal x(v); + mpfr_mul_2si(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode); + return x; +} + +inline const mpreal div_2ui(const mpreal& v, unsigned long int k, mp_rnd_t rnd_mode) +{ + mpreal x(v); + mpfr_div_2ui(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode); + return x; +} + +inline const mpreal div_2si(const mpreal& v, long int k, mp_rnd_t rnd_mode) +{ + mpreal x(v); + mpfr_div_2si(x.mpfr_ptr(),v.mpfr_srcptr(),k,rnd_mode); + return x; +} + +////////////////////////////////////////////////////////////////////////// +//Boolean operators +inline bool operator > (const mpreal& a, const mpreal& b){ return (mpfr_greater_p (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 ); } +inline bool operator >= (const mpreal& a, const mpreal& b){ return (mpfr_greaterequal_p (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 ); } +inline bool operator < (const mpreal& a, const mpreal& b){ return (mpfr_less_p (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 ); } +inline bool operator <= (const mpreal& a, const mpreal& b){ return (mpfr_lessequal_p (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 ); } +inline bool operator == (const mpreal& a, const mpreal& b){ return (mpfr_equal_p (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 ); } +inline bool operator != (const mpreal& a, const mpreal& b){ return (mpfr_lessgreater_p (a.mpfr_srcptr(),b.mpfr_srcptr()) !=0 ); } + +inline bool operator == (const mpreal& a, const unsigned long int b ){ return (mpfr_cmp_ui(a.mpfr_srcptr(),b) == 0 ); } +inline bool operator == (const mpreal& a, const unsigned int b ){ return (mpfr_cmp_ui(a.mpfr_srcptr(),b) == 0 ); } +inline bool operator == (const mpreal& a, const long int b ){ return (mpfr_cmp_si(a.mpfr_srcptr(),b) == 0 ); } +inline bool operator == (const mpreal& a, const int b ){ return (mpfr_cmp_si(a.mpfr_srcptr(),b) == 0 ); } +inline bool operator == (const mpreal& a, const long double b ){ return (mpfr_cmp_ld(a.mpfr_srcptr(),b) == 0 ); } +inline bool operator == (const mpreal& a, const double b ){ return (mpfr_cmp_d (a.mpfr_srcptr(),b) == 0 ); } + + +inline bool isnan (const mpreal& op){ return (mpfr_nan_p (op.mpfr_srcptr()) != 0 ); } +inline bool isinf (const mpreal& op){ return (mpfr_inf_p (op.mpfr_srcptr()) != 0 ); } +inline bool isfinite (const mpreal& op){ return (mpfr_number_p (op.mpfr_srcptr()) != 0 ); } +inline bool iszero (const mpreal& op){ return (mpfr_zero_p (op.mpfr_srcptr()) != 0 ); } +inline bool isint (const mpreal& op){ return (mpfr_integer_p(op.mpfr_srcptr()) != 0 ); } + +#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) +inline bool isregular(const mpreal& op){ return (mpfr_regular_p(op.mpfr_srcptr()));} +#endif + +////////////////////////////////////////////////////////////////////////// +// Type Converters +inline bool mpreal::toBool (mp_rnd_t /*mode*/) const { return mpfr_zero_p (mpfr_srcptr()) == 0; } +inline long mpreal::toLong (mp_rnd_t mode) const { return mpfr_get_si (mpfr_srcptr(), mode); } +inline unsigned long mpreal::toULong (mp_rnd_t mode) const { return mpfr_get_ui (mpfr_srcptr(), mode); } +inline float mpreal::toFloat (mp_rnd_t mode) const { return mpfr_get_flt(mpfr_srcptr(), mode); } +inline double mpreal::toDouble (mp_rnd_t mode) const { return mpfr_get_d (mpfr_srcptr(), mode); } +inline long double mpreal::toLDouble(mp_rnd_t mode) const { return mpfr_get_ld (mpfr_srcptr(), mode); } + +#if defined (MPREAL_HAVE_INT64_SUPPORT) +inline int64_t mpreal::toInt64 (mp_rnd_t mode) const{ return mpfr_get_sj(mpfr_srcptr(), mode); } +inline uint64_t mpreal::toUInt64(mp_rnd_t mode) const{ return mpfr_get_uj(mpfr_srcptr(), mode); } +#endif + +inline ::mpfr_ptr mpreal::mpfr_ptr() { return mp; } +inline ::mpfr_srcptr mpreal::mpfr_ptr() const { return mp; } +inline ::mpfr_srcptr mpreal::mpfr_srcptr() const { return mp; } + +template <class T> +inline std::string toString(T t, std::ios_base & (*f)(std::ios_base&)) +{ + std::ostringstream oss; + oss << f << t; + return oss.str(); +} + +#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) + +inline std::string mpreal::toString(const std::string& format) const +{ + char *s = NULL; + std::string out; + + if( !format.empty() ) + { + if(!(mpfr_asprintf(&s, format.c_str(), mpfr_srcptr()) < 0)) + { + out = std::string(s); + + mpfr_free_str(s); + } + } + + return out; +} + +#endif + +inline std::string mpreal::toString(int n, int b, mp_rnd_t mode) const +{ + // TODO: Add extended format specification (f, e, rounding mode) as it done in output operator + (void)b; + (void)mode; + +#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) + + std::ostringstream format; + + int digits = (n >= 0) ? n : bits2digits(mpfr_get_prec(mpfr_srcptr())); + + format << "%." << digits << "RNg"; + + return toString(format.str()); + +#else + + char *s, *ns = NULL; + size_t slen, nslen; + mp_exp_t exp; + std::string out; + + if(mpfr_inf_p(mp)) + { + if(mpfr_sgn(mp)>0) return "+Inf"; + else return "-Inf"; + } + + if(mpfr_zero_p(mp)) return "0"; + if(mpfr_nan_p(mp)) return "NaN"; + + s = mpfr_get_str(NULL, &exp, b, 0, mp, mode); + ns = mpfr_get_str(NULL, &exp, b, (std::max)(0,n), mp, mode); + + if(s!=NULL && ns!=NULL) + { + slen = strlen(s); + nslen = strlen(ns); + if(nslen<=slen) + { + mpfr_free_str(s); + s = ns; + slen = nslen; + } + else { + mpfr_free_str(ns); + } + + // Make human eye-friendly formatting if possible + if (exp>0 && static_cast<size_t>(exp)<slen) + { + if(s[0]=='-') + { + // Remove zeros starting from right end + char* ptr = s+slen-1; + while (*ptr=='0' && ptr>s+exp) ptr--; + + if(ptr==s+exp) out = std::string(s,exp+1); + else out = std::string(s,exp+1)+'.'+std::string(s+exp+1,ptr-(s+exp+1)+1); + + //out = string(s,exp+1)+'.'+string(s+exp+1); + } + else + { + // Remove zeros starting from right end + char* ptr = s+slen-1; + while (*ptr=='0' && ptr>s+exp-1) ptr--; + + if(ptr==s+exp-1) out = std::string(s,exp); + else out = std::string(s,exp)+'.'+std::string(s+exp,ptr-(s+exp)+1); + + //out = string(s,exp)+'.'+string(s+exp); + } + + }else{ // exp<0 || exp>slen + if(s[0]=='-') + { + // Remove zeros starting from right end + char* ptr = s+slen-1; + while (*ptr=='0' && ptr>s+1) ptr--; + + if(ptr==s+1) out = std::string(s,2); + else out = std::string(s,2)+'.'+std::string(s+2,ptr-(s+2)+1); + + //out = string(s,2)+'.'+string(s+2); + } + else + { + // Remove zeros starting from right end + char* ptr = s+slen-1; + while (*ptr=='0' && ptr>s) ptr--; + + if(ptr==s) out = std::string(s,1); + else out = std::string(s,1)+'.'+std::string(s+1,ptr-(s+1)+1); + + //out = string(s,1)+'.'+string(s+1); + } + + // Make final string + if(--exp) + { + if(exp>0) out += "e+"+mpfr::toString<mp_exp_t>(exp,std::dec); + else out += "e"+mpfr::toString<mp_exp_t>(exp,std::dec); + } + } + + mpfr_free_str(s); + return out; + }else{ + return "conversion error!"; + } +#endif +} + + +////////////////////////////////////////////////////////////////////////// +// I/O +inline std::ostream& mpreal::output(std::ostream& os) const +{ + std::ostringstream format; + const std::ios::fmtflags flags = os.flags(); + + format << ((flags & std::ios::showpos) ? "%+" : "%"); + if (os.precision() >= 0) + format << '.' << os.precision() << "R*" + << ((flags & std::ios::floatfield) == std::ios::fixed ? 'f' : + (flags & std::ios::floatfield) == std::ios::scientific ? 'e' : + 'g'); + else + format << "R*e"; + + char *s = NULL; + if(!(mpfr_asprintf(&s, format.str().c_str(), + mpfr::mpreal::get_default_rnd(), + mpfr_srcptr()) + < 0)) + { + os << std::string(s); + mpfr_free_str(s); + } + return os; +} + +inline std::ostream& operator<<(std::ostream& os, const mpreal& v) +{ + return v.output(os); +} + +inline std::istream& operator>>(std::istream &is, mpreal& v) +{ + // TODO: use cout::hexfloat and other flags to setup base + std::string tmp; + is >> tmp; + mpfr_set_str(v.mpfr_ptr(), tmp.c_str(), 10, mpreal::get_default_rnd()); + return is; +} + +////////////////////////////////////////////////////////////////////////// +// Bits - decimal digits relation +// bits = ceil(digits*log[2](10)) +// digits = floor(bits*log[10](2)) + +inline mp_prec_t digits2bits(int d) +{ + const double LOG2_10 = 3.3219280948873624; + + return mp_prec_t(std::ceil( d * LOG2_10 )); +} + +inline int bits2digits(mp_prec_t b) +{ + const double LOG10_2 = 0.30102999566398119; + + return int(std::floor( b * LOG10_2 )); +} + +////////////////////////////////////////////////////////////////////////// +// Set/Get number properties +inline int sgn(const mpreal& op) +{ + int r = mpfr_signbit(op.mpfr_srcptr()); + return (r > 0? -1 : 1); +} + +inline mpreal& mpreal::setSign(int sign, mp_rnd_t RoundingMode) +{ + mpfr_setsign(mpfr_ptr(), mpfr_srcptr(), (sign < 0 ? 1 : 0), RoundingMode); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline int mpreal::getPrecision() const +{ + return int(mpfr_get_prec(mpfr_srcptr())); +} + +inline mpreal& mpreal::setPrecision(int Precision, mp_rnd_t RoundingMode) +{ + mpfr_prec_round(mpfr_ptr(), Precision, RoundingMode); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::setInf(int sign) +{ + mpfr_set_inf(mpfr_ptr(), sign); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::setNan() +{ + mpfr_set_nan(mpfr_ptr()); + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mpreal& mpreal::setZero(int sign) +{ + +#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) + mpfr_set_zero(mpfr_ptr(), sign); +#else + mpfr_set_si(mpfr_ptr(), 0, (mpfr_get_default_rounding_mode)()); + setSign(sign); +#endif + + MPREAL_MSVC_DEBUGVIEW_CODE; + return *this; +} + +inline mp_prec_t mpreal::get_prec() const +{ + return mpfr_get_prec(mpfr_srcptr()); +} + +inline void mpreal::set_prec(mp_prec_t prec, mp_rnd_t rnd_mode) +{ + mpfr_prec_round(mpfr_ptr(),prec,rnd_mode); + MPREAL_MSVC_DEBUGVIEW_CODE; +} + +inline mp_exp_t mpreal::get_exp () +{ + return mpfr_get_exp(mpfr_srcptr()); +} + +inline int mpreal::set_exp (mp_exp_t e) +{ + int x = mpfr_set_exp(mpfr_ptr(), e); + MPREAL_MSVC_DEBUGVIEW_CODE; + return x; +} + +inline const mpreal frexp(const mpreal& v, mp_exp_t* exp) +{ + mpreal x(v); + *exp = x.get_exp(); + x.set_exp(0); + return x; +} + +inline const mpreal ldexp(const mpreal& v, mp_exp_t exp) +{ + mpreal x(v); + + // rounding is not important since we just increasing the exponent + mpfr_mul_2si(x.mpfr_ptr(), x.mpfr_srcptr(), exp, mpreal::get_default_rnd()); + return x; +} + +inline mpreal machine_epsilon(mp_prec_t prec) +{ + /* the smallest eps such that 1 + eps != 1 */ + return machine_epsilon(mpreal(1, prec)); +} + +inline mpreal machine_epsilon(const mpreal& x) +{ + /* the smallest eps such that x + eps != x */ + if( x < 0) + { + return nextabove(-x) + x; + }else{ + return nextabove( x) - x; + } +} + +// minval is 'safe' meaning 1 / minval does not overflow +inline mpreal minval(mp_prec_t prec) +{ + /* min = 1/2 * 2^emin = 2^(emin - 1) */ + return mpreal(1, prec) << mpreal::get_emin()-1; +} + +// maxval is 'safe' meaning 1 / maxval does not underflow +inline mpreal maxval(mp_prec_t prec) +{ + /* max = (1 - eps) * 2^emax, eps is machine epsilon */ + return (mpreal(1, prec) - machine_epsilon(prec)) << mpreal::get_emax(); +} + +inline bool isEqualUlps(const mpreal& a, const mpreal& b, int maxUlps) +{ + return abs(a - b) <= machine_epsilon((max)(abs(a), abs(b))) * maxUlps; +} + +inline bool isEqualFuzzy(const mpreal& a, const mpreal& b, const mpreal& eps) +{ + return abs(a - b) <= eps; +} + +inline bool isEqualFuzzy(const mpreal& a, const mpreal& b) +{ + return isEqualFuzzy(a, b, machine_epsilon((max)(1, (min)(abs(a), abs(b))))); +} + +inline const mpreal modf(const mpreal& v, mpreal& n) +{ + mpreal f(v); + + // rounding is not important since we are using the same number + mpfr_frac (f.mpfr_ptr(),f.mpfr_srcptr(),mpreal::get_default_rnd()); + mpfr_trunc(n.mpfr_ptr(),v.mpfr_srcptr()); + return f; +} + +inline int mpreal::check_range (int t, mp_rnd_t rnd_mode) +{ + return mpfr_check_range(mpfr_ptr(),t,rnd_mode); +} + +inline int mpreal::subnormalize (int t,mp_rnd_t rnd_mode) +{ + int r = mpfr_subnormalize(mpfr_ptr(),t,rnd_mode); + MPREAL_MSVC_DEBUGVIEW_CODE; + return r; +} + +inline mp_exp_t mpreal::get_emin (void) +{ + return mpfr_get_emin(); +} + +inline int mpreal::set_emin (mp_exp_t exp) +{ + return mpfr_set_emin(exp); +} + +inline mp_exp_t mpreal::get_emax (void) +{ + return mpfr_get_emax(); +} + +inline int mpreal::set_emax (mp_exp_t exp) +{ + return mpfr_set_emax(exp); +} + +inline mp_exp_t mpreal::get_emin_min (void) +{ + return mpfr_get_emin_min(); +} + +inline mp_exp_t mpreal::get_emin_max (void) +{ + return mpfr_get_emin_max(); +} + +inline mp_exp_t mpreal::get_emax_min (void) +{ + return mpfr_get_emax_min(); +} + +inline mp_exp_t mpreal::get_emax_max (void) +{ + return mpfr_get_emax_max(); +} + +////////////////////////////////////////////////////////////////////////// +// Mathematical Functions +////////////////////////////////////////////////////////////////////////// +#define MPREAL_UNARY_MATH_FUNCTION_BODY(f) \ + mpreal y(0, mpfr_get_prec(x.mpfr_srcptr())); \ + mpfr_##f(y.mpfr_ptr(), x.mpfr_srcptr(), r); \ + return y; + +inline const mpreal sqr (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) +{ MPREAL_UNARY_MATH_FUNCTION_BODY(sqr ); } + +inline const mpreal sqrt (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) +{ MPREAL_UNARY_MATH_FUNCTION_BODY(sqrt); } + +inline const mpreal sqrt(const unsigned long int x, mp_rnd_t r) +{ + mpreal y; + mpfr_sqrt_ui(y.mpfr_ptr(), x, r); + return y; +} + +inline const mpreal sqrt(const unsigned int v, mp_rnd_t rnd_mode) +{ + return sqrt(static_cast<unsigned long int>(v),rnd_mode); +} + +inline const mpreal sqrt(const long int v, mp_rnd_t rnd_mode) +{ + if (v>=0) return sqrt(static_cast<unsigned long int>(v),rnd_mode); + else return mpreal().setNan(); // NaN +} + +inline const mpreal sqrt(const int v, mp_rnd_t rnd_mode) +{ + if (v>=0) return sqrt(static_cast<unsigned long int>(v),rnd_mode); + else return mpreal().setNan(); // NaN +} + +inline const mpreal root(const mpreal& x, unsigned long int k, mp_rnd_t r = mpreal::get_default_rnd()) +{ + mpreal y(0, mpfr_get_prec(x.mpfr_srcptr())); + mpfr_root(y.mpfr_ptr(), x.mpfr_srcptr(), k, r); + return y; +} + +inline const mpreal dim(const mpreal& a, const mpreal& b, mp_rnd_t r = mpreal::get_default_rnd()) +{ + mpreal y(0, mpfr_get_prec(a.mpfr_srcptr())); + mpfr_dim(y.mpfr_ptr(), a.mpfr_srcptr(), b.mpfr_srcptr(), r); + return y; +} + +inline int cmpabs(const mpreal& a,const mpreal& b) +{ + return mpfr_cmpabs(a.mpfr_ptr(), b.mpfr_srcptr()); +} + +inline int sin_cos(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + return mpfr_sin_cos(s.mpfr_ptr(), c.mpfr_ptr(), v.mpfr_srcptr(), rnd_mode); +} + +inline const mpreal sqrt (const long double v, mp_rnd_t rnd_mode) { return sqrt(mpreal(v),rnd_mode); } +inline const mpreal sqrt (const double v, mp_rnd_t rnd_mode) { return sqrt(mpreal(v),rnd_mode); } + +inline const mpreal cbrt (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(cbrt ); } +inline const mpreal fabs (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(abs ); } +inline const mpreal abs (const mpreal& x, mp_rnd_t r) { MPREAL_UNARY_MATH_FUNCTION_BODY(abs ); } +inline const mpreal log (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(log ); } +inline const mpreal log2 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(log2 ); } +inline const mpreal log10 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(log10); } +inline const mpreal exp (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(exp ); } +inline const mpreal exp2 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(exp2 ); } +inline const mpreal exp10 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(exp10); } +inline const mpreal cos (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(cos ); } +inline const mpreal sin (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(sin ); } +inline const mpreal tan (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(tan ); } +inline const mpreal sec (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(sec ); } +inline const mpreal csc (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(csc ); } +inline const mpreal cot (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(cot ); } +inline const mpreal acos (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(acos ); } +inline const mpreal asin (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(asin ); } +inline const mpreal atan (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(atan ); } + +inline const mpreal acot (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return atan (1/v, r); } +inline const mpreal asec (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return acos (1/v, r); } +inline const mpreal acsc (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return asin (1/v, r); } +inline const mpreal acoth (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return atanh(1/v, r); } +inline const mpreal asech (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return acosh(1/v, r); } +inline const mpreal acsch (const mpreal& v, mp_rnd_t r = mpreal::get_default_rnd()) { return asinh(1/v, r); } + +inline const mpreal cosh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(cosh ); } +inline const mpreal sinh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(sinh ); } +inline const mpreal tanh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(tanh ); } +inline const mpreal sech (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(sech ); } +inline const mpreal csch (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(csch ); } +inline const mpreal coth (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(coth ); } +inline const mpreal acosh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(acosh); } +inline const mpreal asinh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(asinh); } +inline const mpreal atanh (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(atanh); } + +inline const mpreal log1p (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(log1p ); } +inline const mpreal expm1 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(expm1 ); } +inline const mpreal eint (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(eint ); } +inline const mpreal gamma (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(gamma ); } +inline const mpreal lngamma (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(lngamma); } +inline const mpreal zeta (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(zeta ); } +inline const mpreal erf (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(erf ); } +inline const mpreal erfc (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(erfc ); } +inline const mpreal besselj0(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(j0 ); } +inline const mpreal besselj1(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(j1 ); } +inline const mpreal bessely0(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(y0 ); } +inline const mpreal bessely1(const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(y1 ); } + +inline const mpreal atan2 (const mpreal& y, const mpreal& x, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision())); + mpfr_atan2(a.mpfr_ptr(), y.mpfr_srcptr(), x.mpfr_srcptr(), rnd_mode); + return a; +} + +inline const mpreal hypot (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision())); + mpfr_hypot(a.mpfr_ptr(), x.mpfr_srcptr(), y.mpfr_srcptr(), rnd_mode); + return a; +} + +inline const mpreal remainder (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision())); + mpfr_remainder(a.mpfr_ptr(), x.mpfr_srcptr(), y.mpfr_srcptr(), rnd_mode); + return a; +} + +inline const mpreal remquo (long* q, const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal a(0,(std::max)(y.getPrecision(), x.getPrecision())); + mpfr_remquo(a.mpfr_ptr(),q, x.mpfr_srcptr(), y.mpfr_srcptr(), rnd_mode); + return a; +} + +inline const mpreal fac_ui (unsigned long int v, mp_prec_t prec = mpreal::get_default_prec(), + mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal x(0, prec); + mpfr_fac_ui(x.mpfr_ptr(),v,rnd_mode); + return x; +} + + +inline const mpreal lgamma (const mpreal& v, int *signp = 0, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal x(v); + int tsignp; + + if(signp) mpfr_lgamma(x.mpfr_ptr(), signp,v.mpfr_srcptr(),rnd_mode); + else mpfr_lgamma(x.mpfr_ptr(),&tsignp,v.mpfr_srcptr(),rnd_mode); + + return x; +} + + +inline const mpreal besseljn (long n, const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) +{ + mpreal y(0, x.getPrecision()); + mpfr_jn(y.mpfr_ptr(), n, x.mpfr_srcptr(), r); + return y; +} + +inline const mpreal besselyn (long n, const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) +{ + mpreal y(0, x.getPrecision()); + mpfr_yn(y.mpfr_ptr(), n, x.mpfr_srcptr(), r); + return y; +} + +inline const mpreal fma (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal a; + mp_prec_t p1, p2, p3; + + p1 = v1.get_prec(); + p2 = v2.get_prec(); + p3 = v3.get_prec(); + + a.set_prec(p3>p2?(p3>p1?p3:p1):(p2>p1?p2:p1)); + + mpfr_fma(a.mp,v1.mp,v2.mp,v3.mp,rnd_mode); + return a; +} + +inline const mpreal fms (const mpreal& v1, const mpreal& v2, const mpreal& v3, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal a; + mp_prec_t p1, p2, p3; + + p1 = v1.get_prec(); + p2 = v2.get_prec(); + p3 = v3.get_prec(); + + a.set_prec(p3>p2?(p3>p1?p3:p1):(p2>p1?p2:p1)); + + mpfr_fms(a.mp,v1.mp,v2.mp,v3.mp,rnd_mode); + return a; +} + +inline const mpreal agm (const mpreal& v1, const mpreal& v2, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal a; + mp_prec_t p1, p2; + + p1 = v1.get_prec(); + p2 = v2.get_prec(); + + a.set_prec(p1>p2?p1:p2); + + mpfr_agm(a.mp, v1.mp, v2.mp, rnd_mode); + + return a; +} + +inline const mpreal sum (const mpreal tab[], unsigned long int n, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal x; + mpfr_ptr* t; + unsigned long int i; + + t = new mpfr_ptr[n]; + for (i=0;i<n;i++) t[i] = (mpfr_ptr)tab[i].mp; + mpfr_sum(x.mp,t,n,rnd_mode); + delete[] t; + return x; +} + +////////////////////////////////////////////////////////////////////////// +// MPFR 2.4.0 Specifics +#if (MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0)) + +inline int sinh_cosh(mpreal& s, mpreal& c, const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + return mpfr_sinh_cosh(s.mp,c.mp,v.mp,rnd_mode); +} + +inline const mpreal li2 (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) +{ + MPREAL_UNARY_MATH_FUNCTION_BODY(li2); +} + +inline const mpreal rem (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + /* R = rem(X,Y) if Y != 0, returns X - n * Y where n = trunc(X/Y). */ + return fmod(x, y, rnd_mode); +} + +inline const mpreal mod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + (void)rnd_mode; + + /* + + m = mod(x,y) if y != 0, returns x - n*y where n = floor(x/y) + + The following are true by convention: + - mod(x,0) is x + - mod(x,x) is 0 + - mod(x,y) for x != y and y != 0 has the same sign as y. + + */ + + if(iszero(y)) return x; + if(x == y) return 0; + + mpreal m = x - floor(x / y) * y; + + m.setSign(sgn(y)); // make sure result has the same sign as Y + + return m; +} + +inline const mpreal fmod (const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal a; + mp_prec_t yp, xp; + + yp = y.get_prec(); + xp = x.get_prec(); + + a.set_prec(yp>xp?yp:xp); + + mpfr_fmod(a.mp, x.mp, y.mp, rnd_mode); + + return a; +} + +inline const mpreal rec_sqrt(const mpreal& v, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal x(v); + mpfr_rec_sqrt(x.mp,v.mp,rnd_mode); + return x; +} +#endif // MPFR 2.4.0 Specifics + +////////////////////////////////////////////////////////////////////////// +// MPFR 3.0.0 Specifics +#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) +inline const mpreal digamma (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(digamma); } +inline const mpreal ai (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(ai); } +#endif // MPFR 3.0.0 Specifics + +////////////////////////////////////////////////////////////////////////// +// Constants +inline const mpreal const_log2 (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd()) +{ + mpreal x(0, p); + mpfr_const_log2(x.mpfr_ptr(), r); + return x; +} + +inline const mpreal const_pi (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd()) +{ + mpreal x(0, p); + mpfr_const_pi(x.mpfr_ptr(), r); + return x; +} + +inline const mpreal const_euler (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd()) +{ + mpreal x(0, p); + mpfr_const_euler(x.mpfr_ptr(), r); + return x; +} + +inline const mpreal const_catalan (mp_prec_t p = mpreal::get_default_prec(), mp_rnd_t r = mpreal::get_default_rnd()) +{ + mpreal x(0, p); + mpfr_const_catalan(x.mpfr_ptr(), r); + return x; +} + +inline const mpreal const_infinity (int sign = 1, mp_prec_t p = mpreal::get_default_prec()) +{ + mpreal x(0, p); + mpfr_set_inf(x.mpfr_ptr(), sign); + return x; +} + +////////////////////////////////////////////////////////////////////////// +// Integer Related Functions +inline const mpreal ceil(const mpreal& v) +{ + mpreal x(v); + mpfr_ceil(x.mp,v.mp); + return x; +} + +inline const mpreal floor(const mpreal& v) +{ + mpreal x(v); + mpfr_floor(x.mp,v.mp); + return x; +} + +inline const mpreal round(const mpreal& v) +{ + mpreal x(v); + mpfr_round(x.mp,v.mp); + return x; +} + +inline const mpreal trunc(const mpreal& v) +{ + mpreal x(v); + mpfr_trunc(x.mp,v.mp); + return x; +} + +inline const mpreal rint (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint ); } +inline const mpreal rint_ceil (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint_ceil ); } +inline const mpreal rint_floor (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint_floor); } +inline const mpreal rint_round (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint_round); } +inline const mpreal rint_trunc (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(rint_trunc); } +inline const mpreal frac (const mpreal& x, mp_rnd_t r = mpreal::get_default_rnd()) { MPREAL_UNARY_MATH_FUNCTION_BODY(frac ); } + +////////////////////////////////////////////////////////////////////////// +// Miscellaneous Functions +inline void swap (mpreal& a, mpreal& b) { mpfr_swap(a.mp,b.mp); } +inline const mpreal (max)(const mpreal& x, const mpreal& y){ return (x>y?x:y); } +inline const mpreal (min)(const mpreal& x, const mpreal& y){ return (x<y?x:y); } + +inline const mpreal fmax(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal a; + mpfr_max(a.mp,x.mp,y.mp,rnd_mode); + return a; +} + +inline const mpreal fmin(const mpreal& x, const mpreal& y, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal a; + mpfr_min(a.mp,x.mp,y.mp,rnd_mode); + return a; +} + +inline const mpreal nexttoward (const mpreal& x, const mpreal& y) +{ + mpreal a(x); + mpfr_nexttoward(a.mp,y.mp); + return a; +} + +inline const mpreal nextabove (const mpreal& x) +{ + mpreal a(x); + mpfr_nextabove(a.mp); + return a; +} + +inline const mpreal nextbelow (const mpreal& x) +{ + mpreal a(x); + mpfr_nextbelow(a.mp); + return a; +} + +inline const mpreal urandomb (gmp_randstate_t& state) +{ + mpreal x; + mpfr_urandomb(x.mp,state); + return x; +} + +#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,1,0)) +// use gmp_randinit_default() to init state, gmp_randclear() to clear +inline const mpreal urandom (gmp_randstate_t& state, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal x; + mpfr_urandom(x.mp,state,rnd_mode); + return x; +} + +inline const mpreal grandom (gmp_randstate_t& state, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal x; + mpfr_grandom(x.mp, NULL, state, rnd_mode); + return x; +} + +#endif + +#if (MPFR_VERSION <= MPFR_VERSION_NUM(2,4,2)) +inline const mpreal random2 (mp_size_t size, mp_exp_t exp) +{ + mpreal x; + mpfr_random2(x.mp,size,exp); + return x; +} +#endif + +// Uniformly distributed random number generation +// a = random(seed); <- initialization & first random number generation +// a = random(); <- next random numbers generation +// seed != 0 +inline const mpreal random(unsigned int seed = 0) +{ + +#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) + static gmp_randstate_t state; + static bool isFirstTime = true; + + if(isFirstTime) + { + gmp_randinit_default(state); + gmp_randseed_ui(state,0); + isFirstTime = false; + } + + if(seed != 0) gmp_randseed_ui(state,seed); + + return mpfr::urandom(state); +#else + if(seed != 0) std::srand(seed); + return mpfr::mpreal(std::rand()/(double)RAND_MAX); +#endif + +} + +#if (MPFR_VERSION >= MPFR_VERSION_NUM(3,0,0)) +inline const mpreal grandom(unsigned int seed = 0) +{ + static gmp_randstate_t state; + static bool isFirstTime = true; + + if(isFirstTime) + { + gmp_randinit_default(state); + gmp_randseed_ui(state,0); + isFirstTime = false; + } + + if(seed != 0) gmp_randseed_ui(state,seed); + + return mpfr::grandom(state); +} +#endif + +////////////////////////////////////////////////////////////////////////// +// Set/Get global properties +inline void mpreal::set_default_prec(mp_prec_t prec) +{ + mpfr_set_default_prec(prec); +} + +inline void mpreal::set_default_rnd(mp_rnd_t rnd_mode) +{ + mpfr_set_default_rounding_mode(rnd_mode); +} + +inline bool mpreal::fits_in_bits(double x, int n) +{ + int i; + double t; + return IsInf(x) || (std::modf ( std::ldexp ( std::frexp ( x, &i ), n ), &t ) == 0.0); +} + +inline const mpreal pow(const mpreal& a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal x(a); + mpfr_pow(x.mp,x.mp,b.mp,rnd_mode); + return x; +} + +inline const mpreal pow(const mpreal& a, const mpz_t b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal x(a); + mpfr_pow_z(x.mp,x.mp,b,rnd_mode); + return x; +} + +inline const mpreal pow(const mpreal& a, const unsigned long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal x(a); + mpfr_pow_ui(x.mp,x.mp,b,rnd_mode); + return x; +} + +inline const mpreal pow(const mpreal& a, const unsigned int b, mp_rnd_t rnd_mode) +{ + return pow(a,static_cast<unsigned long int>(b),rnd_mode); +} + +inline const mpreal pow(const mpreal& a, const long int b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal x(a); + mpfr_pow_si(x.mp,x.mp,b,rnd_mode); + return x; +} + +inline const mpreal pow(const mpreal& a, const int b, mp_rnd_t rnd_mode) +{ + return pow(a,static_cast<long int>(b),rnd_mode); +} + +inline const mpreal pow(const mpreal& a, const long double b, mp_rnd_t rnd_mode) +{ + return pow(a,mpreal(b),rnd_mode); +} + +inline const mpreal pow(const mpreal& a, const double b, mp_rnd_t rnd_mode) +{ + return pow(a,mpreal(b),rnd_mode); +} + +inline const mpreal pow(const unsigned long int a, const mpreal& b, mp_rnd_t rnd_mode = mpreal::get_default_rnd()) +{ + mpreal x(a); + mpfr_ui_pow(x.mp,a,b.mp,rnd_mode); + return x; +} + +inline const mpreal pow(const unsigned int a, const mpreal& b, mp_rnd_t rnd_mode) +{ + return pow(static_cast<unsigned long int>(a),b,rnd_mode); +} + +inline const mpreal pow(const long int a, const mpreal& b, mp_rnd_t rnd_mode) +{ + if (a>=0) return pow(static_cast<unsigned long int>(a),b,rnd_mode); + else return pow(mpreal(a),b,rnd_mode); +} + +inline const mpreal pow(const int a, const mpreal& b, mp_rnd_t rnd_mode) +{ + if (a>=0) return pow(static_cast<unsigned long int>(a),b,rnd_mode); + else return pow(mpreal(a),b,rnd_mode); +} + +inline const mpreal pow(const long double a, const mpreal& b, mp_rnd_t rnd_mode) +{ + return pow(mpreal(a),b,rnd_mode); +} + +inline const mpreal pow(const double a, const mpreal& b, mp_rnd_t rnd_mode) +{ + return pow(mpreal(a),b,rnd_mode); +} + +// pow unsigned long int +inline const mpreal pow(const unsigned long int a, const unsigned long int b, mp_rnd_t rnd_mode) +{ + mpreal x(a); + mpfr_ui_pow_ui(x.mp,a,b,rnd_mode); + return x; +} + +inline const mpreal pow(const unsigned long int a, const unsigned int b, mp_rnd_t rnd_mode) +{ + return pow(a,static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui +} + +inline const mpreal pow(const unsigned long int a, const long int b, mp_rnd_t rnd_mode) +{ + if(b>0) return pow(a,static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui + else return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow +} + +inline const mpreal pow(const unsigned long int a, const int b, mp_rnd_t rnd_mode) +{ + if(b>0) return pow(a,static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui + else return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow +} + +inline const mpreal pow(const unsigned long int a, const long double b, mp_rnd_t rnd_mode) +{ + return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow +} + +inline const mpreal pow(const unsigned long int a, const double b, mp_rnd_t rnd_mode) +{ + return pow(a,mpreal(b),rnd_mode); //mpfr_ui_pow +} + +// pow unsigned int +inline const mpreal pow(const unsigned int a, const unsigned long int b, mp_rnd_t rnd_mode) +{ + return pow(static_cast<unsigned long int>(a),b,rnd_mode); //mpfr_ui_pow_ui +} + +inline const mpreal pow(const unsigned int a, const unsigned int b, mp_rnd_t rnd_mode) +{ + return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui +} + +inline const mpreal pow(const unsigned int a, const long int b, mp_rnd_t rnd_mode) +{ + if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui + else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow +} + +inline const mpreal pow(const unsigned int a, const int b, mp_rnd_t rnd_mode) +{ + if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui + else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow +} + +inline const mpreal pow(const unsigned int a, const long double b, mp_rnd_t rnd_mode) +{ + return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow +} + +inline const mpreal pow(const unsigned int a, const double b, mp_rnd_t rnd_mode) +{ + return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow +} + +// pow long int +inline const mpreal pow(const long int a, const unsigned long int b, mp_rnd_t rnd_mode) +{ + if (a>0) return pow(static_cast<unsigned long int>(a),b,rnd_mode); //mpfr_ui_pow_ui + else return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui +} + +inline const mpreal pow(const long int a, const unsigned int b, mp_rnd_t rnd_mode) +{ + if (a>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui + else return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_pow_ui +} + +inline const mpreal pow(const long int a, const long int b, mp_rnd_t rnd_mode) +{ + if (a>0) + { + if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui + else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow + }else{ + return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si + } +} + +inline const mpreal pow(const long int a, const int b, mp_rnd_t rnd_mode) +{ + if (a>0) + { + if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui + else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow + }else{ + return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si + } +} + +inline const mpreal pow(const long int a, const long double b, mp_rnd_t rnd_mode) +{ + if (a>=0) return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow + else return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow +} + +inline const mpreal pow(const long int a, const double b, mp_rnd_t rnd_mode) +{ + if (a>=0) return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow + else return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow +} + +// pow int +inline const mpreal pow(const int a, const unsigned long int b, mp_rnd_t rnd_mode) +{ + if (a>0) return pow(static_cast<unsigned long int>(a),b,rnd_mode); //mpfr_ui_pow_ui + else return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui +} + +inline const mpreal pow(const int a, const unsigned int b, mp_rnd_t rnd_mode) +{ + if (a>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui + else return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_pow_ui +} + +inline const mpreal pow(const int a, const long int b, mp_rnd_t rnd_mode) +{ + if (a>0) + { + if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui + else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow + }else{ + return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si + } +} + +inline const mpreal pow(const int a, const int b, mp_rnd_t rnd_mode) +{ + if (a>0) + { + if(b>0) return pow(static_cast<unsigned long int>(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_ui_pow_ui + else return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow + }else{ + return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si + } +} + +inline const mpreal pow(const int a, const long double b, mp_rnd_t rnd_mode) +{ + if (a>=0) return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow + else return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow +} + +inline const mpreal pow(const int a, const double b, mp_rnd_t rnd_mode) +{ + if (a>=0) return pow(static_cast<unsigned long int>(a),mpreal(b),rnd_mode); //mpfr_ui_pow + else return pow(mpreal(a),mpreal(b),rnd_mode); //mpfr_pow +} + +// pow long double +inline const mpreal pow(const long double a, const long double b, mp_rnd_t rnd_mode) +{ + return pow(mpreal(a),mpreal(b),rnd_mode); +} + +inline const mpreal pow(const long double a, const unsigned long int b, mp_rnd_t rnd_mode) +{ + return pow(mpreal(a),b,rnd_mode); //mpfr_pow_ui +} + +inline const mpreal pow(const long double a, const unsigned int b, mp_rnd_t rnd_mode) +{ + return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); //mpfr_pow_ui +} + +inline const mpreal pow(const long double a, const long int b, mp_rnd_t rnd_mode) +{ + return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si +} + +inline const mpreal pow(const long double a, const int b, mp_rnd_t rnd_mode) +{ + return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si +} + +inline const mpreal pow(const double a, const double b, mp_rnd_t rnd_mode) +{ + return pow(mpreal(a),mpreal(b),rnd_mode); +} + +inline const mpreal pow(const double a, const unsigned long int b, mp_rnd_t rnd_mode) +{ + return pow(mpreal(a),b,rnd_mode); // mpfr_pow_ui +} + +inline const mpreal pow(const double a, const unsigned int b, mp_rnd_t rnd_mode) +{ + return pow(mpreal(a),static_cast<unsigned long int>(b),rnd_mode); // mpfr_pow_ui +} + +inline const mpreal pow(const double a, const long int b, mp_rnd_t rnd_mode) +{ + return pow(mpreal(a),b,rnd_mode); // mpfr_pow_si +} + +inline const mpreal pow(const double a, const int b, mp_rnd_t rnd_mode) +{ + return pow(mpreal(a),static_cast<long int>(b),rnd_mode); // mpfr_pow_si +} +} // End of mpfr namespace + +// Explicit specialization of std::swap for mpreal numbers +// Thus standard algorithms will use efficient version of swap (due to Koenig lookup) +// Non-throwing swap C++ idiom: http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-throwing_swap +namespace std +{ + // we are allowed to extend namespace std with specializations only + template <> + inline void swap(mpfr::mpreal& x, mpfr::mpreal& y) + { + return mpfr::swap(x, y); + } + + template<> + class numeric_limits<mpfr::mpreal> + { + public: + static const bool is_specialized = true; + static const bool is_signed = true; + static const bool is_integer = false; + static const bool is_exact = false; + static const int radix = 2; + + static const bool has_infinity = true; + static const bool has_quiet_NaN = true; + static const bool has_signaling_NaN = true; + + static const bool is_iec559 = true; // = IEEE 754 + static const bool is_bounded = true; + static const bool is_modulo = false; + static const bool traps = true; + static const bool tinyness_before = true; + + static const float_denorm_style has_denorm = denorm_absent; + + inline static mpfr::mpreal (min) (mp_prec_t precision = mpfr::mpreal::get_default_prec()) { return mpfr::minval(precision); } + inline static mpfr::mpreal (max) (mp_prec_t precision = mpfr::mpreal::get_default_prec()) { return mpfr::maxval(precision); } + inline static mpfr::mpreal lowest (mp_prec_t precision = mpfr::mpreal::get_default_prec()) { return -mpfr::maxval(precision); } + + // Returns smallest eps such that 1 + eps != 1 (classic machine epsilon) + inline static mpfr::mpreal epsilon(mp_prec_t precision = mpfr::mpreal::get_default_prec()) { return mpfr::machine_epsilon(precision); } + + // Returns smallest eps such that x + eps != x (relative machine epsilon) + inline static mpfr::mpreal epsilon(const mpfr::mpreal& x) { return mpfr::machine_epsilon(x); } + + inline static mpfr::mpreal round_error(mp_prec_t precision = mpfr::mpreal::get_default_prec()) + { + mp_rnd_t r = mpfr::mpreal::get_default_rnd(); + + if(r == GMP_RNDN) return mpfr::mpreal(0.5, precision); + else return mpfr::mpreal(1.0, precision); + } + + inline static const mpfr::mpreal infinity() { return mpfr::const_infinity(); } + inline static const mpfr::mpreal quiet_NaN() { return mpfr::mpreal().setNan(); } + inline static const mpfr::mpreal signaling_NaN() { return mpfr::mpreal().setNan(); } + inline static const mpfr::mpreal denorm_min() { return (min)(); } + + // Please note, exponent range is not fixed in MPFR + static const int min_exponent = MPFR_EMIN_DEFAULT; + static const int max_exponent = MPFR_EMAX_DEFAULT; + MPREAL_PERMISSIVE_EXPR static const int min_exponent10 = (int) (MPFR_EMIN_DEFAULT * 0.3010299956639811); + MPREAL_PERMISSIVE_EXPR static const int max_exponent10 = (int) (MPFR_EMAX_DEFAULT * 0.3010299956639811); + +#ifdef MPREAL_HAVE_DYNAMIC_STD_NUMERIC_LIMITS + + // Following members should be constant according to standard, but they can be variable in MPFR + // So we define them as functions here. + // + // This is preferable way for std::numeric_limits<mpfr::mpreal> specialization. + // But it is incompatible with standard std::numeric_limits and might not work with other libraries, e.g. boost. + // See below for compatible implementation. + inline static float_round_style round_style() + { + mp_rnd_t r = mpfr::mpreal::get_default_rnd(); + + switch (r) + { + case GMP_RNDN: return round_to_nearest; + case GMP_RNDZ: return round_toward_zero; + case GMP_RNDU: return round_toward_infinity; + case GMP_RNDD: return round_toward_neg_infinity; + default: return round_indeterminate; + } + } + + inline static int digits() { return int(mpfr::mpreal::get_default_prec()); } + inline static int digits(const mpfr::mpreal& x) { return x.getPrecision(); } + + inline static int digits10(mp_prec_t precision = mpfr::mpreal::get_default_prec()) + { + return mpfr::bits2digits(precision); + } + + inline static int digits10(const mpfr::mpreal& x) + { + return mpfr::bits2digits(x.getPrecision()); + } + + inline static int max_digits10(mp_prec_t precision = mpfr::mpreal::get_default_prec()) + { + return digits10(precision); + } +#else + // Digits and round_style are NOT constants when it comes to mpreal. + // If possible, please use functions digits() and round_style() defined above. + // + // These (default) values are preserved for compatibility with existing libraries, e.g. boost. + // Change them accordingly to your application. + // + // For example, if you use 256 bits of precision uniformly in your program, then: + // digits = 256 + // digits10 = 77 + // max_digits10 = 78 + // + // Approximate formula for decimal digits is: digits10 = floor(log10(2) * digits). See bits2digits() for more details. + + static const std::float_round_style round_style = round_to_nearest; + static const int digits = 53; + static const int digits10 = 15; + static const int max_digits10 = 16; +#endif + }; + +} + +#endif /* __MPREAL_H__ */
+ eigen3/unsupported/test/mpreal_support.cpp view
@@ -0,0 +1,57 @@+#include "main.h"+#include <Eigen/MPRealSupport>+#include <Eigen/LU>+#include <Eigen/Eigenvalues>+#include <sstream>++using namespace mpfr;+using namespace Eigen;++void test_mpreal_support()+{+ // set precision to 256 bits (double has only 53 bits)+ mpreal::set_default_prec(256);+ typedef Matrix<mpreal,Eigen::Dynamic,Eigen::Dynamic> MatrixXmp;++ std::cerr << "epsilon = " << NumTraits<mpreal>::epsilon() << "\n";+ std::cerr << "dummy_precision = " << NumTraits<mpreal>::dummy_precision() << "\n";+ std::cerr << "highest = " << NumTraits<mpreal>::highest() << "\n";+ std::cerr << "lowest = " << NumTraits<mpreal>::lowest() << "\n";++ for(int i = 0; i < g_repeat; i++) {+ int s = Eigen::internal::random<int>(1,100);+ MatrixXmp A = MatrixXmp::Random(s,s);+ MatrixXmp B = MatrixXmp::Random(s,s);+ MatrixXmp S = A.adjoint() * A;+ MatrixXmp X;+ + // Basic stuffs+ VERIFY_IS_APPROX(A.real(), A);+ VERIFY(Eigen::internal::isApprox(A.array().abs2().sum(), A.squaredNorm()));+ VERIFY_IS_APPROX(A.array().exp(), exp(A.array()));+ VERIFY_IS_APPROX(A.array().abs2().sqrt(), A.array().abs());+ VERIFY_IS_APPROX(A.array().sin(), sin(A.array()));+ VERIFY_IS_APPROX(A.array().cos(), cos(A.array()));+ ++ // Cholesky+ X = S.selfadjointView<Lower>().llt().solve(B);+ VERIFY_IS_APPROX((S.selfadjointView<Lower>()*X).eval(),B);++ // partial LU+ X = A.lu().solve(B);+ VERIFY_IS_APPROX((A*X).eval(),B);++ // symmetric eigenvalues+ SelfAdjointEigenSolver<MatrixXmp> eig(S);+ VERIFY_IS_EQUAL(eig.info(), Success);+ VERIFY( (S.selfadjointView<Lower>() * eig.eigenvectors()).isApprox(eig.eigenvectors() * eig.eigenvalues().asDiagonal(), NumTraits<mpreal>::dummy_precision()*1e3) );+ }+ + {+ MatrixXmp A(8,3); A.setRandom();+ // test output (interesting things happen in this code)+ std::stringstream stream;+ stream << A;+ }+}
+ eigen3/unsupported/test/openglsupport.cpp view
@@ -0,0 +1,337 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010 Gael Guennebaud <gael.guennebaud@inria.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include <main.h>+#include <iostream>+#include <GL/glew.h>+#include <Eigen/OpenGLSupport>+#include <GL/glut.h>+using namespace Eigen;+++++#define VERIFY_MATRIX(CODE,REF) { \+ glLoadIdentity(); \+ CODE; \+ Matrix<float,4,4,ColMajor> m; m.setZero(); \+ glGet(GL_MODELVIEW_MATRIX, m); \+ if(!(REF).cast<float>().isApprox(m)) { \+ std::cerr << "Expected:\n" << ((REF).cast<float>()) << "\n" << "got\n" << m << "\n\n"; \+ } \+ VERIFY_IS_APPROX((REF).cast<float>(), m); \+ }++#define VERIFY_UNIFORM(SUFFIX,NAME,TYPE) { \+ TYPE value; value.setRandom(); \+ TYPE data; \+ int loc = glGetUniformLocation(prg_id, #NAME); \+ VERIFY((loc!=-1) && "uniform not found"); \+ glUniform(loc,value); \+ EIGEN_CAT(glGetUniform,SUFFIX)(prg_id,loc,data.data()); \+ if(!value.isApprox(data)) { \+ std::cerr << "Expected:\n" << value << "\n" << "got\n" << data << "\n\n"; \+ } \+ VERIFY_IS_APPROX(value, data); \+ }+ +#define VERIFY_UNIFORMi(NAME,TYPE) { \+ TYPE value = TYPE::Random().eval().cast<float>().cast<TYPE::Scalar>(); \+ TYPE data; \+ int loc = glGetUniformLocation(prg_id, #NAME); \+ VERIFY((loc!=-1) && "uniform not found"); \+ glUniform(loc,value); \+ glGetUniformiv(prg_id,loc,(GLint*)data.data()); \+ if(!value.isApprox(data)) { \+ std::cerr << "Expected:\n" << value << "\n" << "got\n" << data << "\n\n"; \+ } \+ VERIFY_IS_APPROX(value, data); \+ }+ +void printInfoLog(GLuint objectID)+{+ int infologLength, charsWritten;+ GLchar *infoLog;+ glGetProgramiv(objectID,GL_INFO_LOG_LENGTH, &infologLength);+ if(infologLength > 0)+ {+ infoLog = new GLchar[infologLength];+ glGetProgramInfoLog(objectID, infologLength, &charsWritten, infoLog);+ if (charsWritten>0)+ std::cerr << "Shader info : \n" << infoLog << std::endl;+ delete[] infoLog;+ }+}++GLint createShader(const char* vtx, const char* frg)+{+ GLint prg_id = glCreateProgram();+ GLint vtx_id = glCreateShader(GL_VERTEX_SHADER);+ GLint frg_id = glCreateShader(GL_FRAGMENT_SHADER);+ GLint ok;+ + glShaderSource(vtx_id, 1, &vtx, 0);+ glCompileShader(vtx_id);+ glGetShaderiv(vtx_id,GL_COMPILE_STATUS,&ok);+ if(!ok)+ {+ std::cerr << "vtx compilation failed\n";+ }+ + glShaderSource(frg_id, 1, &frg, 0);+ glCompileShader(frg_id);+ glGetShaderiv(frg_id,GL_COMPILE_STATUS,&ok);+ if(!ok)+ {+ std::cerr << "frg compilation failed\n";+ }+ + glAttachShader(prg_id, vtx_id);+ glAttachShader(prg_id, frg_id);+ glLinkProgram(prg_id);+ glGetProgramiv(prg_id,GL_LINK_STATUS,&ok);+ if(!ok)+ {+ std::cerr << "linking failed\n";+ }+ printInfoLog(prg_id);+ + glUseProgram(prg_id);+ return prg_id;+}++void test_openglsupport()+{+ int argc = 0;+ glutInit(&argc, 0);+ glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);+ glutInitWindowPosition (0,0);+ glutInitWindowSize(10, 10);++ if(glutCreateWindow("Eigen") <= 0)+ {+ std::cerr << "Error: Unable to create GLUT Window.\n";+ exit(1);+ }+ + glewExperimental = GL_TRUE;+ if(glewInit() != GLEW_OK)+ {+ std::cerr << "Warning: Failed to initialize GLEW\n";+ }++ Vector3f v3f;+ Matrix3f rot;+ glBegin(GL_POINTS);+ + glVertex(v3f);+ glVertex(2*v3f+v3f);+ glVertex(rot*v3f);+ + glEnd();+ + // 4x4 matrices+ Matrix4f mf44; mf44.setRandom();+ VERIFY_MATRIX(glLoadMatrix(mf44), mf44);+ VERIFY_MATRIX(glMultMatrix(mf44), mf44);+ Matrix4d md44; md44.setRandom();+ VERIFY_MATRIX(glLoadMatrix(md44), md44);+ VERIFY_MATRIX(glMultMatrix(md44), md44);+ + // Quaternion+ Quaterniond qd(AngleAxisd(internal::random<double>(), Vector3d::Random()));+ VERIFY_MATRIX(glRotate(qd), Projective3d(qd).matrix());+ + Quaternionf qf(AngleAxisf(internal::random<double>(), Vector3f::Random()));+ VERIFY_MATRIX(glRotate(qf), Projective3f(qf).matrix());+ + // 3D Transform+ Transform<float,3,AffineCompact> acf3; acf3.matrix().setRandom();+ VERIFY_MATRIX(glLoadMatrix(acf3), Projective3f(acf3).matrix());+ VERIFY_MATRIX(glMultMatrix(acf3), Projective3f(acf3).matrix());+ + Transform<float,3,Affine> af3(acf3);+ VERIFY_MATRIX(glLoadMatrix(af3), Projective3f(af3).matrix());+ VERIFY_MATRIX(glMultMatrix(af3), Projective3f(af3).matrix());+ + Transform<float,3,Projective> pf3; pf3.matrix().setRandom();+ VERIFY_MATRIX(glLoadMatrix(pf3), Projective3f(pf3).matrix());+ VERIFY_MATRIX(glMultMatrix(pf3), Projective3f(pf3).matrix());+ + Transform<double,3,AffineCompact> acd3; acd3.matrix().setRandom();+ VERIFY_MATRIX(glLoadMatrix(acd3), Projective3d(acd3).matrix());+ VERIFY_MATRIX(glMultMatrix(acd3), Projective3d(acd3).matrix());+ + Transform<double,3,Affine> ad3(acd3);+ VERIFY_MATRIX(glLoadMatrix(ad3), Projective3d(ad3).matrix());+ VERIFY_MATRIX(glMultMatrix(ad3), Projective3d(ad3).matrix());+ + Transform<double,3,Projective> pd3; pd3.matrix().setRandom();+ VERIFY_MATRIX(glLoadMatrix(pd3), Projective3d(pd3).matrix());+ VERIFY_MATRIX(glMultMatrix(pd3), Projective3d(pd3).matrix());+ + // translations (2D and 3D)+ {+ Vector2f vf2; vf2.setRandom(); Vector3f vf23; vf23 << vf2, 0;+ VERIFY_MATRIX(glTranslate(vf2), Projective3f(Translation3f(vf23)).matrix());+ Vector2d vd2; vd2.setRandom(); Vector3d vd23; vd23 << vd2, 0;+ VERIFY_MATRIX(glTranslate(vd2), Projective3d(Translation3d(vd23)).matrix());+ + Vector3f vf3; vf3.setRandom();+ VERIFY_MATRIX(glTranslate(vf3), Projective3f(Translation3f(vf3)).matrix());+ Vector3d vd3; vd3.setRandom();+ VERIFY_MATRIX(glTranslate(vd3), Projective3d(Translation3d(vd3)).matrix());+ + Translation<float,3> tf3; tf3.vector().setRandom();+ VERIFY_MATRIX(glTranslate(tf3), Projective3f(tf3).matrix());+ + Translation<double,3> td3; td3.vector().setRandom();+ VERIFY_MATRIX(glTranslate(td3), Projective3d(td3).matrix());+ }+ + // scaling (2D and 3D)+ {+ Vector2f vf2; vf2.setRandom(); Vector3f vf23; vf23 << vf2, 1;+ VERIFY_MATRIX(glScale(vf2), Projective3f(Scaling(vf23)).matrix());+ Vector2d vd2; vd2.setRandom(); Vector3d vd23; vd23 << vd2, 1;+ VERIFY_MATRIX(glScale(vd2), Projective3d(Scaling(vd23)).matrix());+ + Vector3f vf3; vf3.setRandom();+ VERIFY_MATRIX(glScale(vf3), Projective3f(Scaling(vf3)).matrix());+ Vector3d vd3; vd3.setRandom();+ VERIFY_MATRIX(glScale(vd3), Projective3d(Scaling(vd3)).matrix());+ + UniformScaling<float> usf(internal::random<float>());+ VERIFY_MATRIX(glScale(usf), Projective3f(usf).matrix());+ + UniformScaling<double> usd(internal::random<double>());+ VERIFY_MATRIX(glScale(usd), Projective3d(usd).matrix());+ }+ + // uniform+ {+ const char* vtx = "void main(void) { gl_Position = gl_Vertex; }\n";+ + if(GLEW_VERSION_2_0)+ {+ #ifdef GL_VERSION_2_0+ const char* frg = ""+ "uniform vec2 v2f;\n"+ "uniform vec3 v3f;\n"+ "uniform vec4 v4f;\n"+ "uniform ivec2 v2i;\n"+ "uniform ivec3 v3i;\n"+ "uniform ivec4 v4i;\n"+ "uniform mat2 m2f;\n"+ "uniform mat3 m3f;\n"+ "uniform mat4 m4f;\n"+ "void main(void) { gl_FragColor = vec4(v2f[0]+v3f[0]+v4f[0])+vec4(v2i[0]+v3i[0]+v4i[0])+vec4(m2f[0][0]+m3f[0][0]+m4f[0][0]); }\n";+ + GLint prg_id = createShader(vtx,frg);+ + VERIFY_UNIFORM(fv,v2f, Vector2f);+ VERIFY_UNIFORM(fv,v3f, Vector3f);+ VERIFY_UNIFORM(fv,v4f, Vector4f);+ VERIFY_UNIFORMi(v2i, Vector2i);+ VERIFY_UNIFORMi(v3i, Vector3i);+ VERIFY_UNIFORMi(v4i, Vector4i);+ VERIFY_UNIFORM(fv,m2f, Matrix2f);+ VERIFY_UNIFORM(fv,m3f, Matrix3f);+ VERIFY_UNIFORM(fv,m4f, Matrix4f);+ #endif+ }+ else+ std::cerr << "Warning: opengl 2.0 was not tested\n";+ + if(GLEW_VERSION_2_1)+ {+ #ifdef GL_VERSION_2_1+ const char* frg = "#version 120\n"+ "uniform mat2x3 m23f;\n"+ "uniform mat3x2 m32f;\n"+ "uniform mat2x4 m24f;\n"+ "uniform mat4x2 m42f;\n"+ "uniform mat3x4 m34f;\n"+ "uniform mat4x3 m43f;\n"+ "void main(void) { gl_FragColor = vec4(m23f[0][0]+m32f[0][0]+m24f[0][0]+m42f[0][0]+m34f[0][0]+m43f[0][0]); }\n";+ + GLint prg_id = createShader(vtx,frg);+ + typedef Matrix<float,2,3> Matrix23f;+ typedef Matrix<float,3,2> Matrix32f;+ typedef Matrix<float,2,4> Matrix24f;+ typedef Matrix<float,4,2> Matrix42f;+ typedef Matrix<float,3,4> Matrix34f;+ typedef Matrix<float,4,3> Matrix43f;+ + VERIFY_UNIFORM(fv,m23f, Matrix23f);+ VERIFY_UNIFORM(fv,m32f, Matrix32f);+ VERIFY_UNIFORM(fv,m24f, Matrix24f);+ VERIFY_UNIFORM(fv,m42f, Matrix42f);+ VERIFY_UNIFORM(fv,m34f, Matrix34f);+ VERIFY_UNIFORM(fv,m43f, Matrix43f);+ #endif+ }+ else+ std::cerr << "Warning: opengl 2.1 was not tested\n";+ + if(GLEW_VERSION_3_0)+ {+ #ifdef GL_VERSION_3_0+ const char* frg = "#version 150\n"+ "uniform uvec2 v2ui;\n"+ "uniform uvec3 v3ui;\n"+ "uniform uvec4 v4ui;\n"+ "out vec4 data;\n"+ "void main(void) { data = vec4(v2ui[0]+v3ui[0]+v4ui[0]); }\n";+ + GLint prg_id = createShader(vtx,frg);+ + typedef Matrix<unsigned int,2,1> Vector2ui;+ typedef Matrix<unsigned int,3,1> Vector3ui;+ typedef Matrix<unsigned int,4,1> Vector4ui;+ + VERIFY_UNIFORMi(v2ui, Vector2ui);+ VERIFY_UNIFORMi(v3ui, Vector3ui);+ VERIFY_UNIFORMi(v4ui, Vector4ui);+ #endif+ }+ else+ std::cerr << "Warning: opengl 3.0 was not tested\n";+ + #ifdef GLEW_ARB_gpu_shader_fp64+ if(GLEW_ARB_gpu_shader_fp64)+ {+ #ifdef GL_ARB_gpu_shader_fp64+ const char* frg = "#version 150\n"+ "uniform dvec2 v2d;\n"+ "uniform dvec3 v3d;\n"+ "uniform dvec4 v4d;\n"+ "out vec4 data;\n"+ "void main(void) { data = vec4(v2d[0]+v3d[0]+v4d[0]); }\n";+ + GLint prg_id = createShader(vtx,frg);+ + typedef Vector2d Vector2d;+ typedef Vector3d Vector3d;+ typedef Vector4d Vector4d;+ + VERIFY_UNIFORM(dv,v2d, Vector2d);+ VERIFY_UNIFORM(dv,v3d, Vector3d);+ VERIFY_UNIFORM(dv,v4d, Vector4d);+ #endif+ }+ else+ std::cerr << "Warning: GLEW_ARB_gpu_shader_fp64 was not tested\n";+ #else+ std::cerr << "Warning: GLEW_ARB_gpu_shader_fp64 was not tested\n";+ #endif+ }+ +}
+ eigen3/unsupported/test/polynomialsolver.cpp view
@@ -0,0 +1,213 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010 Manuel Yguel <manuel.yguel@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <unsupported/Eigen/Polynomials>+#include <iostream>+#include <algorithm>++using namespace std;++namespace Eigen {+namespace internal {+template<int Size>+struct increment_if_fixed_size+{+ enum {+ ret = (Size == Dynamic) ? Dynamic : Size+1+ };+};+}+}+++template<int Deg, typename POLYNOMIAL, typename SOLVER>+bool aux_evalSolver( const POLYNOMIAL& pols, SOLVER& psolve )+{+ typedef typename POLYNOMIAL::Index Index;+ typedef typename POLYNOMIAL::Scalar Scalar;++ typedef typename SOLVER::RootsType RootsType;+ typedef Matrix<Scalar,Deg,1> EvalRootsType;++ const Index deg = pols.size()-1;++ psolve.compute( pols );+ const RootsType& roots( psolve.roots() );+ EvalRootsType evr( deg );+ for( int i=0; i<roots.size(); ++i ){+ evr[i] = std::abs( poly_eval( pols, roots[i] ) ); }++ bool evalToZero = evr.isZero( test_precision<Scalar>() );+ if( !evalToZero )+ {+ cerr << "WRONG root: " << endl;+ cerr << "Polynomial: " << pols.transpose() << endl;+ cerr << "Roots found: " << roots.transpose() << endl;+ cerr << "Abs value of the polynomial at the roots: " << evr.transpose() << endl;+ cerr << endl;+ }++ std::vector<Scalar> rootModuli( roots.size() );+ Map< EvalRootsType > aux( &rootModuli[0], roots.size() );+ aux = roots.array().abs();+ std::sort( rootModuli.begin(), rootModuli.end() );+ bool distinctModuli=true;+ for( size_t i=1; i<rootModuli.size() && distinctModuli; ++i )+ {+ if( internal::isApprox( rootModuli[i], rootModuli[i-1] ) ){+ distinctModuli = false; }+ }+ VERIFY( evalToZero || !distinctModuli );++ return distinctModuli;+}++++++++template<int Deg, typename POLYNOMIAL>+void evalSolver( const POLYNOMIAL& pols )+{+ typedef typename POLYNOMIAL::Scalar Scalar;++ typedef PolynomialSolver<Scalar, Deg > PolynomialSolverType;++ PolynomialSolverType psolve;+ aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>( pols, psolve );+}+++++template< int Deg, typename POLYNOMIAL, typename ROOTS, typename REAL_ROOTS >+void evalSolverSugarFunction( const POLYNOMIAL& pols, const ROOTS& roots, const REAL_ROOTS& real_roots )+{+ using std::sqrt;+ typedef typename POLYNOMIAL::Scalar Scalar;++ typedef PolynomialSolver<Scalar, Deg > PolynomialSolverType;++ PolynomialSolverType psolve;+ if( aux_evalSolver<Deg, POLYNOMIAL, PolynomialSolverType>( pols, psolve ) )+ {+ //It is supposed that+ // 1) the roots found are correct+ // 2) the roots have distinct moduli++ typedef typename REAL_ROOTS::Scalar Real;++ //Test realRoots+ std::vector< Real > calc_realRoots;+ psolve.realRoots( calc_realRoots );+ VERIFY( calc_realRoots.size() == (size_t)real_roots.size() );++ const Scalar psPrec = sqrt( test_precision<Scalar>() );++ for( size_t i=0; i<calc_realRoots.size(); ++i )+ {+ bool found = false;+ for( size_t j=0; j<calc_realRoots.size()&& !found; ++j )+ {+ if( internal::isApprox( calc_realRoots[i], real_roots[j] ), psPrec ){+ found = true; }+ }+ VERIFY( found );+ }++ //Test greatestRoot+ VERIFY( internal::isApprox( roots.array().abs().maxCoeff(),+ abs( psolve.greatestRoot() ), psPrec ) );++ //Test smallestRoot+ VERIFY( internal::isApprox( roots.array().abs().minCoeff(),+ abs( psolve.smallestRoot() ), psPrec ) );++ bool hasRealRoot;+ //Test absGreatestRealRoot+ Real r = psolve.absGreatestRealRoot( hasRealRoot );+ VERIFY( hasRealRoot == (real_roots.size() > 0 ) );+ if( hasRealRoot ){+ VERIFY( internal::isApprox( real_roots.array().abs().maxCoeff(), abs(r), psPrec ) ); }++ //Test absSmallestRealRoot+ r = psolve.absSmallestRealRoot( hasRealRoot );+ VERIFY( hasRealRoot == (real_roots.size() > 0 ) );+ if( hasRealRoot ){+ VERIFY( internal::isApprox( real_roots.array().abs().minCoeff(), abs( r ), psPrec ) ); }++ //Test greatestRealRoot+ r = psolve.greatestRealRoot( hasRealRoot );+ VERIFY( hasRealRoot == (real_roots.size() > 0 ) );+ if( hasRealRoot ){+ VERIFY( internal::isApprox( real_roots.array().maxCoeff(), r, psPrec ) ); }++ //Test smallestRealRoot+ r = psolve.smallestRealRoot( hasRealRoot );+ VERIFY( hasRealRoot == (real_roots.size() > 0 ) );+ if( hasRealRoot ){+ VERIFY( internal::isApprox( real_roots.array().minCoeff(), r, psPrec ) ); }+ }+}+++template<typename _Scalar, int _Deg>+void polynomialsolver(int deg)+{+ typedef internal::increment_if_fixed_size<_Deg> Dim;+ typedef Matrix<_Scalar,Dim::ret,1> PolynomialType;+ typedef Matrix<_Scalar,_Deg,1> EvalRootsType;++ cout << "Standard cases" << endl;+ PolynomialType pols = PolynomialType::Random(deg+1);+ evalSolver<_Deg,PolynomialType>( pols );++ cout << "Hard cases" << endl;+ _Scalar multipleRoot = internal::random<_Scalar>();+ EvalRootsType allRoots = EvalRootsType::Constant(deg,multipleRoot);+ roots_to_monicPolynomial( allRoots, pols );+ evalSolver<_Deg,PolynomialType>( pols );++ cout << "Test sugar" << endl;+ EvalRootsType realRoots = EvalRootsType::Random(deg);+ roots_to_monicPolynomial( realRoots, pols );+ evalSolverSugarFunction<_Deg>(+ pols,+ realRoots.template cast <+ std::complex<+ typename NumTraits<_Scalar>::Real+ >+ >(),+ realRoots );+}++void test_polynomialsolver()+{+ for(int i = 0; i < g_repeat; i++)+ {+ CALL_SUBTEST_1( (polynomialsolver<float,1>(1)) );+ CALL_SUBTEST_2( (polynomialsolver<double,2>(2)) );+ CALL_SUBTEST_3( (polynomialsolver<double,3>(3)) );+ CALL_SUBTEST_4( (polynomialsolver<float,4>(4)) );+ CALL_SUBTEST_5( (polynomialsolver<double,5>(5)) );+ CALL_SUBTEST_6( (polynomialsolver<float,6>(6)) );+ CALL_SUBTEST_7( (polynomialsolver<float,7>(7)) );+ CALL_SUBTEST_8( (polynomialsolver<double,8>(8)) );++ CALL_SUBTEST_9( (polynomialsolver<float,Dynamic>(+ internal::random<int>(9,13)+ )) );+ CALL_SUBTEST_10((polynomialsolver<double,Dynamic>(+ internal::random<int>(9,13)+ )) );+ }+}
+ eigen3/unsupported/test/polynomialutils.cpp view
@@ -0,0 +1,113 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010 Manuel Yguel <manuel.yguel@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"+#include <unsupported/Eigen/Polynomials>+#include <iostream>++using namespace std;++namespace Eigen {+namespace internal {+template<int Size>+struct increment_if_fixed_size+{+ enum {+ ret = (Size == Dynamic) ? Dynamic : Size+1+ };+};+}+}++template<typename _Scalar, int _Deg>+void realRoots_to_monicPolynomial_test(int deg)+{+ typedef internal::increment_if_fixed_size<_Deg> Dim;+ typedef Matrix<_Scalar,Dim::ret,1> PolynomialType;+ typedef Matrix<_Scalar,_Deg,1> EvalRootsType;++ PolynomialType pols(deg+1);+ EvalRootsType roots = EvalRootsType::Random(deg);+ roots_to_monicPolynomial( roots, pols );++ EvalRootsType evr( deg );+ for( int i=0; i<roots.size(); ++i ){+ evr[i] = std::abs( poly_eval( pols, roots[i] ) ); }++ bool evalToZero = evr.isZero( test_precision<_Scalar>() );+ if( !evalToZero ){+ cerr << evr.transpose() << endl; }+ VERIFY( evalToZero );+}++template<typename _Scalar> void realRoots_to_monicPolynomial_scalar()+{+ CALL_SUBTEST_2( (realRoots_to_monicPolynomial_test<_Scalar,2>(2)) );+ CALL_SUBTEST_3( (realRoots_to_monicPolynomial_test<_Scalar,3>(3)) );+ CALL_SUBTEST_4( (realRoots_to_monicPolynomial_test<_Scalar,4>(4)) );+ CALL_SUBTEST_5( (realRoots_to_monicPolynomial_test<_Scalar,5>(5)) );+ CALL_SUBTEST_6( (realRoots_to_monicPolynomial_test<_Scalar,6>(6)) );+ CALL_SUBTEST_7( (realRoots_to_monicPolynomial_test<_Scalar,7>(7)) );+ CALL_SUBTEST_8( (realRoots_to_monicPolynomial_test<_Scalar,17>(17)) );++ CALL_SUBTEST_9( (realRoots_to_monicPolynomial_test<_Scalar,Dynamic>(+ internal::random<int>(18,26) )) );+}+++++template<typename _Scalar, int _Deg>+void CauchyBounds(int deg)+{+ typedef internal::increment_if_fixed_size<_Deg> Dim;+ typedef Matrix<_Scalar,Dim::ret,1> PolynomialType;+ typedef Matrix<_Scalar,_Deg,1> EvalRootsType;++ PolynomialType pols(deg+1);+ EvalRootsType roots = EvalRootsType::Random(deg);+ roots_to_monicPolynomial( roots, pols );+ _Scalar M = cauchy_max_bound( pols );+ _Scalar m = cauchy_min_bound( pols );+ _Scalar Max = roots.array().abs().maxCoeff();+ _Scalar min = roots.array().abs().minCoeff();+ bool eval = (M >= Max) && (m <= min);+ if( !eval )+ {+ cerr << "Roots: " << roots << endl;+ cerr << "Bounds: (" << m << ", " << M << ")" << endl;+ cerr << "Min,Max: (" << min << ", " << Max << ")" << endl;+ }+ VERIFY( eval );+}++template<typename _Scalar> void CauchyBounds_scalar()+{+ CALL_SUBTEST_2( (CauchyBounds<_Scalar,2>(2)) );+ CALL_SUBTEST_3( (CauchyBounds<_Scalar,3>(3)) );+ CALL_SUBTEST_4( (CauchyBounds<_Scalar,4>(4)) );+ CALL_SUBTEST_5( (CauchyBounds<_Scalar,5>(5)) );+ CALL_SUBTEST_6( (CauchyBounds<_Scalar,6>(6)) );+ CALL_SUBTEST_7( (CauchyBounds<_Scalar,7>(7)) );+ CALL_SUBTEST_8( (CauchyBounds<_Scalar,17>(17)) );++ CALL_SUBTEST_9( (CauchyBounds<_Scalar,Dynamic>(+ internal::random<int>(18,26) )) );+}++void test_polynomialutils()+{+ for(int i = 0; i < g_repeat; i++)+ {+ realRoots_to_monicPolynomial_scalar<double>();+ realRoots_to_monicPolynomial_scalar<float>();+ CauchyBounds_scalar<double>();+ CauchyBounds_scalar<float>();+ }+}
+ eigen3/unsupported/test/sparse_extra.cpp view
@@ -0,0 +1,148 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008-2010 Gael Guennebaud <g.gael@free.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.+++// import basic and product tests for deprectaed DynamicSparseMatrix+#define EIGEN_NO_DEPRECATED_WARNING+#include "sparse_basic.cpp"+#include "sparse_product.cpp"+#include <Eigen/SparseExtra>++template<typename SetterType,typename DenseType, typename Scalar, int Options>+bool test_random_setter(SparseMatrix<Scalar,Options>& sm, const DenseType& ref, const std::vector<Vector2i>& nonzeroCoords)+{+ {+ sm.setZero();+ SetterType w(sm);+ std::vector<Vector2i> remaining = nonzeroCoords;+ while(!remaining.empty())+ {+ int i = internal::random<int>(0,static_cast<int>(remaining.size())-1);+ w(remaining[i].x(),remaining[i].y()) = ref.coeff(remaining[i].x(),remaining[i].y());+ remaining[i] = remaining.back();+ remaining.pop_back();+ }+ }+ return sm.isApprox(ref);+}++template<typename SetterType,typename DenseType, typename T>+bool test_random_setter(DynamicSparseMatrix<T>& sm, const DenseType& ref, const std::vector<Vector2i>& nonzeroCoords)+{+ sm.setZero();+ std::vector<Vector2i> remaining = nonzeroCoords;+ while(!remaining.empty())+ {+ int i = internal::random<int>(0,static_cast<int>(remaining.size())-1);+ sm.coeffRef(remaining[i].x(),remaining[i].y()) = ref.coeff(remaining[i].x(),remaining[i].y());+ remaining[i] = remaining.back();+ remaining.pop_back();+ }+ return sm.isApprox(ref);+}++template<typename SparseMatrixType> void sparse_extra(const SparseMatrixType& ref)+{+ typedef typename SparseMatrixType::Index Index;+ const Index rows = ref.rows();+ const Index cols = ref.cols();+ typedef typename SparseMatrixType::Scalar Scalar;+ enum { Flags = SparseMatrixType::Flags };++ double density = (std::max)(8./(rows*cols), 0.01);+ typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;+ typedef Matrix<Scalar,Dynamic,1> DenseVector;+ Scalar eps = 1e-6;++ SparseMatrixType m(rows, cols);+ DenseMatrix refMat = DenseMatrix::Zero(rows, cols);+ DenseVector vec1 = DenseVector::Random(rows);++ std::vector<Vector2i> zeroCoords;+ std::vector<Vector2i> nonzeroCoords;+ initSparse<Scalar>(density, refMat, m, 0, &zeroCoords, &nonzeroCoords);++ if (zeroCoords.size()==0 || nonzeroCoords.size()==0)+ return;++ // test coeff and coeffRef+ for (int i=0; i<(int)zeroCoords.size(); ++i)+ {+ VERIFY_IS_MUCH_SMALLER_THAN( m.coeff(zeroCoords[i].x(),zeroCoords[i].y()), eps );+ if(internal::is_same<SparseMatrixType,SparseMatrix<Scalar,Flags> >::value)+ VERIFY_RAISES_ASSERT( m.coeffRef(zeroCoords[0].x(),zeroCoords[0].y()) = 5 );+ }+ VERIFY_IS_APPROX(m, refMat);++ m.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);+ refMat.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);++ VERIFY_IS_APPROX(m, refMat);++ // random setter+// {+// m.setZero();+// VERIFY_IS_NOT_APPROX(m, refMat);+// SparseSetter<SparseMatrixType, RandomAccessPattern> w(m);+// std::vector<Vector2i> remaining = nonzeroCoords;+// while(!remaining.empty())+// {+// int i = internal::random<int>(0,remaining.size()-1);+// w->coeffRef(remaining[i].x(),remaining[i].y()) = refMat.coeff(remaining[i].x(),remaining[i].y());+// remaining[i] = remaining.back();+// remaining.pop_back();+// }+// }+// VERIFY_IS_APPROX(m, refMat);++ VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, StdMapTraits> >(m,refMat,nonzeroCoords) ));+ #ifdef EIGEN_UNORDERED_MAP_SUPPORT+ VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, StdUnorderedMapTraits> >(m,refMat,nonzeroCoords) ));+ #endif+ #ifdef _DENSE_HASH_MAP_H_+ VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, GoogleDenseHashMapTraits> >(m,refMat,nonzeroCoords) ));+ #endif+ #ifdef _SPARSE_HASH_MAP_H_+ VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, GoogleSparseHashMapTraits> >(m,refMat,nonzeroCoords) ));+ #endif+++ // test RandomSetter+ /*{+ SparseMatrixType m1(rows,cols), m2(rows,cols);+ DenseMatrix refM1 = DenseMatrix::Zero(rows, rows);+ initSparse<Scalar>(density, refM1, m1);+ {+ Eigen::RandomSetter<SparseMatrixType > setter(m2);+ for (int j=0; j<m1.outerSize(); ++j)+ for (typename SparseMatrixType::InnerIterator i(m1,j); i; ++i)+ setter(i.index(), j) = i.value();+ }+ VERIFY_IS_APPROX(m1, m2);+ }*/+++}++void test_sparse_extra()+{+ for(int i = 0; i < g_repeat; i++) {+ int s = Eigen::internal::random<int>(1,50);+ CALL_SUBTEST_1( sparse_extra(SparseMatrix<double>(8, 8)) );+ CALL_SUBTEST_2( sparse_extra(SparseMatrix<std::complex<double> >(s, s)) );+ CALL_SUBTEST_1( sparse_extra(SparseMatrix<double>(s, s)) );++ CALL_SUBTEST_3( sparse_extra(DynamicSparseMatrix<double>(s, s)) );+// CALL_SUBTEST_3(( sparse_basic(DynamicSparseMatrix<double>(s, s)) ));+// CALL_SUBTEST_3(( sparse_basic(DynamicSparseMatrix<double,ColMajor,long int>(s, s)) ));++ CALL_SUBTEST_3( (sparse_product<DynamicSparseMatrix<float, ColMajor> >()) );+ CALL_SUBTEST_3( (sparse_product<DynamicSparseMatrix<float, RowMajor> >()) );+ }+}
+ eigen3/unsupported/test/splines.cpp view
@@ -0,0 +1,244 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2010-2011 Hauke Heibel <heibel@gmail.com>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++#include "main.h"++#include <unsupported/Eigen/Splines>++namespace Eigen {+ +// lets do some explicit instantiations and thus+// force the compilation of all spline functions...+template class Spline<double, 2, Dynamic>;+template class Spline<double, 3, Dynamic>;++template class Spline<double, 2, 2>;+template class Spline<double, 2, 3>;+template class Spline<double, 2, 4>;+template class Spline<double, 2, 5>;++template class Spline<float, 2, Dynamic>;+template class Spline<float, 3, Dynamic>;++template class Spline<float, 3, 2>;+template class Spline<float, 3, 3>;+template class Spline<float, 3, 4>;+template class Spline<float, 3, 5>;++}++Spline<double, 2, Dynamic> closed_spline2d()+{+ RowVectorXd knots(12);+ knots << 0,+ 0,+ 0,+ 0,+ 0.867193179093898,+ 1.660330955342408,+ 2.605084834823134,+ 3.484154586374428,+ 4.252699478956276,+ 4.252699478956276,+ 4.252699478956276,+ 4.252699478956276;++ MatrixXd ctrls(8,2);+ ctrls << -0.370967741935484, 0.236842105263158,+ -0.231401860693277, 0.442245185027632,+ 0.344361228532831, 0.773369994120753,+ 0.828990216203802, 0.106550882647595,+ 0.407270163678382, -1.043452922172848,+ -0.488467813584053, -0.390098582530090,+ -0.494657189446427, 0.054804824897884,+ -0.370967741935484, 0.236842105263158;+ ctrls.transposeInPlace();++ return Spline<double, 2, Dynamic>(knots, ctrls);+}++/* create a reference spline */+Spline<double, 3, Dynamic> spline3d()+{+ RowVectorXd knots(11);+ knots << 0,+ 0,+ 0,+ 0.118997681558377,+ 0.162611735194631,+ 0.498364051982143,+ 0.655098003973841,+ 0.679702676853675,+ 1.000000000000000,+ 1.000000000000000,+ 1.000000000000000;++ MatrixXd ctrls(8,3);+ ctrls << 0.959743958516081, 0.340385726666133, 0.585267750979777,+ 0.223811939491137, 0.751267059305653, 0.255095115459269,+ 0.505957051665142, 0.699076722656686, 0.890903252535799,+ 0.959291425205444, 0.547215529963803, 0.138624442828679,+ 0.149294005559057, 0.257508254123736, 0.840717255983663,+ 0.254282178971531, 0.814284826068816, 0.243524968724989,+ 0.929263623187228, 0.349983765984809, 0.196595250431208,+ 0.251083857976031, 0.616044676146639, 0.473288848902729;+ ctrls.transposeInPlace();++ return Spline<double, 3, Dynamic>(knots, ctrls);+}++/* compares evaluations against known results */+void eval_spline3d()+{+ Spline3d spline = spline3d();++ RowVectorXd u(10);+ u << 0.351659507062997,+ 0.830828627896291,+ 0.585264091152724,+ 0.549723608291140,+ 0.917193663829810,+ 0.285839018820374,+ 0.757200229110721,+ 0.753729094278495,+ 0.380445846975357,+ 0.567821640725221;++ MatrixXd pts(10,3);+ pts << 0.707620811535916, 0.510258911240815, 0.417485437023409,+ 0.603422256426978, 0.529498282727551, 0.270351549348981,+ 0.228364197569334, 0.423745615677815, 0.637687289287490,+ 0.275556796335168, 0.350856706427970, 0.684295784598905,+ 0.514519311047655, 0.525077224890754, 0.351628308305896,+ 0.724152914315666, 0.574461155457304, 0.469860285484058,+ 0.529365063753288, 0.613328702656816, 0.237837040141739,+ 0.522469395136878, 0.619099658652895, 0.237139665242069,+ 0.677357023849552, 0.480655768435853, 0.422227610314397,+ 0.247046593173758, 0.380604672404750, 0.670065791405019;+ pts.transposeInPlace();++ for (int i=0; i<u.size(); ++i)+ {+ Vector3d pt = spline(u(i));+ VERIFY( (pt - pts.col(i)).norm() < 1e-14 );+ }+}++/* compares evaluations on corner cases */+void eval_spline3d_onbrks()+{+ Spline3d spline = spline3d();++ RowVectorXd u = spline.knots();++ MatrixXd pts(11,3);+ pts << 0.959743958516081, 0.340385726666133, 0.585267750979777,+ 0.959743958516081, 0.340385726666133, 0.585267750979777,+ 0.959743958516081, 0.340385726666133, 0.585267750979777,+ 0.430282980289940, 0.713074680056118, 0.720373307943349,+ 0.558074875553060, 0.681617921034459, 0.804417124839942,+ 0.407076008291750, 0.349707710518163, 0.617275937419545,+ 0.240037008286602, 0.738739390398014, 0.324554153129411,+ 0.302434111480572, 0.781162443963899, 0.240177089094644,+ 0.251083857976031, 0.616044676146639, 0.473288848902729,+ 0.251083857976031, 0.616044676146639, 0.473288848902729,+ 0.251083857976031, 0.616044676146639, 0.473288848902729;+ pts.transposeInPlace();++ for (int i=0; i<u.size(); ++i)+ {+ Vector3d pt = spline(u(i));+ VERIFY( (pt - pts.col(i)).norm() < 1e-14 );+ }+}++void eval_closed_spline2d()+{+ Spline2d spline = closed_spline2d();++ RowVectorXd u(12);+ u << 0,+ 0.332457030395796,+ 0.356467130532952,+ 0.453562180176215,+ 0.648017921874804,+ 0.973770235555003,+ 1.882577647219307,+ 2.289408593930498,+ 3.511951429883045,+ 3.884149321369450,+ 4.236261590369414,+ 4.252699478956276;++ MatrixXd pts(12,2);+ pts << -0.370967741935484, 0.236842105263158,+ -0.152576775123250, 0.448975001279334,+ -0.133417538277668, 0.461615613865667,+ -0.053199060826740, 0.507630360006299,+ 0.114249591147281, 0.570414135097409,+ 0.377810316891987, 0.560497102875315,+ 0.665052120135908, -0.157557441109611,+ 0.516006487053228, -0.559763292174825,+ -0.379486035348887, -0.331959640488223,+ -0.462034726249078, -0.039105670080824,+ -0.378730600917982, 0.225127015099919,+ -0.370967741935484, 0.236842105263158;+ pts.transposeInPlace();++ for (int i=0; i<u.size(); ++i)+ {+ Vector2d pt = spline(u(i));+ VERIFY( (pt - pts.col(i)).norm() < 1e-14 );+ }+}++void check_global_interpolation2d()+{+ typedef Spline2d::PointType PointType;+ typedef Spline2d::KnotVectorType KnotVectorType;+ typedef Spline2d::ControlPointVectorType ControlPointVectorType;++ ControlPointVectorType points = ControlPointVectorType::Random(2,100);++ KnotVectorType chord_lengths; // knot parameters+ Eigen::ChordLengths(points, chord_lengths);++ // interpolation without knot parameters+ {+ const Spline2d spline = SplineFitting<Spline2d>::Interpolate(points,3); ++ for (Eigen::DenseIndex i=0; i<points.cols(); ++i)+ {+ PointType pt = spline( chord_lengths(i) );+ PointType ref = points.col(i);+ VERIFY( (pt - ref).matrix().norm() < 1e-14 );+ }+ }++ // interpolation with given knot parameters+ {+ const Spline2d spline = SplineFitting<Spline2d>::Interpolate(points,3,chord_lengths); ++ for (Eigen::DenseIndex i=0; i<points.cols(); ++i)+ {+ PointType pt = spline( chord_lengths(i) );+ PointType ref = points.col(i);+ VERIFY( (pt - ref).matrix().norm() < 1e-14 );+ }+ }+}+++void test_splines()+{+ CALL_SUBTEST( eval_spline3d() );+ CALL_SUBTEST( eval_spline3d_onbrks() );+ CALL_SUBTEST( eval_closed_spline2d() );+ CALL_SUBTEST( check_global_interpolation2d() );+}
+ eigen3/unsupported/test/svd_common.h view
@@ -0,0 +1,261 @@+// This file is part of Eigen, a lightweight C++ template library+// for linear algebra.+//+// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>+// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>+//+// Copyright (C) 2013 Gauthier Brun <brun.gauthier@gmail.com>+// Copyright (C) 2013 Nicolas Carre <nicolas.carre@ensimag.fr>+// Copyright (C) 2013 Jean Ceccato <jean.ceccato@ensimag.fr>+// Copyright (C) 2013 Pierre Zoppitelli <pierre.zoppitelli@ensimag.fr>+//+// This Source Code Form is subject to the terms of the Mozilla+// Public License v. 2.0. If a copy of the MPL was not distributed+// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.++// discard stack allocation as that too bypasses malloc+#define EIGEN_STACK_ALLOCATION_LIMIT 0+#define EIGEN_RUNTIME_NO_MALLOC++#include "main.h"+#include <unsupported/Eigen/SVD>+#include <Eigen/LU>+++// check if "svd" is the good image of "m" +template<typename MatrixType, typename SVD>+void svd_check_full(const MatrixType& m, const SVD& svd)+{+ typedef typename MatrixType::Index Index;+ Index rows = m.rows();+ Index cols = m.cols();+ enum {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,+ ColsAtCompileTime = MatrixType::ColsAtCompileTime+ };++ typedef typename MatrixType::Scalar Scalar;+ typedef Matrix<Scalar, RowsAtCompileTime, RowsAtCompileTime> MatrixUType;+ typedef Matrix<Scalar, ColsAtCompileTime, ColsAtCompileTime> MatrixVType;++ + MatrixType sigma = MatrixType::Zero(rows, cols);+ sigma.diagonal() = svd.singularValues().template cast<Scalar>();+ MatrixUType u = svd.matrixU();+ MatrixVType v = svd.matrixV();+ VERIFY_IS_APPROX(m, u * sigma * v.adjoint());+ VERIFY_IS_UNITARY(u);+ VERIFY_IS_UNITARY(v);+} // end svd_check_full++++// Compare to a reference value+template<typename MatrixType, typename SVD>+void svd_compare_to_full(const MatrixType& m,+ unsigned int computationOptions,+ const SVD& referenceSvd)+{+ typedef typename MatrixType::Index Index;+ Index rows = m.rows();+ Index cols = m.cols();+ Index diagSize = (std::min)(rows, cols);++ SVD svd(m, computationOptions);++ VERIFY_IS_APPROX(svd.singularValues(), referenceSvd.singularValues());+ if(computationOptions & ComputeFullU)+ VERIFY_IS_APPROX(svd.matrixU(), referenceSvd.matrixU());+ if(computationOptions & ComputeThinU)+ VERIFY_IS_APPROX(svd.matrixU(), referenceSvd.matrixU().leftCols(diagSize));+ if(computationOptions & ComputeFullV)+ VERIFY_IS_APPROX(svd.matrixV(), referenceSvd.matrixV());+ if(computationOptions & ComputeThinV)+ VERIFY_IS_APPROX(svd.matrixV(), referenceSvd.matrixV().leftCols(diagSize));+} // end svd_compare_to_full++++template<typename MatrixType, typename SVD>+void svd_solve(const MatrixType& m, unsigned int computationOptions)+{+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::Index Index;+ Index rows = m.rows();+ Index cols = m.cols();++ enum {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,+ ColsAtCompileTime = MatrixType::ColsAtCompileTime+ };++ typedef Matrix<Scalar, RowsAtCompileTime, Dynamic> RhsType;+ typedef Matrix<Scalar, ColsAtCompileTime, Dynamic> SolutionType;++ RhsType rhs = RhsType::Random(rows, internal::random<Index>(1, cols));+ SVD svd(m, computationOptions);+ SolutionType x = svd.solve(rhs);+ // evaluate normal equation which works also for least-squares solutions+ VERIFY_IS_APPROX(m.adjoint()*m*x,m.adjoint()*rhs);+} // end svd_solve+++// test computations options+// 2 functions because Jacobisvd can return before the second function+template<typename MatrixType, typename SVD>+void svd_test_computation_options_1(const MatrixType& m, const SVD& fullSvd)+{+ svd_check_full< MatrixType, SVD >(m, fullSvd);+ svd_solve< MatrixType, SVD >(m, ComputeFullU | ComputeFullV);+}+++template<typename MatrixType, typename SVD>+void svd_test_computation_options_2(const MatrixType& m, const SVD& fullSvd)+{+ svd_compare_to_full< MatrixType, SVD >(m, ComputeFullU, fullSvd);+ svd_compare_to_full< MatrixType, SVD >(m, ComputeFullV, fullSvd);+ svd_compare_to_full< MatrixType, SVD >(m, 0, fullSvd);++ if (MatrixType::ColsAtCompileTime == Dynamic) {+ // thin U/V are only available with dynamic number of columns+ + svd_compare_to_full< MatrixType, SVD >(m, ComputeFullU|ComputeThinV, fullSvd);+ svd_compare_to_full< MatrixType, SVD >(m, ComputeThinV, fullSvd);+ svd_compare_to_full< MatrixType, SVD >(m, ComputeThinU|ComputeFullV, fullSvd);+ svd_compare_to_full< MatrixType, SVD >(m, ComputeThinU , fullSvd);+ svd_compare_to_full< MatrixType, SVD >(m, ComputeThinU|ComputeThinV, fullSvd);+ svd_solve<MatrixType, SVD>(m, ComputeFullU | ComputeThinV);+ svd_solve<MatrixType, SVD>(m, ComputeThinU | ComputeFullV);+ svd_solve<MatrixType, SVD>(m, ComputeThinU | ComputeThinV);+ + typedef typename MatrixType::Index Index;+ Index diagSize = (std::min)(m.rows(), m.cols());+ SVD svd(m, ComputeThinU | ComputeThinV);+ VERIFY_IS_APPROX(m, svd.matrixU().leftCols(diagSize) * svd.singularValues().asDiagonal() * svd.matrixV().leftCols(diagSize).adjoint());+ }+}++template<typename MatrixType, typename SVD> +void svd_verify_assert(const MatrixType& m)+{+ typedef typename MatrixType::Scalar Scalar;+ typedef typename MatrixType::Index Index;+ Index rows = m.rows();+ Index cols = m.cols();++ enum {+ RowsAtCompileTime = MatrixType::RowsAtCompileTime,+ ColsAtCompileTime = MatrixType::ColsAtCompileTime+ };++ typedef Matrix<Scalar, RowsAtCompileTime, 1> RhsType;+ RhsType rhs(rows);+ SVD svd;+ VERIFY_RAISES_ASSERT(svd.matrixU())+ VERIFY_RAISES_ASSERT(svd.singularValues())+ VERIFY_RAISES_ASSERT(svd.matrixV())+ VERIFY_RAISES_ASSERT(svd.solve(rhs))+ MatrixType a = MatrixType::Zero(rows, cols);+ a.setZero();+ svd.compute(a, 0);+ VERIFY_RAISES_ASSERT(svd.matrixU())+ VERIFY_RAISES_ASSERT(svd.matrixV())+ svd.singularValues();+ VERIFY_RAISES_ASSERT(svd.solve(rhs))+ + if (ColsAtCompileTime == Dynamic)+ {+ svd.compute(a, ComputeThinU);+ svd.matrixU();+ VERIFY_RAISES_ASSERT(svd.matrixV())+ VERIFY_RAISES_ASSERT(svd.solve(rhs))+ svd.compute(a, ComputeThinV);+ svd.matrixV();+ VERIFY_RAISES_ASSERT(svd.matrixU())+ VERIFY_RAISES_ASSERT(svd.solve(rhs))+ }+ else+ {+ VERIFY_RAISES_ASSERT(svd.compute(a, ComputeThinU))+ VERIFY_RAISES_ASSERT(svd.compute(a, ComputeThinV))+ }+}++// work around stupid msvc error when constructing at compile time an expression that involves+// a division by zero, even if the numeric type has floating point+template<typename Scalar>+EIGEN_DONT_INLINE Scalar zero() { return Scalar(0); }++// workaround aggressive optimization in ICC+template<typename T> EIGEN_DONT_INLINE T sub(T a, T b) { return a - b; }+++template<typename MatrixType, typename SVD>+void svd_inf_nan()+{+ // all this function does is verify we don't iterate infinitely on nan/inf values++ SVD svd;+ typedef typename MatrixType::Scalar Scalar;+ Scalar some_inf = Scalar(1) / zero<Scalar>();+ VERIFY(sub(some_inf, some_inf) != sub(some_inf, some_inf));+ svd.compute(MatrixType::Constant(10,10,some_inf), ComputeFullU | ComputeFullV);++ Scalar some_nan = zero<Scalar> () / zero<Scalar> ();+ VERIFY(some_nan != some_nan);+ svd.compute(MatrixType::Constant(10,10,some_nan), ComputeFullU | ComputeFullV);++ MatrixType m = MatrixType::Zero(10,10);+ m(internal::random<int>(0,9), internal::random<int>(0,9)) = some_inf;+ svd.compute(m, ComputeFullU | ComputeFullV);++ m = MatrixType::Zero(10,10);+ m(internal::random<int>(0,9), internal::random<int>(0,9)) = some_nan;+ svd.compute(m, ComputeFullU | ComputeFullV);+}+++template<typename SVD>+void svd_preallocate()+{+ Vector3f v(3.f, 2.f, 1.f);+ MatrixXf m = v.asDiagonal();++ internal::set_is_malloc_allowed(false);+ VERIFY_RAISES_ASSERT(VectorXf v(10);)+ SVD svd;+ internal::set_is_malloc_allowed(true);+ svd.compute(m);+ VERIFY_IS_APPROX(svd.singularValues(), v);++ SVD svd2(3,3);+ internal::set_is_malloc_allowed(false);+ svd2.compute(m);+ internal::set_is_malloc_allowed(true);+ VERIFY_IS_APPROX(svd2.singularValues(), v);+ VERIFY_RAISES_ASSERT(svd2.matrixU());+ VERIFY_RAISES_ASSERT(svd2.matrixV());+ svd2.compute(m, ComputeFullU | ComputeFullV);+ VERIFY_IS_APPROX(svd2.matrixU(), Matrix3f::Identity());+ VERIFY_IS_APPROX(svd2.matrixV(), Matrix3f::Identity());+ internal::set_is_malloc_allowed(false);+ svd2.compute(m);+ internal::set_is_malloc_allowed(true);++ SVD svd3(3,3,ComputeFullU|ComputeFullV);+ internal::set_is_malloc_allowed(false);+ svd2.compute(m);+ internal::set_is_malloc_allowed(true);+ VERIFY_IS_APPROX(svd2.singularValues(), v);+ VERIFY_IS_APPROX(svd2.matrixU(), Matrix3f::Identity());+ VERIFY_IS_APPROX(svd2.matrixV(), Matrix3f::Identity());+ internal::set_is_malloc_allowed(false);+ svd2.compute(m, ComputeFullU|ComputeFullV);+ internal::set_is_malloc_allowed(true);+}+++++
test/regression.hs view
@@ -30,7 +30,7 @@ putStrLn "\n-2.34666 - 0.25349 x1 - 0.174965 x2" putStrLn "done" - print $ (identity 4 :: MatrixXd)+ print $ (identity 4 4 :: MatrixXd) print $ M.normalize a print $ M.transpose a