tomoto 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (420) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +3 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +123 -0
  5. data/ext/tomoto/ext.cpp +245 -0
  6. data/ext/tomoto/extconf.rb +28 -0
  7. data/lib/tomoto.rb +12 -0
  8. data/lib/tomoto/ct.rb +11 -0
  9. data/lib/tomoto/hdp.rb +11 -0
  10. data/lib/tomoto/lda.rb +67 -0
  11. data/lib/tomoto/version.rb +3 -0
  12. data/vendor/EigenRand/EigenRand/Core.h +1139 -0
  13. data/vendor/EigenRand/EigenRand/Dists/Basic.h +111 -0
  14. data/vendor/EigenRand/EigenRand/Dists/Discrete.h +877 -0
  15. data/vendor/EigenRand/EigenRand/Dists/GammaPoisson.h +108 -0
  16. data/vendor/EigenRand/EigenRand/Dists/NormalExp.h +626 -0
  17. data/vendor/EigenRand/EigenRand/EigenRand +19 -0
  18. data/vendor/EigenRand/EigenRand/Macro.h +24 -0
  19. data/vendor/EigenRand/EigenRand/MorePacketMath.h +978 -0
  20. data/vendor/EigenRand/EigenRand/PacketFilter.h +286 -0
  21. data/vendor/EigenRand/EigenRand/PacketRandomEngine.h +624 -0
  22. data/vendor/EigenRand/EigenRand/RandUtils.h +413 -0
  23. data/vendor/EigenRand/EigenRand/doc.h +220 -0
  24. data/vendor/EigenRand/LICENSE +21 -0
  25. data/vendor/EigenRand/README.md +288 -0
  26. data/vendor/eigen/COPYING.BSD +26 -0
  27. data/vendor/eigen/COPYING.GPL +674 -0
  28. data/vendor/eigen/COPYING.LGPL +502 -0
  29. data/vendor/eigen/COPYING.MINPACK +52 -0
  30. data/vendor/eigen/COPYING.MPL2 +373 -0
  31. data/vendor/eigen/COPYING.README +18 -0
  32. data/vendor/eigen/Eigen/CMakeLists.txt +19 -0
  33. data/vendor/eigen/Eigen/Cholesky +46 -0
  34. data/vendor/eigen/Eigen/CholmodSupport +48 -0
  35. data/vendor/eigen/Eigen/Core +537 -0
  36. data/vendor/eigen/Eigen/Dense +7 -0
  37. data/vendor/eigen/Eigen/Eigen +2 -0
  38. data/vendor/eigen/Eigen/Eigenvalues +61 -0
  39. data/vendor/eigen/Eigen/Geometry +62 -0
  40. data/vendor/eigen/Eigen/Householder +30 -0
  41. data/vendor/eigen/Eigen/IterativeLinearSolvers +48 -0
  42. data/vendor/eigen/Eigen/Jacobi +33 -0
  43. data/vendor/eigen/Eigen/LU +50 -0
  44. data/vendor/eigen/Eigen/MetisSupport +35 -0
  45. data/vendor/eigen/Eigen/OrderingMethods +73 -0
  46. data/vendor/eigen/Eigen/PaStiXSupport +48 -0
  47. data/vendor/eigen/Eigen/PardisoSupport +35 -0
  48. data/vendor/eigen/Eigen/QR +51 -0
  49. data/vendor/eigen/Eigen/QtAlignedMalloc +40 -0
  50. data/vendor/eigen/Eigen/SPQRSupport +34 -0
  51. data/vendor/eigen/Eigen/SVD +51 -0
  52. data/vendor/eigen/Eigen/Sparse +36 -0
  53. data/vendor/eigen/Eigen/SparseCholesky +45 -0
  54. data/vendor/eigen/Eigen/SparseCore +69 -0
  55. data/vendor/eigen/Eigen/SparseLU +46 -0
  56. data/vendor/eigen/Eigen/SparseQR +37 -0
  57. data/vendor/eigen/Eigen/StdDeque +27 -0
  58. data/vendor/eigen/Eigen/StdList +26 -0
  59. data/vendor/eigen/Eigen/StdVector +27 -0
  60. data/vendor/eigen/Eigen/SuperLUSupport +64 -0
  61. data/vendor/eigen/Eigen/UmfPackSupport +40 -0
  62. data/vendor/eigen/Eigen/src/Cholesky/LDLT.h +673 -0
  63. data/vendor/eigen/Eigen/src/Cholesky/LLT.h +542 -0
  64. data/vendor/eigen/Eigen/src/Cholesky/LLT_LAPACKE.h +99 -0
  65. data/vendor/eigen/Eigen/src/CholmodSupport/CholmodSupport.h +639 -0
  66. data/vendor/eigen/Eigen/src/Core/Array.h +329 -0
  67. data/vendor/eigen/Eigen/src/Core/ArrayBase.h +226 -0
  68. data/vendor/eigen/Eigen/src/Core/ArrayWrapper.h +209 -0
  69. data/vendor/eigen/Eigen/src/Core/Assign.h +90 -0
  70. data/vendor/eigen/Eigen/src/Core/AssignEvaluator.h +935 -0
  71. data/vendor/eigen/Eigen/src/Core/Assign_MKL.h +178 -0
  72. data/vendor/eigen/Eigen/src/Core/BandMatrix.h +353 -0
  73. data/vendor/eigen/Eigen/src/Core/Block.h +452 -0
  74. data/vendor/eigen/Eigen/src/Core/BooleanRedux.h +164 -0
  75. data/vendor/eigen/Eigen/src/Core/CommaInitializer.h +160 -0
  76. data/vendor/eigen/Eigen/src/Core/ConditionEstimator.h +175 -0
  77. data/vendor/eigen/Eigen/src/Core/CoreEvaluators.h +1688 -0
  78. data/vendor/eigen/Eigen/src/Core/CoreIterators.h +127 -0
  79. data/vendor/eigen/Eigen/src/Core/CwiseBinaryOp.h +184 -0
  80. data/vendor/eigen/Eigen/src/Core/CwiseNullaryOp.h +866 -0
  81. data/vendor/eigen/Eigen/src/Core/CwiseTernaryOp.h +197 -0
  82. data/vendor/eigen/Eigen/src/Core/CwiseUnaryOp.h +103 -0
  83. data/vendor/eigen/Eigen/src/Core/CwiseUnaryView.h +128 -0
  84. data/vendor/eigen/Eigen/src/Core/DenseBase.h +611 -0
  85. data/vendor/eigen/Eigen/src/Core/DenseCoeffsBase.h +681 -0
  86. data/vendor/eigen/Eigen/src/Core/DenseStorage.h +570 -0
  87. data/vendor/eigen/Eigen/src/Core/Diagonal.h +260 -0
  88. data/vendor/eigen/Eigen/src/Core/DiagonalMatrix.h +343 -0
  89. data/vendor/eigen/Eigen/src/Core/DiagonalProduct.h +28 -0
  90. data/vendor/eigen/Eigen/src/Core/Dot.h +318 -0
  91. data/vendor/eigen/Eigen/src/Core/EigenBase.h +159 -0
  92. data/vendor/eigen/Eigen/src/Core/ForceAlignedAccess.h +146 -0
  93. data/vendor/eigen/Eigen/src/Core/Fuzzy.h +155 -0
  94. data/vendor/eigen/Eigen/src/Core/GeneralProduct.h +455 -0
  95. data/vendor/eigen/Eigen/src/Core/GenericPacketMath.h +593 -0
  96. data/vendor/eigen/Eigen/src/Core/GlobalFunctions.h +187 -0
  97. data/vendor/eigen/Eigen/src/Core/IO.h +225 -0
  98. data/vendor/eigen/Eigen/src/Core/Inverse.h +118 -0
  99. data/vendor/eigen/Eigen/src/Core/Map.h +171 -0
  100. data/vendor/eigen/Eigen/src/Core/MapBase.h +303 -0
  101. data/vendor/eigen/Eigen/src/Core/MathFunctions.h +1415 -0
  102. data/vendor/eigen/Eigen/src/Core/MathFunctionsImpl.h +101 -0
  103. data/vendor/eigen/Eigen/src/Core/Matrix.h +459 -0
  104. data/vendor/eigen/Eigen/src/Core/MatrixBase.h +529 -0
  105. data/vendor/eigen/Eigen/src/Core/NestByValue.h +110 -0
  106. data/vendor/eigen/Eigen/src/Core/NoAlias.h +108 -0
  107. data/vendor/eigen/Eigen/src/Core/NumTraits.h +248 -0
  108. data/vendor/eigen/Eigen/src/Core/PermutationMatrix.h +633 -0
  109. data/vendor/eigen/Eigen/src/Core/PlainObjectBase.h +1035 -0
  110. data/vendor/eigen/Eigen/src/Core/Product.h +186 -0
  111. data/vendor/eigen/Eigen/src/Core/ProductEvaluators.h +1112 -0
  112. data/vendor/eigen/Eigen/src/Core/Random.h +182 -0
  113. data/vendor/eigen/Eigen/src/Core/Redux.h +505 -0
  114. data/vendor/eigen/Eigen/src/Core/Ref.h +283 -0
  115. data/vendor/eigen/Eigen/src/Core/Replicate.h +142 -0
  116. data/vendor/eigen/Eigen/src/Core/ReturnByValue.h +117 -0
  117. data/vendor/eigen/Eigen/src/Core/Reverse.h +211 -0
  118. data/vendor/eigen/Eigen/src/Core/Select.h +162 -0
  119. data/vendor/eigen/Eigen/src/Core/SelfAdjointView.h +352 -0
  120. data/vendor/eigen/Eigen/src/Core/SelfCwiseBinaryOp.h +47 -0
  121. data/vendor/eigen/Eigen/src/Core/Solve.h +188 -0
  122. data/vendor/eigen/Eigen/src/Core/SolveTriangular.h +235 -0
  123. data/vendor/eigen/Eigen/src/Core/SolverBase.h +130 -0
  124. data/vendor/eigen/Eigen/src/Core/StableNorm.h +221 -0
  125. data/vendor/eigen/Eigen/src/Core/Stride.h +111 -0
  126. data/vendor/eigen/Eigen/src/Core/Swap.h +67 -0
  127. data/vendor/eigen/Eigen/src/Core/Transpose.h +403 -0
  128. data/vendor/eigen/Eigen/src/Core/Transpositions.h +407 -0
  129. data/vendor/eigen/Eigen/src/Core/TriangularMatrix.h +983 -0
  130. data/vendor/eigen/Eigen/src/Core/VectorBlock.h +96 -0
  131. data/vendor/eigen/Eigen/src/Core/VectorwiseOp.h +695 -0
  132. data/vendor/eigen/Eigen/src/Core/Visitor.h +273 -0
  133. data/vendor/eigen/Eigen/src/Core/arch/AVX/Complex.h +451 -0
  134. data/vendor/eigen/Eigen/src/Core/arch/AVX/MathFunctions.h +439 -0
  135. data/vendor/eigen/Eigen/src/Core/arch/AVX/PacketMath.h +637 -0
  136. data/vendor/eigen/Eigen/src/Core/arch/AVX/TypeCasting.h +51 -0
  137. data/vendor/eigen/Eigen/src/Core/arch/AVX512/MathFunctions.h +391 -0
  138. data/vendor/eigen/Eigen/src/Core/arch/AVX512/PacketMath.h +1316 -0
  139. data/vendor/eigen/Eigen/src/Core/arch/AltiVec/Complex.h +430 -0
  140. data/vendor/eigen/Eigen/src/Core/arch/AltiVec/MathFunctions.h +322 -0
  141. data/vendor/eigen/Eigen/src/Core/arch/AltiVec/PacketMath.h +1061 -0
  142. data/vendor/eigen/Eigen/src/Core/arch/CUDA/Complex.h +103 -0
  143. data/vendor/eigen/Eigen/src/Core/arch/CUDA/Half.h +674 -0
  144. data/vendor/eigen/Eigen/src/Core/arch/CUDA/MathFunctions.h +91 -0
  145. data/vendor/eigen/Eigen/src/Core/arch/CUDA/PacketMath.h +333 -0
  146. data/vendor/eigen/Eigen/src/Core/arch/CUDA/PacketMathHalf.h +1124 -0
  147. data/vendor/eigen/Eigen/src/Core/arch/CUDA/TypeCasting.h +212 -0
  148. data/vendor/eigen/Eigen/src/Core/arch/Default/ConjHelper.h +29 -0
  149. data/vendor/eigen/Eigen/src/Core/arch/Default/Settings.h +49 -0
  150. data/vendor/eigen/Eigen/src/Core/arch/NEON/Complex.h +490 -0
  151. data/vendor/eigen/Eigen/src/Core/arch/NEON/MathFunctions.h +91 -0
  152. data/vendor/eigen/Eigen/src/Core/arch/NEON/PacketMath.h +760 -0
  153. data/vendor/eigen/Eigen/src/Core/arch/SSE/Complex.h +471 -0
  154. data/vendor/eigen/Eigen/src/Core/arch/SSE/MathFunctions.h +562 -0
  155. data/vendor/eigen/Eigen/src/Core/arch/SSE/PacketMath.h +895 -0
  156. data/vendor/eigen/Eigen/src/Core/arch/SSE/TypeCasting.h +77 -0
  157. data/vendor/eigen/Eigen/src/Core/arch/ZVector/Complex.h +397 -0
  158. data/vendor/eigen/Eigen/src/Core/arch/ZVector/MathFunctions.h +137 -0
  159. data/vendor/eigen/Eigen/src/Core/arch/ZVector/PacketMath.h +945 -0
  160. data/vendor/eigen/Eigen/src/Core/functors/AssignmentFunctors.h +168 -0
  161. data/vendor/eigen/Eigen/src/Core/functors/BinaryFunctors.h +475 -0
  162. data/vendor/eigen/Eigen/src/Core/functors/NullaryFunctors.h +188 -0
  163. data/vendor/eigen/Eigen/src/Core/functors/StlFunctors.h +136 -0
  164. data/vendor/eigen/Eigen/src/Core/functors/TernaryFunctors.h +25 -0
  165. data/vendor/eigen/Eigen/src/Core/functors/UnaryFunctors.h +792 -0
  166. data/vendor/eigen/Eigen/src/Core/products/GeneralBlockPanelKernel.h +2156 -0
  167. data/vendor/eigen/Eigen/src/Core/products/GeneralMatrixMatrix.h +492 -0
  168. data/vendor/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +311 -0
  169. data/vendor/eigen/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h +145 -0
  170. data/vendor/eigen/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h +122 -0
  171. data/vendor/eigen/Eigen/src/Core/products/GeneralMatrixVector.h +619 -0
  172. data/vendor/eigen/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h +136 -0
  173. data/vendor/eigen/Eigen/src/Core/products/Parallelizer.h +163 -0
  174. data/vendor/eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +521 -0
  175. data/vendor/eigen/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h +287 -0
  176. data/vendor/eigen/Eigen/src/Core/products/SelfadjointMatrixVector.h +260 -0
  177. data/vendor/eigen/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h +118 -0
  178. data/vendor/eigen/Eigen/src/Core/products/SelfadjointProduct.h +133 -0
  179. data/vendor/eigen/Eigen/src/Core/products/SelfadjointRank2Update.h +93 -0
  180. data/vendor/eigen/Eigen/src/Core/products/TriangularMatrixMatrix.h +466 -0
  181. data/vendor/eigen/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h +315 -0
  182. data/vendor/eigen/Eigen/src/Core/products/TriangularMatrixVector.h +350 -0
  183. data/vendor/eigen/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h +255 -0
  184. data/vendor/eigen/Eigen/src/Core/products/TriangularSolverMatrix.h +335 -0
  185. data/vendor/eigen/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h +163 -0
  186. data/vendor/eigen/Eigen/src/Core/products/TriangularSolverVector.h +145 -0
  187. data/vendor/eigen/Eigen/src/Core/util/BlasUtil.h +398 -0
  188. data/vendor/eigen/Eigen/src/Core/util/Constants.h +547 -0
  189. data/vendor/eigen/Eigen/src/Core/util/DisableStupidWarnings.h +83 -0
  190. data/vendor/eigen/Eigen/src/Core/util/ForwardDeclarations.h +302 -0
  191. data/vendor/eigen/Eigen/src/Core/util/MKL_support.h +130 -0
  192. data/vendor/eigen/Eigen/src/Core/util/Macros.h +1001 -0
  193. data/vendor/eigen/Eigen/src/Core/util/Memory.h +993 -0
  194. data/vendor/eigen/Eigen/src/Core/util/Meta.h +534 -0
  195. data/vendor/eigen/Eigen/src/Core/util/NonMPL2.h +3 -0
  196. data/vendor/eigen/Eigen/src/Core/util/ReenableStupidWarnings.h +27 -0
  197. data/vendor/eigen/Eigen/src/Core/util/StaticAssert.h +218 -0
  198. data/vendor/eigen/Eigen/src/Core/util/XprHelper.h +821 -0
  199. data/vendor/eigen/Eigen/src/Eigenvalues/ComplexEigenSolver.h +346 -0
  200. data/vendor/eigen/Eigen/src/Eigenvalues/ComplexSchur.h +459 -0
  201. data/vendor/eigen/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h +91 -0
  202. data/vendor/eigen/Eigen/src/Eigenvalues/EigenSolver.h +622 -0
  203. data/vendor/eigen/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h +418 -0
  204. data/vendor/eigen/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h +226 -0
  205. data/vendor/eigen/Eigen/src/Eigenvalues/HessenbergDecomposition.h +374 -0
  206. data/vendor/eigen/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h +158 -0
  207. data/vendor/eigen/Eigen/src/Eigenvalues/RealQZ.h +654 -0
  208. data/vendor/eigen/Eigen/src/Eigenvalues/RealSchur.h +546 -0
  209. data/vendor/eigen/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h +77 -0
  210. data/vendor/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +870 -0
  211. data/vendor/eigen/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h +87 -0
  212. data/vendor/eigen/Eigen/src/Eigenvalues/Tridiagonalization.h +556 -0
  213. data/vendor/eigen/Eigen/src/Geometry/AlignedBox.h +392 -0
  214. data/vendor/eigen/Eigen/src/Geometry/AngleAxis.h +247 -0
  215. data/vendor/eigen/Eigen/src/Geometry/EulerAngles.h +114 -0
  216. data/vendor/eigen/Eigen/src/Geometry/Homogeneous.h +497 -0
  217. data/vendor/eigen/Eigen/src/Geometry/Hyperplane.h +282 -0
  218. data/vendor/eigen/Eigen/src/Geometry/OrthoMethods.h +234 -0
  219. data/vendor/eigen/Eigen/src/Geometry/ParametrizedLine.h +195 -0
  220. data/vendor/eigen/Eigen/src/Geometry/Quaternion.h +814 -0
  221. data/vendor/eigen/Eigen/src/Geometry/Rotation2D.h +199 -0
  222. data/vendor/eigen/Eigen/src/Geometry/RotationBase.h +206 -0
  223. data/vendor/eigen/Eigen/src/Geometry/Scaling.h +170 -0
  224. data/vendor/eigen/Eigen/src/Geometry/Transform.h +1542 -0
  225. data/vendor/eigen/Eigen/src/Geometry/Translation.h +208 -0
  226. data/vendor/eigen/Eigen/src/Geometry/Umeyama.h +166 -0
  227. data/vendor/eigen/Eigen/src/Geometry/arch/Geometry_SSE.h +161 -0
  228. data/vendor/eigen/Eigen/src/Householder/BlockHouseholder.h +103 -0
  229. data/vendor/eigen/Eigen/src/Householder/Householder.h +172 -0
  230. data/vendor/eigen/Eigen/src/Householder/HouseholderSequence.h +470 -0
  231. data/vendor/eigen/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +226 -0
  232. data/vendor/eigen/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +228 -0
  233. data/vendor/eigen/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +246 -0
  234. data/vendor/eigen/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h +400 -0
  235. data/vendor/eigen/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +462 -0
  236. data/vendor/eigen/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +394 -0
  237. data/vendor/eigen/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h +216 -0
  238. data/vendor/eigen/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h +115 -0
  239. data/vendor/eigen/Eigen/src/Jacobi/Jacobi.h +462 -0
  240. data/vendor/eigen/Eigen/src/LU/Determinant.h +101 -0
  241. data/vendor/eigen/Eigen/src/LU/FullPivLU.h +891 -0
  242. data/vendor/eigen/Eigen/src/LU/InverseImpl.h +415 -0
  243. data/vendor/eigen/Eigen/src/LU/PartialPivLU.h +611 -0
  244. data/vendor/eigen/Eigen/src/LU/PartialPivLU_LAPACKE.h +83 -0
  245. data/vendor/eigen/Eigen/src/LU/arch/Inverse_SSE.h +338 -0
  246. data/vendor/eigen/Eigen/src/MetisSupport/MetisSupport.h +137 -0
  247. data/vendor/eigen/Eigen/src/OrderingMethods/Amd.h +445 -0
  248. data/vendor/eigen/Eigen/src/OrderingMethods/Eigen_Colamd.h +1843 -0
  249. data/vendor/eigen/Eigen/src/OrderingMethods/Ordering.h +157 -0
  250. data/vendor/eigen/Eigen/src/PaStiXSupport/PaStiXSupport.h +678 -0
  251. data/vendor/eigen/Eigen/src/PardisoSupport/PardisoSupport.h +543 -0
  252. data/vendor/eigen/Eigen/src/QR/ColPivHouseholderQR.h +653 -0
  253. data/vendor/eigen/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h +97 -0
  254. data/vendor/eigen/Eigen/src/QR/CompleteOrthogonalDecomposition.h +562 -0
  255. data/vendor/eigen/Eigen/src/QR/FullPivHouseholderQR.h +676 -0
  256. data/vendor/eigen/Eigen/src/QR/HouseholderQR.h +409 -0
  257. data/vendor/eigen/Eigen/src/QR/HouseholderQR_LAPACKE.h +68 -0
  258. data/vendor/eigen/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h +313 -0
  259. data/vendor/eigen/Eigen/src/SVD/BDCSVD.h +1246 -0
  260. data/vendor/eigen/Eigen/src/SVD/JacobiSVD.h +804 -0
  261. data/vendor/eigen/Eigen/src/SVD/JacobiSVD_LAPACKE.h +91 -0
  262. data/vendor/eigen/Eigen/src/SVD/SVDBase.h +315 -0
  263. data/vendor/eigen/Eigen/src/SVD/UpperBidiagonalization.h +414 -0
  264. data/vendor/eigen/Eigen/src/SparseCholesky/SimplicialCholesky.h +689 -0
  265. data/vendor/eigen/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h +199 -0
  266. data/vendor/eigen/Eigen/src/SparseCore/AmbiVector.h +377 -0
  267. data/vendor/eigen/Eigen/src/SparseCore/CompressedStorage.h +258 -0
  268. data/vendor/eigen/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h +352 -0
  269. data/vendor/eigen/Eigen/src/SparseCore/MappedSparseMatrix.h +67 -0
  270. data/vendor/eigen/Eigen/src/SparseCore/SparseAssign.h +216 -0
  271. data/vendor/eigen/Eigen/src/SparseCore/SparseBlock.h +603 -0
  272. data/vendor/eigen/Eigen/src/SparseCore/SparseColEtree.h +206 -0
  273. data/vendor/eigen/Eigen/src/SparseCore/SparseCompressedBase.h +341 -0
  274. data/vendor/eigen/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +726 -0
  275. data/vendor/eigen/Eigen/src/SparseCore/SparseCwiseUnaryOp.h +148 -0
  276. data/vendor/eigen/Eigen/src/SparseCore/SparseDenseProduct.h +320 -0
  277. data/vendor/eigen/Eigen/src/SparseCore/SparseDiagonalProduct.h +138 -0
  278. data/vendor/eigen/Eigen/src/SparseCore/SparseDot.h +98 -0
  279. data/vendor/eigen/Eigen/src/SparseCore/SparseFuzzy.h +29 -0
  280. data/vendor/eigen/Eigen/src/SparseCore/SparseMap.h +305 -0
  281. data/vendor/eigen/Eigen/src/SparseCore/SparseMatrix.h +1403 -0
  282. data/vendor/eigen/Eigen/src/SparseCore/SparseMatrixBase.h +405 -0
  283. data/vendor/eigen/Eigen/src/SparseCore/SparsePermutation.h +178 -0
  284. data/vendor/eigen/Eigen/src/SparseCore/SparseProduct.h +169 -0
  285. data/vendor/eigen/Eigen/src/SparseCore/SparseRedux.h +49 -0
  286. data/vendor/eigen/Eigen/src/SparseCore/SparseRef.h +397 -0
  287. data/vendor/eigen/Eigen/src/SparseCore/SparseSelfAdjointView.h +656 -0
  288. data/vendor/eigen/Eigen/src/SparseCore/SparseSolverBase.h +124 -0
  289. data/vendor/eigen/Eigen/src/SparseCore/SparseSparseProductWithPruning.h +198 -0
  290. data/vendor/eigen/Eigen/src/SparseCore/SparseTranspose.h +92 -0
  291. data/vendor/eigen/Eigen/src/SparseCore/SparseTriangularView.h +189 -0
  292. data/vendor/eigen/Eigen/src/SparseCore/SparseUtil.h +178 -0
  293. data/vendor/eigen/Eigen/src/SparseCore/SparseVector.h +478 -0
  294. data/vendor/eigen/Eigen/src/SparseCore/SparseView.h +253 -0
  295. data/vendor/eigen/Eigen/src/SparseCore/TriangularSolver.h +315 -0
  296. data/vendor/eigen/Eigen/src/SparseLU/SparseLU.h +773 -0
  297. data/vendor/eigen/Eigen/src/SparseLU/SparseLUImpl.h +66 -0
  298. data/vendor/eigen/Eigen/src/SparseLU/SparseLU_Memory.h +226 -0
  299. data/vendor/eigen/Eigen/src/SparseLU/SparseLU_Structs.h +110 -0
  300. data/vendor/eigen/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h +301 -0
  301. data/vendor/eigen/Eigen/src/SparseLU/SparseLU_Utils.h +80 -0
  302. data/vendor/eigen/Eigen/src/SparseLU/SparseLU_column_bmod.h +181 -0
  303. data/vendor/eigen/Eigen/src/SparseLU/SparseLU_column_dfs.h +179 -0
  304. data/vendor/eigen/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h +107 -0
  305. data/vendor/eigen/Eigen/src/SparseLU/SparseLU_gemm_kernel.h +280 -0
  306. data/vendor/eigen/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h +126 -0
  307. data/vendor/eigen/Eigen/src/SparseLU/SparseLU_kernel_bmod.h +130 -0
  308. data/vendor/eigen/Eigen/src/SparseLU/SparseLU_panel_bmod.h +223 -0
  309. data/vendor/eigen/Eigen/src/SparseLU/SparseLU_panel_dfs.h +258 -0
  310. data/vendor/eigen/Eigen/src/SparseLU/SparseLU_pivotL.h +137 -0
  311. data/vendor/eigen/Eigen/src/SparseLU/SparseLU_pruneL.h +136 -0
  312. data/vendor/eigen/Eigen/src/SparseLU/SparseLU_relax_snode.h +83 -0
  313. data/vendor/eigen/Eigen/src/SparseQR/SparseQR.h +745 -0
  314. data/vendor/eigen/Eigen/src/StlSupport/StdDeque.h +126 -0
  315. data/vendor/eigen/Eigen/src/StlSupport/StdList.h +106 -0
  316. data/vendor/eigen/Eigen/src/StlSupport/StdVector.h +131 -0
  317. data/vendor/eigen/Eigen/src/StlSupport/details.h +84 -0
  318. data/vendor/eigen/Eigen/src/SuperLUSupport/SuperLUSupport.h +1027 -0
  319. data/vendor/eigen/Eigen/src/UmfPackSupport/UmfPackSupport.h +506 -0
  320. data/vendor/eigen/Eigen/src/misc/Image.h +82 -0
  321. data/vendor/eigen/Eigen/src/misc/Kernel.h +79 -0
  322. data/vendor/eigen/Eigen/src/misc/RealSvd2x2.h +55 -0
  323. data/vendor/eigen/Eigen/src/misc/blas.h +440 -0
  324. data/vendor/eigen/Eigen/src/misc/lapack.h +152 -0
  325. data/vendor/eigen/Eigen/src/misc/lapacke.h +16291 -0
  326. data/vendor/eigen/Eigen/src/misc/lapacke_mangling.h +17 -0
  327. data/vendor/eigen/Eigen/src/plugins/ArrayCwiseBinaryOps.h +332 -0
  328. data/vendor/eigen/Eigen/src/plugins/ArrayCwiseUnaryOps.h +552 -0
  329. data/vendor/eigen/Eigen/src/plugins/BlockMethods.h +1058 -0
  330. data/vendor/eigen/Eigen/src/plugins/CommonCwiseBinaryOps.h +115 -0
  331. data/vendor/eigen/Eigen/src/plugins/CommonCwiseUnaryOps.h +163 -0
  332. data/vendor/eigen/Eigen/src/plugins/MatrixCwiseBinaryOps.h +152 -0
  333. data/vendor/eigen/Eigen/src/plugins/MatrixCwiseUnaryOps.h +85 -0
  334. data/vendor/eigen/README.md +3 -0
  335. data/vendor/eigen/bench/README.txt +55 -0
  336. data/vendor/eigen/bench/btl/COPYING +340 -0
  337. data/vendor/eigen/bench/btl/README +154 -0
  338. data/vendor/eigen/bench/tensors/README +21 -0
  339. data/vendor/eigen/blas/README.txt +6 -0
  340. data/vendor/eigen/demos/mandelbrot/README +10 -0
  341. data/vendor/eigen/demos/mix_eigen_and_c/README +9 -0
  342. data/vendor/eigen/demos/opengl/README +13 -0
  343. data/vendor/eigen/unsupported/Eigen/CXX11/src/Tensor/README.md +1760 -0
  344. data/vendor/eigen/unsupported/README.txt +50 -0
  345. data/vendor/tomotopy/LICENSE +21 -0
  346. data/vendor/tomotopy/README.kr.rst +375 -0
  347. data/vendor/tomotopy/README.rst +382 -0
  348. data/vendor/tomotopy/src/Labeling/FoRelevance.cpp +362 -0
  349. data/vendor/tomotopy/src/Labeling/FoRelevance.h +88 -0
  350. data/vendor/tomotopy/src/Labeling/Labeler.h +50 -0
  351. data/vendor/tomotopy/src/TopicModel/CT.h +37 -0
  352. data/vendor/tomotopy/src/TopicModel/CTModel.cpp +13 -0
  353. data/vendor/tomotopy/src/TopicModel/CTModel.hpp +293 -0
  354. data/vendor/tomotopy/src/TopicModel/DMR.h +51 -0
  355. data/vendor/tomotopy/src/TopicModel/DMRModel.cpp +13 -0
  356. data/vendor/tomotopy/src/TopicModel/DMRModel.hpp +374 -0
  357. data/vendor/tomotopy/src/TopicModel/DT.h +65 -0
  358. data/vendor/tomotopy/src/TopicModel/DTM.h +22 -0
  359. data/vendor/tomotopy/src/TopicModel/DTModel.cpp +15 -0
  360. data/vendor/tomotopy/src/TopicModel/DTModel.hpp +572 -0
  361. data/vendor/tomotopy/src/TopicModel/GDMR.h +37 -0
  362. data/vendor/tomotopy/src/TopicModel/GDMRModel.cpp +14 -0
  363. data/vendor/tomotopy/src/TopicModel/GDMRModel.hpp +485 -0
  364. data/vendor/tomotopy/src/TopicModel/HDP.h +74 -0
  365. data/vendor/tomotopy/src/TopicModel/HDPModel.cpp +13 -0
  366. data/vendor/tomotopy/src/TopicModel/HDPModel.hpp +592 -0
  367. data/vendor/tomotopy/src/TopicModel/HLDA.h +40 -0
  368. data/vendor/tomotopy/src/TopicModel/HLDAModel.cpp +13 -0
  369. data/vendor/tomotopy/src/TopicModel/HLDAModel.hpp +681 -0
  370. data/vendor/tomotopy/src/TopicModel/HPA.h +27 -0
  371. data/vendor/tomotopy/src/TopicModel/HPAModel.cpp +21 -0
  372. data/vendor/tomotopy/src/TopicModel/HPAModel.hpp +588 -0
  373. data/vendor/tomotopy/src/TopicModel/LDA.h +144 -0
  374. data/vendor/tomotopy/src/TopicModel/LDACVB0Model.hpp +442 -0
  375. data/vendor/tomotopy/src/TopicModel/LDAModel.cpp +13 -0
  376. data/vendor/tomotopy/src/TopicModel/LDAModel.hpp +1058 -0
  377. data/vendor/tomotopy/src/TopicModel/LLDA.h +45 -0
  378. data/vendor/tomotopy/src/TopicModel/LLDAModel.cpp +13 -0
  379. data/vendor/tomotopy/src/TopicModel/LLDAModel.hpp +203 -0
  380. data/vendor/tomotopy/src/TopicModel/MGLDA.h +63 -0
  381. data/vendor/tomotopy/src/TopicModel/MGLDAModel.cpp +17 -0
  382. data/vendor/tomotopy/src/TopicModel/MGLDAModel.hpp +558 -0
  383. data/vendor/tomotopy/src/TopicModel/PA.h +43 -0
  384. data/vendor/tomotopy/src/TopicModel/PAModel.cpp +13 -0
  385. data/vendor/tomotopy/src/TopicModel/PAModel.hpp +467 -0
  386. data/vendor/tomotopy/src/TopicModel/PLDA.h +17 -0
  387. data/vendor/tomotopy/src/TopicModel/PLDAModel.cpp +13 -0
  388. data/vendor/tomotopy/src/TopicModel/PLDAModel.hpp +214 -0
  389. data/vendor/tomotopy/src/TopicModel/SLDA.h +54 -0
  390. data/vendor/tomotopy/src/TopicModel/SLDAModel.cpp +17 -0
  391. data/vendor/tomotopy/src/TopicModel/SLDAModel.hpp +456 -0
  392. data/vendor/tomotopy/src/TopicModel/TopicModel.hpp +692 -0
  393. data/vendor/tomotopy/src/Utils/AliasMethod.hpp +169 -0
  394. data/vendor/tomotopy/src/Utils/Dictionary.h +80 -0
  395. data/vendor/tomotopy/src/Utils/EigenAddonOps.hpp +181 -0
  396. data/vendor/tomotopy/src/Utils/LBFGS.h +202 -0
  397. data/vendor/tomotopy/src/Utils/LBFGS/LineSearchBacktracking.h +120 -0
  398. data/vendor/tomotopy/src/Utils/LBFGS/LineSearchBracketing.h +122 -0
  399. data/vendor/tomotopy/src/Utils/LBFGS/Param.h +213 -0
  400. data/vendor/tomotopy/src/Utils/LUT.hpp +82 -0
  401. data/vendor/tomotopy/src/Utils/MultiNormalDistribution.hpp +69 -0
  402. data/vendor/tomotopy/src/Utils/PolyaGamma.hpp +200 -0
  403. data/vendor/tomotopy/src/Utils/PolyaGammaHybrid.hpp +672 -0
  404. data/vendor/tomotopy/src/Utils/ThreadPool.hpp +150 -0
  405. data/vendor/tomotopy/src/Utils/Trie.hpp +220 -0
  406. data/vendor/tomotopy/src/Utils/TruncMultiNormal.hpp +94 -0
  407. data/vendor/tomotopy/src/Utils/Utils.hpp +337 -0
  408. data/vendor/tomotopy/src/Utils/avx_gamma.h +46 -0
  409. data/vendor/tomotopy/src/Utils/avx_mathfun.h +736 -0
  410. data/vendor/tomotopy/src/Utils/exception.h +28 -0
  411. data/vendor/tomotopy/src/Utils/math.h +281 -0
  412. data/vendor/tomotopy/src/Utils/rtnorm.hpp +2690 -0
  413. data/vendor/tomotopy/src/Utils/sample.hpp +192 -0
  414. data/vendor/tomotopy/src/Utils/serializer.hpp +695 -0
  415. data/vendor/tomotopy/src/Utils/slp.hpp +131 -0
  416. data/vendor/tomotopy/src/Utils/sse_gamma.h +48 -0
  417. data/vendor/tomotopy/src/Utils/sse_mathfun.h +710 -0
  418. data/vendor/tomotopy/src/Utils/text.hpp +49 -0
  419. data/vendor/tomotopy/src/Utils/tvector.hpp +543 -0
  420. metadata +531 -0
@@ -0,0 +1,186 @@
1
+ // This file is part of Eigen, a lightweight C++ template library
2
+ // for linear algebra.
3
+ //
4
+ // Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
5
+ //
6
+ // This Source Code Form is subject to the terms of the Mozilla
7
+ // Public License v. 2.0. If a copy of the MPL was not distributed
8
+ // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
+
10
+ #ifndef EIGEN_PRODUCT_H
11
+ #define EIGEN_PRODUCT_H
12
+
13
+ namespace Eigen {
14
+
15
+ template<typename Lhs, typename Rhs, int Option, typename StorageKind> class ProductImpl;
16
+
17
+ namespace internal {
18
+
19
+ template<typename Lhs, typename Rhs, int Option>
20
+ struct traits<Product<Lhs, Rhs, Option> >
21
+ {
22
+ typedef typename remove_all<Lhs>::type LhsCleaned;
23
+ typedef typename remove_all<Rhs>::type RhsCleaned;
24
+ typedef traits<LhsCleaned> LhsTraits;
25
+ typedef traits<RhsCleaned> RhsTraits;
26
+
27
+ typedef MatrixXpr XprKind;
28
+
29
+ typedef typename ScalarBinaryOpTraits<typename traits<LhsCleaned>::Scalar, typename traits<RhsCleaned>::Scalar>::ReturnType Scalar;
30
+ typedef typename product_promote_storage_type<typename LhsTraits::StorageKind,
31
+ typename RhsTraits::StorageKind,
32
+ internal::product_type<Lhs,Rhs>::ret>::ret StorageKind;
33
+ typedef typename promote_index_type<typename LhsTraits::StorageIndex,
34
+ typename RhsTraits::StorageIndex>::type StorageIndex;
35
+
36
+ enum {
37
+ RowsAtCompileTime = LhsTraits::RowsAtCompileTime,
38
+ ColsAtCompileTime = RhsTraits::ColsAtCompileTime,
39
+ MaxRowsAtCompileTime = LhsTraits::MaxRowsAtCompileTime,
40
+ MaxColsAtCompileTime = RhsTraits::MaxColsAtCompileTime,
41
+
42
+ // FIXME: only needed by GeneralMatrixMatrixTriangular
43
+ InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(LhsTraits::ColsAtCompileTime, RhsTraits::RowsAtCompileTime),
44
+
45
+ // The storage order is somewhat arbitrary here. The correct one will be determined through the evaluator.
46
+ Flags = (MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1) ? RowMajorBit
47
+ : (MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1) ? 0
48
+ : ( ((LhsTraits::Flags&NoPreferredStorageOrderBit) && (RhsTraits::Flags&RowMajorBit))
49
+ || ((RhsTraits::Flags&NoPreferredStorageOrderBit) && (LhsTraits::Flags&RowMajorBit)) ) ? RowMajorBit
50
+ : NoPreferredStorageOrderBit
51
+ };
52
+ };
53
+
54
+ } // end namespace internal
55
+
56
+ /** \class Product
57
+ * \ingroup Core_Module
58
+ *
59
+ * \brief Expression of the product of two arbitrary matrices or vectors
60
+ *
61
+ * \tparam _Lhs the type of the left-hand side expression
62
+ * \tparam _Rhs the type of the right-hand side expression
63
+ *
64
+ * This class represents an expression of the product of two arbitrary matrices.
65
+ *
66
+ * The other template parameters are:
67
+ * \tparam Option can be DefaultProduct, AliasFreeProduct, or LazyProduct
68
+ *
69
+ */
70
+ template<typename _Lhs, typename _Rhs, int Option>
71
+ class Product : public ProductImpl<_Lhs,_Rhs,Option,
72
+ typename internal::product_promote_storage_type<typename internal::traits<_Lhs>::StorageKind,
73
+ typename internal::traits<_Rhs>::StorageKind,
74
+ internal::product_type<_Lhs,_Rhs>::ret>::ret>
75
+ {
76
+ public:
77
+
78
+ typedef _Lhs Lhs;
79
+ typedef _Rhs Rhs;
80
+
81
+ typedef typename ProductImpl<
82
+ Lhs, Rhs, Option,
83
+ typename internal::product_promote_storage_type<typename internal::traits<Lhs>::StorageKind,
84
+ typename internal::traits<Rhs>::StorageKind,
85
+ internal::product_type<Lhs,Rhs>::ret>::ret>::Base Base;
86
+ EIGEN_GENERIC_PUBLIC_INTERFACE(Product)
87
+
88
+ typedef typename internal::ref_selector<Lhs>::type LhsNested;
89
+ typedef typename internal::ref_selector<Rhs>::type RhsNested;
90
+ typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned;
91
+ typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned;
92
+
93
+ EIGEN_DEVICE_FUNC Product(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs)
94
+ {
95
+ eigen_assert(lhs.cols() == rhs.rows()
96
+ && "invalid matrix product"
97
+ && "if you wanted a coeff-wise or a dot product use the respective explicit functions");
98
+ }
99
+
100
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); }
101
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); }
102
+
103
+ EIGEN_DEVICE_FUNC const LhsNestedCleaned& lhs() const { return m_lhs; }
104
+ EIGEN_DEVICE_FUNC const RhsNestedCleaned& rhs() const { return m_rhs; }
105
+
106
+ protected:
107
+
108
+ LhsNested m_lhs;
109
+ RhsNested m_rhs;
110
+ };
111
+
112
+ namespace internal {
113
+
114
+ template<typename Lhs, typename Rhs, int Option, int ProductTag = internal::product_type<Lhs,Rhs>::ret>
115
+ class dense_product_base
116
+ : public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
117
+ {};
118
+
119
+ /** Convertion to scalar for inner-products */
120
+ template<typename Lhs, typename Rhs, int Option>
121
+ class dense_product_base<Lhs, Rhs, Option, InnerProduct>
122
+ : public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
123
+ {
124
+ typedef Product<Lhs,Rhs,Option> ProductXpr;
125
+ typedef typename internal::dense_xpr_base<ProductXpr>::type Base;
126
+ public:
127
+ using Base::derived;
128
+ typedef typename Base::Scalar Scalar;
129
+
130
+ EIGEN_STRONG_INLINE operator const Scalar() const
131
+ {
132
+ return internal::evaluator<ProductXpr>(derived()).coeff(0,0);
133
+ }
134
+ };
135
+
136
+ } // namespace internal
137
+
138
+ // Generic API dispatcher
139
+ template<typename Lhs, typename Rhs, int Option, typename StorageKind>
140
+ class ProductImpl : public internal::generic_xpr_base<Product<Lhs,Rhs,Option>, MatrixXpr, StorageKind>::type
141
+ {
142
+ public:
143
+ typedef typename internal::generic_xpr_base<Product<Lhs,Rhs,Option>, MatrixXpr, StorageKind>::type Base;
144
+ };
145
+
146
+ template<typename Lhs, typename Rhs, int Option>
147
+ class ProductImpl<Lhs,Rhs,Option,Dense>
148
+ : public internal::dense_product_base<Lhs,Rhs,Option>
149
+ {
150
+ typedef Product<Lhs, Rhs, Option> Derived;
151
+
152
+ public:
153
+
154
+ typedef typename internal::dense_product_base<Lhs, Rhs, Option> Base;
155
+ EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
156
+ protected:
157
+ enum {
158
+ IsOneByOne = (RowsAtCompileTime == 1 || RowsAtCompileTime == Dynamic) &&
159
+ (ColsAtCompileTime == 1 || ColsAtCompileTime == Dynamic),
160
+ EnableCoeff = IsOneByOne || Option==LazyProduct
161
+ };
162
+
163
+ public:
164
+
165
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index row, Index col) const
166
+ {
167
+ EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
168
+ eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
169
+
170
+ return internal::evaluator<Derived>(derived()).coeff(row,col);
171
+ }
172
+
173
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index i) const
174
+ {
175
+ EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
176
+ eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
177
+
178
+ return internal::evaluator<Derived>(derived()).coeff(i);
179
+ }
180
+
181
+
182
+ };
183
+
184
+ } // end namespace Eigen
185
+
186
+ #endif // EIGEN_PRODUCT_H
@@ -0,0 +1,1112 @@
1
+ // This file is part of Eigen, a lightweight C++ template library
2
+ // for linear algebra.
3
+ //
4
+ // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
5
+ // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
6
+ // Copyright (C) 2011 Jitse Niesen <jitse@maths.leeds.ac.uk>
7
+ //
8
+ // This Source Code Form is subject to the terms of the Mozilla
9
+ // Public License v. 2.0. If a copy of the MPL was not distributed
10
+ // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
11
+
12
+
13
+ #ifndef EIGEN_PRODUCTEVALUATORS_H
14
+ #define EIGEN_PRODUCTEVALUATORS_H
15
+
16
+ namespace Eigen {
17
+
18
+ namespace internal {
19
+
20
+ /** \internal
21
+ * Evaluator of a product expression.
22
+ * Since products require special treatments to handle all possible cases,
23
+ * we simply deffer the evaluation logic to a product_evaluator class
24
+ * which offers more partial specialization possibilities.
25
+ *
26
+ * \sa class product_evaluator
27
+ */
28
+ template<typename Lhs, typename Rhs, int Options>
29
+ struct evaluator<Product<Lhs, Rhs, Options> >
30
+ : public product_evaluator<Product<Lhs, Rhs, Options> >
31
+ {
32
+ typedef Product<Lhs, Rhs, Options> XprType;
33
+ typedef product_evaluator<XprType> Base;
34
+
35
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit evaluator(const XprType& xpr) : Base(xpr) {}
36
+ };
37
+
38
+ // Catch "scalar * ( A * B )" and transform it to "(A*scalar) * B"
39
+ // TODO we should apply that rule only if that's really helpful
40
+ template<typename Lhs, typename Rhs, typename Scalar1, typename Scalar2, typename Plain1>
41
+ struct evaluator_assume_aliasing<CwiseBinaryOp<internal::scalar_product_op<Scalar1,Scalar2>,
42
+ const CwiseNullaryOp<internal::scalar_constant_op<Scalar1>, Plain1>,
43
+ const Product<Lhs, Rhs, DefaultProduct> > >
44
+ {
45
+ static const bool value = true;
46
+ };
47
+ template<typename Lhs, typename Rhs, typename Scalar1, typename Scalar2, typename Plain1>
48
+ struct evaluator<CwiseBinaryOp<internal::scalar_product_op<Scalar1,Scalar2>,
49
+ const CwiseNullaryOp<internal::scalar_constant_op<Scalar1>, Plain1>,
50
+ const Product<Lhs, Rhs, DefaultProduct> > >
51
+ : public evaluator<Product<EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar1,Lhs,product), Rhs, DefaultProduct> >
52
+ {
53
+ typedef CwiseBinaryOp<internal::scalar_product_op<Scalar1,Scalar2>,
54
+ const CwiseNullaryOp<internal::scalar_constant_op<Scalar1>, Plain1>,
55
+ const Product<Lhs, Rhs, DefaultProduct> > XprType;
56
+ typedef evaluator<Product<EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar1,Lhs,product), Rhs, DefaultProduct> > Base;
57
+
58
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit evaluator(const XprType& xpr)
59
+ : Base(xpr.lhs().functor().m_other * xpr.rhs().lhs() * xpr.rhs().rhs())
60
+ {}
61
+ };
62
+
63
+
64
+ template<typename Lhs, typename Rhs, int DiagIndex>
65
+ struct evaluator<Diagonal<const Product<Lhs, Rhs, DefaultProduct>, DiagIndex> >
66
+ : public evaluator<Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex> >
67
+ {
68
+ typedef Diagonal<const Product<Lhs, Rhs, DefaultProduct>, DiagIndex> XprType;
69
+ typedef evaluator<Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex> > Base;
70
+
71
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE explicit evaluator(const XprType& xpr)
72
+ : Base(Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex>(
73
+ Product<Lhs, Rhs, LazyProduct>(xpr.nestedExpression().lhs(), xpr.nestedExpression().rhs()),
74
+ xpr.index() ))
75
+ {}
76
+ };
77
+
78
+
79
+ // Helper class to perform a matrix product with the destination at hand.
80
+ // Depending on the sizes of the factors, there are different evaluation strategies
81
+ // as controlled by internal::product_type.
82
+ template< typename Lhs, typename Rhs,
83
+ typename LhsShape = typename evaluator_traits<Lhs>::Shape,
84
+ typename RhsShape = typename evaluator_traits<Rhs>::Shape,
85
+ int ProductType = internal::product_type<Lhs,Rhs>::value>
86
+ struct generic_product_impl;
87
+
88
+ template<typename Lhs, typename Rhs>
89
+ struct evaluator_assume_aliasing<Product<Lhs, Rhs, DefaultProduct> > {
90
+ static const bool value = true;
91
+ };
92
+
93
+ // This is the default evaluator implementation for products:
94
+ // It creates a temporary and call generic_product_impl
95
+ template<typename Lhs, typename Rhs, int Options, int ProductTag, typename LhsShape, typename RhsShape>
96
+ struct product_evaluator<Product<Lhs, Rhs, Options>, ProductTag, LhsShape, RhsShape>
97
+ : public evaluator<typename Product<Lhs, Rhs, Options>::PlainObject>
98
+ {
99
+ typedef Product<Lhs, Rhs, Options> XprType;
100
+ typedef typename XprType::PlainObject PlainObject;
101
+ typedef evaluator<PlainObject> Base;
102
+ enum {
103
+ Flags = Base::Flags | EvalBeforeNestingBit
104
+ };
105
+
106
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
107
+ explicit product_evaluator(const XprType& xpr)
108
+ : m_result(xpr.rows(), xpr.cols())
109
+ {
110
+ ::new (static_cast<Base*>(this)) Base(m_result);
111
+
112
+ // FIXME shall we handle nested_eval here?,
113
+ // if so, then we must take care at removing the call to nested_eval in the specializations (e.g., in permutation_matrix_product, transposition_matrix_product, etc.)
114
+ // typedef typename internal::nested_eval<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
115
+ // typedef typename internal::nested_eval<Rhs,Lhs::RowsAtCompileTime>::type RhsNested;
116
+ // typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned;
117
+ // typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned;
118
+ //
119
+ // const LhsNested lhs(xpr.lhs());
120
+ // const RhsNested rhs(xpr.rhs());
121
+ //
122
+ // generic_product_impl<LhsNestedCleaned, RhsNestedCleaned>::evalTo(m_result, lhs, rhs);
123
+
124
+ generic_product_impl<Lhs, Rhs, LhsShape, RhsShape, ProductTag>::evalTo(m_result, xpr.lhs(), xpr.rhs());
125
+ }
126
+
127
+ protected:
128
+ PlainObject m_result;
129
+ };
130
+
131
+ // The following three shortcuts are enabled only if the scalar types match excatly.
132
+ // TODO: we could enable them for different scalar types when the product is not vectorized.
133
+
134
+ // Dense = Product
135
+ template< typename DstXprType, typename Lhs, typename Rhs, int Options, typename Scalar>
136
+ struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::assign_op<Scalar,Scalar>, Dense2Dense,
137
+ typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
138
+ {
139
+ typedef Product<Lhs,Rhs,Options> SrcXprType;
140
+ static EIGEN_STRONG_INLINE
141
+ void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,Scalar> &)
142
+ {
143
+ Index dstRows = src.rows();
144
+ Index dstCols = src.cols();
145
+ if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
146
+ dst.resize(dstRows, dstCols);
147
+ // FIXME shall we handle nested_eval here?
148
+ generic_product_impl<Lhs, Rhs>::evalTo(dst, src.lhs(), src.rhs());
149
+ }
150
+ };
151
+
152
+ // Dense += Product
153
+ template< typename DstXprType, typename Lhs, typename Rhs, int Options, typename Scalar>
154
+ struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::add_assign_op<Scalar,Scalar>, Dense2Dense,
155
+ typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
156
+ {
157
+ typedef Product<Lhs,Rhs,Options> SrcXprType;
158
+ static EIGEN_STRONG_INLINE
159
+ void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar,Scalar> &)
160
+ {
161
+ eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
162
+ // FIXME shall we handle nested_eval here?
163
+ generic_product_impl<Lhs, Rhs>::addTo(dst, src.lhs(), src.rhs());
164
+ }
165
+ };
166
+
167
+ // Dense -= Product
168
+ template< typename DstXprType, typename Lhs, typename Rhs, int Options, typename Scalar>
169
+ struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::sub_assign_op<Scalar,Scalar>, Dense2Dense,
170
+ typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct)>::type>
171
+ {
172
+ typedef Product<Lhs,Rhs,Options> SrcXprType;
173
+ static EIGEN_STRONG_INLINE
174
+ void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar,Scalar> &)
175
+ {
176
+ eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
177
+ // FIXME shall we handle nested_eval here?
178
+ generic_product_impl<Lhs, Rhs>::subTo(dst, src.lhs(), src.rhs());
179
+ }
180
+ };
181
+
182
+
183
+ // Dense ?= scalar * Product
184
+ // TODO we should apply that rule if that's really helpful
185
+ // for instance, this is not good for inner products
186
+ template< typename DstXprType, typename Lhs, typename Rhs, typename AssignFunc, typename Scalar, typename ScalarBis, typename Plain>
187
+ struct Assignment<DstXprType, CwiseBinaryOp<internal::scalar_product_op<ScalarBis,Scalar>, const CwiseNullaryOp<internal::scalar_constant_op<ScalarBis>,Plain>,
188
+ const Product<Lhs,Rhs,DefaultProduct> >, AssignFunc, Dense2Dense>
189
+ {
190
+ typedef CwiseBinaryOp<internal::scalar_product_op<ScalarBis,Scalar>,
191
+ const CwiseNullaryOp<internal::scalar_constant_op<ScalarBis>,Plain>,
192
+ const Product<Lhs,Rhs,DefaultProduct> > SrcXprType;
193
+ static EIGEN_STRONG_INLINE
194
+ void run(DstXprType &dst, const SrcXprType &src, const AssignFunc& func)
195
+ {
196
+ call_assignment_no_alias(dst, (src.lhs().functor().m_other * src.rhs().lhs())*src.rhs().rhs(), func);
197
+ }
198
+ };
199
+
200
+ //----------------------------------------
201
+ // Catch "Dense ?= xpr + Product<>" expression to save one temporary
202
+ // FIXME we could probably enable these rules for any product, i.e., not only Dense and DefaultProduct
203
+
204
+ template<typename OtherXpr, typename Lhs, typename Rhs>
205
+ struct evaluator_assume_aliasing<CwiseBinaryOp<internal::scalar_sum_op<typename OtherXpr::Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, const OtherXpr,
206
+ const Product<Lhs,Rhs,DefaultProduct> >, DenseShape > {
207
+ static const bool value = true;
208
+ };
209
+
210
+ template<typename OtherXpr, typename Lhs, typename Rhs>
211
+ struct evaluator_assume_aliasing<CwiseBinaryOp<internal::scalar_difference_op<typename OtherXpr::Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, const OtherXpr,
212
+ const Product<Lhs,Rhs,DefaultProduct> >, DenseShape > {
213
+ static const bool value = true;
214
+ };
215
+
216
+ template<typename DstXprType, typename OtherXpr, typename ProductType, typename Func1, typename Func2>
217
+ struct assignment_from_xpr_op_product
218
+ {
219
+ template<typename SrcXprType, typename InitialFunc>
220
+ static EIGEN_STRONG_INLINE
221
+ void run(DstXprType &dst, const SrcXprType &src, const InitialFunc& /*func*/)
222
+ {
223
+ call_assignment_no_alias(dst, src.lhs(), Func1());
224
+ call_assignment_no_alias(dst, src.rhs(), Func2());
225
+ }
226
+ };
227
+
228
+ #define EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(ASSIGN_OP,BINOP,ASSIGN_OP2) \
229
+ template< typename DstXprType, typename OtherXpr, typename Lhs, typename Rhs, typename DstScalar, typename SrcScalar, typename OtherScalar,typename ProdScalar> \
230
+ struct Assignment<DstXprType, CwiseBinaryOp<internal::BINOP<OtherScalar,ProdScalar>, const OtherXpr, \
231
+ const Product<Lhs,Rhs,DefaultProduct> >, internal::ASSIGN_OP<DstScalar,SrcScalar>, Dense2Dense> \
232
+ : assignment_from_xpr_op_product<DstXprType, OtherXpr, Product<Lhs,Rhs,DefaultProduct>, internal::ASSIGN_OP<DstScalar,OtherScalar>, internal::ASSIGN_OP2<DstScalar,ProdScalar> > \
233
+ {}
234
+
235
+ EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(assign_op, scalar_sum_op,add_assign_op);
236
+ EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(add_assign_op,scalar_sum_op,add_assign_op);
237
+ EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(sub_assign_op,scalar_sum_op,sub_assign_op);
238
+
239
+ EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(assign_op, scalar_difference_op,sub_assign_op);
240
+ EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(add_assign_op,scalar_difference_op,sub_assign_op);
241
+ EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(sub_assign_op,scalar_difference_op,add_assign_op);
242
+
243
+ //----------------------------------------
244
+
245
+ template<typename Lhs, typename Rhs>
246
+ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,InnerProduct>
247
+ {
248
+ template<typename Dst>
249
+ static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
250
+ {
251
+ dst.coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum();
252
+ }
253
+
254
+ template<typename Dst>
255
+ static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
256
+ {
257
+ dst.coeffRef(0,0) += (lhs.transpose().cwiseProduct(rhs)).sum();
258
+ }
259
+
260
+ template<typename Dst>
261
+ static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
262
+ { dst.coeffRef(0,0) -= (lhs.transpose().cwiseProduct(rhs)).sum(); }
263
+ };
264
+
265
+
266
+ /***********************************************************************
267
+ * Implementation of outer dense * dense vector product
268
+ ***********************************************************************/
269
+
270
+ // Column major result
271
+ template<typename Dst, typename Lhs, typename Rhs, typename Func>
272
+ void outer_product_selector_run(Dst& dst, const Lhs &lhs, const Rhs &rhs, const Func& func, const false_type&)
273
+ {
274
+ evaluator<Rhs> rhsEval(rhs);
275
+ typename nested_eval<Lhs,Rhs::SizeAtCompileTime>::type actual_lhs(lhs);
276
+ // FIXME if cols is large enough, then it might be useful to make sure that lhs is sequentially stored
277
+ // FIXME not very good if rhs is real and lhs complex while alpha is real too
278
+ const Index cols = dst.cols();
279
+ for (Index j=0; j<cols; ++j)
280
+ func(dst.col(j), rhsEval.coeff(Index(0),j) * actual_lhs);
281
+ }
282
+
283
+ // Row major result
284
+ template<typename Dst, typename Lhs, typename Rhs, typename Func>
285
+ void outer_product_selector_run(Dst& dst, const Lhs &lhs, const Rhs &rhs, const Func& func, const true_type&)
286
+ {
287
+ evaluator<Lhs> lhsEval(lhs);
288
+ typename nested_eval<Rhs,Lhs::SizeAtCompileTime>::type actual_rhs(rhs);
289
+ // FIXME if rows is large enough, then it might be useful to make sure that rhs is sequentially stored
290
+ // FIXME not very good if lhs is real and rhs complex while alpha is real too
291
+ const Index rows = dst.rows();
292
+ for (Index i=0; i<rows; ++i)
293
+ func(dst.row(i), lhsEval.coeff(i,Index(0)) * actual_rhs);
294
+ }
295
+
296
+ template<typename Lhs, typename Rhs>
297
+ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,OuterProduct>
298
+ {
299
+ template<typename T> struct is_row_major : internal::conditional<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type>::type {};
300
+ typedef typename Product<Lhs,Rhs>::Scalar Scalar;
301
+
302
+ // TODO it would be nice to be able to exploit our *_assign_op functors for that purpose
303
+ struct set { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() = src; } };
304
+ struct add { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() += src; } };
305
+ struct sub { template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const { dst.const_cast_derived() -= src; } };
306
+ struct adds {
307
+ Scalar m_scale;
308
+ explicit adds(const Scalar& s) : m_scale(s) {}
309
+ template<typename Dst, typename Src> void operator()(const Dst& dst, const Src& src) const {
310
+ dst.const_cast_derived() += m_scale * src;
311
+ }
312
+ };
313
+
314
+ template<typename Dst>
315
+ static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
316
+ {
317
+ internal::outer_product_selector_run(dst, lhs, rhs, set(), is_row_major<Dst>());
318
+ }
319
+
320
+ template<typename Dst>
321
+ static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
322
+ {
323
+ internal::outer_product_selector_run(dst, lhs, rhs, add(), is_row_major<Dst>());
324
+ }
325
+
326
+ template<typename Dst>
327
+ static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
328
+ {
329
+ internal::outer_product_selector_run(dst, lhs, rhs, sub(), is_row_major<Dst>());
330
+ }
331
+
332
+ template<typename Dst>
333
+ static EIGEN_STRONG_INLINE void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
334
+ {
335
+ internal::outer_product_selector_run(dst, lhs, rhs, adds(alpha), is_row_major<Dst>());
336
+ }
337
+
338
+ };
339
+
340
+
341
+ // This base class provides default implementations for evalTo, addTo, subTo, in terms of scaleAndAddTo
342
+ template<typename Lhs, typename Rhs, typename Derived>
343
+ struct generic_product_impl_base
344
+ {
345
+ typedef typename Product<Lhs,Rhs>::Scalar Scalar;
346
+
347
+ template<typename Dst>
348
+ static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
349
+ { dst.setZero(); scaleAndAddTo(dst, lhs, rhs, Scalar(1)); }
350
+
351
+ template<typename Dst>
352
+ static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
353
+ { scaleAndAddTo(dst,lhs, rhs, Scalar(1)); }
354
+
355
+ template<typename Dst>
356
+ static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
357
+ { scaleAndAddTo(dst, lhs, rhs, Scalar(-1)); }
358
+
359
+ template<typename Dst>
360
+ static EIGEN_STRONG_INLINE void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
361
+ { Derived::scaleAndAddTo(dst,lhs,rhs,alpha); }
362
+
363
+ };
364
+
365
+ template<typename Lhs, typename Rhs>
366
+ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemvProduct>
367
+ : generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemvProduct> >
368
+ {
369
+ typedef typename nested_eval<Lhs,1>::type LhsNested;
370
+ typedef typename nested_eval<Rhs,1>::type RhsNested;
371
+ typedef typename Product<Lhs,Rhs>::Scalar Scalar;
372
+ enum { Side = Lhs::IsVectorAtCompileTime ? OnTheLeft : OnTheRight };
373
+ typedef typename internal::remove_all<typename internal::conditional<int(Side)==OnTheRight,LhsNested,RhsNested>::type>::type MatrixType;
374
+
375
+ template<typename Dest>
376
+ static EIGEN_STRONG_INLINE void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
377
+ {
378
+ LhsNested actual_lhs(lhs);
379
+ RhsNested actual_rhs(rhs);
380
+ internal::gemv_dense_selector<Side,
381
+ (int(MatrixType::Flags)&RowMajorBit) ? RowMajor : ColMajor,
382
+ bool(internal::blas_traits<MatrixType>::HasUsableDirectAccess)
383
+ >::run(actual_lhs, actual_rhs, dst, alpha);
384
+ }
385
+ };
386
+
387
+ template<typename Lhs, typename Rhs>
388
+ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,CoeffBasedProductMode>
389
+ {
390
+ typedef typename Product<Lhs,Rhs>::Scalar Scalar;
391
+
392
+ template<typename Dst>
393
+ static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
394
+ {
395
+ // Same as: dst.noalias() = lhs.lazyProduct(rhs);
396
+ // but easier on the compiler side
397
+ call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::assign_op<typename Dst::Scalar,Scalar>());
398
+ }
399
+
400
+ template<typename Dst>
401
+ static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
402
+ {
403
+ // dst.noalias() += lhs.lazyProduct(rhs);
404
+ call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::add_assign_op<typename Dst::Scalar,Scalar>());
405
+ }
406
+
407
+ template<typename Dst>
408
+ static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs)
409
+ {
410
+ // dst.noalias() -= lhs.lazyProduct(rhs);
411
+ call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::sub_assign_op<typename Dst::Scalar,Scalar>());
412
+ }
413
+
414
+ // template<typename Dst>
415
+ // static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
416
+ // { dst.noalias() += alpha * lhs.lazyProduct(rhs); }
417
+ };
418
+
419
+ // This specialization enforces the use of a coefficient-based evaluation strategy
420
+ template<typename Lhs, typename Rhs>
421
+ struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,LazyCoeffBasedProductMode>
422
+ : generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,CoeffBasedProductMode> {};
423
+
424
+ // Case 2: Evaluate coeff by coeff
425
+ //
426
+ // This is mostly taken from CoeffBasedProduct.h
427
+ // The main difference is that we add an extra argument to the etor_product_*_impl::run() function
428
+ // for the inner dimension of the product, because evaluator object do not know their size.
429
+
430
+ template<int Traversal, int UnrollingIndex, typename Lhs, typename Rhs, typename RetScalar>
431
+ struct etor_product_coeff_impl;
432
+
433
+ template<int StorageOrder, int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
434
+ struct etor_product_packet_impl;
435
+
436
+ template<typename Lhs, typename Rhs, int ProductTag>
437
+ struct product_evaluator<Product<Lhs, Rhs, LazyProduct>, ProductTag, DenseShape, DenseShape>
438
+ : evaluator_base<Product<Lhs, Rhs, LazyProduct> >
439
+ {
440
+ typedef Product<Lhs, Rhs, LazyProduct> XprType;
441
+ typedef typename XprType::Scalar Scalar;
442
+ typedef typename XprType::CoeffReturnType CoeffReturnType;
443
+
444
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
445
+ explicit product_evaluator(const XprType& xpr)
446
+ : m_lhs(xpr.lhs()),
447
+ m_rhs(xpr.rhs()),
448
+ m_lhsImpl(m_lhs), // FIXME the creation of the evaluator objects should result in a no-op, but check that!
449
+ m_rhsImpl(m_rhs), // Moreover, they are only useful for the packet path, so we could completely disable them when not needed,
450
+ // or perhaps declare them on the fly on the packet method... We have experiment to check what's best.
451
+ m_innerDim(xpr.lhs().cols())
452
+ {
453
+ EIGEN_INTERNAL_CHECK_COST_VALUE(NumTraits<Scalar>::MulCost);
454
+ EIGEN_INTERNAL_CHECK_COST_VALUE(NumTraits<Scalar>::AddCost);
455
+ EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
456
+ #if 0
457
+ std::cerr << "LhsOuterStrideBytes= " << LhsOuterStrideBytes << "\n";
458
+ std::cerr << "RhsOuterStrideBytes= " << RhsOuterStrideBytes << "\n";
459
+ std::cerr << "LhsAlignment= " << LhsAlignment << "\n";
460
+ std::cerr << "RhsAlignment= " << RhsAlignment << "\n";
461
+ std::cerr << "CanVectorizeLhs= " << CanVectorizeLhs << "\n";
462
+ std::cerr << "CanVectorizeRhs= " << CanVectorizeRhs << "\n";
463
+ std::cerr << "CanVectorizeInner= " << CanVectorizeInner << "\n";
464
+ std::cerr << "EvalToRowMajor= " << EvalToRowMajor << "\n";
465
+ std::cerr << "Alignment= " << Alignment << "\n";
466
+ std::cerr << "Flags= " << Flags << "\n";
467
+ #endif
468
+ }
469
+
470
+ // Everything below here is taken from CoeffBasedProduct.h
471
+
472
+ typedef typename internal::nested_eval<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
473
+ typedef typename internal::nested_eval<Rhs,Lhs::RowsAtCompileTime>::type RhsNested;
474
+
475
+ typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned;
476
+ typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned;
477
+
478
+ typedef evaluator<LhsNestedCleaned> LhsEtorType;
479
+ typedef evaluator<RhsNestedCleaned> RhsEtorType;
480
+
481
+ enum {
482
+ RowsAtCompileTime = LhsNestedCleaned::RowsAtCompileTime,
483
+ ColsAtCompileTime = RhsNestedCleaned::ColsAtCompileTime,
484
+ InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(LhsNestedCleaned::ColsAtCompileTime, RhsNestedCleaned::RowsAtCompileTime),
485
+ MaxRowsAtCompileTime = LhsNestedCleaned::MaxRowsAtCompileTime,
486
+ MaxColsAtCompileTime = RhsNestedCleaned::MaxColsAtCompileTime
487
+ };
488
+
489
+ typedef typename find_best_packet<Scalar,RowsAtCompileTime>::type LhsVecPacketType;
490
+ typedef typename find_best_packet<Scalar,ColsAtCompileTime>::type RhsVecPacketType;
491
+
492
+ enum {
493
+
494
+ LhsCoeffReadCost = LhsEtorType::CoeffReadCost,
495
+ RhsCoeffReadCost = RhsEtorType::CoeffReadCost,
496
+ CoeffReadCost = InnerSize==0 ? NumTraits<Scalar>::ReadCost
497
+ : InnerSize == Dynamic ? HugeCost
498
+ : InnerSize * (NumTraits<Scalar>::MulCost + LhsCoeffReadCost + RhsCoeffReadCost)
499
+ + (InnerSize - 1) * NumTraits<Scalar>::AddCost,
500
+
501
+ Unroll = CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
502
+
503
+ LhsFlags = LhsEtorType::Flags,
504
+ RhsFlags = RhsEtorType::Flags,
505
+
506
+ LhsRowMajor = LhsFlags & RowMajorBit,
507
+ RhsRowMajor = RhsFlags & RowMajorBit,
508
+
509
+ LhsVecPacketSize = unpacket_traits<LhsVecPacketType>::size,
510
+ RhsVecPacketSize = unpacket_traits<RhsVecPacketType>::size,
511
+
512
+ // Here, we don't care about alignment larger than the usable packet size.
513
+ LhsAlignment = EIGEN_PLAIN_ENUM_MIN(LhsEtorType::Alignment,LhsVecPacketSize*int(sizeof(typename LhsNestedCleaned::Scalar))),
514
+ RhsAlignment = EIGEN_PLAIN_ENUM_MIN(RhsEtorType::Alignment,RhsVecPacketSize*int(sizeof(typename RhsNestedCleaned::Scalar))),
515
+
516
+ SameType = is_same<typename LhsNestedCleaned::Scalar,typename RhsNestedCleaned::Scalar>::value,
517
+
518
+ CanVectorizeRhs = bool(RhsRowMajor) && (RhsFlags & PacketAccessBit) && (ColsAtCompileTime!=1),
519
+ CanVectorizeLhs = (!LhsRowMajor) && (LhsFlags & PacketAccessBit) && (RowsAtCompileTime!=1),
520
+
521
+ EvalToRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
522
+ : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
523
+ : (bool(RhsRowMajor) && !CanVectorizeLhs),
524
+
525
+ Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & ~RowMajorBit)
526
+ | (EvalToRowMajor ? RowMajorBit : 0)
527
+ // TODO enable vectorization for mixed types
528
+ | (SameType && (CanVectorizeLhs || CanVectorizeRhs) ? PacketAccessBit : 0)
529
+ | (XprType::IsVectorAtCompileTime ? LinearAccessBit : 0),
530
+
531
+ LhsOuterStrideBytes = int(LhsNestedCleaned::OuterStrideAtCompileTime) * int(sizeof(typename LhsNestedCleaned::Scalar)),
532
+ RhsOuterStrideBytes = int(RhsNestedCleaned::OuterStrideAtCompileTime) * int(sizeof(typename RhsNestedCleaned::Scalar)),
533
+
534
+ Alignment = bool(CanVectorizeLhs) ? (LhsOuterStrideBytes<=0 || (int(LhsOuterStrideBytes) % EIGEN_PLAIN_ENUM_MAX(1,LhsAlignment))!=0 ? 0 : LhsAlignment)
535
+ : bool(CanVectorizeRhs) ? (RhsOuterStrideBytes<=0 || (int(RhsOuterStrideBytes) % EIGEN_PLAIN_ENUM_MAX(1,RhsAlignment))!=0 ? 0 : RhsAlignment)
536
+ : 0,
537
+
538
+ /* CanVectorizeInner deserves special explanation. It does not affect the product flags. It is not used outside
539
+ * of Product. If the Product itself is not a packet-access expression, there is still a chance that the inner
540
+ * loop of the product might be vectorized. This is the meaning of CanVectorizeInner. Since it doesn't affect
541
+ * the Flags, it is safe to make this value depend on ActualPacketAccessBit, that doesn't affect the ABI.
542
+ */
543
+ CanVectorizeInner = SameType
544
+ && LhsRowMajor
545
+ && (!RhsRowMajor)
546
+ && (LhsFlags & RhsFlags & ActualPacketAccessBit)
547
+ && (InnerSize % packet_traits<Scalar>::size == 0)
548
+ };
549
+
550
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index row, Index col) const
551
+ {
552
+ return (m_lhs.row(row).transpose().cwiseProduct( m_rhs.col(col) )).sum();
553
+ }
554
+
555
+ /* Allow index-based non-packet access. It is impossible though to allow index-based packed access,
556
+ * which is why we don't set the LinearAccessBit.
557
+ * TODO: this seems possible when the result is a vector
558
+ */
559
+ EIGEN_DEVICE_FUNC const CoeffReturnType coeff(Index index) const
560
+ {
561
+ const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? 0 : index;
562
+ const Index col = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? index : 0;
563
+ return (m_lhs.row(row).transpose().cwiseProduct( m_rhs.col(col) )).sum();
564
+ }
565
+
566
+ template<int LoadMode, typename PacketType>
567
+ const PacketType packet(Index row, Index col) const
568
+ {
569
+ PacketType res;
570
+ typedef etor_product_packet_impl<bool(int(Flags)&RowMajorBit) ? RowMajor : ColMajor,
571
+ Unroll ? int(InnerSize) : Dynamic,
572
+ LhsEtorType, RhsEtorType, PacketType, LoadMode> PacketImpl;
573
+ PacketImpl::run(row, col, m_lhsImpl, m_rhsImpl, m_innerDim, res);
574
+ return res;
575
+ }
576
+
577
+ template<int LoadMode, typename PacketType>
578
+ const PacketType packet(Index index) const
579
+ {
580
+ const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? 0 : index;
581
+ const Index col = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? index : 0;
582
+ return packet<LoadMode,PacketType>(row,col);
583
+ }
584
+
585
+ protected:
586
+ typename internal::add_const_on_value_type<LhsNested>::type m_lhs;
587
+ typename internal::add_const_on_value_type<RhsNested>::type m_rhs;
588
+
589
+ LhsEtorType m_lhsImpl;
590
+ RhsEtorType m_rhsImpl;
591
+
592
+ // TODO: Get rid of m_innerDim if known at compile time
593
+ Index m_innerDim;
594
+ };
595
+
596
+ template<typename Lhs, typename Rhs>
597
+ struct product_evaluator<Product<Lhs, Rhs, DefaultProduct>, LazyCoeffBasedProductMode, DenseShape, DenseShape>
598
+ : product_evaluator<Product<Lhs, Rhs, LazyProduct>, CoeffBasedProductMode, DenseShape, DenseShape>
599
+ {
600
+ typedef Product<Lhs, Rhs, DefaultProduct> XprType;
601
+ typedef Product<Lhs, Rhs, LazyProduct> BaseProduct;
602
+ typedef product_evaluator<BaseProduct, CoeffBasedProductMode, DenseShape, DenseShape> Base;
603
+ enum {
604
+ Flags = Base::Flags | EvalBeforeNestingBit
605
+ };
606
+ EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
607
+ : Base(BaseProduct(xpr.lhs(),xpr.rhs()))
608
+ {}
609
+ };
610
+
611
+ /****************************************
612
+ *** Coeff based product, Packet path ***
613
+ ****************************************/
614
+
615
+ template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
616
+ struct etor_product_packet_impl<RowMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
617
+ {
618
+ static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet &res)
619
+ {
620
+ etor_product_packet_impl<RowMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, innerDim, res);
621
+ res = pmadd(pset1<Packet>(lhs.coeff(row, Index(UnrollingIndex-1))), rhs.template packet<LoadMode,Packet>(Index(UnrollingIndex-1), col), res);
622
+ }
623
+ };
624
+
625
+ template<int UnrollingIndex, typename Lhs, typename Rhs, typename Packet, int LoadMode>
626
+ struct etor_product_packet_impl<ColMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
627
+ {
628
+ static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet &res)
629
+ {
630
+ etor_product_packet_impl<ColMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(row, col, lhs, rhs, innerDim, res);
631
+ res = pmadd(lhs.template packet<LoadMode,Packet>(row, Index(UnrollingIndex-1)), pset1<Packet>(rhs.coeff(Index(UnrollingIndex-1), col)), res);
632
+ }
633
+ };
634
+
635
+ template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
636
+ struct etor_product_packet_impl<RowMajor, 1, Lhs, Rhs, Packet, LoadMode>
637
+ {
638
+ static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, Packet &res)
639
+ {
640
+ res = pmul(pset1<Packet>(lhs.coeff(row, Index(0))),rhs.template packet<LoadMode,Packet>(Index(0), col));
641
+ }
642
+ };
643
+
644
+ template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
645
+ struct etor_product_packet_impl<ColMajor, 1, Lhs, Rhs, Packet, LoadMode>
646
+ {
647
+ static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index /*innerDim*/, Packet &res)
648
+ {
649
+ res = pmul(lhs.template packet<LoadMode,Packet>(row, Index(0)), pset1<Packet>(rhs.coeff(Index(0), col)));
650
+ }
651
+ };
652
+
653
+ template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
654
+ struct etor_product_packet_impl<RowMajor, 0, Lhs, Rhs, Packet, LoadMode>
655
+ {
656
+ static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Index /*innerDim*/, Packet &res)
657
+ {
658
+ res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
659
+ }
660
+ };
661
+
662
+ template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
663
+ struct etor_product_packet_impl<ColMajor, 0, Lhs, Rhs, Packet, LoadMode>
664
+ {
665
+ static EIGEN_STRONG_INLINE void run(Index /*row*/, Index /*col*/, const Lhs& /*lhs*/, const Rhs& /*rhs*/, Index /*innerDim*/, Packet &res)
666
+ {
667
+ res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
668
+ }
669
+ };
670
+
671
+ template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
672
+ struct etor_product_packet_impl<RowMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
673
+ {
674
+ static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet& res)
675
+ {
676
+ res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
677
+ for(Index i = 0; i < innerDim; ++i)
678
+ res = pmadd(pset1<Packet>(lhs.coeff(row, i)), rhs.template packet<LoadMode,Packet>(i, col), res);
679
+ }
680
+ };
681
+
682
+ template<typename Lhs, typename Rhs, typename Packet, int LoadMode>
683
+ struct etor_product_packet_impl<ColMajor, Dynamic, Lhs, Rhs, Packet, LoadMode>
684
+ {
685
+ static EIGEN_STRONG_INLINE void run(Index row, Index col, const Lhs& lhs, const Rhs& rhs, Index innerDim, Packet& res)
686
+ {
687
+ res = pset1<Packet>(typename unpacket_traits<Packet>::type(0));
688
+ for(Index i = 0; i < innerDim; ++i)
689
+ res = pmadd(lhs.template packet<LoadMode,Packet>(row, i), pset1<Packet>(rhs.coeff(i, col)), res);
690
+ }
691
+ };
692
+
693
+
694
+ /***************************************************************************
695
+ * Triangular products
696
+ ***************************************************************************/
697
+ template<int Mode, bool LhsIsTriangular,
698
+ typename Lhs, bool LhsIsVector,
699
+ typename Rhs, bool RhsIsVector>
700
+ struct triangular_product_impl;
701
+
702
+ template<typename Lhs, typename Rhs, int ProductTag>
703
+ struct generic_product_impl<Lhs,Rhs,TriangularShape,DenseShape,ProductTag>
704
+ : generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,TriangularShape,DenseShape,ProductTag> >
705
+ {
706
+ typedef typename Product<Lhs,Rhs>::Scalar Scalar;
707
+
708
+ template<typename Dest>
709
+ static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
710
+ {
711
+ triangular_product_impl<Lhs::Mode,true,typename Lhs::MatrixType,false,Rhs, Rhs::ColsAtCompileTime==1>
712
+ ::run(dst, lhs.nestedExpression(), rhs, alpha);
713
+ }
714
+ };
715
+
716
+ template<typename Lhs, typename Rhs, int ProductTag>
717
+ struct generic_product_impl<Lhs,Rhs,DenseShape,TriangularShape,ProductTag>
718
+ : generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,DenseShape,TriangularShape,ProductTag> >
719
+ {
720
+ typedef typename Product<Lhs,Rhs>::Scalar Scalar;
721
+
722
+ template<typename Dest>
723
+ static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
724
+ {
725
+ triangular_product_impl<Rhs::Mode,false,Lhs,Lhs::RowsAtCompileTime==1, typename Rhs::MatrixType, false>::run(dst, lhs, rhs.nestedExpression(), alpha);
726
+ }
727
+ };
728
+
729
+
730
+ /***************************************************************************
731
+ * SelfAdjoint products
732
+ ***************************************************************************/
733
+ template <typename Lhs, int LhsMode, bool LhsIsVector,
734
+ typename Rhs, int RhsMode, bool RhsIsVector>
735
+ struct selfadjoint_product_impl;
736
+
737
+ template<typename Lhs, typename Rhs, int ProductTag>
738
+ struct generic_product_impl<Lhs,Rhs,SelfAdjointShape,DenseShape,ProductTag>
739
+ : generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,SelfAdjointShape,DenseShape,ProductTag> >
740
+ {
741
+ typedef typename Product<Lhs,Rhs>::Scalar Scalar;
742
+
743
+ template<typename Dest>
744
+ static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
745
+ {
746
+ selfadjoint_product_impl<typename Lhs::MatrixType,Lhs::Mode,false,Rhs,0,Rhs::IsVectorAtCompileTime>::run(dst, lhs.nestedExpression(), rhs, alpha);
747
+ }
748
+ };
749
+
750
+ template<typename Lhs, typename Rhs, int ProductTag>
751
+ struct generic_product_impl<Lhs,Rhs,DenseShape,SelfAdjointShape,ProductTag>
752
+ : generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,DenseShape,SelfAdjointShape,ProductTag> >
753
+ {
754
+ typedef typename Product<Lhs,Rhs>::Scalar Scalar;
755
+
756
+ template<typename Dest>
757
+ static void scaleAndAddTo(Dest& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha)
758
+ {
759
+ selfadjoint_product_impl<Lhs,0,Lhs::IsVectorAtCompileTime,typename Rhs::MatrixType,Rhs::Mode,false>::run(dst, lhs, rhs.nestedExpression(), alpha);
760
+ }
761
+ };
762
+
763
+
764
+ /***************************************************************************
765
+ * Diagonal products
766
+ ***************************************************************************/
767
+
768
+ template<typename MatrixType, typename DiagonalType, typename Derived, int ProductOrder>
769
+ struct diagonal_product_evaluator_base
770
+ : evaluator_base<Derived>
771
+ {
772
+ typedef typename ScalarBinaryOpTraits<typename MatrixType::Scalar, typename DiagonalType::Scalar>::ReturnType Scalar;
773
+ public:
774
+ enum {
775
+ CoeffReadCost = NumTraits<Scalar>::MulCost + evaluator<MatrixType>::CoeffReadCost + evaluator<DiagonalType>::CoeffReadCost,
776
+
777
+ MatrixFlags = evaluator<MatrixType>::Flags,
778
+ DiagFlags = evaluator<DiagonalType>::Flags,
779
+ _StorageOrder = MatrixFlags & RowMajorBit ? RowMajor : ColMajor,
780
+ _ScalarAccessOnDiag = !((int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheLeft)
781
+ ||(int(_StorageOrder) == RowMajor && int(ProductOrder) == OnTheRight)),
782
+ _SameTypes = is_same<typename MatrixType::Scalar, typename DiagonalType::Scalar>::value,
783
+ // FIXME currently we need same types, but in the future the next rule should be the one
784
+ //_Vectorizable = bool(int(MatrixFlags)&PacketAccessBit) && ((!_PacketOnDiag) || (_SameTypes && bool(int(DiagFlags)&PacketAccessBit))),
785
+ _Vectorizable = bool(int(MatrixFlags)&PacketAccessBit) && _SameTypes && (_ScalarAccessOnDiag || (bool(int(DiagFlags)&PacketAccessBit))),
786
+ _LinearAccessMask = (MatrixType::RowsAtCompileTime==1 || MatrixType::ColsAtCompileTime==1) ? LinearAccessBit : 0,
787
+ Flags = ((HereditaryBits|_LinearAccessMask) & (unsigned int)(MatrixFlags)) | (_Vectorizable ? PacketAccessBit : 0),
788
+ Alignment = evaluator<MatrixType>::Alignment,
789
+
790
+ AsScalarProduct = (DiagonalType::SizeAtCompileTime==1)
791
+ || (DiagonalType::SizeAtCompileTime==Dynamic && MatrixType::RowsAtCompileTime==1 && ProductOrder==OnTheLeft)
792
+ || (DiagonalType::SizeAtCompileTime==Dynamic && MatrixType::ColsAtCompileTime==1 && ProductOrder==OnTheRight)
793
+ };
794
+
795
+ diagonal_product_evaluator_base(const MatrixType &mat, const DiagonalType &diag)
796
+ : m_diagImpl(diag), m_matImpl(mat)
797
+ {
798
+ EIGEN_INTERNAL_CHECK_COST_VALUE(NumTraits<Scalar>::MulCost);
799
+ EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
800
+ }
801
+
802
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(Index idx) const
803
+ {
804
+ if(AsScalarProduct)
805
+ return m_diagImpl.coeff(0) * m_matImpl.coeff(idx);
806
+ else
807
+ return m_diagImpl.coeff(idx) * m_matImpl.coeff(idx);
808
+ }
809
+
810
+ protected:
811
+ template<int LoadMode,typename PacketType>
812
+ EIGEN_STRONG_INLINE PacketType packet_impl(Index row, Index col, Index id, internal::true_type) const
813
+ {
814
+ return internal::pmul(m_matImpl.template packet<LoadMode,PacketType>(row, col),
815
+ internal::pset1<PacketType>(m_diagImpl.coeff(id)));
816
+ }
817
+
818
+ template<int LoadMode,typename PacketType>
819
+ EIGEN_STRONG_INLINE PacketType packet_impl(Index row, Index col, Index id, internal::false_type) const
820
+ {
821
+ enum {
822
+ InnerSize = (MatrixType::Flags & RowMajorBit) ? MatrixType::ColsAtCompileTime : MatrixType::RowsAtCompileTime,
823
+ DiagonalPacketLoadMode = EIGEN_PLAIN_ENUM_MIN(LoadMode,((InnerSize%16) == 0) ? int(Aligned16) : int(evaluator<DiagonalType>::Alignment)) // FIXME hardcoded 16!!
824
+ };
825
+ return internal::pmul(m_matImpl.template packet<LoadMode,PacketType>(row, col),
826
+ m_diagImpl.template packet<DiagonalPacketLoadMode,PacketType>(id));
827
+ }
828
+
829
+ evaluator<DiagonalType> m_diagImpl;
830
+ evaluator<MatrixType> m_matImpl;
831
+ };
832
+
833
+ // diagonal * dense
834
+ template<typename Lhs, typename Rhs, int ProductKind, int ProductTag>
835
+ struct product_evaluator<Product<Lhs, Rhs, ProductKind>, ProductTag, DiagonalShape, DenseShape>
836
+ : diagonal_product_evaluator_base<Rhs, typename Lhs::DiagonalVectorType, Product<Lhs, Rhs, LazyProduct>, OnTheLeft>
837
+ {
838
+ typedef diagonal_product_evaluator_base<Rhs, typename Lhs::DiagonalVectorType, Product<Lhs, Rhs, LazyProduct>, OnTheLeft> Base;
839
+ using Base::m_diagImpl;
840
+ using Base::m_matImpl;
841
+ using Base::coeff;
842
+ typedef typename Base::Scalar Scalar;
843
+
844
+ typedef Product<Lhs, Rhs, ProductKind> XprType;
845
+ typedef typename XprType::PlainObject PlainObject;
846
+
847
+ enum {
848
+ StorageOrder = int(Rhs::Flags) & RowMajorBit ? RowMajor : ColMajor
849
+ };
850
+
851
+ EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
852
+ : Base(xpr.rhs(), xpr.lhs().diagonal())
853
+ {
854
+ }
855
+
856
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const
857
+ {
858
+ return m_diagImpl.coeff(row) * m_matImpl.coeff(row, col);
859
+ }
860
+
861
+ #ifndef __CUDACC__
862
+ template<int LoadMode,typename PacketType>
863
+ EIGEN_STRONG_INLINE PacketType packet(Index row, Index col) const
864
+ {
865
+ // FIXME: NVCC used to complain about the template keyword, but we have to check whether this is still the case.
866
+ // See also similar calls below.
867
+ return this->template packet_impl<LoadMode,PacketType>(row,col, row,
868
+ typename internal::conditional<int(StorageOrder)==RowMajor, internal::true_type, internal::false_type>::type());
869
+ }
870
+
871
+ template<int LoadMode,typename PacketType>
872
+ EIGEN_STRONG_INLINE PacketType packet(Index idx) const
873
+ {
874
+ return packet<LoadMode,PacketType>(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx);
875
+ }
876
+ #endif
877
+ };
878
+
879
+ // dense * diagonal
880
+ template<typename Lhs, typename Rhs, int ProductKind, int ProductTag>
881
+ struct product_evaluator<Product<Lhs, Rhs, ProductKind>, ProductTag, DenseShape, DiagonalShape>
882
+ : diagonal_product_evaluator_base<Lhs, typename Rhs::DiagonalVectorType, Product<Lhs, Rhs, LazyProduct>, OnTheRight>
883
+ {
884
+ typedef diagonal_product_evaluator_base<Lhs, typename Rhs::DiagonalVectorType, Product<Lhs, Rhs, LazyProduct>, OnTheRight> Base;
885
+ using Base::m_diagImpl;
886
+ using Base::m_matImpl;
887
+ using Base::coeff;
888
+ typedef typename Base::Scalar Scalar;
889
+
890
+ typedef Product<Lhs, Rhs, ProductKind> XprType;
891
+ typedef typename XprType::PlainObject PlainObject;
892
+
893
+ enum { StorageOrder = int(Lhs::Flags) & RowMajorBit ? RowMajor : ColMajor };
894
+
895
+ EIGEN_DEVICE_FUNC explicit product_evaluator(const XprType& xpr)
896
+ : Base(xpr.lhs(), xpr.rhs().diagonal())
897
+ {
898
+ }
899
+
900
+ EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar coeff(Index row, Index col) const
901
+ {
902
+ return m_matImpl.coeff(row, col) * m_diagImpl.coeff(col);
903
+ }
904
+
905
+ #ifndef __CUDACC__
906
+ template<int LoadMode,typename PacketType>
907
+ EIGEN_STRONG_INLINE PacketType packet(Index row, Index col) const
908
+ {
909
+ return this->template packet_impl<LoadMode,PacketType>(row,col, col,
910
+ typename internal::conditional<int(StorageOrder)==ColMajor, internal::true_type, internal::false_type>::type());
911
+ }
912
+
913
+ template<int LoadMode,typename PacketType>
914
+ EIGEN_STRONG_INLINE PacketType packet(Index idx) const
915
+ {
916
+ return packet<LoadMode,PacketType>(int(StorageOrder)==ColMajor?idx:0,int(StorageOrder)==ColMajor?0:idx);
917
+ }
918
+ #endif
919
+ };
920
+
921
+ /***************************************************************************
922
+ * Products with permutation matrices
923
+ ***************************************************************************/
924
+
925
+ /** \internal
926
+ * \class permutation_matrix_product
927
+ * Internal helper class implementing the product between a permutation matrix and a matrix.
928
+ * This class is specialized for DenseShape below and for SparseShape in SparseCore/SparsePermutation.h
929
+ */
930
+ template<typename ExpressionType, int Side, bool Transposed, typename ExpressionShape>
931
+ struct permutation_matrix_product;
932
+
933
+ template<typename ExpressionType, int Side, bool Transposed>
934
+ struct permutation_matrix_product<ExpressionType, Side, Transposed, DenseShape>
935
+ {
936
+ typedef typename nested_eval<ExpressionType, 1>::type MatrixType;
937
+ typedef typename remove_all<MatrixType>::type MatrixTypeCleaned;
938
+
939
+ template<typename Dest, typename PermutationType>
940
+ static inline void run(Dest& dst, const PermutationType& perm, const ExpressionType& xpr)
941
+ {
942
+ MatrixType mat(xpr);
943
+ const Index n = Side==OnTheLeft ? mat.rows() : mat.cols();
944
+ // FIXME we need an is_same for expression that is not sensitive to constness. For instance
945
+ // is_same_xpr<Block<const Matrix>, Block<Matrix> >::value should be true.
946
+ //if(is_same<MatrixTypeCleaned,Dest>::value && extract_data(dst) == extract_data(mat))
947
+ if(is_same_dense(dst, mat))
948
+ {
949
+ // apply the permutation inplace
950
+ Matrix<bool,PermutationType::RowsAtCompileTime,1,0,PermutationType::MaxRowsAtCompileTime> mask(perm.size());
951
+ mask.fill(false);
952
+ Index r = 0;
953
+ while(r < perm.size())
954
+ {
955
+ // search for the next seed
956
+ while(r<perm.size() && mask[r]) r++;
957
+ if(r>=perm.size())
958
+ break;
959
+ // we got one, let's follow it until we are back to the seed
960
+ Index k0 = r++;
961
+ Index kPrev = k0;
962
+ mask.coeffRef(k0) = true;
963
+ for(Index k=perm.indices().coeff(k0); k!=k0; k=perm.indices().coeff(k))
964
+ {
965
+ Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>(dst, k)
966
+ .swap(Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
967
+ (dst,((Side==OnTheLeft) ^ Transposed) ? k0 : kPrev));
968
+
969
+ mask.coeffRef(k) = true;
970
+ kPrev = k;
971
+ }
972
+ }
973
+ }
974
+ else
975
+ {
976
+ for(Index i = 0; i < n; ++i)
977
+ {
978
+ Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
979
+ (dst, ((Side==OnTheLeft) ^ Transposed) ? perm.indices().coeff(i) : i)
980
+
981
+ =
982
+
983
+ Block<const MatrixTypeCleaned,Side==OnTheLeft ? 1 : MatrixTypeCleaned::RowsAtCompileTime,Side==OnTheRight ? 1 : MatrixTypeCleaned::ColsAtCompileTime>
984
+ (mat, ((Side==OnTheRight) ^ Transposed) ? perm.indices().coeff(i) : i);
985
+ }
986
+ }
987
+ }
988
+ };
989
+
990
+ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
991
+ struct generic_product_impl<Lhs, Rhs, PermutationShape, MatrixShape, ProductTag>
992
+ {
993
+ template<typename Dest>
994
+ static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
995
+ {
996
+ permutation_matrix_product<Rhs, OnTheLeft, false, MatrixShape>::run(dst, lhs, rhs);
997
+ }
998
+ };
999
+
1000
+ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
1001
+ struct generic_product_impl<Lhs, Rhs, MatrixShape, PermutationShape, ProductTag>
1002
+ {
1003
+ template<typename Dest>
1004
+ static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
1005
+ {
1006
+ permutation_matrix_product<Lhs, OnTheRight, false, MatrixShape>::run(dst, rhs, lhs);
1007
+ }
1008
+ };
1009
+
1010
+ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
1011
+ struct generic_product_impl<Inverse<Lhs>, Rhs, PermutationShape, MatrixShape, ProductTag>
1012
+ {
1013
+ template<typename Dest>
1014
+ static void evalTo(Dest& dst, const Inverse<Lhs>& lhs, const Rhs& rhs)
1015
+ {
1016
+ permutation_matrix_product<Rhs, OnTheLeft, true, MatrixShape>::run(dst, lhs.nestedExpression(), rhs);
1017
+ }
1018
+ };
1019
+
1020
+ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
1021
+ struct generic_product_impl<Lhs, Inverse<Rhs>, MatrixShape, PermutationShape, ProductTag>
1022
+ {
1023
+ template<typename Dest>
1024
+ static void evalTo(Dest& dst, const Lhs& lhs, const Inverse<Rhs>& rhs)
1025
+ {
1026
+ permutation_matrix_product<Lhs, OnTheRight, true, MatrixShape>::run(dst, rhs.nestedExpression(), lhs);
1027
+ }
1028
+ };
1029
+
1030
+
1031
+ /***************************************************************************
1032
+ * Products with transpositions matrices
1033
+ ***************************************************************************/
1034
+
1035
+ // FIXME could we unify Transpositions and Permutation into a single "shape"??
1036
+
1037
+ /** \internal
1038
+ * \class transposition_matrix_product
1039
+ * Internal helper class implementing the product between a permutation matrix and a matrix.
1040
+ */
1041
+ template<typename ExpressionType, int Side, bool Transposed, typename ExpressionShape>
1042
+ struct transposition_matrix_product
1043
+ {
1044
+ typedef typename nested_eval<ExpressionType, 1>::type MatrixType;
1045
+ typedef typename remove_all<MatrixType>::type MatrixTypeCleaned;
1046
+
1047
+ template<typename Dest, typename TranspositionType>
1048
+ static inline void run(Dest& dst, const TranspositionType& tr, const ExpressionType& xpr)
1049
+ {
1050
+ MatrixType mat(xpr);
1051
+ typedef typename TranspositionType::StorageIndex StorageIndex;
1052
+ const Index size = tr.size();
1053
+ StorageIndex j = 0;
1054
+
1055
+ if(!is_same_dense(dst,mat))
1056
+ dst = mat;
1057
+
1058
+ for(Index k=(Transposed?size-1:0) ; Transposed?k>=0:k<size ; Transposed?--k:++k)
1059
+ if(Index(j=tr.coeff(k))!=k)
1060
+ {
1061
+ if(Side==OnTheLeft) dst.row(k).swap(dst.row(j));
1062
+ else if(Side==OnTheRight) dst.col(k).swap(dst.col(j));
1063
+ }
1064
+ }
1065
+ };
1066
+
1067
+ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
1068
+ struct generic_product_impl<Lhs, Rhs, TranspositionsShape, MatrixShape, ProductTag>
1069
+ {
1070
+ template<typename Dest>
1071
+ static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
1072
+ {
1073
+ transposition_matrix_product<Rhs, OnTheLeft, false, MatrixShape>::run(dst, lhs, rhs);
1074
+ }
1075
+ };
1076
+
1077
+ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
1078
+ struct generic_product_impl<Lhs, Rhs, MatrixShape, TranspositionsShape, ProductTag>
1079
+ {
1080
+ template<typename Dest>
1081
+ static void evalTo(Dest& dst, const Lhs& lhs, const Rhs& rhs)
1082
+ {
1083
+ transposition_matrix_product<Lhs, OnTheRight, false, MatrixShape>::run(dst, rhs, lhs);
1084
+ }
1085
+ };
1086
+
1087
+
1088
+ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
1089
+ struct generic_product_impl<Transpose<Lhs>, Rhs, TranspositionsShape, MatrixShape, ProductTag>
1090
+ {
1091
+ template<typename Dest>
1092
+ static void evalTo(Dest& dst, const Transpose<Lhs>& lhs, const Rhs& rhs)
1093
+ {
1094
+ transposition_matrix_product<Rhs, OnTheLeft, true, MatrixShape>::run(dst, lhs.nestedExpression(), rhs);
1095
+ }
1096
+ };
1097
+
1098
+ template<typename Lhs, typename Rhs, int ProductTag, typename MatrixShape>
1099
+ struct generic_product_impl<Lhs, Transpose<Rhs>, MatrixShape, TranspositionsShape, ProductTag>
1100
+ {
1101
+ template<typename Dest>
1102
+ static void evalTo(Dest& dst, const Lhs& lhs, const Transpose<Rhs>& rhs)
1103
+ {
1104
+ transposition_matrix_product<Lhs, OnTheRight, true, MatrixShape>::run(dst, rhs.nestedExpression(), lhs);
1105
+ }
1106
+ };
1107
+
1108
+ } // end namespace internal
1109
+
1110
+ } // end namespace Eigen
1111
+
1112
+ #endif // EIGEN_PRODUCT_EVALUATORS_H