General Purpose Geodetic Library
SgUtMatrix.cpp
Go to the documentation of this file.
1 /*
2  *
3  * This file is a part of Space Geodetic Library. The library is used by
4  * nuSolve, a part of CALC/SOLVE system, and designed to make analysis of
5  * geodetic VLBI observations.
6  * Copyright (C) 2010-2020 Sergei Bolotin.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #include <iostream>
24 
25 #include <QtCore/QString>
26 
27 #include <SgUtMatrix.h>
28 
29 
30 
31 
32 /*=======================================================================================================
33 *
34 * METHODS:
35 *
36 *======================================================================================================*/
37 //
38 // make a copy:
40 {
41 #ifdef DEBUG
42  if (NRow_!=R.NRow_)
43  std::cerr << "WARNING: SgUtMatrix& SgUtMatrix::operator= (const SgUtMatrix&):"
44  << " ranges of matrices " << "are different (rows): " << NRow_ << " and "
45  << R.NRow_ << "\n";
46  if (NCol_!=R.NCol_)
47  std::cerr << "WARNING: SgUtMatrix& SgUtMatrix::operator= (const SgUtMatrix&):"
48  << " ranges of matrices " << "are different (columns): " << NCol_ << " and "
49  << R.NCol_ << "\n";
50 #endif //DEBUG
51 
52  double **w=B_, **q=R.B_;
53  unsigned int N=std::min(NCol_,R.NCol_);
54  for (unsigned int i=0; i<N; i++,w++,q++)
55  memcpy((void*)(*w), (const void*)(*q), (i+1)*sizeof(double));
56  return *this;
57 };
58 
59 
60 
61 
62 /*=======================================================================================================
63 *
64 * FRIENDS:
65 *
66 *======================================================================================================*/
67 //
68 // matrix x vector
70 {
71 #ifdef DEBUG
72  if (R.nCol()!=V.n())
73  std::cerr << "WARNING: SgVector operator*(const SgUtMatrix&, const SgVector&): "
74  << "incompatible ranges of matrix (" << R.nCol()
75  << ") and vector (" << V.n() << ")\n";
76 #endif //DEBUG
77 
78  SgVector X(R.nRow(), false);
79  double *x=X.B_, **r=R.B_, *v=V.B_;
80  unsigned int i, j;
81  for (j=0; j<X.N_; j++,r++)
82  for (*x=0.0,i=j; i<R.NCol_; i++)
83  *x += *(*(r+j)+i)**(v+i);
84  return X;
85 };
86 
87 
88 
89 // inverse matrix:
91 {
92  SgUtMatrix U(R.n(), false);
93  double s;
94 
95  if (!R.n())
96  return U;
97 
98  if (R.getElement(0,0) != 0.0)
99  U(0,0) = 1.0/R.getElement(0,0);
100  else
101  std::cerr << "WARNING: SgUtMatrix operator~(const SgUtMatrix&): R[0,0] is zero.\n";
102 
103  for (unsigned int j=1; j<R.n(); j++)
104  if (R.getElement(j,j) != 0.0)
105  {
106  U(j,j) = 1.0/R.getElement(j,j);
107  for (unsigned int k=0; k<j; k++)
108  {
109  s = 0.0;
110  for (unsigned int i=k; i<j; i++)
111  s += U.getElement(k,i)*R.getElement(i,j);
112  U(k,j) = -s*U.getElement(j,j);
113  };
114  }
115  else
116  std::cerr << "WARNING: SgUtMatrix operator~(const SgUtMatrix&): R[j,j] is zero, j="
117  << j << ".\n";
118  return U;
119 };
120 
121 
122 
123 // matrix x matrix
125 {
126 #ifdef DEBUG
127  if (R1.nCol()!=M2.nRow()) // complain:
128  std::cerr << "WARNING: SgMatrix calcProduct_mat_x_mat(const SgUtMatrix& R1, "
129  << "const SgMatrix& M2): matrix size mismatch.\n";
130 #endif //DEBUG
131 
132  unsigned int N=std::min(R1.nCol(), M2.nRow()), i, j, l;
133  unsigned int NRow=R1.nRow(), NCol=M2.nCol();
134  SgMatrix M(NRow, NCol, false);
135 /*
136  // optimized version:
137  double **m=M.B_, **m1=M1.B_, **m2=M2.B_, *mm, *mm2;
138 
139  for (j=0; j<M.NCol_; j++,m++,m2++)
140  for (mm=*m,i=0; i<M.NRow_; i++,mm++)
141  for (mm2=*m2,*mm=0.0,l=0; l<N; l++,mm2++)
142  *mm += *(*(m1+l)+i)**mm2;
143 */
144  // that should be good for all types of matrices:
145  for (j=0; j<NCol; j++)
146  for (i=0; i<NRow; i++)
147  {
148 // long double d=0.0;
149  double d=0.0;
150  for (l=i; l<N; l++)
151  d += R1.getElement(i,l)*M2.getElement(l,j);
152 // M.setElement(i,j, ((double)d));
153  M.setElement(i,j, d);
154  };
155  return M;
156 };
157 
158 
159 
160 /*=====================================================================================================*/
161 //
162 // aux functions:
163 //
164 // R*x = z;
165 // x-?
167 {
168 #ifdef DEBUG
169  if (x.n()!=z.n())
170  std::cerr << "WARNING: SgVector& solveEquation(const SgUtMatrix&, SgVector&,"
171  "const SgVector&): incompatible ranges of vectors.\n";
172  if (R.nRow()!=x.n())
173  std::cerr << "WARNING: SgVector& solveEquation(const SgUtMatrix&, SgVector&,"
174  "const SgVector&): incompatible ranges of vector and matrix.\n";
175 #endif //DEBUG
176  unsigned int i, j, n=x.n()-1;
177  double s;
178 
179  if (!x.n())
180  return x;
181 
182  if (R.getElement(n,n)!=0.0)
183  x(n)=z.getElement(n)/R.getElement(n,n);
184  else
185  std::cerr << "WARNING: SgVector& solveEquation(const SgUtMatrix& R, SgVector& x,"
186  << " const SgVector& z): division by zero caused by R[0,0]==0.\n";
187 
188  for (i=n; i>0; i--) // i ==> (i+1)
189  {
190  for (j=i, s=0.0; j<x.n(); j++)
191  s += R.getElement(i-1,j)*x.getElement(j);
192  if (R.getElement(i-1,i-1)!=0.0)
193  x(i-1) = (z.getElement(i-1) - s)/R.getElement(i-1,i-1);
194  else
195  std::cerr << "WARNING: SgVector& solveEquation(const SgUtMatrix& R, SgVector& x,"
196  << " const SgVector& z): division by zero caused by R[j,j]==0, j="
197  << j << ".\n";
198  };
199  return x;
200 };
201 
202 
203 
204 // i/o:
205 std::ostream &operator<<(std::ostream& s, const SgUtMatrix& R)
206 {
207  QString str;
208  unsigned int i, j;
209  if (R.nCol()<30) // trying to write in conventional form:
210  {
211  for (i=0; i<R.nRow(); i++)
212  {
213  s << "|";
214  for (j=0; j<i; j++)
215  {
216  str.sprintf(" %.6g", 0.0);
217  s << qPrintable(str);
218  };
219  for (j=i; j<R.nCol(); j++)
220  {
221  str.sprintf(" %.6g", R.getElement(i,j));
222  s << qPrintable(str);
223  };
224  s << " |\n";
225  };
226  }
227  else // will use a similar to SINEX format presentation:
228  {
229  for (j=0; j<R.nCol(); j++)
230  for (i=0; i<=j; i++)
231  s << i << " " << j << " " << R.getElement(i,j) << "\n";
232  };
233  return s;
234 };
235 /*=====================================================================================================*/
std::ostream & operator<<(std::ostream &s, const SgUtMatrix &R)
Definition: SgUtMatrix.cpp:205
SgVector & solveEquation(const SgUtMatrix &R, SgVector &x, const SgVector &z)
Definition: SgUtMatrix.cpp:166
SgMatrix calcProduct_mat_x_mat(const SgUtMatrix &R1, const SgMatrix &M2)
Definition: SgUtMatrix.cpp:124
SgUtMatrix operator~(const SgUtMatrix &R)
Definition: SgUtMatrix.cpp:90
SgVector operator*(const SgUtMatrix &R, const SgVector &V)
Definition: SgUtMatrix.cpp:69
unsigned int NCol_
An number of columns in a matrix.
Definition: SgMatrix.h:260
unsigned int nRow() const
Definition: SgMatrix.h:352
void setElement(unsigned int i, unsigned int j, double d)
Definition: SgMatrix.h:402
double getElement(unsigned int i, unsigned int j) const
Definition: SgMatrix.h:385
double ** B_
A pointer on a pointer of a first element of the matrix.
Definition: SgMatrix.h:261
unsigned int nCol() const
Definition: SgMatrix.h:360
unsigned int NRow_
An number of rows in a matrix.
Definition: SgMatrix.h:249
unsigned int n() const
Definition: SgUtMatrix.h:290
SgUtMatrix & operator=(const SgUtMatrix &R)
Definition: SgUtMatrix.cpp:39
double getElement(unsigned int i, unsigned int j) const
Definition: SgUtMatrix.h:318
double * B_
A pointer on a first element of the vector.
Definition: SgVector.h:258
unsigned int n() const
Definition: SgVector.h:327
double getElement(unsigned int i) const
Definition: SgVector.h:362
unsigned int N_
An number of elements in a vector (dimension).
Definition: SgVector.h:248