qupid 0.2
Quasi-Signal Generation Model for Pixelized Detector
Loading...
Searching...
No Matches
QPMatrix.cpp
1#include <iostream>
2#include <cstdlib>
3#include <cstdarg>
4#include <cmath>
5#include <sstream>
6
7#include "QPMatrix.hpp"
8
9
10QPMatrix::QPMatrix(): fElement(0), fM(0), fN(0){
11 // Init();
12}
13
14QPMatrix::QPMatrix(const int n): fElement(0), fM(n), fN(n){
15 Init();
16}
17
18QPMatrix::QPMatrix(const int m, const int n): fElement(0), fM(m), fN(n){
19 Init();
20}
21
22
23QPMatrix::QPMatrix(const int m, const int n, const int npassed, ...): fElement(0), fM(m), fN(n){
24 Init();
25
26 va_list vl;
27 va_start( vl, npassed );
28
29 for(int i=0; i<m*n && i<npassed; i++){
30 fElement[i] = va_arg(vl, double);
31 }
32
33 va_end(vl);
34}
35
36QPMatrix::QPMatrix(QPVector& vec, int ncomp): fElement(0), fM(ncomp), fN(1){
37 Init();
38 for(int i=0; i<ncomp && i<3; i++){
39 fElement[i] = vec(i);
40 }
41}
42
43QPMatrix::QPMatrix(const QPMatrix& other): fElement(0), fM(other.fM), fN(other.fN){
44 Init();
45
46 int fMN = fM*fN;
47 for(int i=0; i<fMN; i++){
48 fElement[i] = other.fElement[i];
49 }
50}
51
53 Freeing();
54 fM = other.fM;
55 fN = other.fN;
56
57 Init();
58 for(int i=0; i<fM*fN; i++){
59 fElement[i] = other.fElement[i];
60 // std::cout<<"COPIED\t"<<fElement[i]<<"\t"<<At(i)<<std::endl;
61 }
62
63 return *this;
64}
65
69
70void QPMatrix::Init(){
71 fElement = (double*) std::malloc(fM*fN*sizeof(double));
72 for(int i=0; i<fN*fM; i++){
73 fElement[i] = 0.;
74 }
75}
76
78 // if(fElement == nullptr){
79 // return;
80 // }
81 std::free(fElement);
82}
83
85 if(i >= 0 && i< fN*fM) return true;
86 return false;
87}
88
89bool QPMatrix::IsInside(int i, int j){
90 if (i>=0 && i<fM && j>=0 && j<fN){
91 return true;
92 }
93 return false;
94}
95
96double QPMatrix::At(int i){
97 if( !IsInside(i) ){
98 std::cout<<"QPMatrix::At(1) - Out if index"<<"["<<i<<"]"<<std::endl;
99 return -1;
100 }
101 return fElement[i];
102}
103
104double QPMatrix::At(int i, int j){
105 if( !IsInside(i,j) ){
106 std::cout<<"QPMatrix::At(2) - Out if index "<<"["<<i<<","<<j<<"]"<<std::endl;
107 return -1;
108 }
109 return fElement[i*fN+j];
110}
111
113 if(fN == other.fN && fM == other.fM) return true;
114 return false;
115}
116
118 if(fN == other.fM && fM == other.fN) return true;
119 return false;
120}
121
122double& QPMatrix::operator[](int i){
123 if( !IsInside(i) ){
124 std::cout<<"QPMatrix::operator[](1) - Out if index"<<"["<<i<<"]"<<std::endl;
125 return nval;
126 }
127 return fElement[i];
128}
129
130double& QPMatrix::operator()(int i){
131 if( !IsInside(i) ){
132 std::cout<<"QPMatrix::operator()(1) - Out if index"<<"["<<i<<"]"<<std::endl;
133 return nval;
134 }
135 return fElement[i];
136}
137
138double& QPMatrix::operator()(int i, int j){
139 if( !IsInside(i, j) ){
140 std::cout<<"QPMatrix::operator()(2) - Out if index"<<"["<<i<<"]"<<std::endl;
141 return nval;
142 }
143 return fElement[i*fM+j];
144}
145
147 if(fM != fN){
148 std::cout<<"QPMatrix::Det() - Determinant can be defined only for square matrix "<<"["<<fM<<","<<fN<<"]"<<std::endl;
149 return 0.;
150 }
151 if(fM==0) return 0.;
152
153 if(fM==1) return At(0);
154
155 if(fM==2){
156 return At(0,0)*At(1,1) - At(0,1)*At(1,0);
157 }
158
159 double ans = 0;
160 for(int i=0; i<fN; i++){
161 ans += pow(-1, i)*At(0,i)*SubMatrix(0, i).Det();
162 }
163
164 return ans;
165}
166
168 double ans = 0;
169 int ii = fN>fM ? fM : fN;
170
171 for(int i=0; i<ii; i++){
172 ans += operator()(i,i);
173 }
174 return ans;
175}
176
177QPMatrix QPMatrix::SubMatrix(const int i_, const int j_){
178
179 QPMatrix ans = QPMatrix(fM-1, fN-1);
180
181 for(int i=0; i<fM-1; i++){
182 for(int j=0; j<fN-1; j++){
183 ans(i,j) = At(
184 i < i_ ? i : i+1,
185 j < j_ ? j : j+1
186 );
187 }
188 }
189 return ans;
190}
191
192double QPMatrix::Cofactor(const int i, const int j){
193 if(fM != fN){
194 std::cout<<"QPMatrix::Cofactor() - Cofactor can be defined only for square matrix "<<"["<<fM<<","<<fN<<"]"<<std::endl;
195 return 0;
196 }
197 return pow(-1, i+j) * (SubMatrix(i,j).Det());
198}
199
201 if(fM != fN){
202 std::cout<<"QPMatrix::Inverse() - Inverse can be defined only for square matrix "<<"["<<fM<<","<<fN<<"]"<<std::endl;
203 return QPMatrix();
204 }
205
206 double det = Det();
207
208 if(det<0.0000000001 && det>-0.0000000001 ){
209 std::cout<<"QPMatrix::Inverse() - Determinant is near zero. No inverse matrix "<<"["<<det<<"]"<<std::endl;
210 return QPMatrix();
211 }
212
213 QPMatrix ans = QPMatrix(fM, fN);
214 for(int i=0; i<fM; i++){
215 for(int j=0; j<fN; j++){
216 ans(i,j) = Cofactor(j,i);
217 }
218 }
219
220 ans*=(1/Det());
221
222 return ans;
223}
224
225
226
228 QPMatrix ans(fN, fM);
229
230 for(int i=0; i<fM; i++){
231 for(int j=0; j<fN; j++){
232 ans(j,i) = At(i,j);
233 }
234 }
235 return ans;
236}
237
238QPMatrix operator*(QPMatrix self, double other){
239 QPMatrix ans = QPMatrix(self);
240 for(int i=0; i<(self.fN*self.fM); i++){
241 ans(i) *= other;
242 }
243 return ans;
244}
245
246QPMatrix operator*(double other, QPMatrix self){
247 QPMatrix ans = QPMatrix(self);
248 for(int i=0; i<(self.fN*self.fM); i++){
249 ans(i) *= other;
250 }
251 return ans;
252}
253
254QPMatrix operator*(QPMatrix self, QPMatrix other){
255 if(self.fN != other.fM){
256 std::cout<<"QPMatrix::operator*()(3) - inner part of 2 matrices are not same : "<<self.fN<<", "<<other.fM<<std::endl;
257 return QPMatrix();
258 }
259 QPMatrix ans = QPMatrix(self.fM, other.fN);
260 for(int i=0; i<(ans.fM); i++){
261 for(int j=0; j<(ans.fN); j++){
262 for(int k=0; k<(self.fN); k++){
263 ans(i,j)+= self.At(i,k) * other.At(k,j);
264 }
265 }
266 }
267 return ans;
268}
269
270QPMatrix operator+(QPMatrix & self, QPMatrix & other){
271 if(! self.IsSameShape(other) ){
272 std::cout<<"operator+ (QPMatrix&, QPMatrix&) - Not same shape"<<std::endl;
273 return QPMatrix();
274 }
275
276 QPMatrix ans = QPMatrix(self.fM, self.fN);
277
278 int length = self.fN * self.fM;
279 for(int i=0; i<length; i++){
280 ans[i] = self[i] + other[i];
281 }
282
283 return ans;
284
285}
286
287QPMatrix operator-(QPMatrix & self, QPMatrix & other){
288 if(! self.IsSameShape(other) ){
289 std::cout<<"operator- (QPMatrix&, QPMatrix&) - Not same shape"<<std::endl;
290 return QPMatrix();
291 }
292
293 QPMatrix ans(self.fM, self.fN);
294
295 int length = self.fN * self.fM;
296 for(int i=0; i<length; i++){
297 ans[i] = self[i] - other[i];
298 }
299
300 return ans;
301
302}
303
304std::string QPMatrix::Print(bool quite){
305
306 std::ostringstream anss;
307
308 anss.precision(4);
309
310 for(int i=0; i<fM; i++){
311 for(int j=0; j<fN; j++){
312 anss << At(i,j) << "\t";
313 }
314 anss<<std::endl;
315 }
316 anss.unsetf(std::ios::fixed);
317
318 std::string ans = anss.str();
319
320 if(!quite){
321 std::cout<<ans;
322 }
323
324 return ans;
325}
326
Dense m×n matrix of double with hand-rolled linear algebra.
Definition QPMatrix.hpp:15
QPMatrix Transpose()
Definition QPMatrix.cpp:227
bool IsTransShape(QPMatrix &other)
Definition QPMatrix.cpp:117
~QPMatrix()
Frees the element storage.
Definition QPMatrix.cpp:66
QPMatrix Inverse()
Inverse by the adjugate formula .
Definition QPMatrix.cpp:200
bool IsInside(int i)
Definition QPMatrix.cpp:84
std::string Print(bool quite=false)
Formats the matrix as tab-separated rows.
Definition QPMatrix.cpp:304
double Trace()
Sum of the diagonal elements up to min(m, n).
Definition QPMatrix.cpp:167
double Cofactor(const int i, const int j)
Cofactor where is the minor.
Definition QPMatrix.cpp:192
QPMatrix & operator=(const QPMatrix &)
Deep copy assignment; reallocates the storage.
Definition QPMatrix.cpp:52
double At(int i)
Value of linear element i of the row-major storage.
Definition QPMatrix.cpp:96
QPMatrix()
Null matrix: 0×0, no storage.
Definition QPMatrix.cpp:10
QPMatrix SubMatrix(const int i, const int j)
Minor matrix: this matrix with row i and column j removed.
Definition QPMatrix.cpp:177
bool IsSameShape(QPMatrix &other)
Definition QPMatrix.cpp:112
double & operator[](int i)
Reference to linear element i of the row-major storage.
Definition QPMatrix.cpp:122
void Freeing()
Releases the element storage.
Definition QPMatrix.cpp:77
double Det()
Determinant by recursive Laplace expansion along the first row.
Definition QPMatrix.cpp:146
double & operator()(int i)
Same as operator[].
Definition QPMatrix.cpp:130
3-component double vector with hand-rolled operations.
Definition QPVector.hpp:13