SheafSystem  0.0.0.0
general_matrix_3x3.impl.h
1 
2 //
3 // Copyright (c) 2014 Limit Point Systems, Inc.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 
18 // Implementation for general_matrix_3x3.
19 
20 
21 #ifndef GENERAL_MATRIX_3X3_IMPL_H
22 #define GENERAL_MATRIX_3X3_IMPL_H
23 
24 #ifndef SHEAF_DLL_SPEC_H
25 #include "SheafSystem/sheaf_dll_spec.h"
26 #endif
27 
28 #ifndef ASSERT_CONTRACT_H
29 #include "SheafSystem/assert_contract.h"
30 #endif
31 
32 #ifndef ERROR_MESSAGE_H
33 #include "SheafSystem/error_message.h"
34 #endif
35 
36 #ifndef ANTISYMMETRIC_MATRIX_3X3_H
37 #include "SheafSystem/antisymmetric_matrix_3x3.h"
38 #endif
39 
40 #ifndef GENERAL_MATRIX_1x3_H
41 #include "SheafSystem/general_matrix_1x3.h"
42 #endif
43 
44 #ifndef GENERAL_MATRIX_3X1_H
45 #include "SheafSystem/general_matrix_3x1.h"
46 #endif
47 
48 #ifndef GENERAL_MATRIX_3X2_H
49 #include "SheafSystem/general_matrix_3x2.h"
50 #endif
51 
52 #ifndef GENERAL_MATRIX_3X3_H
53 #include "SheafSystem/general_matrix_3x3.h"
54 #endif
55 
56 #ifndef SYMMETRIC_MATRIX_3X3_H
57 #include "SheafSystem/symmetric_matrix_3x3.h"
58 #endif
59 
60 #ifndef STD_SSTREAM_H
61 #include "SheafSystem/std_sstream.h"
62 #endif
63 
64 #ifndef STD_CMATH_H
65 #include "SheafSystem/std_cmath.h"
66 #endif
67 
68 #ifndef STD_ALGORITHM_H
69 #include "SheafSystem/std_algorithm.h"
70 #endif
71 
72 namespace fiber_bundle
73 {
74 
75 using namespace sheaf;
76 
77 //==============================================================================
78 // MEMBER FUNCTIONS
79 //==============================================================================
80 
82 template <typename T>
83 general_matrix_3x3<T>::
84 operator gl3_row_dofs_type<T>& () const
85 {
86  // Preconditions:
87 
88  // Body:
89 
90  T* lcomps = const_cast<T*>(components);
91 
92  gl3_row_dofs_type<T>& result =
93  reinterpret_cast<gl3_row_dofs_type<T>&>(*lcomps);
94 
95  // Postconditions:
96 
97  // Exit:
98 
99  return result;
100 }
101 
103 template <typename T>
105 operator jcb_e33_row_dofs_type<T>& () const
106 {
107  // Preconditions:
108 
109  // Body:
110 
111  T* lcomps = const_cast<T*>(components);
112 
113  jcb_e33_row_dofs_type<T>& result =
114  reinterpret_cast<jcb_e33_row_dofs_type<T>&>(*lcomps);
115 
116  // Postconditions:
117 
118  // Exit:
119 
120  return result;
121 }
122 
124 template <typename T>
126 operator t02_e3_row_dofs_type<T>& () const
127 {
128  // Preconditions:
129 
130  // Body:
131 
132  T* lcomps = const_cast<T*>(components);
133 
134  t02_e3_row_dofs_type<T>& result =
135  reinterpret_cast<t02_e3_row_dofs_type<T>&>(*lcomps);
136 
137  // Postconditions:
138 
139  // Exit:
140 
141  return result;
142 }
143 
145 template <typename T>
146 int
149 {
150  // Preconditions:
151 
152  // Body:
153 
154  // Postconditions:
155 
156  // Exit:
157 
158  return 3;
159 }
160 
162 template <typename T>
163 int
166 {
167  // Preconditions:
168 
169  // Body:
170 
171  // Postconditions:
172 
173  // Exit:
174 
175  return 3;
176 }
177 
179 template <typename T>
180 int
182 d()
183 {
184  // Preconditions:
185 
186  // Body:
187 
188  // Postconditions:
189 
190  // Exit:
191 
192  return 9;
193 }
194 
196 template <typename T>
197 T*
199 operator[](int xrow)
200 {
201  // Preconditions:
202 
203  require(xrow >= 0 && xrow < number_of_rows());
204 
205  // Body:
206 
207  T* result = &components[row_index(xrow)];
208 
209  // Postconditions:
210 
211  ensure(result != 0);
212 
213  // Exit:
214 
215  return result;
216 }
217 
218 template <typename T>
219 const T*
221 operator[](int xrow) const
222 {
223  // Preconditions:
224 
225  require(xrow >= 0 && xrow < number_of_rows());
226 
227  // Body:
228 
229  const T* result = &components[row_index(xrow)];
230 
231  // Postconditions:
232 
233  ensure(result != 0);
234 
235  // Exit:
236 
237  return result;
238 }
239 
241 template <typename T>
244 row(int xrow) const
245 {
246  // Preconditions:
247 
248  require(xrow >= 0 && xrow < number_of_rows());
249 
250  // Body:
251 
252  general_matrix_1x3<T> result;
253 
254  int lindex = row_index(xrow);
255  result.components[0] = components[lindex++];
256  result.components[1] = components[lindex++];
257  result.components[2] = components[lindex];
258 
259  // Postconditions:
260 
261  // Exit:
262 
263  return result;
264 
265 }
266 
268 template <typename T>
271 column(int xcolumn) const
272 {
273  // Preconditions:
274 
275  require(xcolumn >= 0 && xcolumn < number_of_columns());
276 
277  // Body:
278 
279  general_matrix_3x1<T> result;
280 
281  int lindex = xcolumn;
282  result.components[0] = components[lindex];
283  lindex += 3; // += number_of_columns();
284  result.components[1] = components[lindex];
285  lindex += 3; // += number_of_columns();
286  result.components[2] = components[lindex];
287 
288  // Postconditions:
289 
290  // Exit:
291 
292  return result;
293 }
294 
296 template <typename T>
298 operator T* ()
299 {
300  // Preconditions:
301 
302  // Body:
303 
304  //cout << "general_matrix_3x3<T>::operator T* () " << std::endl;
305 
306  T* result = components;
307 
308  // Postconditions:
309 
310  ensure(result != 0);
311 
312  // Exit:
313 
314  return result;
315 }
316 
318 template <typename T>
320 operator const T* () const
321 {
322  // Preconditions:
323 
324  // Body:
325 
326  //cout << "general_matrix_3x3<T>::operator const T* () const " << std::endl;
327 
328  const T* result = components;
329 
330  // Postconditions:
331 
332  ensure(result != 0);
333 
334  // Exit:
335 
336  return result;
337 }
338 
340 template <typename T>
341 int
343 row_index(int xrow) const
344 {
345  // Preconditions:
346 
347  require(xrow >= 0 && xrow < number_of_rows());
348 
349  // Body:
350 
351  //int result = number_of_columns()*xrow;
352  int result = 3*xrow;
353 
354  // Postconditions:
355 
356  ensure(result == number_of_columns()*xrow);
357 
358  // Exit:
359 
360  return result;
361 }
362 
363 
365 template <typename T>
366 void
369 {
370  // Preconditions:
371 
372  // Body:
373 
374  // Get the cofactors.
375 
376  const general_matrix_3x3<T>& lm = *this;
377 
378  T a00 = lm[0][0];
379  T a01 = lm[0][1];
380  T a02 = lm[0][2];
381  T a10 = lm[1][0];
382  T a11 = lm[1][1];
383  T a12 = lm[1][2];
384  T a20 = lm[2][0];
385  T a21 = lm[2][1];
386  T a22 = lm[2][2];
387 
388  T c00 = a11*a22 - a12*a21;
389  T c01 = a12*a20 - a10*a22;
390  T c02 = a10*a21 - a11*a20;
391 
392  T c10 = a02*a21 - a01*a22;
393  T c11 = a00*a22 - a02*a20;
394  T c12 = a01*a20 - a00*a21;
395 
396  T c20 = a01*a12 - a02*a11;
397  T c21 = a02*a10 - a00*a12;
398  T c22 = a00*a11 - a01*a10;
399 
400  // Adjoint is the transpose of the cofactor matrix.
401 
402  xresult[0][0] = c00;
403  xresult[0][1] = c10;
404  xresult[0][2] = c20;
405 
406  xresult[1][0] = c01;
407  xresult[1][1] = c11;
408  xresult[1][2] = c21;
409 
410  xresult[2][0] = c02;
411  xresult[2][1] = c12;
412  xresult[2][2] = c22;
413 
414  // Postconditions:
415 
416  // Exit:
417 }
418 
420 template <typename T>
423 adjoint() const
424 {
425  // Preconditions:
426 
427  // Body:
428 
429  general_matrix_3x3<T> result;
430  adjoint(result);
431 
432  // Postconditions:
433 
434  // Exit:
435 
436  return result;
437 }
438 
440 template <typename T>
441 void
443 assign(const T& xvalue)
444 {
445  // Preconditions:
446 
447  // Body:
448 
449  for(int i=0; i<d(); ++i)
450  {
451  components[i] = xvalue;
452  }
453 
454  // Postconditions:
455 
456  ensure_for_all(i, 0, d(), components[i] == xvalue);
457 
458  // Exit:
459 }
460 
462 template <typename T>
463 void
465 determinant(T& xresult) const
466 {
467  // Preconditions:
468 
469  // Body:
470 
471  const general_matrix_3x3<T>& lm = *this;
472 
473  T a00 = lm[0][0];
474  T a01 = lm[0][1];
475  T a02 = lm[0][2];
476  T a10 = lm[1][0];
477  T a11 = lm[1][1];
478  T a12 = lm[1][2];
479  T a20 = lm[2][0];
480  T a21 = lm[2][1];
481  T a22 = lm[2][2];
482 
483  T c00 = a11*a22 - a12*a21;
484  T c01 = a12*a20 - a10*a22;
485  T c02 = a10*a21 - a11*a20;
486 
487  xresult = a00*c00 + a01*c01 + a02*c02;
488 
489  // Postconditions:
490 
491  // Exit:
492 
493 }
494 
496 template <typename T>
497 T
499 determinant() const
500 {
501  // Preconditions:
502 
503  // Body:
504 
505  T result;
506 
507  determinant(result);
508 
509  // Postconditions:
510 
511  // Exit:
512 
513  return result;
514 }
515 
517 template <typename T>
518 void
521 {
522  // Preconditions:
523 
524  // Body:
525 
526  // Calculate the eigenvalues of the matrix.
527 
528  // For 3x3 matrices the eigenvalues can be determined
529  // by solving a cubic equation, ie;
530  // a*x*x*x = b*x*x +c*x +d = 0.
531 
532  //@todo $$TODO: We need a templated cubic equation solver function.
533  // For example:
534  // template <typename T> cubic_solver(T a, T b, T c, T d,
535  // T result[3]);
536 
537  T lambda_0;
538  T lambda_1;
539  T lambda_2;
540 
541  const T zero = T(0);
542 
543  const general_matrix_3x3<T>& lm = *this;
544 
545  T a00 = lm[0][0];
546  T a01 = lm[0][1];
547  T a02 = lm[0][2];
548  T a10 = lm[1][0];
549  T a11 = lm[1][1];
550  T a12 = lm[1][2];
551  T a20 = lm[2][0];
552  T a21 = lm[2][1];
553  T a22 = lm[2][2];
554 
555  T d = -determinant();
556  T c = a00*(a11 + a22) + a11*a22 - a01*a10 - a02*a20 - a12*a21;
557  T b = -(a00 + a11 + a22);
558  T a = 1.0;
559 
560  // If the determanant (-d) == 0.0, one eigenvalue is 0 and we can factor
561  // to get a quadratic to solve (a*x*x = b*x +c = 0).
562 
563  if(d == 0)
564  {
565  T discriminant = b*b - 4.0*c;
566 
567  if(discriminant < 0.0)
568  {
569  post_fatal_error_message("Matrix has 2 complex roots.");
570  }
571 
572  T sqrt_discriminant = sqrt(discriminant);
573 
574  lambda_0 = zero;
575  lambda_1 = 0.5*(-b+sqrt_discriminant);;
576  lambda_2 = 0.5*(-b-sqrt_discriminant);
577  }
578  else
579  {
580  T q = (3.0*c - b*b)/9.0;
581  T r = (b*(9.0*c - 2.0*b*b) - 27.0*d) / 54.0;
582 
583  T discriminant = q*q*q + r*r;
584  T b3 = b/3.0;
585 
586  if(discriminant > 0.0)
587  {
588  // There is 1 real root and 2 complex conjugate roots.
589 
590  post_fatal_error_message("Matrix has 2 complex roots.");
591  }
592  else if(discriminant== 0.0)
593  {
594  // There are 3 real roots and 2 are equal.
595 
596  T powr = (r < 0) ? -pow(-r, 1.0/3.0) : pow(r, 1.0/3.0);
597  lambda_0 = (2.0*powr) - b3;
598  lambda_1 = (-powr) - b3;
599  lambda_2 = lambda_1;
600  }
601  else
602  {
603  // There are 3 real unequal roots.
604 
605  // Need pi but M_PI is not part of the standard; so compute it.
606 
607  static const T L_PI = acos(T(-1.0));
608 
609  q = -q;
610  T t1 = acos(r/sqrt(q*q*q));
611  T t2 = 2.0*sqrt(q);
612 
613  lambda_0 = t2*cos(t1/3.0) - b3;
614  lambda_1 = t2*cos((t1 + 2.0*L_PI)/3.0) - b3;
615  lambda_2 = t2*cos((t1 + 4.0*L_PI)/3.0) - b3;
616  }
617 
618  // Assign the diagonals of the result matrix to the
619  // eigenvalues and zero to the rest of the elements.
620 
621  xresult.assign(zero);
622 
623  // Sort into accending order.
624 
625  T tmp[3] = {lambda_0, lambda_1, lambda_2};
626 
627  std::sort(&tmp[0], &tmp[3]);
628 
629  xresult[0][0] = tmp[0];
630  xresult[1][1] = tmp[1];
631  xresult[2][2] = tmp[2];
632 
633  }
634 
635  // Postconditions:
636 
637  ensure(xresult.is_diagonal());
638  ensure(unexecutable("for_all i, 0, 2, xresult[i][i] == real number"));
639 
640  // Exit:
641 
642 }
643 
645 template <typename T>
649 {
650  // Preconditions:
651 
652  // Body:
653 
654  general_matrix_3x3<T> result;
655  diagonalization(result);
656 
657  // Postconditions:
658 
659  ensure(result.is_diagonal());
660  ensure(unexecutable("for_all i, 0, 2, result[i][i] == real number"));
661 
662  // Exit:
663 
664  return result;
665 }
666 
668 template <typename T>
669 void
672 {
673  // Preconditions:
674 
675  // Body:
676 
677  const T one = T(1);
678  const T zero = T(0);
679 
680  xresult.assign(zero);
681 
682  xresult[0][0] = one;
683  xresult[1][1] = one;
684  xresult[2][2] = one;
685 
686  // Postconditions:
687 
688  ensure(xresult.is_identity());
689 
690  // Exit:
691 }
692 
694 template <typename T>
697 identity() const
698 {
699  // Preconditions:
700 
701  // Body:
702 
703  general_matrix_3x3<T> result;
704  identity(result);
705 
706  // Postconditions:
707 
708  ensure(result.is_identity());
709 
710  // Exit:
711 
712  return result;
713 }
714 
715 
717 template <typename T>
718 void
721 {
722  // Preconditions:
723 
724  // Body:
725 
726  const general_matrix_3x3<T>& lm = *this;
727 
728  T a00 = lm[0][0];
729  T a01 = lm[0][1];
730  T a02 = lm[0][2];
731  T a10 = lm[1][0];
732  T a11 = lm[1][1];
733  T a12 = lm[1][2];
734  T a20 = lm[2][0];
735  T a21 = lm[2][1];
736  T a22 = lm[2][2];
737 
738  // Cofactors:
739 
740  T c00 = a11*a22 - a12*a21;
741  T c01 = a12*a20 - a10*a22;
742  T c02 = a10*a21 - a11*a20;
743 
744  T determinant = a00*c00 + a01*c01 + a02*c02;
745 
746  if(determinant == 0.0)
747  {
748  post_fatal_error_message("No inverse; determinant is zero.");
749  }
750 
751  T c10 = a02*a21 - a01*a22;
752  T c11 = a00*a22 - a02*a20;
753  T c12 = a01*a20 - a00*a21;
754 
755  T c20 = a01*a12 - a02*a11;
756  T c21 = a02*a10 - a00*a12;
757  T c22 = a00*a11 - a01*a10;
758 
759  xresult[0][0] = c00/determinant;
760  xresult[0][1] = c10/determinant;
761  xresult[0][2] = c20/determinant;
762 
763  xresult[1][0] = c01/determinant;
764  xresult[1][1] = c11/determinant;
765  xresult[1][2] = c21/determinant;
766 
767  xresult[2][0] = c02/determinant;
768  xresult[2][1] = c12/determinant;
769  xresult[2][2] = c22/determinant;
770 
771  // Postconditions:
772 
773  // Exit:
774 }
775 
777 template <typename T>
780 inverse() const
781 {
782  // Preconditions:
783 
784  // Body:
785 
786  general_matrix_3x3<T> result;
787  inverse(result);
788 
789  // Postconditions:
790 
791  // Exit:
792 
793  return result;
794 }
795 
797 template <typename T>
798 bool
801 {
802  // Preconditions:
803 
804  // Body:
805 
806  const general_matrix_3x3<T>& lm = *this;
807 
808  bool result = (lm[0][0]==0.0) && (lm[1][1]==0.0) && (lm[2][2]==0.0) &&
809  (lm[1][0]==-lm[0][1]) &&
810  (lm[2][0]==-lm[0][2]) &&
811  (lm[2][1]==-lm[1][2]);
812 
813  // Postconditions:
814 
815  // Exit:
816 
817  return result;
818 
819 }
820 
822 template <typename T>
823 bool
825 is_diagonal() const
826 {
827  // Preconditions:
828 
829  // Body:
830 
831  const general_matrix_3x3<T>& lm = *this;
832 
833  bool result =
834  (lm[0][1]==0.0) && (lm[0][2]==0.0) && (lm[1][0]==0.0) &&
835  (lm[1][2]==0.0) && (lm[2][0]==0.0) && (lm[2][1]==0.0);
836 
837  // Postconditions:
838 
839  // Exit:
840 
841  return result;
842 
843 }
844 
846 template <typename T>
847 bool
849 is_identity() const
850 {
851  // Preconditions:
852 
853  // Body:
854 
855  const general_matrix_3x3<T>& lm = *this;
856 
857  bool result = is_diagonal() &&
858  (lm[0][0]==1.0) && (lm[1][1]==1.0) && (lm[2][2]==1.0);
859 
860  // Postconditions:
861 
862  // Exit:
863 
864  return result;
865 
866 }
867 
868 
870 template <typename T>
871 bool
874 {
875  // Preconditions:
876 
877  // Body:
878 
879  //$ISSUE: Does this test mean anything for the general case? Maybe.
880  // See http://mathworld.wolfram.com/PositiveDefiniteMatrix.html.
881 
882  // Get the symmetric part and test it.
883 
884  symmetric_matrix_3x3<T> lsym = symmetric_part();
885  bool result = lsym.is_positive_definite();
886 
887  // Postconditions:
888 
889  // Exit:
890 
891  return result;
892 }
893 
895 template <typename T>
896 bool
899 {
900  // Preconditions:
901 
902  // Body:
903 
904  const general_matrix_3x3<T>& lm = *this;
905 
906  bool result = (lm[1][0]==lm[0][1]) &&
907  (lm[2][0]==lm[0][2]) &&
908  (lm[2][1]==lm[1][2]);
909 
910  // Postconditions:
911 
912  // Exit:
913 
914  return result;
915 
916 }
917 
919 template <typename T>
920 void
922 multiply(const T& xscalar, general_matrix_3x3<T>& xresult) const
923 {
924  // Preconditions:
925 
926  // Body:
927 
928  for(int i=0; i<d(); ++i)
929  {
930  xresult.components[i] = xscalar*components[i];
931  }
932 
933  // Postconditions:
934 
935  //@issue $$ISSUE: We can't make the following comparison because of
936  // floating point roundoff.
937  //ensure_for_all(i, 0, d(), xresult.components[i] == xscalar*components[i]);
938 
939  // Exit:
940 
941 }
942 
944 template <typename T>
947 multiply(const T& xscalar) const
948 {
949  // Preconditions:
950 
951  // Body:
952 
953  general_matrix_3x3<T> result;
954  multiply(xscalar, result);
955 
956  // Postconditions:
957 
958  // Exit:
959 
960  return result;
961 }
962 
964 template <typename T>
965 void
968  general_matrix_3x3<T>& xresult) const
969 {
970  // Preconditions:
971 
972  // Body:
973 
974  // Multiply [A][B] where [A] = *this & [B] = xother.
975 
976  const general_matrix_3x3<T>& lm = *this;
977 
978  int nra = number_of_rows();
979  int nca = number_of_columns();
980  int ncb = xother.number_of_columns();
981 
982  for(int i=0; i<nra; ++i)
983  {
984  for(int j=0; j<ncb; ++j)
985  {
986  T sum = T(0);
987 
988  for(int k=0; k<nca; ++k)
989  {
990  sum += lm[i][k]*xother[k][j];
991  }
992 
993  xresult[i][j] = sum;
994  }
995  }
996 
997  // Postconditions:
998 
999  // Exit:
1000 
1001 }
1002 
1004 template <typename T>
1007 multiply(const general_matrix_3x3<T>& xother) const
1008 {
1009  // Preconditions:
1010 
1011  // Body:
1012 
1013  general_matrix_3x3<T> result;
1014  multiply(xother, result);
1015 
1016  // Postconditions:
1017 
1018  // Exit:
1019 
1020  return result;
1021 }
1022 
1024 template <typename T>
1025 void
1028  general_matrix_3x2<T>& xresult) const
1029 {
1030  // Preconditions:
1031 
1032  // Body:
1033 
1034  // Multiply [A][B] where [A] = *this & [B] = xother.
1035 
1036  const general_matrix_3x3<T>& lm = *this;
1037 
1038  int nra = number_of_rows();
1039  int nca = number_of_columns();
1040  int ncb = xother.number_of_columns();
1041 
1042  for(int i=0; i<nra; ++i)
1043  {
1044  for(int j=0; j<ncb; ++j)
1045  {
1046  T sum = T(0);
1047 
1048  for(int k=0; k<nca; ++k)
1049  {
1050  sum += lm[i][k]*xother[k][j];
1051  }
1052 
1053  xresult[i][j] = sum;
1054  }
1055  }
1056 
1057  // Postconditions:
1058 
1059  // Exit:
1060 
1061 }
1062 
1064 template <typename T>
1067 multiply(const general_matrix_3x2<T>& xother) const
1068 {
1069  // Preconditions:
1070 
1071  // Body:
1072 
1073  general_matrix_3x2<T> result;
1074  multiply(xother, result);
1075 
1076  // Postconditions:
1077 
1078  // Exit:
1079 
1080  return result;
1081 }
1082 
1084 template <typename T>
1085 void
1088  general_matrix_3x1<T>& xresult) const
1089 {
1090  // Preconditions:
1091 
1092  // Body:
1093 
1094  // Multiply [A][B] where [A] = *this & [B] = xother.
1095 
1096  const general_matrix_3x3<T>& lm = *this;
1097 
1098  int nra = number_of_rows();
1099  int nca = number_of_columns();
1100  int ncb = xother.number_of_columns();
1101 
1102  for(int i=0; i<nra; ++i)
1103  {
1104  for(int j=0; j<ncb; ++j)
1105  {
1106  T sum = T(0);
1107 
1108  for(int k=0; k<nca; ++k)
1109  {
1110  sum += lm[i][k]*xother[k][j];
1111  }
1112 
1113  xresult[i][j] = sum;
1114  }
1115  }
1116 
1117  // Postconditions:
1118 
1119  // Exit:
1120 
1121 }
1122 
1124 template <typename T>
1127 multiply(const general_matrix_3x1<T>& xother) const
1128 {
1129  // Preconditions:
1130 
1131  // Body:
1132 
1133  general_matrix_3x1<T> result;
1134  multiply(xother, result);
1135 
1136  // Postconditions:
1137 
1138  // Exit:
1139 
1140  return result;
1141 }
1142 
1143 
1145 template <typename T>
1146 void
1148 trace(T& xresult) const
1149 {
1150  // Preconditions:
1151 
1152  // Body:
1153 
1154  const general_matrix_3x3<T>& lm = *this;
1155 
1156  // Unroll the loop for efficiency.
1157 
1158  xresult = lm[0][0] + lm[1][1] + lm[2][2];
1159 
1160  // Postconditions:
1161 
1162  ensure(xresult == lm[0][0] + lm[1][1] + lm[2][2]);
1163 
1164  // Exit:
1165 }
1166 
1168 template <typename T>
1169 T
1171 trace() const
1172 {
1173  // Preconditions:
1174 
1175  // Body:
1176 
1177  T result;
1178 
1179  trace(result);
1180 
1181  // Postconditions:
1182 
1183  // Exit:
1184 
1185  return result;
1186 }
1187 
1189 template <typename T>
1190 void
1193 {
1194  // Preconditions:
1195 
1196  // Body:
1197 
1198  const general_matrix_3x3<T>& lm = *this;
1199 
1200  int nrows = number_of_rows();
1201  int ncols = number_of_columns();
1202 
1203  for(int i=0; i<nrows; ++i)
1204  {
1205  for(int j=0; j<ncols; ++j)
1206  {
1207  xresult[i][j] = lm[j][i];
1208  }
1209  }
1210 
1211  // Postconditions:
1212 
1213  // Exit:
1214 
1215 }
1216 
1218 template <typename T>
1221 transpose() const
1222 {
1223  // Preconditions:
1224 
1225  // Body:
1226 
1227  general_matrix_3x3<T> result;
1228  transpose(result);
1229 
1230  // Postconditions:
1231 
1232  // Exit:
1233 
1234  return result;
1235 }
1236 
1238 template <typename T>
1239 void
1242 {
1243  // Preconditions:
1244 
1245  // Body:
1246 
1247  // A - A(transpose) is the antisymmetric part.
1248 
1249  const general_matrix_3x3<T>& lm = *this;
1250 
1251  int n = number_of_rows();
1252 
1253  for(int i=0; i<n-1; ++i)
1254  {
1255  for(int j=i+1; j<n; ++j)
1256  {
1257  xresult[i][j] = lm[i][j] - lm[j][i];
1258  }
1259  }
1260 
1261  // Postconditions:
1262 
1263  // Exit:
1264 }
1265 
1267 template <typename T>
1271 {
1272  // Preconditions:
1273 
1274  // Body:
1275 
1277  antisymmetric_part(result);
1278 
1279  // Postconditions:
1280 
1281  // Exit:
1282 
1283  return result;
1284 }
1285 
1286 
1288 template <typename T>
1289 void
1292 {
1293  // Preconditions:
1294 
1295  // Body:
1296 
1297  // A + A(transpose) is the antisymmetric part.
1298 
1299  const general_matrix_3x3<T>& lm = *this;
1300 
1301  int n = number_of_rows();
1302 
1303  for(int i=0; i<n; ++i)
1304  {
1305  for(int j=i; j<n; ++j)
1306  {
1307  xresult[i][j] = lm[i][j] + lm[j][i];
1308  }
1309  }
1310 
1311  // Postconditions:
1312 
1313  // Exit:
1314 }
1315 
1317 template <typename T>
1321 {
1322  // Preconditions:
1323 
1324  // Body:
1325 
1326  symmetric_matrix_3x3<T> result;
1327  symmetric_part(result);
1328 
1329  // Postconditions:
1330 
1331  // Exit:
1332 
1333  return result;
1334 }
1335 
1336 
1337 // =============================================================================
1338 // NON-MEMBER FUNCTIONS
1339 // =============================================================================
1340 
1341 #ifndef DOXYGEN_SKIP_IMPLEMENTATIONS
1342 
1344 template <typename T>
1345 std::ostream& operator<<(std::ostream& xos, const general_matrix_3x3<T>& xm)
1346 {
1347  // Preconditions:
1348 
1349  // Body:
1350 
1351  int nrows = xm.number_of_rows();
1352  int ncols = xm.number_of_columns();
1353 
1354  for(int i=0; i<nrows; ++i)
1355  {
1356  for(int j=0; j<ncols; ++j)
1357  {
1358  xos << " " << xm[i][j];
1359  }
1360  xos << std::endl;
1361  }
1362 
1363  // Postconditions:
1364 
1365  // Exit:
1366 
1367  return xos;
1368 }
1369 
1370 #endif // ifndef DOXYGEN_SKIP_IMPLEMENTATIONS
1371 
1372 //==============================================================================
1373 //==============================================================================
1374 
1375 } // namespace fiber_bundle
1376 
1377 #endif // GENERAL_MATRIX_3X3_IMPL_H
1378 
SHEAF_DLL_SPEC void sqrt(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute sqrt of x0 (sqrt(x0)) (pre-allocated version).
Definition: sec_at0.cc:1556
T trace() const
The trace of the matrix (auto-allocated).
bool is_symmetric() const
True if this matrix is symmetric.
static int number_of_columns()
The number of columns.
static int number_of_columns()
The number of columns.
symmetric_matrix_3x3< T > symmetric_part() const
The symmetric part of a this matrix (auto-allocated).
antisymmetric_matrix_3x3< T > antisymmetric_part() const
The antisymmetric part of a this matrix (auto-allocated).
Antisymmetric matrix with 3 rows and 3 columns.
general_matrix_3x3< T > identity() const
The identity matrix (auto-allocated).
general_matrix_1x3< T > row(int xrow) const
A 1x3 matrix containing the elements or row xrow.
bool is_antisymmetric() const
True if this matrix is antisymmetric.
general_matrix_3x3< T > diagonalization() const
The diagonalization of the matrix (auto-allocated).
bool is_identity() const
True if this is an identity matrix.
static int d()
Dimension of the underlying elements.
General matrix with 3 rows and 2 columns.
static int number_of_rows()
The number of rows.
void assign(const T &xvalue)
Assign all elements of this matrix to the value xvalue.
bool is_positive_definite() const
True if this matrix is positive definite.
void trace(const S0 &x0, SR &xresult, bool xauto_access)
Definition: sec_st2.impl.h:99
General matrix with 3 rows and 1 column.
T determinant() const
The determinant of the matrix (auto-allocated).
void multiply(const T &xscalar, general_matrix_3x3< T > &xresult) const
This matrix multiplied by a scalar (pre-allocated).
general_matrix_3x3< T > transpose() const
The transpose of the matrix (auto-allocated).
bool is_positive_definite() const
True if this matrix is positive definite.
bool is_diagonal() const
True if this matrix is diagonal.
int row_index(int xrow) const
Index for row xrow in the linear storage array.
Row dofs type for class gl3.
Definition: gl3.h:50
T components[3]
Linear storage array.
static int number_of_columns()
The number of columns.
SHEAF_DLL_SPEC void cos(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute cos of x0 (cos(x0)) (pre-allocated version).
Definition: sec_at0.cc:1270
void determinant(const S0 &x0, SR &xresult, bool xauto_access)
Definition: sec_st2.impl.h:131
Row dofs type for class jcb_e33.
Definition: jcb_e33.h:48
general_matrix_3x3< T > inverse() const
The inverse of the matrix (auto-allocated).
T * operator[](int xrow)
Pointer to the first element in row xrow of this matrix. Facilitates accessing elements via matrix[i]...
SHEAF_DLL_SPEC void acos(const sec_at0 &x0, sec_at0 &xresult, bool xauto_access)
Compute acos of x0 (acos(x0)) (pre-allocated version).
Definition: sec_at0.cc:1154
General matrix with 3 rows and 3 columns.
General matrix with 1 row and 3 columns.
Namespace for the sheaves component of the sheaf system.
general_matrix_3x1< T > column(int xcolumn) const
A 3x1 matrix containing the elements or column xcolumn.
T components[3]
Linear storage array.
static int number_of_rows()
The number of rows.
SHEAF_DLL_SPEC void multiply(const vd &x0, const vd_value_type &x1, vd &xresult, bool xauto_access)
Vector x0 multiplied by scalar x1 (pre-allocated version for persistent types).
Definition: vd.cc:1924
Namespace for the fiber_bundles component of the sheaf system.
SHEAF_DLL_SPEC void pow(const sec_at0 &x0, const vd_value_type &xexponent, sec_at0 &xresult, bool xauto_access)
Compute x0 to power xexponent (pow(x0, xexponent)) (pre-allocated version).
Definition: sec_at0.cc:1495
SHEAF_DLL_SPEC void inverse(const gl2_lite &xlite, gl2_lite &xresult)
Inverse (pre-allocated version for volatile type).
Definition: gl2.cc:1484
general_matrix_3x3< T > adjoint() const
The adjoint of the matrix (auto-allocated).
T components[9]
Linear storage array.
A tensor of degree 2 over an abstract vector space (persistent version).
Definition: t2.h:226
Symmetric matrix with 3 rows and 3 columns.