Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ExampleSparseMatrix.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5 Multimediale Systeme der Informationsverarbeitung
6 Institut fuer Informatik
7 Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 
27 /** @example ExampleSparseMatrix.cpp
28  @relates SparseMatrix
29  @brief Test implementation of sparse matrix operations.
30  @see BIAS::SparseMatrix
31  @ingroup g_examples
32  @author esquivel
33  @date 11/2008
34 */
35 
36 #include <iostream>
37 #include <Base/Math/Random.hh>
38 #include <Base/Math/SparseMatrix.hh>
39 #include <MathAlgo/SVD.hh>
40 
41 using namespace std;
42 using namespace BIAS;
43 
44 /** brief Helper function to get rid of small matrix entries. */
45 BIAS::Matrix<double> CropMatrix(const BIAS::Matrix<double> &M,
46  double epsilon = 1e-15)
47 {
49  const unsigned int n = A.GetRows();
50  const unsigned int m = A.GetCols();
51  for (unsigned int i = 0; i < n; i++) {
52  for (unsigned int j = 0; j < m; j++) {
53  if (fabs(A[i][j]) < epsilon) A[i][j] = 0.0;
54  }
55  }
56  return A;
57 }
58 
59 int main()
60 {
61 
62  cout << "-- Testing base operations -- " << endl;
63 
64  BIAS::Matrix<double> A(6, 6, MatrixIdentity);
65  A[2][1] = 17;
66  A[3][5] = -0.1;
67  A[4][4] = 0.0;
68  BIAS::SparseMatrix S(A);
69 
70  cout << "- Dense is A = " << A << endl;
71  cout << "- Sparse is S = " << endl;
72  S.Print("S", cout);
73 
74  cout << "- Modifying S (consistency check)... " << flush;
75  S.AddToDiagonal(2.0);
76  cout << (S.CheckConsistency() ? "OK, " : "Not OK!, ") << flush;
77  S.MultiplyDiagonalBy(0.5);
78  cout << (S.CheckConsistency() ? "OK, " : "Not OK!, ") << flush;
79  S.SetElement(1, 1, 0.0);
80  cout << (S.CheckConsistency() ? "OK, " : "Not OK!, ") << flush;
81  S.SetElement(1, 4, 1.0);
82  cout << (S.CheckConsistency() ? "OK" : "Not OK!")
83  << endl << flush;
84 //
85 // S.SetElement(6,2,1.0);
86 // S.SetElement(6,2,2.0);
87 // cout << (S.CheckConsistency() ? "OK" : "Not OK!")
88 // << endl << flush;
89 
90  cout << "sparse S after setting single elements is " << S << endl << flush;
91 
92  SparseMatrix SAddTest(2,2);
93  SAddTest.SetElement(0,0,1.0);
94  SAddTest.SetElement(1,1,1.0);
95  cout << "s before adding " << SAddTest << endl;
96  Matrix<double> addBottom(2,3,MatrixIdentity);
97  addBottom[0][2] = 2;
98  Matrix<double> addRight(3,2,MatrixIdentity);
99  addRight[2][0] = 3;
100  SparseMatrix addBottomSparse(addBottom);
101  SparseMatrix addRightSparse(addRight);
102 
103  cout << "adding to bottom " << addBottomSparse << addBottomSparse.GetRows() << " " << addBottomSparse.GetCols() << endl;
104  cout << "adding to right " << addRightSparse << addRightSparse.GetRows() << " " << addRightSparse.GetCols() <<endl;
105  SAddTest.AppendMatrixBottom(addBottomSparse);
106  cout << "s after adding to bottom " << SAddTest << " size " << SAddTest.GetRows() << " " << SAddTest.GetCols() << endl;
107  SAddTest.AppendMatrixRight(addRightSparse);
108  cout << "s after adding to right " << SAddTest << " size " << SAddTest.GetRows() << " " << SAddTest.GetCols() << endl;
109 
110  cout << (SAddTest.CheckConsistency() ? "OK" : "Not OK!")
111  << endl << flush;
112 
114  S.GetAsDense(B);
115 
116  cout << "- Modified sparse is S = " << endl;
117  S.Print("S", cout);
118  cout << "- Conversion to dense is B = " << B << endl;
119 
120  BIAS::Matrix<double> BT, BTB;
121  BT = B.Transpose();
122  BTB = BT * B;
123  BIAS::SparseMatrix ST(S.GetColsNum(), S.GetRowsNum()), STS(ST.GetRowsNum(), S.GetColsNum());
124  S.Transpose(ST);
125  ST.Multiply(S, STS);
126 
127  cout << "- Sparse multiplication S'S = " << endl;
128  STS.Print("S'S", cout);
129  cout << "- Dense multiplication B'B = " << BTB << endl;
130 
131  double m;
132  unsigned int i, j;
133  m = STS.GetMaxDiagonalElement(i);
134  cout << "- Maximal diagonal element of S'S is [" << i << "][" << i
135  << "] = " << m << endl;
136  j = 4;
137  m = S.GetMaxRowElement(j, i);
138  cout << "- Maximal element of row " << j << " in S is [" << j << "][" << i
139  << "] = " << m << endl;
140  m = ST.GetMaxColumnElement(j, i);
141  cout << "- Maximal element of column " << j << " of S' is [" << i
142  << "][" << j << "] = " << m << endl;
143 
144  cout << "- Checking consistency of S... ";
145  cout << (S.CheckConsistency() ? "OK!" : "failed!") << endl;
146  cout << "- Checking consistency of S'... ";
147  cout << (ST.CheckConsistency() ? "OK!" : "failed!") << endl;
148  cout << "- Checking consistency of S'S... ";
149  cout << (STS.CheckConsistency() ? "OK!" : "failed!") << endl;
150 
151 
152  cout << endl << "-- Testing matrix inversion -- " << endl << endl;
153 
154  BIAS::Matrix<double> M(6, 6, MatrixZero);
155  M[0][0] = 2.0;
156  M[1][1] = 4.0;
157  M[2][2] = -1.0;
158  M[3][3] = -3.0;
159  M[4][4] = 0.5;
160  M[5][5] = 1.0;
161  M[3][4] = 1.5;
162  M[2][4] = 0.1;
163  M[3][1] = 2.5;
164  BIAS::SparseMatrix N(M);
165  BIAS::SparseMatrix Nold(M);
166  N.SetElement(5, 5, 1.0);
167  cout << "- Dense is M = " << M << endl;
168  cout << "- Sparse is N = " << endl;
169  N.Print("N", cout);
170  cout << "- Checking consistency of N... ";
171  cout << (N.CheckConsistency() ? "OK!" : "failed!") << endl;
172 
173  BIAS::SVD svd;
174  BIAS::Matrix<double> Minv = svd.Invert(M);
175  cout << "SVD result of inverse is M^-1 = " << CropMatrix(Minv) << endl;
176 
177  BIAS::SparseMatrix Ninv(N.GetRowsNum(), N.GetColsNum());
178  N.Invert(Ninv);
179 
180  cout << "- Sparse after inversion by Gauss-Jordan is N = " << endl;
181  N.Print("N", cout);
182  cout << "- Inverse is N^-1 = " << endl;
183  Ninv.Print("N^-1", cout);
184  cout << "- Checking consistency of N... ";
185  cout << (N.CheckConsistency() ? "OK!" : "failed!") << endl;
186  cout << "- Checking consistency of N^-1... ";
187  cout << (Ninv.CheckConsistency() ? "OK!" : "failed!") << endl;
188 
189  cout << "- M * M^-1 = " << CropMatrix(M*Minv) << endl;
190 
191  BIAS::SparseMatrix NNinv(Nold.GetRowsNum(), Ninv.GetColsNum());
192  Nold.Multiply(Ninv, NNinv);
193  cout << "- N * N^-1 = " << endl;
194  NNinv.Print("N*N^-1", cout);
195  cout << "- Checking consistency of N*Ninv... ";
196  cout << (NNinv.CheckConsistency() ? "OK!" : "failed!") << endl;
197 
198 
199  cout << endl << "-- Testing linear equation systems -- " << endl << endl;
200 
201  BIAS::SparseMatrix L(M);
202  BIAS::SparseMatrix Lold(M);
203  BIAS::Vector<double> b(6), x(6), b2(6), x2(6);
204  b[0] = 1.0;
205  b[1] = 2.0;
206  b[2] = 3.0;
207  b[3] = -4.0;
208  b[4] = 5.0;
209  b[5] = -6.0;
210 
211  cout << "- Solving linear equation system L*x = b via dense SVD and sparse "
212  << "matrix Gauss-Jordan approach..." << endl;
213  svd.Solve(M, b, x);
214  L.Solve(b, x2);
215  cout << "- Sparse LES matrix after Gauss-Jordan is L = " << endl;
216  L.Print("L", cout);
217  cout << "- Checking consistency of L... ";
218  cout << (L.CheckConsistency() ? "OK!" : "failed!") << endl;
219 
220  cout << "- Result of SVD is x = " << x << endl;
221  cout << "- Result of sparse Gauss-Jordan is x = " << x2 << endl;
222  Lold.Multiply(x2, b2);
223  cout << "- Evaluation of |L*x - b| yields "
224  << BIAS::Vector<double>(b-b2).NormL2()
225  << " (compare with dense SVD: "
226  << BIAS::Vector<double>(b-(M*x)).NormL2()
227  << ")" << endl << endl;
228 
229  return 0;
230 }
int Invert(BIAS::Matrix< double > &inverse)
Returns inverse matrix as dense matrix.
computes and holds the singular value decomposition of a rectangular (not necessarily quadratic) Matr...
Definition: SVD.hh:92
Matrix< T > Transpose() const
transpose function, storing data destination matrix
Definition: Matrix.hh:823
double NormL2() const
Return the L2 norm: sqrt(a^1 + a^2 + ...)
Definition: Vector.hh:416
void Multiply(SparseMatrix &A, SparseMatrix &result)
Multiplies with A and returns result M*A.
Implementation of sparse matrix operations.
Definition: SparseMatrix.hh:51
std::ostream & Print(std::ostream &s, const int width, const int precision, bool scientific=true) const
void Transpose(SparseMatrix &result)
Returns transposed matrix in result (as sparse matrix).