35 template<
class Matrix,
class Permutation>
36 static auto decompose(Matrix&&
A, Permutation&& P,
double tol = std::numeric_limits<double>::epsilon()){
40 assert( P.size() >=
N );
42 auto&& ret =
A({0,
N}, {0,
N});
43 for(
auto i : extension(ret)){
46 for(
auto&& row :
A({i + 1,
N})){
47 auto&& urow = row({i + 1,
N});
49 cbegin(urow), cend(urow), cbegin(
A[i]({i + 1,
N})), begin(urow),
50 [f = row[i] /=
A[i][i]](
auto const& a,
auto const& b){
return a - f*b;}
54 return A({0,
N}, {0,
N});
57 template<
class Matrix,
class Permutation,
class VectorSol>
58 static auto solve(Matrix
const& LU, Permutation
const& P, VectorSol&& x) -> VectorSol&&{
64 template<
class Matrix,
class Permutation,
class Index>
66 auto mi = std::max_element(begin(LU) + i, end(LU), [i](
auto const& a,
auto const& b){
return std::abs(a[i]) <
std::abs(b[i]);}) - begin(LU);
68 std::swap(P [i], P [mi]);
72 template<
class Permutation,
class Vector>
73 static auto permute(Permutation
const& p, Vector&& data) -> Vector&&{
74 assert(size(p) <= size(data));
75 using index =
typename Permutation::size_type;
76 for(index i = 0; i != size(p); ++i){
78 for( ; k > i; k = p[k]){}
80 if(k >=i and pk != i){
81 auto const t = data[i];
82 for( ; pk != i; k = pk, pk = p[k]){
88 return std::forward<Vector>(data);
91 template<
class LUMatrix,
class Vector>
92 static auto lower_solve(LUMatrix
const& LU, Vector&& x) -> Vector&&{
93 assert(size(LU) <= size(x));
94 auto const N = size(LU);
95 for(
typename LUMatrix::size_type i = 0; i !=
N; ++i){
96 auto const& Lrowi = LU[i]({0, i});
97 x[i] -= std::inner_product(begin(Lrowi), end(Lrowi), cbegin(x), 0.);
99 return std::forward<Vector>(x);
102 template<
class LUMatrix,
class Vector>
103 static auto upper_solve(LUMatrix
const& LU, Vector&& x) -> Vector&&{
104 assert(size(LU) <= size(x));
105 auto const N = size(LU);
106 for(
typename LUMatrix::size_type i =
N - 1; i >= 0; --i){
107 auto const& Urowi = LU[i]({i + 1,
N});
108 (x[i] -= std::inner_product(begin(Urowi), end(Urowi), cbegin(x) + i + 1, 0.)) /= LU[i][i];
110 return std::forward<Vector>(x);
118 Array<std::complex<double>, 2>& U,
120 Array<std::complex<double>, 2>& V);
128 Array<std::complex<double>, 2>& Vectors);
143 const Array<std::complex<double>, 2>&
B,
144 Array<std::complex<double>, 2>&
C);
171 for (
int i = 0; i <
m; i++)
172 for (
int j = 0; j <
n; j++)
173 Atrans(j, i) =
A(i, j);
183 for (
int i = 0; i <
m; i++)
184 for (
int j = 0; j <
n; j++)
185 Atrans(j, i) =
A(i, j);
198 for (
int i = 0; i <
m; i++)
199 for (
int j = i + 1; j <
m; j++)
200 std::swap(
A(i, j),
A(j, i));
212 for (
int i = 0; i <
m; i++)
213 for (
int j = i + 1; j <
m; j++)
214 std::swap(
A(i, j),
A(j, i));
221 fprintf(stderr,
"%14.6e %14.6e %14.6e\n",
A(0, 0),
A(0, 1),
A(0, 2));
222 fprintf(stderr,
"%14.6e %14.6e %14.6e\n",
A(1, 0),
A(1, 1),
A(1, 2));
223 fprintf(stderr,
"%14.6e %14.6e %14.6e\n",
A(2, 0),
A(2, 1),
A(2, 2));
226 inline void CubicFormula(
double a,
double b,
double c,
double d,
double& x1,
double& x2,
double& x3)
231 double Q = (
A *
A - 3.0 *
B) / 9.0;
232 double R = (2.0 *
A *
A *
A - 9.0 *
A *
B + 27.0 *
C) / 54.0;
234 if ((R * R) < (Q * Q * Q))
236 double theta =
acos(R /
sqrt(Q * Q * Q));
237 double twosqrtQ = 2.0 *
sqrt(Q);
238 double third = 1.0 / 3.0;
239 double thirdA = third *
A;
240 x1 = -twosqrtQ *
cos(third * theta) - thirdA;
241 x2 = -twosqrtQ *
cos(third * (theta + 2.0 * M_PI)) - thirdA;
242 x3 = -twosqrtQ *
cos(third * (theta - 2.0 * M_PI)) - thirdA;
246 std::cerr <<
"Complex roots detected in CubicFormula.\n";
258 double b = -(x1 + x2 + x3);
259 double c = (x1 * x2 + x1 * x3 + x2 * x3);
260 double d = -x1 * x2 * x3;
264 std::cerr <<
"y1 = " << y1 <<
"\n";
265 std::cerr <<
"y2 = " << y2 <<
"\n";
266 std::cerr <<
"y3 = " << y3 <<
"\n";
270 inline void EigVals(
const Mat3& M,
double& lambda1,
double& lambda2,
double& lambda3)
273 double b = M(0, 0) + M(1, 1) + M(2, 2);
274 double c = (-M(0, 0) * M(1, 1) - M(0, 0) * M(2, 2) - M(1, 1) * M(2, 2) + M(0, 1) * M(1, 0) + M(0, 2) * M(2, 0) +
276 double d = (M(0, 0) * M(1, 1) * M(2, 2) + M(0, 1) * M(1, 2) * M(2, 0) + M(0, 2) * M(1, 0) * M(2, 1) -
277 M(0, 1) * M(1, 0) * M(2, 2) - M(0, 2) * M(1, 1) * M(2, 0) - M(0, 0) * M(1, 2) * M(2, 1));
284 EigVals(M, Lambda(0), Lambda(1), Lambda(2));
285 for (
int i = 0; i < 3; i++)
287 double L = Lambda(i);
289 U(1, i) = (M(1, 2) / M(0, 2) * (M(0, 0) - L) - M(1, 0)) / (M(1, 1) - M(1, 2) / M(0, 2) * M(0, 1) - L);
290 U(2, i) = ((L - M(1, 1)) * U(1, i) - M(1, 0)) / M(1, 2);
291 double norm = 1.0 /
sqrt(U(0, i) * U(0, i) + U(1, i) * U(1, i) + U(2, i) * U(2, i));
299 inline double det(
const Mat2&
C) {
return (
C(0, 0) *
C(1, 1) -
C(0, 1) *
C(1, 0)); }
365 L(0, 0) =
sqrt(
C(0, 0));
366 L00Inv = 1.0 / L(0, 0);
367 L(1, 0) =
C(1, 0) * L00Inv;
368 L(2, 0) =
C(2, 0) * L00Inv;
369 L(1, 1) =
sqrt(
C(1, 1) - L(1, 0) * L(1, 0));
370 L(2, 1) = (
C(2, 1) - L(2, 0) * L(1, 0)) / L(1, 1);
371 L(2, 2) =
sqrt(
C(2, 2) - (L(2, 0) * L(2, 0) + L(2, 1) * L(2, 1)));
400 std::cerr <<
"C = " <<
C <<
"\n";
401 std::cerr <<
"V = " << V <<
"\n";
403 std::cerr <<
"L = " << L <<
"\n";
404 std::cerr <<
"L L^T = " << L *
Transpose(L) <<
"\n";
408 for (
int i = 0; i < 10000000; i++)
double GJInverse(Array< double, 2 > &A)
void LinearLeastSquares(Array< double, 2 > &A, Array< double, 1 > &x, Array< double, 1 > &b)
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
void Print(const Mat3 &A)
void SymmEigenPairs(const Array< double, 2 > &A, int NumPairs, Array< double, 1 > &Vals, Array< double, 2 > &Vectors)
double GJInversePartial(Array< double, 2 > &A)
static auto lower_solve(LUMatrix const &LU, Vector &&x) -> Vector &&
std::complex< double > ComplexDetCofactors(Array< std::complex< double >, 2 > &A, Array< std::complex< double >, 1 > &work)
Complex versions of the functions above.
void MatVecProd(Array< double, 2 > &A, Array< double, 1 > &x, Array< double, 1 > &Ax)
static auto permute_max_diagonal(Matrix &&LU, Permutation &&P, Index i)
static auto solve(Matrix const &LU, Permutation const &P, VectorSol &&x) -> VectorSol &&
void PolarOrthogonalize(Array< std::complex< double >, 2 > &A)
void MatMult(const Array< double, 2 > &A, const Array< double, 2 > &B, Array< double, 2 > &C)
double DetCofactors(Array< double, 2 > &A, Array< double, 1 > &work)
This function returns the determinant of A and replaces A with its cofactors.
void OuterProduct(const Array< double, 1 > &A, const Array< double, 1 > &B, Array< double, 2 > &AB)
void CholeskyBig(Array< double, 2 > &A)
MakeReturn< UnaryNode< FnCos, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t cos(const Vector< T1, C1 > &l)
double norm(const zVec &c)
MakeReturn< UnaryNode< FnArcCos, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t acos(const Vector< T1, C1 > &l)
int ComplexDetCofactorsWorksize(int N)
Array< double, 2 > Inverse(Array< double, 2 > &A)
const Array< double, 2 > operator*(const Array< double, 2 > &A, const Array< double, 2 > &B)
void Eig(const Mat3 &M, Mat3 &U, Vec3 &Lambda)
void Transpose(Array< double, 2 > &A)
void CubicFormula(double a, double b, double c, double d, double &x1, double &x2, double &x3)
static auto permute(Permutation const &p, Vector &&data) -> Vector &&
MakeReturn< UnaryNode< FnSqrt, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t sqrt(const Vector< T1, C1 > &l)
void EigVals(const Mat3 &M, double &lambda1, double &lambda2, double &lambda3)
double B(double x, int k, int i, const std::vector< double > &t)
double Determinant(const Array< double, 2 > &A)
void SVdecomp(Array< double, 2 > &A, Array< double, 2 > &U, Array< double, 1 > &S, Array< double, 2 > &V)
double InnerProduct(const Array< double, 1 > &A, const Array< double, 1 > &B)
static auto upper_solve(LUMatrix const &LU, Vector &&x) -> Vector &&
QMCTraits::FullPrecRealType value_type
void OutOfPlaceTranspose(Array< double, 2 > &A)
int DetCofactorsWorksize(int N)
This function returns the worksize needed by the previous function.
static auto decompose(Matrix &&A, Permutation &&P, double tol=std::numeric_limits< double >::epsilon())
double det(const Mat2 &C)