34 #include <tests/myratest.h> 40 template<
class Precision>
void test(
int I,
int J, Precision tolerance)
42 typedef std::complex<Precision> Number;
43 myra::out() << typestring<Number>() << std::endl;
46 auto A = G + transpose(G);
56 solver.solve(B,
'L',
'N');
57 Precision error = frobenius(B-X)/frobenius(X);
58 myra::out() <<
" |inv(A)*B-X| = " << error << std::endl;
59 REQUIRE(error < tolerance);
64 auto B = transpose(A)*X;
65 solver.solve(B,
'L',
'T');
66 Precision error = frobenius(B-X)/frobenius(X);
67 myra::out() <<
" |inv(A^T)*B-X| = " << error << std::endl;
68 REQUIRE(error < tolerance);
73 auto B = hermitian(A)*X;
74 solver.solve(B,
'L',
'H');
75 Precision error = frobenius(B-X)/frobenius(X);
76 myra::out() <<
" |inv(A^H)*B-X| = " << error << std::endl;
77 REQUIRE(error < tolerance);
82 auto B = conjugate(A)*X;
83 solver.solve(B,
'L',
'C');
84 Precision error = frobenius(B-X)/frobenius(X);
85 myra::out() <<
" |inv(A^C)*B-X| = " << error << std::endl;
86 REQUIRE(error < tolerance);
92 solver.solve(B,
'R',
'N');
93 Precision error = frobenius(B-X)/frobenius(X);
94 myra::out() <<
" |B*inv(A)-X| = " << error << std::endl;
95 REQUIRE(error < tolerance);
100 auto B = X*transpose(A);
101 solver.solve(B,
'R',
'T');
102 Precision error = frobenius(B-X)/frobenius(X);
103 myra::out() <<
" |B*inv(A^T)-X| = " << error << std::endl;
104 REQUIRE(error < tolerance);
109 auto B = X*hermitian(A);
110 solver.solve(B,
'R',
'H');
111 Precision error = frobenius(B-X)/frobenius(X);
112 myra::out() <<
" |B*inv(A^H)-X| = " << error << std::endl;
113 REQUIRE(error < tolerance);
118 auto B = X*conjugate(A);
119 solver.solve(B,
'R',
'C');
120 Precision error = frobenius(B-X)/frobenius(X);
121 myra::out() <<
" |B*inv(A^C)-X| = " << error << std::endl;
122 REQUIRE(error < tolerance);
134 int n_plus = solver.inertia().first;
135 int n_minus = solver.inertia().second;
137 solver.solveL(B,
'L',
'N');
138 syrk_inplace(S2,B.
top(n_plus),
'T',one,one);
139 syrk_inplace(S2,B.
bottom(n_minus),
'T',-one,one);
141 Precision error = frobenius(S1-S2) / frobenius(S1);
142 myra::out() <<
" |B'*inv(A)*B - (L\\B)'*(L\\B)| = " << error << std::endl;
143 REQUIRE(error < tolerance);
156 int n_plus = solver.inertia().first;
157 int n_minus = solver.inertia().second;
159 solver.solveL(B,
'L',
'N');
160 solver.solveL(C,
'L',
'N');
161 gemm_inplace(S2,C.
top(n_plus),
'T',B.top(n_plus),
'N',one,one);
162 gemm_inplace(S2,C.
bottom(n_minus),
'T',B.bottom(n_minus),
'N',-one,one);
164 Precision error = frobenius(S1-S2) / frobenius(S1);
165 myra::out() <<
" |C'*inv(A)*B - (L\\C)'*(L\\B)| = " << error << std::endl;
166 REQUIRE(error < tolerance);
175 saved.solve(B,
'L',
'N');
176 Precision error = frobenius(B-X)/frobenius(X);
177 myra::out() <<
" |inv(A)*B-X| (saved)= " << error << std::endl;
178 REQUIRE(error < tolerance);
182 template<
class Precision>
void test3(Precision tolerance)
184 typedef std::complex<Precision> Number;
185 myra::out() << typestring<Number>() << std::endl;
190 Precision pi = std::acos(-one);
191 Precision phase = two*pi*random<Precision>();
192 Number phasor(std::cos(phase),std::sin(phase));
203 solver.solve(B,
'L',
'N');
204 Precision error = frobenius(B-X)/frobenius(X);
205 myra::out() <<
" |inv(A)*B-X| = " << error << std::endl;
206 REQUIRE(error < tolerance);
211 ADD_TEST(
"cLDLTSolver",
"[dense][solver]")
212 { test<float>(43,14,1.0e-3f); }
214 ADD_TEST(
"zLDLTSolver",
"[dense][solver]")
215 { test<double>(82,45,1.0e-10); }
217 ADD_TEST(
"cLDLTSolver3",
"[dense][solver]")
218 { test3<float>(1.0e-3f); }
220 ADD_TEST(
"zLDLTSolver3",
"[dense][solver]")
221 { test3<double>(1.0e-10); }
Returns a conjugated copy of a Matrix or Vector. Or, conjugate one inplace.
Factors A = L*D*Lt, where D is a "sign matrix" of the form [I 0; 0 -I]. Presents solve methods...
Definition: ZLDLTSolver.h:30
Tabulates an IxJ matrix. Allows random access, has column major layout to be compatible with BLAS/LAP...
Definition: bdsqr.h:20
static Matrix< Number > zeros(int I, int J)
Generates a zeros Matrix of specified size.
Definition: Matrix.cpp:357
Routines for computing Frobenius norms of various algebraic containers.
static Matrix< Number > random(int I, int J)
Generates a random Matrix of specified size.
Definition: Matrix.cpp:353
CMatrixRange< Number > bottom(int i) const
Returns a MatrixRange over the i bottommost rows, this(I-i:I,:)
Definition: Matrix.cpp:225
Wraps a std::vector<char>, presents it as both an InputStream and OutputStream. Useful for hygienic u...
Definition: VectorStream.h:22
Range construct for a lower triangular matrix stored in rectangular packed format.
Specialized container for a lower triangular matrix, O(N^2/2) storage. Used by symmetry exploiting ma...
Returns a transposed copy of a Matrix. The inplace version only works on a square operand...
Various utility functions/classes related to scalar Number types.
A solver suitable for a complex symmetric Matrix (indefinite is fine). Encapsulates sytrf() ...
A stream that serialize/deserializes to std::vector<char> buffer.
General purpose dense matrix container, O(i*j) storage.
Overwrites a LowerMatrix, DiagonalMatrix, or square Matrix with its own inverse. Or, returns it as a copy.
Returns a hermitian copy of a Matrix. The inplace version only works on a square operand.
Simplistic random number functions.
Stores a lower triangular matrix in rectangular packed format.
Definition: conjugate.h:22
Routines for symmetric rank-k updates, a specialized form of Matrix*Matrix multiplication.
Variety of routines all for dense Matrix*Matrix multiplies. Delegates to the BLAS.
CMatrixRange< Number > top(int i) const
Returns a MatrixRange over the i topmost rows, this(0:i,:)
Definition: Matrix.cpp:207
std::complex<float>
|inv(A)*B-X| = 1.07733e-05
|inv(A^T)*B-X| = 1.40538e-05
|inv(A^H)*B-X| = 1.10574e-05
|inv(A^C)*B-X| = 1.15433e-05
|B*inv(A)-X| = 1.14482e-05
|B*inv(A^T)-X| = 1.20242e-05
|B*inv(A^H)-X| = 1.19082e-05
|B*inv(A^C)-X| = 1.24889e-05
|B'*inv(A)*B - (L\B)'*(L\B)| = 1.22627e-05
|C'*inv(A)*B - (L\C)'*(L\B)| = 1.20489e-05
|inv(A)*B-X| (saved)= 1.15767e-05