Garfield++ 4.0
A toolkit for the detailed simulation of particle detectors based on ionisation measurement in gases and semiconductors
Loading...
Searching...
No Matches
multiply.h
Go to the documentation of this file.
1#ifndef MULTIPLY_H
2#define MULTIPLY_H
3/*
4Various matrix operations performed upon arrays of DynLinArr and
5DynArr classes.
6
7Copyright (c) 2001 Igor B. Smirnov
8
9The file can be used, copied, modified, and distributed
10according to the terms of GNU Lesser General Public License version 2.1
11as published by the Free Software Foundation,
12and provided that the above copyright notice, this permission notice,
13and notices about any modifications of the original text
14appear in all copies and in supporting documentation.
15The file is provided "as is" without express or implied warranty.
16*/
17
20
21namespace Heed {
22
23// Matrix multiplication of two matrices:
24template <class T>
25DynArr<T> operator*(const DynArr<T>& mt1, const DynArr<T>& mt2) {
27 "template<class T> DynArr<T> operator*(const DynArr<T>& mt1, const "
28 "DynArr<T>& mt2)");
29 check_econd11(mt1.get_qdim(), != 2, mcerr);
30 check_econd11(mt2.get_qdim(), > 2, mcerr);
31 check_econd11(mt2.get_qdim(), < 1, mcerr);
32 const DynLinArr<long>& qel_mt1(mt1.get_qel());
33 const DynLinArr<long>& qel_mt2(mt2.get_qel());
34 check_econd12(qel_mt1[1], !=, qel_mt2[0], mcerr);
35 if (mt2.get_qdim() == 2) { // otherwise 1
36 long q1 = qel_mt1[0];
37 long q2 = qel_mt2[1];
38 long q3 = qel_mt1[1];
39 DynArr<T> res(q1, q2);
40 for (long n1 = 0; n1 < q1; ++n1) {
41 for (long n2 = 0; n2 < q2; ++n2) {
42 T t(0.0);
43 for (long n3 = 0; n3 < q3; ++n3) {
44 t += mt1.acu(n1, n3) * mt2.acu(n3, n2);
45 }
46 res.acu(n1, n2) = t;
47 }
48 }
49 return res;
50 } else {
51 long q1 = qel_mt1[0];
52 long q3 = qel_mt1[1];
53 DynArr<T> res(q1);
54 for (long n1 = 0; n1 < q1; ++n1) {
55 T t(0.0);
56 for (long n3 = 0; n3 < q3; ++n3) {
57 t += mt1.acu(n1, n3) * mt2.acu(n3);
58 }
59 res.acu(n1) = t;
60 }
61 return res;
62 }
63}
64
65template <class T>
67 const DynLinArr<long>& qel_mt(mt.get_qel());
68 if (qel_mt.get_qel() != 2) {
69 mcerr << "template<class T>\n"
70 << "DynLinArr<T> operator*(const DynArr<T>& mt, "
71 << "const DynLinArr<T>& vc):\n";
72 mcerr << "qel_mt.get_qel() != 2, qel_mt.get_qel() =" << qel_mt.get_qel()
73 << '\n';
75 }
76 long q = vc.get_qel();
77 if (q != qel_mt[1]) {
78 mcerr << "template<class T>\n"
79 << "DynLinArr<T> operator*(const DynArr<T>& mt, "
80 << "const DynLinArr<T>& vc):\n";
81 mcerr << "q != qel_mt[1], q =" << q << "qel_mt[1]=" << qel_mt[1] << '\n';
83 }
84 T s(0); // assumes that this clears the element
85 DynLinArr<T> res(qel_mt[0], s);
86 for (long n1 = 0; n1 < qel_mt[0]; n1++) {
87 for (long n2 = 0; n2 < q; n2++) {
88 res[n1] += mt.acu(n1, n2) * vc.acu(n2);
89 }
90 }
91 return res;
92}
93
94DynLinArr<DoubleAc> operator*(const DynArr<DoubleAc>& mt,
95 const DynLinArr<double>& vc);
96DynLinArr<DoubleAc> operator*(const DynArr<double>& mt,
97 const DynLinArr<DoubleAc>& vc);
98
99template <class T>
100T operator*(const DynLinArr<T>& vc1, const DynLinArr<T>& vc2) {
101 // mcout<<"T operator*(const DynLinArr<T>& vc1, const DynLinArr<T>& vc2):\n";
102 long q1 = vc1.get_qel();
103 long q2 = vc2.get_qel();
104 if (q1 != q2) {
105 mcerr << "template<class T>\n"
106 << "DynLinArr<T> operator*(const DynArr<T>& mt, "
107 << "const DynLinArr<T>& vc):\n";
108 mcerr << "q1 != q2, q1 =" << q1 << "q2=" << q2 << '\n';
109 spexit(mcerr);
110 }
111 T s(0); // assumes that this clears the element
112 // mcout<<"s="<<s<<'\n';
113 for (long n = 0; n < q1; n++) {
114 s += vc1.acu(n) * vc2.acu(n);
115 // mcout<<"vc1[n]="<<vc1[n]<<'\n';
116 // mcout<<"vc2[n]="<<vc2[n]<<'\n';
117 // mcout<<"vc1[n] * vc2[n]="<<vc1[n] * vc2[n]<<'\n';
118 // mcout<<"s="<<s<<'\n';
119 }
120 return s;
121}
122
123DoubleAc operator*(const DynLinArr<DoubleAc>& vc1,
124 const DynLinArr<double>& vc2);
125DoubleAc operator*(const DynLinArr<double>& vc1,
126 const DynLinArr<DoubleAc>& vc2);
127
128template <class T, class X>
129DynLinArr<T> operator*(const DynLinArr<T>& ar, const X& t) {
130 const long q = ar.get_qel();
131 DynLinArr<T> res(q);
132 for (long n = 0; n < q; n++) {
133 res.acu(n) = ar.acu(n) * t;
134 }
135 return res;
136}
137
138template <class T, class X>
140 const long q = ar.get_qel();
141 for (long n = 0; n < q; n++) {
142 ar.acu(n) *= t;
143 }
144 return ar;
145}
146
147template <class T, class X>
148DynLinArr<T> operator*(const X& t, const DynLinArr<T>& ar) {
149 mfunnamep(
150 "template<class T, class X> DynLinArr<T> operator*(const X& t, "
151 "const DynLinArr<T>& ar)");
152 const long q = ar.get_qel();
153 DynLinArr<T> res(q);
154 for (long n = 0; n < q; n++) {
155 res.acu(n) = t * ar.acu(n);
156 }
157 return res;
158}
159
160template <class T, class X>
161DynLinArr<T> operator/(const DynLinArr<T>& ar, const X& t) {
162 mfunname("DynLinArr<T> operator/(const DynLinArr<T>& ar, const X& t)");
163 check_econd11(t, == 0, mcerr);
164 const long q = ar.get_qel();
165 DynLinArr<T> res(q);
166 for (long n = 0; n < q; n++) {
167 res.acu(n) = ar.acu(n) / t;
168 }
169 return res;
170}
171
172template <class T, class X>
174 mfunname("DynLinArr<T>& operator/=(DynLinArr<T>& ar, const X& t)");
175 check_econd11(t, == 0, mcerr);
176 const long q = ar.get_qel();
177 for (long n = 0; n < q; n++) {
178 ar.acu(n) /= t;
179 }
180 return ar;
181}
182
183template <class T, class X>
184DynArr<T> operator*(const DynArr<T>& mt, const X& t) {
185 mfunnamep(
186 "template<class T, class X> DynArr<T> operator*(const DynArr<T>& "
187 "mt, const X& t)");
188 DynArr<T> ms(mt.get_qel(), NULL);
189 const long qel_lin = mt.get_qel_lin();
190 for (long n = 0; n < qel_lin; n++) {
191 ms.acu_lin(n) = mt.acu_lin(n) * t;
192 }
193 return ms;
194}
195
196template <class T, class X>
197DynArr<T> operator*(const X& t, const DynArr<T>& mt) {
198 mfunnamep(
199 "template<class T, class X> DynArr<T> operator*(const X& t, const "
200 "DynArr<T>& mt)");
201 DynArr<T> ms(mt.get_qel(), NULL);
202 const long qel_lin = mt.get_qel_lin();
203 for (long n = 0; n < qel_lin; n++) {
204 ms.acu_lin(n) = t * mt.acu_lin(n);
205 }
206 return ms;
207}
208
209template <class T, class X>
210DynArr<T>& operator*=(DynArr<T>& mt, const X& t) {
211 mfunnamep(
212 "template<class T, class X> DynArr<T>& operator*=(DynArr<T>& mt, "
213 "const X& t)");
214 const long qel_lin = mt.get_qel_lin();
215 for (long n = 0; n < qel_lin; n++) {
216 mt.acu_lin(n) *= t;
217 }
218 return mt;
219}
220
221template <class T, class X>
222DynArr<T> operator/(const DynArr<T>& mt, const X& t) {
223 mfunnamep(
224 "template<class T, class X> DynArr<T> operator/(const DynArr<T>& "
225 "mt, const X& t)");
226 check_econd11(t, == 0, mcerr);
227 DynArr<T> ms(mt.get_qel(), NULL);
228 const long qel_lin = mt.get_qel_lin();
229 for (long n = 0; n < qel_lin; n++) {
230 ms.acu_lin(n) = mt.acu_lin(n) / t;
231 }
232 return ms;
233}
234
235template <class T, class X>
236DynArr<T>& operator/=(DynArr<T>& mt, const X& t) {
237 mfunnamep(
238 "template<class T, class X> DynArr<T>& operator/(DynArr<T>& mt, "
239 "const X& t)");
240 check_econd11(t, == 0, mcerr);
241 const long qel_lin = mt.get_qel_lin();
242 for (long n = 0; n < qel_lin; n++) {
243 mt.acu_lin(n) /= t;
244 }
245 return mt;
246}
247
248template <class T>
250 long q1 = vc1.get_qel();
251 long q2 = vc2.get_qel();
252 if (q1 != q2) {
253 mcerr << "template<class T>\n"
254 << "DynLinArr<T> operator+(const DynLinArr<T>& vc1, "
255 << "const DynLinArr<T>& vc2):\n";
256 mcerr << "q1 != q2, q1 =" << q1 << "q2=" << q2 << '\n';
257 spexit(mcerr);
258 }
259 DynLinArr<T> s(q1);
260 for (long n = 0; n < q1; n++) {
261 s.acu(n) = vc1.acu(n) + vc2.acu(n);
262 }
263 return s;
264}
265
266template <class T>
268 long q1 = vc1.get_qel();
269 long q2 = vc2.get_qel();
270 if (q1 != q2) {
271 mcerr << "template<class T>\n"
272 << "DynLinArr<T>& operator+=(DynLinArr<T>& vc1, "
273 << "const DynLinArr<T>& vc2):\n";
274 mcerr << "q1 != q2, q1 =" << q1 << "q2=" << q2 << '\n';
275 spexit(mcerr);
276 }
277 for (long n = 0; n < q1; n++) {
278 vc1.acu(n) += vc2.acu(n);
279 }
280 return vc1;
281}
282
283template <class T>
285 long q1 = vc1.get_qel();
286 long q2 = vc2.get_qel();
287 if (q1 != q2) {
288 mcerr << "template<class T>\n"
289 << "DynLinArr<T> operator-(const DynLinArr<T>& vc1, "
290 << "const DynLinArr<T>& vc2):\n";
291 mcerr << "q1 != q2, q1 =" << q1 << "q2=" << q2 << '\n';
292 spexit(mcerr);
293 }
294 DynLinArr<T> s(q1);
295 for (long n = 0; n < q1; n++) {
296 s.acu(n) = vc1.acu(n) - vc2.acu(n);
297 }
298 return s;
299}
300
301template <class T>
303 long q1 = vc1.get_qel();
304 long q2 = vc2.get_qel();
305 if (q1 != q2) {
306 mcerr << "template<class T>\n"
307 << "DynLinArr<T>& operator-=(DynLinArr<T>& vc1, "
308 << "const DynLinArr<T>& vc2):\n";
309 mcerr << "q1 != q2, q1 =" << q1 << "q2=" << q2 << '\n';
310 spexit(mcerr);
311 }
312 for (long n = 0; n < q1; n++) {
313 vc1.acu(n) -= vc2.acu(n);
314 }
315 return vc1;
316}
317
318DynLinArr<DoubleAc> operator+(const DynLinArr<DoubleAc>& vc1,
319 const DynLinArr<double>& vc2);
320DynLinArr<DoubleAc> operator+(const DynLinArr<double>& vc1,
321 const DynLinArr<DoubleAc>& vc2);
322DynLinArr<DoubleAc> operator-(const DynLinArr<DoubleAc>& vc1,
323 const DynLinArr<double>& vc2);
324DynLinArr<DoubleAc> operator-(const DynLinArr<double>& vc1,
325 const DynLinArr<DoubleAc>& vc2);
326template <class T>
327DynLinArr<T> operator-(const DynLinArr<T>& ar) { // creates local copy and
328 // returns it - may
329 // be inefficient
330 const long q = ar.get_qel();
331 DynLinArr<T> s(q);
332 for (long n = 0; n < q; n++) {
333 s.acu(n) = -ar.acu(n);
334 }
335 return s;
336}
337
338template <class T>
339void change_sign(DynLinArr<T>& ar) { // just change sign without copying total
340 // content,
341 // but correspondent member function should exist for type of elements T
342 const long q = ar.get_qel();
343 DynLinArr<T> s(q);
344 for (long n = 0; n < q; n++) {
345 change_sign(ar.acu(n));
346 }
347}
348
349inline void change_sign(float& f) { f = -f; }
350
351inline void change_sign(double& f) { f = -f; }
352
353template <class T, class X>
355 const long q = ar.get_qel();
356 for (long n = 0; n < q; n++) {
357 ar.acu(n) += t;
358 }
359 return ar;
360}
361
362template <class T, class X>
364 const long q = ar.get_qel();
365 for (long n = 0; n < q; n++) {
366 ar.acu(n) -= t;
367 }
368 return ar;
369}
370
371template <class T>
372DynArr<T> operator+(const DynArr<T>& mt1, const DynArr<T>& mt2) {
373 mfunnamep(
374 "template<class T> DynArr<T> operator+(const DynArr<T>& mt1, const "
375 "DynArr<T>& mt2)");
376 long qdim1 = mt1.get_qdim();
377 long qdim2 = mt2.get_qdim();
378 check_econd12(qdim1, !=, qdim2, mcerr);
379 const DynLinArr<long>& qe1 = mt1.get_qel();
380 const DynLinArr<long>& qe2 = mt2.get_qel();
381 check_econd12(qe1, !=, qe2, mcerr);
382 DynArr<T> ms(mt1.get_qel(), NULL);
383 const long qel_lin = mt1.get_qel_lin();
384 for (long n = 0; n < qel_lin; n++) {
385 ms.acu_lin(n) = mt1.acu_lin(n) + mt2.acu_lin(n);
386 }
387 return ms;
388}
389
390template <class T>
392 mfunnamep(
393 "template<class T> DynArr<T>& operator+(DynArr<T>& mt1, const "
394 "DynArr<T>& mt2)");
395 long qdim1 = mt1.get_qdim();
396 long qdim2 = mt2.get_qdim();
397 check_econd12(qdim1, !=, qdim2, mcerr);
398 const DynLinArr<long>& qe1 = mt1.get_qel();
399 const DynLinArr<long>& qe2 = mt2.get_qel();
400 check_econd12(qe1, !=, qe2, mcerr);
401 const long qel_lin = mt1.get_qel_lin();
402 for (long n = 0; n < qel_lin; n++) {
403 mt1.acu_lin(n) += mt2.acu_lin(n);
404 }
405 return mt1;
406}
407
408template <class T>
409DynArr<T> operator-(const DynArr<T>& mt1, const DynArr<T>& mt2) {
410 mfunnamep(
411 "template<class T> DynArr<T> operator-(const DynArr<T>& mt1, const "
412 "DynArr<T>& mt2)");
413 long qdim1 = mt1.get_qdim();
414 long qdim2 = mt2.get_qdim();
415 check_econd12(qdim1, !=, qdim2, mcerr);
416 const DynLinArr<long>& qe1 = mt1.get_qel();
417 const DynLinArr<long>& qe2 = mt2.get_qel();
418 check_econd12(qe1, !=, qe2, mcerr);
419 DynArr<T> ms(mt1.get_qel(), NULL);
420 const long qel_lin = mt1.get_qel_lin();
421 for (long n = 0; n < qel_lin; n++) {
422 ms.acu_lin(n) = mt1.acu_lin(n) - mt2.acu_lin(n);
423 }
424 return ms;
425}
426
427template <class T>
429 mfunnamep(
430 "template<class T> DynArr<T>& operator-(DynArr<T>& mt1, const "
431 "DynArr<T>& mt2)");
432 long qdim1 = mt1.get_qdim();
433 long qdim2 = mt2.get_qdim();
434 check_econd12(qdim1, !=, qdim2, mcerr);
435 const DynLinArr<long>& qe1 = mt1.get_qel();
436 const DynLinArr<long>& qe2 = mt2.get_qel();
437 check_econd12(qe1, !=, qe2, mcerr);
438 const long qel_lin = mt1.get_qel_lin();
439 for (long n = 0; n < qel_lin; n++) {
440 mt1.acu_lin(n) -= mt2.acu_lin(n);
441 }
442 return mt1;
443}
444
445template <class T>
447 mfunnamep("template<class T> DynArr<T> operator-(const DynArr<T>& mt)");
448 DynArr<T> ms(mt.get_qel(), NULL);
449 const long qel_lin = mt.get_qel_lin();
450 for (long n = 0; n < qel_lin; n++) {
451 ms.acu_lin(n) -= mt.acu_lin(n);
452 }
453 return ms;
454}
455
456template <class T>
458 // just change sign without copying total content,
459 // but correspondent member function should exist for type of elements T
460 const long qel_lin = mt.get_qel_lin();
461 for (long n = 0; n < qel_lin; n++) {
462 change_sign(mt.acu_lin(n));
463 }
464}
465
466template <class T, class X>
467DynArr<T>& operator+=(DynArr<T>& mt, const X& t) {
468 mfunnamep(
469 "template<class T, class X> DynArr<T>& operator+=(DynArr<T>& mt, "
470 "const X& t)");
471 const long qel_lin = mt.get_qel_lin();
472 for (long n = 0; n < qel_lin; n++) {
473 mt.acu_lin(n) += t;
474 }
475 return mt;
476}
477
478template <class T, class X>
479DynArr<T>& operator-=(DynArr<T>& mt, const X& t) {
480 mfunnamep(
481 "template<class T, class X> DynArr<T>& operator-=(DynArr<T>& mt, "
482 "const X& t)");
483 const long qel_lin = mt.get_qel_lin();
484 for (long n = 0; n < qel_lin; n++) {
485 mt.acu_lin(n) += t;
486 }
487 return mt;
488}
489
490DynArr<DoubleAc> operator+(const DynArr<DoubleAc>& mt1,
491 const DynArr<double>& mt2);
492DynArr<DoubleAc> operator+(const DynArr<double>& mt1,
493 const DynArr<DoubleAc>& mt2);
494DynArr<DoubleAc> operator-(const DynArr<DoubleAc>& mt1,
495 const DynArr<double>& mt2);
496DynArr<DoubleAc> operator-(const DynArr<double>& mt1,
497 const DynArr<DoubleAc>& mt2);
498
499}
500
501#endif
#define check_econd11(a, signb, stream)
Definition: FunNameStack.h:155
#define mfunnamep(string)
Definition: FunNameStack.h:49
#define spexit(stream)
Definition: FunNameStack.h:256
#define check_econd12(a, sign, b, stream)
Definition: FunNameStack.h:163
#define mfunname(string)
Definition: FunNameStack.h:45
T & acu(long i1)
Definition: AbsArr.h:1720
long get_qel_lin(void) const
Definition: AbsArr.h:2114
const DynLinArr< long > & get_qel(void) const
Definition: AbsArr.h:2152
T & acu_lin(long n)
Definition: AbsArr.h:2146
long get_qdim(void) const
Definition: AbsArr.h:2151
long get_qel(void) const
Definition: AbsArr.h:283
T & acu(long n)
Definition: AbsArr.h:247
Definition: BGMesh.cpp:6
DynLinArr< T > & operator/=(DynLinArr< T > &ar, const X &t)
Definition: multiply.h:173
DoubleAc operator+(const DoubleAc &f1, const DoubleAc &f2)
Definition: DoubleAc.h:431
DoubleAc operator-(const DoubleAc &f)
Definition: DoubleAc.h:419
DoubleAc operator/(const DoubleAc &f1, const DoubleAc &f2)
Definition: DoubleAc.h:569
DynLinArr< T > & operator-=(DynLinArr< T > &vc1, const DynLinArr< T > &vc2)
Definition: multiply.h:302
void change_sign(DoubleAc &f)
Definition: DoubleAc.h:424
DoubleAc operator*(const DoubleAc &f1, const DoubleAc &f2)
Definition: DoubleAc.h:523
DynLinArr< T > & operator*=(DynLinArr< T > &ar, const X &t)
Definition: multiply.h:139
DynLinArr< T > & operator+=(DynLinArr< T > &vc1, const DynLinArr< T > &vc2)
Definition: multiply.h:267
#define mcerr
Definition: prstream.h:128