General Purpose Geodetic Library
SgMatrix.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 
24 
25 #include <QtCore/QString>
26 
27 
28 #include <SgMatrix.h>
29 
30 
31 
32 /*=======================================================================================================
33 *
34 * METHODS:
35 *
36 *======================================================================================================*/
37 //
38 // copy one matrix into another one:
40 {
41  unsigned int i;
42  double **w, **q;
43  if (NCol_ != M.NCol_ || NRow_ != M.NRow_) // adjust dimensions:
44  {
45  // delete previously allocated array:
46  if (B_)
47  {
48  for (i=0,w=B_; i<NCol_; i++,w++)
49  delete[] *w;
50  delete[] B_;
51  };
52  // create a new one:
53  NRow_ = M.NRow_;
54  B_ = new double*[NCol_=M.NCol_];
55  for (i=0,w=B_; i<NCol_; i++,w++)
56  *w=new double[NRow_];
57  };
58  //make a copy:
59  for (w=B_,q=M.B_,i=0; i<NCol_; i++,w++,q++)
60  memcpy((void*)(*w), (const void*)(*q), NRow_*sizeof(double));
61  return *this;
62 };
63 
64 
65 
66 /*=======================================================================================================
67 *
68 * FRIENDS:
69 *
70 *======================================================================================================*/
71 //
72 // matrix x vector
73 SgVector operator*(const SgMatrix& M, const SgVector& V)
74 {
75  SgVector R(M.NRow_, false);
76  double *v=V.B_, *r=R.B_;
77  unsigned int N=std::min(M.NCol_, V.N_), i, l;
78 
79 #ifdef DEBUG
80  if (M.NCol_!=V.N_)
81  std::cout << "WARNING: SgVector operator*(const SgMatrix&, const SgVector&):"
82  << " incompatible ranges of the matrix and the vector\n";
83 #endif //DEBUG
84 
85  for (i=0; i<R.N_; i++,r++)
86  for (*r=0.0,v=V.B_,l=0; l<N; l++,v++)
87  *r += *(*(M.B_+l)+i)**v;
88  return R;
89 };
90 
91 
92 
93 // matrix x matrix
95 {
96 #ifdef DEBUG
97  if (M1.nCol()!=M2.nRow()) // complain:
98  std::cerr << "WARNING: SgMatrix calcProduct_mat_x_mat(const SgMatrix& M1, "
99  << "const SgMatrix& M2): matrix size mismatch.\n";
100 #endif //DEBUG
101 
102  unsigned int N=std::min(M1.nCol(), M2.nRow()), i, j, l;
103  unsigned int NRow=M1.nRow(), NCol=M2.nCol();
104  SgMatrix M(NRow, NCol, false);
105 /*
106  // optimized version:
107  double **m=M.B_, **m1=M1.B_, **m2=M2.B_, *mm, *mm2;
108 
109  for (j=0; j<M.NCol_; j++,m++,m2++)
110  for (mm=*m,i=0; i<M.NRow_; i++,mm++)
111  for (mm2=*m2,*mm=0.0,l=0; l<N; l++,mm2++)
112  *mm += *(*(m1+l)+i)**mm2;
113 */
114  // that should be good for all types of matrices:
115  for (j=0; j<NCol; j++)
116  for (i=0; i<NRow; i++)
117  {
118 // long double d=0.0;
119  double d=0.0;
120  for (l=0; l<N; l++)
121  d += M1.getElement(i,l)*M2.getElement(l,j);
122 // M.setElement(i,j, ((double)d));
123  M.setElement(i,j, d);
124  };
125  return M;
126 };
127 
128 
129 
130 // (matrix)^T x matrix
132 {
133 #ifdef DEBUG
134  if (M1.nRow()!=M2.nRow())
135  std::cerr << "WARNING: SgMatrix matT_x_mat(const SgMatrix&, const SgMatrix&):"
136  << " matrix size mismatch\n";
137 #endif //DEBUG
138 
139  unsigned int N=std::min(M1.nRow(), M2.nRow()), i, j, l;
140  unsigned int NRow=M1.nCol(), NCol=M2.nCol();
141  SgMatrix M(NRow, NCol, false);
142 /*
143  // optimized version:
144  double **m=M.B_, **m1=M1.B_, **m2=M2.B_, *mm, *mm1, *mm2;
145  for (j=0; j<M.NCol_; j++,m++,m2++)
146  for (mm=*m,m1=M1.B_,i=0; i<M.NRow_; i++,mm++,m1++)
147  for (mm2=*m2,mm1=*m1,*mm=0.0,l=0; l<N; l++,mm1++,mm2++)
148  *mm += *mm1**mm2;
149 */
150  // that should be good for all types of matrices:
151  for (j=0; j<NCol; j++)
152  for (i=0; i<NRow; i++)
153  {
154  double d=0.0;
155  for (l=0; l<N; l++)
156  d += M1.getElement(l,i)*M2.getElement(l,j);
157  M.setElement(i,j, d);
158  };
159  return M;
160 };
161 
162 
163 
164 // matrix x (matrix)^T
166 {
167 #ifdef DEBUG
168  if (M1.nCol()!=M2.nCol())
169  std::cerr << "WARNING: SgMatrix mat_x_matT(const SgMatrix&, const SgMatrix&):"
170  << " matrix size mismatch\n";
171 #endif //DEBUG
172 
173  unsigned int N=std::min(M1.nCol(), M2.nCol()), i, j, l;
174  unsigned int NRow=M1.nRow(), NCol=M2.nRow();
175  SgMatrix M(NRow, NCol, false);
176 
177  // that should be good for all types of matrices:
178  for (j=0; j<NCol; j++)
179  for (i=0; i<NRow; i++)
180  {
181  double d=0.0;
182  for (l=0; l<N; l++)
183  d += M1.getElement(i,l)*M2.getElement(j,l);
184  M.setElement(i,j, d);
185  };
186  return M;
187 };
188 
189 
190 
191 // (matrix)^T x vector
193 {
194 #ifdef DEBUG
195  if (M.nRow()!=V.n())
196  std::cout << "WARNING: SgVector matT_x_vec(const SgMatrix&, const SgVector&):"
197  << " incompatible ranges of the matrix and the vector\n";
198 #endif //DEBUG
199 
200  unsigned int N=std::min(M.nRow(), V.n()), i, l;
201  unsigned int NRow=M.nCol();
202  SgVector X(NRow, false);
203 /*
204  // optimized version:
205  double **m=M.B_, *r=R.B_, *v, *mm;
206  for (i=0; i<R.N_; i++,r++,m++)
207  for (*r=0.0,v=V.B_,mm=*m,l=0; l<N; l++,v++,mm++)
208  *r += *mm**v;
209 */
210  // that should be good for all types of matrices:
211  for (i=0; i<NRow; i++)
212  {
213  double d=0.0;
214  for (l=0; l<N; l++)
215  d += M.getElement(l,i)*V.getElement(l);
216  X.setElement(i, d);
217  }
218  return X;
219 };
220 
221 
222 
223 /*=====================================================================================================*/
224 //
225 // aux functions:
226 //
227 // i/o:
228 std::ostream &operator<<(std::ostream& s, const SgMatrix& M)
229 {
230  unsigned int i, j, NRow=M.nRow(), NCol=M.nCol();
231  QString str("");
232  if (NCol<55) // trying to write in conventional form:
233  {
234  for (i=0; i<NRow; i++)
235  {
236  s << "|";
237  for (j=0; j<NCol; j++)
238  s << " " << qPrintable(str.sprintf("%12.5e", M.getElement(i,j))) << " ";
239  s << "|\n";
240  };
241  }
242  else // will use a similar to SINEX format presentation:
243  {
244  for (j=0; j<NCol; j++)
245  for (i=0; i<NRow; i++)
246  s << i << " " << j << " " << M.getElement(i,j) << "\n";
247  };
248  return s;
249 };
250 /*=====================================================================================================*/
SgMatrix calcProduct_mat_x_matT(const SgMatrix &M1, const SgMatrix &M2)
Definition: SgMatrix.cpp:165
SgVector calcProduct_matT_x_vec(const SgMatrix &M, const SgVector &V)
Definition: SgMatrix.cpp:192
std::ostream & operator<<(std::ostream &s, const SgMatrix &M)
Definition: SgMatrix.cpp:228
SgVector operator*(const SgMatrix &M, const SgVector &V)
Definition: SgMatrix.cpp:73
SgMatrix calcProduct_matT_x_mat(const SgMatrix &M1, const SgMatrix &M2)
Definition: SgMatrix.cpp:131
SgMatrix calcProduct_mat_x_mat(const SgMatrix &M1, const SgMatrix &M2)
Definition: SgMatrix.cpp:94
unsigned int NCol_
An number of columns in a matrix.
Definition: SgMatrix.h:260
unsigned int nRow() const
Definition: SgMatrix.h:352
SgMatrix & operator=(const SgMatrix &M)
Definition: SgMatrix.cpp:39
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
double * B_
A pointer on a first element of the vector.
Definition: SgVector.h:258
unsigned int n() const
Definition: SgVector.h:327
void setElement(unsigned int i, double d)
Definition: SgVector.h:348
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