Jpp test-rotations-old
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.
Auxiliary classes and methods for mathematical operations.
Definition JEigen3D.hh:88
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