Jpp test-rotations-old-533-g2bdbdb559
the software that should make you happy
Loading...
Searching...
No Matches
JMatrixND.hh
Go to the documentation of this file.
1#ifndef __JMATH__JMATRIXND__
2#define __JMATH__JMATRIXND__
3
4#include <cstring>
5#include <limits>
6#include <cmath>
7#include <algorithm>
8
10#include "JLang/JException.hh"
11#include "JLang/JEquals.hh"
12#include "JLang/JManip.hh"
13#include "JMath/JMath.hh"
14#include "JMath/JVectorND.hh"
15
16/**
17 * \author mdejong
18 */
19
20namespace JMATH {}
21namespace JPP { using namespace JMATH; }
22
23namespace JMATH {
24
25 using JIO::JReader;
26 using JIO::JWriter;
27 using JLANG::JEquals;
31
32
33 /**
34 * Basic NxN matrix.
35 */
36 struct JMatrixND_t {
37 /**
38 * Default constructor.
39 */
41 __p(NULL),
42 __n(0),
43 __m(0)
44 {}
45
46
47 /**
48 * Copy constructor.
49 *
50 * \param A matrix
51 */
54 {
55 set(A);
56 }
57
58
59 /**
60 * Move constructor.
61 *
62 * \param A matrix
63 */
66 {
67 swap(A);
68 }
69
70
71 /**
72 * Destructor.
73 */
75 {
76 clear();
77 }
78
79
80 /**
81 * Clear memory.
82 */
83 void clear()
84 {
85 if (__p != NULL) {
86 delete [] __p;
87 }
88
89 __p = NULL;
90 __n = 0;
91 __m = 0;
92 }
93
94
95 /**
96 * Resize matrix.
97 *
98 * Note that this method does not maintain data in the matrix.
99 *
100 * \param size dimension
101 */
102 void resize(const size_t size)
103 {
104 if (size != this->__n) {
105
106 if (size > this->__m) {
107
108 if (__p != NULL) {
109 delete[] __p;
110 }
111
112 __m = size;
113 __p = new double[__m*__m];
114
115 if (__p == NULL) {
116 THROW(JNewException, "JMatrixND::resize(" << size << "): Memory allocation failure.");
117 }
118 }
119
120 __n = size;
121 }
122 }
123
124
125 /**
126 * Set matrix to the null matrix.
127 *
128 * \return this matrix
129 */
131 {
132 double* p0 = this->data();
133 double* p1 = this->data();
134
135 if (!this->empty()) {
136
137 for (size_t i = this->size(); i != 0; --i, ++p1) {
138 *p1 = 0.0;
139 }
140
141 for (size_t i = this->size(); i != 1; --i, p1 += this->size()) {
142 memcpy(p1, p0, this->size() * sizeof(double));
143 }
144 }
145
146 return *this;
147 }
148
149
150 /**
151 * Set matrix.
152 *
153 * \param A matrix
154 */
155 void set(const JMatrixND_t& A)
156 {
157 this->resize(A.size());
158
159 memcpy(this->data(), A.data(), A.size() * A.size() * sizeof(double));
160 }
161
162
163 /**
164 * Swap matrices
165 *
166 * \param A matrix
167 */
169 {
170 using std::swap;
171
172 swap(this->__p, A.__p);
173 swap(this->__n, A.__n);
174 swap(this->__m, A.__m);
175 }
176
177
178 /**
179 * Transpose.
180 *
181 * \return this matrix
182 */
184 {
185 using std::swap;
186
187 for (size_t row = 0; row != this->size(); ++row) {
188 for (size_t col = 0; col != row; ++col) {
189 swap((*this)(row,col), (*this)(col,row));
190 }
191 }
192
193 return *this;
194 }
195
196
197 /**
198 * Get dimension of matrix.
199 *
200 * \return dimension
201 */
202 size_t size() const
203 {
204 return __n;
205 }
206
207
208 /**
209 * Get capacity of dimension.
210 *
211 * \return capacity
212 */
213 size_t capacity() const
214 {
215 return __m;
216 }
217
218
219 /**
220 * Check emptyness.
221 *
222 * \return true if empty; else false
223 */
224 bool empty() const
225 {
226 return __n == 0;
227 }
228
229
230 /**
231 * Get pointer to data.
232 *
233 * \return pointer to data.
234 */
235 const double* data() const
236 {
237 return __p;
238 }
239
240
241 /**
242 * Get pointer to data.
243 *
244 * \return pointer to data.
245 */
246 double* data()
247 {
248 return __p;
249 }
250
251
252 /**
253 * Get row data.
254 *
255 * \param row row number
256 * \return pointer to row data
257 */
258 const double* operator[](size_t row) const
259 {
260 return __p + row*__n;
261 }
262
263
264 /**
265 * Get row data.
266 *
267 * \param row row number
268 * \return pointer to row data
269 */
270 double* operator[](size_t row)
271 {
272 return __p + row*__n;
273 }
274
275
276 /**
277 * Get matrix element.
278 *
279 * \param row row number
280 * \param col column number
281 * \return matrix element at (row,col)
282 */
283 double operator()(const size_t row, const size_t col) const
284 {
285 return *(__p + row*__n + col);
286 }
287
288
289 /**
290 * Get matrix element.
291 *
292 * \param row row number
293 * \param col column number
294 * \return matrix element at (row,col)
295 */
296 double& operator()(const size_t row, const size_t col)
297 {
298 return *(__p + row*__n + col);
299 }
300
301
302 /**
303 * Get matrix element.
304 *
305 * \param row row number
306 * \param col column number
307 * \return matrix element at (row,col)
308 */
309 double at(size_t row, size_t col) const
310 {
311 if (row >= this->size() ||
312 col >= this->size()) {
313 THROW(JIndexOutOfRange, "JMatrixND::at(" << row << "," << col << "): index out of range.");
314 }
315
316 return (*this)(row, col);
317 }
318
319
320 /**
321 * Get matrix element.
322 *
323 * \param row row number
324 * \param col column number
325 * \return matrix element at (row,col)
326 */
327 double& at(size_t row, size_t col)
328 {
329 if (row >= this->size() ||
330 col >= this->size()) {
331 THROW(JIndexOutOfRange, "JMatrixND::at(" << row << "," << col << "): index out of range.");
332 }
333
334 return (*this)(row, col);
335 }
336
337
338 protected:
339 double* __p; //!< pointer to data
340 size_t __n; //!< dimension of matrix
341 size_t __m; //!< capacity of matrix
342 };
343
344
345 /**
346 * NxN matrix.
347 */
348 struct JMatrixND :
349 public JMatrixND_t,
350 public JMath <JMatrixND>,
351 public JEquals<JMatrixND>
352 {
353 protected:
355
356 /**
357 * Get work space.
358 *
359 * \return work space
360 */
362 {
363 return ws;
364 }
365
366 public:
367
368 using JMath<JMatrixND>::mul;
369
370 /**
371 * Default constructor.
372 */
374 {}
375
376
377 /**
378 * Constructor.
379 *
380 * The matrix is set to zero.
381 *
382 * \param size dimension
383 */
384 JMatrixND(const size_t size)
385 {
386 resize(size);
387 reset();
388 }
389
390
391 /**
392 * Copy constructor.
393 *
394 * \param A matrix
395 */
397 {
398 set(A);
399 }
400
401
402 /**
403 * Move constructor.
404 *
405 * \param A matrix
406 */
408 {
409 swap(A);
410 }
411
412
413 /**
414 * Assignment operator.
415 *
416 * \param A matrix
417 */
419 {
420 this->set(A);
421
422 return *this;
423 }
424
425
426 /**
427 * Move assignment operator.
428 *
429 * \param A matrix
430 */
432 {
433 this->swap(A);
434
435 return *this;
436 }
437
438
439 /**
440 * Resize matrix.
441 *
442 * Note that this method does not maintain data in the matrix.
443 *
444 * \param size dimension
445 */
446 void resize(const size_t size)
447 {
448 static_cast<JMatrixND_t&>(*this).resize(size);
449
451 }
452
453
454 /**
455 * Set matrix to the null matrix.
456 *
457 * \return this matrix
458 */
460 {
462
464
465 A.resize(this->size());
466
467 return *this;
468 }
469
470
471 /**
472 * Set to identity matrix
473 *
474 * \return this matrix
475 */
477 {
478 reset();
479
480 for (size_t i = 0; i != this->size(); ++i) {
481 (*this)(i,i) = 1.0;
482 }
483
484 return *this;
485 }
486
487
488 /**
489 * Negate matrix.
490 *
491 * \return this matrix
492 */
494 {
495 double* p = this->data();
496
497 for (size_t i = this->size()*this->size(); i != 0; --i, ++p) {
498 *p = -*p;
499 }
500
501 return *this;
502 }
503
504
505 /**
506 * Matrix addition.
507 *
508 * \param A matrix
509 * \return this matrix
510 */
512 {
513 if (this->size() == A.size()) {
514
515 double* p = this->data();
516 const double* q = A.data();
517
518 for (size_t i = this->size()*this->size(); i != 0; --i, ++p, ++q) {
519 *p += *q;
520 }
521
522 } else {
523 THROW(JException, "JMatrixND::add() inconsistent matrix dimensions " << this->size() << ' ' << A.size());
524 }
525
526 return *this;
527 }
528
529
530 /**
531 * Matrix subtraction.
532 *
533 * \param A matrix
534 * \return this matrix
535 */
537 {
538 if (this->size() == A.size()) {
539
540 double* p = this->data();
541 const double* q = A.data();
542
543 for (size_t i = this->size()*this->size(); i != 0; --i, ++p, ++q) {
544 *p -= *q;
545 }
546
547 } else {
548 THROW(JException, "JMatrixND::sub() inconsistent matrix dimensions " << this->size() << ' ' << A.size());
549 }
550
551 return *this;
552 }
553
554
555 /**
556 * Scale matrix.
557 *
558 * \param factor factor
559 * \return this matrix
560 */
561 JMatrixND& mul(const double factor)
562 {
563 double* p = this->data();
564
565 for (size_t i = this->size()*this->size(); i != 0; --i, ++p) {
566 *p *= factor;
567 }
568
569 return *this;
570 }
571
572
573 /**
574 * Scale matrix.
575 *
576 * \param factor factor
577 * \return this matrix
578 */
579 JMatrixND& div(const double factor)
580 {
581 double* p = this->data();
582
583 for (size_t i = this->size()*this->size(); i != 0; --i, ++p) {
584 *p /= factor;
585 }
586
587 return *this;
588 }
589
590
591 /**
592 * Matrix multiplication.
593 *
594 * \param A matrix
595 * \param B matrix
596 * \return this matrix
597 */
599 const JMatrixND& B)
600 {
601 if (A.size() == B.size()) {
602
603 this->resize(A.size());
604
605 if (!this->empty()) {
606
608
609 C.set(B);
610 C.transpose();
611
612 size_t i, row;
613
614 for (row = 0; row + 4 <= this->size(); row += 4) { // process rows by four
615
616 double* p0 = (*this)[row + 0];
617 double* p1 = (*this)[row + 1];
618 double* p2 = (*this)[row + 2];
619 double* p3 = (*this)[row + 3];
620
621 for (size_t col = 0; col != this->size(); ++col, ++p0, ++p1, ++p2, ++p3) {
622
623 double w0 = 0.0;
624 double w1 = 0.0;
625 double w2 = 0.0;
626 double w3 = 0.0;
627
628 const double* a0 = A[row + 0];
629 const double* a1 = A[row + 1];
630 const double* a2 = A[row + 2];
631 const double* a3 = A[row + 3];
632
633 const double* c0 = C[col];
634
635 for (i = 0; i + 4 <= this->size(); i += 4, a0 += 4, a1 += 4, a2 += 4, a3 += 4, c0 += 4) {
636 w0 += a0[0] * c0[0] + a0[1] * c0[1] + a0[2] * c0[2] + a0[3] * c0[3];
637 w1 += a1[0] * c0[0] + a1[1] * c0[1] + a1[2] * c0[2] + a1[3] * c0[3];
638 w2 += a2[0] * c0[0] + a2[1] * c0[1] + a2[2] * c0[2] + a2[3] * c0[3];
639 w3 += a3[0] * c0[0] + a3[1] * c0[1] + a3[2] * c0[2] + a3[3] * c0[3];
640 }
641
642 for ( ; i != this->size(); ++i, ++a0, ++a1, ++a2, ++a3, ++c0) {
643 w0 += (*a0) * (*c0);
644 w1 += (*a1) * (*c0);
645 w2 += (*a2) * (*c0);
646 w3 += (*a3) * (*c0);
647 }
648
649 *p0 = w0;
650 *p1 = w1;
651 *p2 = w2;
652 *p3 = w3;
653 }
654 }
655
656 for ( ; row != this->size(); ++row) { // remaining rows
657
658 double* p0 = (*this)[row + 0];
659
660 for (size_t col = 0; col != this->size(); ++col, ++p0) {
661
662 double w0 = 0.0;
663
664 const double* a0 = A[row + 0];
665 const double* c0 = C[col];
666
667 for (i = 0; i + 4 <= this->size(); i += 4, a0 += 4, c0 += 4) {
668 w0 += a0[0] * c0[0] + a0[1] * c0[1] + a0[2] * c0[2] + a0[3] * c0[3];
669 }
670
671 for ( ; i != this->size(); ++i, ++a0, ++c0) {
672 w0 += (*a0) * (*c0);
673 }
674
675 *p0 = w0;
676 }
677 }
678 }
679
680 } else {
681 THROW(JException, "JMatrixND::mul() inconsistent matrix dimensions " << A.size() << ' ' << B.size());
682 }
683
684 return *this;
685 }
686
687
688 /**
689 * Equality.
690 *
691 * \param A matrix
692 * \param eps numerical precision
693 * \return true if matrices identical; else false
694 */
695 bool equals(const JMatrixND& A,
696 const double eps = std::numeric_limits<double>::min()) const
697 {
698 if (this->size() == A.size()) {
699
700 for (size_t row = 0; row != this->size(); ++row) {
701
702 const double* p = (*this)[row];
703 const double* q = A [row];
704
705 for (size_t i = this->size(); i != 0; --i, ++p, ++q) {
706 if (fabs(*p - *q) > eps) {
707 return false;
708 }
709 }
710 }
711
712 return true;
713
714 } else {
715 THROW(JException, "JMatrixND::equals() inconsistent matrix dimensions " << this->size() << ' ' << A.size());
716 }
717 }
718
719
720 /**
721 * Test identity.
722 *
723 * \param eps numerical precision
724 * \return true if identity matrix; else false
725 */
726 bool isIdentity(const double eps = std::numeric_limits<double>::min()) const
727 {
728 for (size_t i = 0; i != this->size(); ++i) {
729
730 if (fabs(1.0 - (*this)(i,i)) > eps) {
731 return false;
732 };
733
734 for (size_t j = 0; j != i; ++j) {
735 if (fabs((*this)(i,j)) > eps || fabs((*this)(j,i)) > eps) {
736 return false;
737 };
738 }
739 }
740
741 return true;
742 }
743
744
745 /**
746 * Test symmetry.
747 *
748 * \param eps numerical precision
749 * \return true if symmetric matrix; else false
750 */
751 bool isSymmetric(const double eps = std::numeric_limits<double>::min()) const
752 {
753 for (size_t i = 0; i != this->size(); ++i) {
754 for (size_t j = 0; j != i; ++j) {
755 if (fabs((*this)(i,j) - (*this)(j,i)) > eps) {
756 return false;
757 };
758 }
759 }
760
761 return true;
762 }
763
764
765 /**
766 * Get dot product.
767 *
768 * The dot product corresponds to \f[ v^{T} \times A \times v \f].
769 *
770 * \param v vector
771 * \return dot product
772 */
773 double getDot(const JVectorND& v) const
774 {
775 double dot = 0.0;
776
777 for (size_t i = 0; i != v.size(); ++i) {
778
779 const double* p = (*this)[i];
780
781 double w = 0.0;
782
783 for (JVectorND::const_iterator y = v.begin(); y != v.end(); ++y, ++p) {
784 w += (*p) * (*y);
785 }
786
787 dot += v[i] * w;
788 }
789
790 return dot;
791 }
792
793
794 /**
795 * Read matrix from input.
796 *
797 * \param in reader
798 * \param A matrix
799 * \return reader
800 */
801 friend inline JReader& operator>>(JReader& in, JMatrixND& A)
802 {
803 size_t size;
804
805 in >> size;
806
807 A.resize(size);
808
809 size_t n = A.size() * A.size();
810
811 for (double* p = A.data(); n != 0; --n, ++p) {
812 in >> *p;
813 }
814
815 return in;
816 }
817
818
819 /**
820 * Write matrix to output.
821 *
822 * \param out writer
823 * \param A matrix
824 * \return writer
825 */
826 friend inline JWriter& operator<<(JWriter& out, const JMatrixND& A)
827 {
828 out << A.size();
829
830 size_t n = A.size() * A.size();
831
832 for (const double* p = A.data(); n != 0; --n, ++p) {
833 out << *p;
834 }
835
836 return out;
837 }
838
839
840 /**
841 * Print ASCII formatted output.
842 *
843 * \param out output stream
844 * \param A matrix
845 * \return output stream
846 */
847 friend inline std::ostream& operator<<(std::ostream& out, const JMatrixND& A)
848 {
849 using namespace std;
850
851 const JFormat format(out, getFormat<JMatrixND>(JFormat_t(10, 3, std::ios::fixed | std::ios::showpos)));
852
853 for (size_t row = 0; row != A.size(); ++row) {
854
855 for (size_t col = 0; col != A.size(); ++col) {
856 out << format << A(row,col) << ' ';
857 }
858
859 out << endl;
860 }
861
862 return out;
863 }
864
865
866 protected:
867 /*
868 * Swap rows.
869 *
870 * \param r1 row
871 * \param r2 row
872 */
873 void rswap(size_t r1, size_t r2)
874 {
876
877 A.resize(this->size());
878
879 memcpy(A.data(), (*this)[r1], this->size() * sizeof(double));
880 memcpy((*this)[r1], (*this)[r2], this->size() * sizeof(double));
881 memcpy((*this)[r2], A.data(), this->size() * sizeof(double));
882 }
883
884
885 /**
886 * Swap columns.
887 *
888 * \param c1 column
889 * \param c2 column
890 */
891 void cswap(size_t c1, size_t c2)
892 {
893 using std::swap;
894
895 double* p1 = this->data() + c1;
896 double* p2 = this->data() + c2;
897
898 for (size_t i = this->size(); i != 0; --i, p1 += this->size(), p2 += this->size()) {
899 swap(*p1, *p2);
900 }
901 }
902 };
903}
904
905#endif
TCanvas * c1
Global variables to handle mouse events.
TPaveText * p1
Exceptions.
#define THROW(JException_t, A)
Marco for throwing exception with std::ostream compatible message.
I/O manipulators.
JFormat_t & getFormat()
Get format for given type.
Definition JManip.hh:682
Base class for data structures with artithmetic capabilities.
Interface for binary input.
Interface for binary output.
General exception.
Definition JException.hh:24
Exception for accessing an index in a collection that is outside of its range.
Exception for failure of memory allocation.
This name space includes all other name spaces (except KM3NETDAQ, KM3NET and ANTARES).
Data structure for format specifications.
Definition JManip.hh:524
Auxiliary class to temporarily define format specifications.
Definition JManip.hh:636
Template definition of auxiliary base class for comparison of data structures.
Definition JEquals.hh:84
Auxiliary base class for aritmetic operations of derived class types.
Definition JMath.hh:347
Basic NxN matrix.
Definition JMatrixND.hh:36
size_t size() const
Get dimension of matrix.
Definition JMatrixND.hh:202
double at(size_t row, size_t col) const
Get matrix element.
Definition JMatrixND.hh:309
JMatrixND_t & reset()
Set matrix to the null matrix.
Definition JMatrixND.hh:130
~JMatrixND_t()
Destructor.
Definition JMatrixND.hh:74
void clear()
Clear memory.
Definition JMatrixND.hh:83
void set(const JMatrixND_t &A)
Set matrix.
Definition JMatrixND.hh:155
void swap(JMatrixND_t &A)
Swap matrices.
Definition JMatrixND.hh:168
size_t capacity() const
Get capacity of dimension.
Definition JMatrixND.hh:213
JMatrixND_t & transpose()
Transpose.
Definition JMatrixND.hh:183
double & operator()(const size_t row, const size_t col)
Get matrix element.
Definition JMatrixND.hh:296
JMatrixND_t(const JMatrixND_t &A)
Copy constructor.
Definition JMatrixND.hh:52
double * __p
pointer to data
Definition JMatrixND.hh:339
double operator()(const size_t row, const size_t col) const
Get matrix element.
Definition JMatrixND.hh:283
JMatrixND_t()
Default constructor.
Definition JMatrixND.hh:40
size_t __m
capacity of matrix
Definition JMatrixND.hh:341
const double * data() const
Get pointer to data.
Definition JMatrixND.hh:235
const double * operator[](size_t row) const
Get row data.
Definition JMatrixND.hh:258
double * data()
Get pointer to data.
Definition JMatrixND.hh:246
bool empty() const
Check emptyness.
Definition JMatrixND.hh:224
double & at(size_t row, size_t col)
Get matrix element.
Definition JMatrixND.hh:327
double * operator[](size_t row)
Get row data.
Definition JMatrixND.hh:270
JMatrixND_t(JMatrixND_t &&A)
Move constructor.
Definition JMatrixND.hh:64
void resize(const size_t size)
Resize matrix.
Definition JMatrixND.hh:102
size_t __n
dimension of matrix
Definition JMatrixND.hh:340
NxN matrix.
Definition JMatrixND.hh:352
friend JReader & operator>>(JReader &in, JMatrixND &A)
Read matrix from input.
Definition JMatrixND.hh:801
void cswap(size_t c1, size_t c2)
Swap columns.
Definition JMatrixND.hh:891
JMatrixND()
Default constructor.
Definition JMatrixND.hh:373
JMatrixND_t ws
Definition JMatrixND.hh:354
friend std::ostream & operator<<(std::ostream &out, const JMatrixND &A)
Print ASCII formatted output.
Definition JMatrixND.hh:847
JMatrixND & negate()
Negate matrix.
Definition JMatrixND.hh:493
JMatrixND & add(const JMatrixND &A)
Matrix addition.
Definition JMatrixND.hh:511
JMatrixND & setIdentity()
Set to identity matrix.
Definition JMatrixND.hh:476
JMatrixND & div(const double factor)
Scale matrix.
Definition JMatrixND.hh:579
void resize(const size_t size)
Resize matrix.
Definition JMatrixND.hh:446
bool equals(const JMatrixND &A, const double eps=std::numeric_limits< double >::min()) const
Equality.
Definition JMatrixND.hh:695
bool isIdentity(const double eps=std::numeric_limits< double >::min()) const
Test identity.
Definition JMatrixND.hh:726
JMatrixND & reset()
Set matrix to the null matrix.
Definition JMatrixND.hh:459
double getDot(const JVectorND &v) const
Get dot product.
Definition JMatrixND.hh:773
friend JWriter & operator<<(JWriter &out, const JMatrixND &A)
Write matrix to output.
Definition JMatrixND.hh:826
JMatrixND & operator=(JMatrixND &&A)
Move assignment operator.
Definition JMatrixND.hh:431
JMatrixND(JMatrixND &&A)
Move constructor.
Definition JMatrixND.hh:407
JMatrixND & mul(const JMatrixND &A, const JMatrixND &B)
Matrix multiplication.
Definition JMatrixND.hh:598
JMatrixND(const JMatrixND &A)
Copy constructor.
Definition JMatrixND.hh:396
JMatrixND & sub(const JMatrixND &A)
Matrix subtraction.
Definition JMatrixND.hh:536
bool isSymmetric(const double eps=std::numeric_limits< double >::min()) const
Test symmetry.
Definition JMatrixND.hh:751
JMatrixND_t & getInstance()
Get work space.
Definition JMatrixND.hh:361
JMatrixND(const size_t size)
Constructor.
Definition JMatrixND.hh:384
void rswap(size_t r1, size_t r2)
Definition JMatrixND.hh:873
JMatrixND & operator=(const JMatrixND &A)
Assignment operator.
Definition JMatrixND.hh:418
JMatrixND & mul(const double factor)
Scale matrix.
Definition JMatrixND.hh:561
Nx1 matrix.
Definition JVectorND.hh:23