35 #include <tests/myratest.h> 42 template<
class Precision>
void test(
int I,
int J, Precision tolerance)
44 typedef std::complex<Precision> Number;
45 myra::out() << typestring<Number>() << std::endl;
48 auto A = G + hermitian(G);
59 solver.solve(B,
'L',
'N');
60 Precision error = frobenius(B-X)/frobenius(X);
61 myra::out() <<
" |inv(A)*B-X| = " << error << std::endl;
62 REQUIRE(error < tolerance);
67 auto B = transpose(A)*X;
68 solver.solve(B,
'L',
'T');
69 Precision error = frobenius(B-X)/frobenius(X);
70 myra::out() <<
" |inv(A^T)*B-X| = " << error << std::endl;
71 REQUIRE(error < tolerance);
76 auto B = hermitian(A)*X;
77 solver.solve(B,
'L',
'H');
78 Precision error = frobenius(B-X)/frobenius(X);
79 myra::out() <<
" |inv(A^H)*B-X| = " << error << std::endl;
80 REQUIRE(error < tolerance);
85 auto B = conjugate(A)*X;
86 solver.solve(B,
'L',
'C');
87 Precision error = frobenius(B-X)/frobenius(X);
88 myra::out() <<
" |inv(A^C)*B-X| = " << error << std::endl;
89 REQUIRE(error < tolerance);
96 solver.solve(B,
'R',
'N');
97 Precision error = frobenius(B-X)/frobenius(X);
98 myra::out() <<
" |B*inv(A)-X| = " << error << std::endl;
99 REQUIRE(error < tolerance);
104 auto B = X*transpose(A);
105 solver.solve(B,
'R',
'T');
106 Precision error = frobenius(B-X)/frobenius(X);
107 myra::out() <<
" |B*inv(A^T)-X| = " << error << std::endl;
108 REQUIRE(error < tolerance);
113 auto B = X*hermitian(A);
114 solver.solve(B,
'R',
'H');
115 Precision error = frobenius(B-X)/frobenius(X);
116 myra::out() <<
" |B*inv(A^H)-X| = " << error << std::endl;
117 REQUIRE(error < tolerance);
122 auto B = X*conjugate(A);
123 solver.solve(B,
'R',
'C');
124 Precision error = frobenius(B-X)/frobenius(X);
125 myra::out() <<
" |B*inv(A^C)-X| = " << error << std::endl;
126 REQUIRE(error < tolerance);
138 int n_plus = solver.inertia().first;
139 int n_minus = solver.inertia().second;
141 solver.solveL(B,
'L',
'N');
142 herk_inplace(S2,B.
top(n_plus),
'H',one,one);
143 herk_inplace(S2,B.
bottom(n_minus),
'H',-one,one);
145 Precision error = frobenius(S1-S2) / frobenius(S1);
146 myra::out() <<
" |B'*inv(A)*B - (L\\B)'*I*(L\\B)| = " << error << std::endl;
147 REQUIRE(error < tolerance);
160 int n_plus = solver.inertia().first;
161 int n_minus = solver.inertia().second;
163 solver.solveL(B,
'L',
'N');
164 solver.solveL(C,
'L',
'N');
165 gemm_inplace(S2,C.
top(n_plus),
'H',B.top(n_plus),
'N',one,one);
166 gemm_inplace(S2,C.
bottom(n_minus),
'H',B.bottom(n_minus),
'N',-one,one);
168 Precision error = frobenius(S1-S2) / frobenius(S1);
169 myra::out() <<
" |C'*inv(A)*B - (L\\C)'*I*(L\\B)| = " << error << std::endl;
170 REQUIRE(error < tolerance);
179 saved.solve(B,
'L',
'N');
180 Precision error = frobenius(B-X)/frobenius(X);
181 myra::out() <<
" |inv(A)*B-X| (saved) = " << error << std::endl;
182 REQUIRE(error < tolerance);
186 template<
class Precision>
void test3(Precision tolerance)
188 typedef std::complex<Precision> Number;
189 myra::out() << typestring<Number>() << std::endl;
194 Precision pi = std::acos(-one);
195 Precision phase = two*pi*random<Precision>();
196 Number phasor(std::cos(phase),std::sin(phase));
198 A(0,1) = conjugate(phasor);
207 solver.solve(B,
'L',
'N');
208 Precision error = frobenius(B-X)/frobenius(X);
209 myra::out() <<
" |inv(A)*B-X| = " << error << std::endl;
210 REQUIRE(error < tolerance);
215 ADD_TEST(
"cLDLHSolver",
"[dense][solver]")
216 { test<float>(43,14,1.0e-3f); }
218 ADD_TEST(
"zLDLHSolver",
"[dense][solver]")
219 { test<double>(82,45,1.0e-10); }
221 ADD_TEST(
"cLDLHSolver3",
"[dense][solver]")
222 { test3<float>(1.0e-3f); }
224 ADD_TEST(
"zLDLHSolver3",
"[dense][solver]")
225 { test3<double>(1.0e-10); }
Returns a conjugated copy of a Matrix or Vector. Or, conjugate one inplace.
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 hermitian rank-k updates, a specialized form of Matrix*Matrix multiplication.
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.
Factors A = L*D*Lh, where D is a "sign matrix" of the form [I 0; 0 -I]. Presents solve methods...
Definition: ZLDLHSolver.h:30
A stream that serialize/deserializes to std::vector<char> buffer.
General purpose dense matrix container, O(i*j) storage.
Routines for computing singular value decompositions.
Overwrites a LowerMatrix, DiagonalMatrix, or square Matrix with its own inverse. Or, returns it as a copy.
A solver suitable for a complex hermitian Matrix (indefinite is fine). Encapsulates hetrf() ...
Returns a hermitian copy of a Matrix. The inplace version only works on a square operand.
Simplistic random number functions.
Streams that serialize/deserialize to/from files.
Stores a lower triangular matrix in rectangular packed format.
Definition: conjugate.h:22
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<double>
|inv(A)*B-X| = 4.05524e-13
|inv(A^T)*B-X| = 4.14987e-13
|inv(A^H)*B-X| = 4.31034e-13
|inv(A^C)*B-X| = 4.68652e-13
|B*inv(A)-X| = 3.55262e-13
|B*inv(A^T)-X| = 4.06983e-13
|B*inv(A^H)-X| = 4.0139e-13
|B*inv(A^C)-X| = 4.33901e-13
|B'*inv(A)*B - (L\B)'*I*(L\B)| = 5.47594e-13
|C'*inv(A)*B - (L\C)'*I*(L\B)| = 4.93021e-13
|inv(A)*B-X| (saved) = 4.07922e-13