You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

88 lines
3.1 KiB

  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra.
  3. //
  4. // Copyright (C) 2012 Chen-Pang He <jdh8@ms63.hinet.net>
  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. #ifndef STORMEIGEN_PACKED_TRIANGULAR_SOLVER_VECTOR_H
  10. #define STORMEIGEN_PACKED_TRIANGULAR_SOLVER_VECTOR_H
  11. namespace internal {
  12. template<typename LhsScalar, typename RhsScalar, typename Index, int Side, int Mode, bool Conjugate, int StorageOrder>
  13. struct packed_triangular_solve_vector;
  14. // forward and backward substitution, row-major, rhs is a vector
  15. template<typename LhsScalar, typename RhsScalar, typename Index, int Mode, bool Conjugate>
  16. struct packed_triangular_solve_vector<LhsScalar, RhsScalar, Index, OnTheLeft, Mode, Conjugate, RowMajor>
  17. {
  18. enum {
  19. IsLower = (Mode&Lower)==Lower
  20. };
  21. static void run(Index size, const LhsScalar* lhs, RhsScalar* rhs)
  22. {
  23. internal::conj_if<Conjugate> cj;
  24. typedef Map<const Matrix<LhsScalar,Dynamic,1> > LhsMap;
  25. typedef typename conj_expr_if<Conjugate,LhsMap>::type ConjLhsType;
  26. lhs += IsLower ? 0 : (size*(size+1)>>1)-1;
  27. for(Index pi=0; pi<size; ++pi)
  28. {
  29. Index i = IsLower ? pi : size-pi-1;
  30. Index s = IsLower ? 0 : 1;
  31. if (pi>0)
  32. rhs[i] -= (ConjLhsType(LhsMap(lhs+s,pi))
  33. .cwiseProduct(Map<const Matrix<RhsScalar,Dynamic,1> >(rhs+(IsLower ? 0 : i+1),pi))).sum();
  34. if (!(Mode & UnitDiag))
  35. rhs[i] /= cj(lhs[IsLower ? i : 0]);
  36. IsLower ? lhs += pi+1 : lhs -= pi+2;
  37. }
  38. }
  39. };
  40. // forward and backward substitution, column-major, rhs is a vector
  41. template<typename LhsScalar, typename RhsScalar, typename Index, int Mode, bool Conjugate>
  42. struct packed_triangular_solve_vector<LhsScalar, RhsScalar, Index, OnTheLeft, Mode, Conjugate, ColMajor>
  43. {
  44. enum {
  45. IsLower = (Mode&Lower)==Lower
  46. };
  47. static void run(Index size, const LhsScalar* lhs, RhsScalar* rhs)
  48. {
  49. internal::conj_if<Conjugate> cj;
  50. typedef Map<const Matrix<LhsScalar,Dynamic,1> > LhsMap;
  51. typedef typename conj_expr_if<Conjugate,LhsMap>::type ConjLhsType;
  52. lhs += IsLower ? 0 : size*(size-1)>>1;
  53. for(Index pi=0; pi<size; ++pi)
  54. {
  55. Index i = IsLower ? pi : size-pi-1;
  56. Index r = size - pi - 1;
  57. if (!(Mode & UnitDiag))
  58. rhs[i] /= cj(lhs[IsLower ? 0 : i]);
  59. if (r>0)
  60. Map<Matrix<RhsScalar,Dynamic,1> >(rhs+(IsLower? i+1 : 0),r) -=
  61. rhs[i] * ConjLhsType(LhsMap(lhs+(IsLower? 1 : 0),r));
  62. IsLower ? lhs += size-pi : lhs -= r;
  63. }
  64. }
  65. };
  66. template<typename LhsScalar, typename RhsScalar, typename Index, int Mode, bool Conjugate, int StorageOrder>
  67. struct packed_triangular_solve_vector<LhsScalar, RhsScalar, Index, OnTheRight, Mode, Conjugate, StorageOrder>
  68. {
  69. static void run(Index size, const LhsScalar* lhs, RhsScalar* rhs)
  70. {
  71. packed_triangular_solve_vector<LhsScalar,RhsScalar,Index,OnTheLeft,
  72. ((Mode&Upper)==Upper ? Lower : Upper) | (Mode&UnitDiag),
  73. Conjugate,StorageOrder==RowMajor?ColMajor:RowMajor
  74. >::run(size, lhs, rhs);
  75. }
  76. };
  77. } // end namespace internal
  78. #endif // STORMEIGEN_PACKED_TRIANGULAR_SOLVER_VECTOR_H