LCOV - code coverage report
Current view: top level - export/home/mano/Workspace/CAS-14220/install/include/casacore/scimath/Mathematics - SquareMatrix.tcc (source / functions) Hit Total Coverage
Test: casa_coverage.info Lines: 9 34 26.5 %
Date: 2023-10-25 08:47:59 Functions: 1 6 16.7 %

          Line data    Source code
       1             : //# SquareMatrix.cc: Fast Square Matrix class with fixed (templated) size
       2             : //# Copyright (C) 1996,1998,1999,2001,2002
       3             : //# Associated Universities, Inc. Washington DC, USA.
       4             : //#
       5             : //# This library is free software; you can redistribute it and/or modify it
       6             : //# under the terms of the GNU Library General Public License as published by
       7             : //# the Free Software Foundation; either version 2 of the License, or (at your
       8             : //# option) any later version.
       9             : //#
      10             : //# This library is distributed in the hope that it will be useful, but WITHOUT
      11             : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12             : //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
      13             : //# License for more details.
      14             : //#
      15             : //# You should have received a copy of the GNU Library General Public License
      16             : //# along with this library; if not, write to the Free Software Foundation,
      17             : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
      18             : //#
      19             : //# Correspondence concerning AIPS++ should be addressed as follows:
      20             : //#        Internet email: aips2-request@nrao.edu.
      21             : //#        Postal address: AIPS++ Project Office
      22             : //#                        National Radio Astronomy Observatory
      23             : //#                        520 Edgemont Road
      24             : //#                        Charlottesville, VA 22903-2475 USA
      25             : 
      26             : #ifndef SCIMATH_SQUAREMATRIX_TCC
      27             : #define SCIMATH_SQUAREMATRIX_TCC
      28             : 
      29             : //# Includes
      30             : #include <casacore/scimath/Mathematics/SquareMatrix.h>
      31             : #include <casacore/scimath/Mathematics/MatrixMathLA.h>
      32             : #include <casacore/casa/BasicSL/Complex.h>
      33             : #include <casacore/casa/IO/ArrayIO.h>
      34             : #include <casacore/casa/Exceptions/Error.h>
      35             : #include <casacore/casa/iostream.h>
      36             : 
      37             : namespace casacore { //# NAMESPACE CASACORE - BEGIN
      38             : 
      39             : template <class T, Int n> 
      40             : SquareMatrix<T,n>& 
      41       17672 : SquareMatrix<T,n>::operator=(const SquareMatrix<T,n>& m) {
      42       17672 :     type_p=m.type_p;
      43       17672 :     switch (type_p) {
      44        3380 :         case ScalarId: a_p[0][0]=m.a_p[0][0]; break;
      45           0 :         case Diagonal: {
      46           0 :             for (Int i=0; i<n; i++) a_p[i][i]=m.a_p[i][i];
      47           0 :             break;
      48             :         }
      49       14292 :         case General: {
      50       14292 :             const T* pm=&m.a_p[0][0];
      51       14292 :             T* pa_p=&a_p[0][0];
      52       71460 :             for (Int i=0; i<n*n; i++) *pa_p++=*pm++;
      53             :         }
      54             :     }
      55       17672 :     return *this;
      56             : }
      57             : //# not accepted out of line by native compiler- moved inline
      58             : template <class T, Int n> 
      59             : SquareMatrix<T,n>& 
      60             : SquareMatrix<T,n>::operator=(const Vector<T>& v) {
      61             :     for (Int i=0; i<n; i++) a_p[i][i]=v(i);
      62             :     type_p=Diagonal;
      63             :     return *this;
      64             : }
      65             : template <class T, Int n> 
      66             : SquareMatrix<T,n>& 
      67           0 : SquareMatrix<T,n>::operator=(const Matrix<T>& m) {
      68           0 :     for (Int i=0; i<n; i++)
      69           0 :         for (Int j=0; j<n; j++) a_p[i][j]=m(i,j);
      70           0 :     type_p=General;
      71           0 :     return *this;
      72             : }
      73             : template <class T, Int n> 
      74             : SquareMatrix<T,n>& 
      75             : SquareMatrix<T,n>::operator+=(const SquareMatrix<T,n>& other) {
      76             :     switch (type_p) {
      77             :     case ScalarId: 
      78             :         switch (other.type_p) {
      79             :             case ScalarId: {
      80             :                 a_p[0][0]+=other.a_p[0][0]; 
      81             :                 return *this;
      82             :             }
      83             :             case Diagonal: {
      84             :                 T tmp=a_p[0][0];
      85             :                 for (Int i=0; i<n; i++) a_p[i][i]=tmp+other.a_p[i][i];
      86             :                 type_p=Diagonal;
      87             :                 return *this;
      88             :             }
      89             :             case General: {
      90             :                 T tmp=a_p[0][0];
      91             :                 for (Int i=0; i<n; i++) {
      92             :                     a_p[i][i]=tmp+other.a_p[i][i];
      93             :                     for (Int j=0; j<n; j++) 
      94             :                         if (i!=j) a_p[i][j]=other.a_p[i][j];
      95             :                 }
      96             :                 type_p=General;
      97             :                 return *this;
      98             :             }
      99             :         }
     100             :     case Diagonal: 
     101             :         switch (other.type_p) {
     102             :             case ScalarId: {
     103             :                 for (Int i=0; i<n; i++) a_p[i][i]+=other.a_p[0][0];
     104             :                 return *this;
     105             :             }
     106             :             case Diagonal: {
     107             :                 for (Int i=0; i<n; i++) a_p[i][i]+=other.a_p[i][i];
     108             :                 return *this;
     109             :             }
     110             :             case General: {
     111             :                 for (Int i=0; i<n; i++) {
     112             :                     a_p[i][i]+=other.a_p[i][i];
     113             :                     for (Int j=0; j<n; j++) 
     114             :                         if (i!=j) a_p[i][j]=other.a_p[i][j];
     115             :                 }
     116             :                 type_p=General;
     117             :                 return *this;
     118             :             }
     119             :         }
     120             : //  case General: 
     121             :     default:
     122             :         switch (other.type_p) {
     123             :             case ScalarId: {
     124             :                 for (Int i=0; i<n; i++) a_p[i][i]+=other.a_p[0][0];
     125             :                 return *this;
     126             :             }           
     127             :             case Diagonal: {
     128             :                 for (Int i=0; i<n; i++) a_p[i][i]+=other.a_p[i][i];
     129             :                 return *this;
     130             :             }
     131             :             case General: {
     132             :                 const T* po=&other.a_p[0][0];
     133             :                 T* pa_p=&a_p[0][0];
     134             :                 for (Int i=0; i<n*n; i++) *(pa_p++)+=*po++;
     135             :                 return *this;
     136             :             }
     137             :         }
     138             :     }
     139             :     return *this;
     140             : }
     141             : 
     142             : template <class T, Int n> 
     143             : SquareMatrix<T,n>& SquareMatrix<T,n>::operator*=(const SquareMatrix<T,n>& other) {
     144             :     switch (type_p) {
     145             :     case ScalarId: 
     146             :         switch (other.type_p) {
     147             :             case ScalarId: {
     148             :                 a_p[0][0]*=other.a_p[0][0]; 
     149             :                 return *this;
     150             :             }
     151             :             case Diagonal: {
     152             :                 T tmp=a_p[0][0];
     153             :                 for (Int i=0; i<n; i++) {
     154             :                     a_p[i][i]=tmp; a_p[i][i]*=other.a_p[i][i];
     155             :                 }
     156             :                 type_p=Diagonal;
     157             :                 return *this;
     158             :             }
     159             :             case General: {
     160             :                 T tmp=a_p[0][0];
     161             :                 for (Int i=0; i<n; i++) 
     162             :                     for (Int j=0; j<n; j++) {
     163             :                         a_p[i][j]=tmp; a_p[i][j]*=other.a_p[i][j];
     164             :                     }
     165             :                 type_p=General;
     166             :                 return *this;
     167             :             }
     168             :         }
     169             :         CASACORE_FALLTHROUGH;
     170             :     case Diagonal: 
     171             :         switch (other.type_p) {
     172             :             case ScalarId: {
     173             :                 for (Int i=0; i<n; i++) a_p[i][i]*=other.a_p[0][0];
     174             :                 return *this;
     175             :             }
     176             :             case Diagonal: {
     177             :                 for (Int i=0; i<n; i++) a_p[i][i]*=other.a_p[i][i];
     178             :                 return *this;
     179             :             }
     180             :             case General: {
     181             :                 T a[n];
     182             :                 Int i;
     183             :                 for (i=0; i<n; i++) a[i]=a_p[i][i];
     184             :                 for (i=0; i<n; i++) {
     185             :                     for (Int j=0; j<n; j++) {
     186             :                         a_p[i][j]=a[i]; a_p[i][j]*=other.a_p[i][j];
     187             :                     }
     188             :                 }
     189             :                 type_p=General;
     190             :                 return *this;
     191             :             }
     192             :         }
     193             :         CASACORE_FALLTHROUGH;
     194             :     case General: 
     195             :         switch (other.type_p) {
     196             :             case ScalarId: {
     197             :                 for (Int i=0; i<n; i++) 
     198             :                     for (Int j=0; j<n; j++) a_p[i][j]*=other.a_p[0][0];
     199             :                 return *this;
     200             :             }           
     201             :             case Diagonal: {
     202             :                 for (Int i=0; i<n; i++) 
     203             :                     for (Int j=0; j<n; j++) a_p[i][j]*=other.a_p[j][j];
     204             :                 return *this;
     205             :             }
     206             : //      case General: 
     207             :         default: {
     208             :                 T a[n], tmp;
     209             :                 for (Int i=0; i<n; i++) {
     210             :                     Int j;
     211             :                     for (j=0; j<n; j++) a[j]=a_p[i][j];
     212             :                     for (j=0; j<n; j++) {
     213             :                         a_p[i][j]=a[0]; a_p[i][j]*=other.a_p[0][j];
     214             :                         for (Int k=1; k<n; k++) {
     215             :                             //#a_p[i][j]+=a[k]*other.a_p[k][j]; inlining fails
     216             :                             tmp=a[k]; tmp*=other.a_p[k][j]; a_p[i][j]+=tmp;
     217             :                         }
     218             :                     }
     219             :                 }
     220             :                 return *this;
     221             :             }
     222             :         }
     223             :     }
     224             :     return *this;
     225             : }
     226             : template <class T, Int n> 
     227             : SquareMatrix<T,n>& SquareMatrix<T,n>::operator*=(Float f) 
     228             : {
     229             :     switch (type_p) {
     230             :         case ScalarId: a_p[0][0]*=f; break;
     231             :         case Diagonal: {
     232             :             for (Int i=0; i<n; i++) a_p[i][i]*=f;
     233             :             break;
     234             :         }
     235             :         case General: {
     236             :             T* pa_p=&a_p[0][0];
     237             :             for (Int i=0; i<n*n; i++) *pa_p++*=f;
     238             :         }
     239             :     }
     240             :     return *this;
     241             : }
     242             : 
     243             : /* fails to compile - use explicitly instantiated global function instead
     244             : template <class T, Int n> 
     245             : SquareMatrix<T,n*n>& SquareMatrix<T,n>::directProduct(SquareMatrix<T,n*n>& dp,
     246             : const SquareMatrix<T,n>& other) const
     247             : {
     248             :     switch (type_p) {
     249             :     case ScalarId: 
     250             :         switch (other.type_p) {
     251             :             case ScalarId: {
     252             :                 dp.a_p[0][0]=a_p[0][0]*other.a_p[0][0]; 
     253             :                 dp.type_p=ScalarId;
     254             :                 return dp;
     255             :             }
     256             :             case Diagonal: {
     257             :                 T tmp=a_p[0][0];
     258             :                 for (Int i=0; i<n*n; i++) dp.a_p[i][i]=tmp*other.a_p[i%n][i%n];
     259             :                 dp.type_p=Diagonal;
     260             :                 return dp;
     261             :             }
     262             :             case General: {
     263             :                 T tmp=a_p[0][0];
     264             :                 for (Int i=0; i<n*n; i++) 
     265             :                     for (Int j=0; j<n*n; j++) {
     266             :                         if (i/n == j/n) dp.a_p[i][j]=tmp*other.a_p[i%n][j%n];
     267             :                         else dp.a_p[i][j]=T();
     268             :                     }
     269             :                 dp.type_p=General
     270             :                 return dp;
     271             :             }
     272             :         }
     273             :     case Diagonal: 
     274             :         switch (other.type_p) {
     275             :             case ScalarId: {
     276             :                 T tmp=other.a_p[0][0];
     277             :                 for (Int i=0; i<n*n; i++) dp.a_p[i][i]=a_p[i/n][i/n]*tmp;
     278             :                 dp.type_p=Diagonal;
     279             :                 return dp;
     280             :             }
     281             :             case Diagonal: {
     282             :                 for (Int i=0; i<n*n; i++) 
     283             :                     dp.a_p[i][i]=a_p[i/n][i/n]*other.a_p[i%n][i%n];
     284             :                 dp.type_p=Diagonal;
     285             :                 return dp;
     286             :             }
     287             :             case General: {
     288             :                 for (Int i=0; i<n*n; i++) {
     289             :                     for (Int j=0; j<n*n; j++) {
     290             :                         if (i/n == j/n) 
     291             :                             dp.a_p[i][j]=a_p[i/n][i/n]*other.a_p[i%n][j%n];
     292             :                         else dp.a_p[i][j]=T();
     293             :                     }
     294             :                 }
     295             :                 dp.type_p=General;
     296             :                 return dp;
     297             :             }
     298             :         }
     299             :     case General: 
     300             :         switch (other.type_p) {
     301             :             case ScalarId: {
     302             :                 T tmp=other.a_p[0][0];
     303             :                 for (Int i=0; i<n*n; i++) 
     304             :                     for (Int j=0; j<n*n; j++) {
     305             :                         if (i%n == j%n) dp.a_p[i][j]=a_p[i/n][j/n]*tmp;
     306             :                         else dp.a_p[i][j]=T();
     307             :                     }
     308             :                 dp.type_p=General;
     309             :                 return dp;
     310             :             }           
     311             :             case Diagonal: {
     312             :                 for (Int i=0; i<n*n; i++) 
     313             :                     for (Int j=0; j<n*n; j++) {
     314             :                         if (i%n == j%n) 
     315             :                             dp.a_p[i][j]=a_p[i/n][j/n]*other.a_p[i%n][j%n];
     316             :                         else dp.a_p[i][j]=T();
     317             :                     }
     318             :                 dp.type_p=General;
     319             :                 return dp;
     320             :             }
     321             :             case General: {
     322             :                 for (Int i=0; i<n*n; i++) 
     323             :                     for (Int j=0; j<n*n; j++) 
     324             :                         dp.a_p[i][j]=a_p[i/n][j/n]*other.a_p[i%n][j%n];
     325             :                 dp.type_p=General;
     326             :                 return dp;
     327             :             }
     328             :         }
     329             :     }
     330             : }
     331             : */
     332             : //# above instantiated for T=Complex, n=2 in SquareMatrix2.cc
     333             : 
     334             : template <class T, Int n> 
     335             : SquareMatrix<T,n>& SquareMatrix<T,n>::conj() {
     336             :     switch (type_p) {
     337             :         case ScalarId: {
     338             :             a_p[0][0]=std::conj(a_p[0][0]);
     339             :             return *this;
     340             :         }
     341             :         case Diagonal: {
     342             :             for (Int i=0; i<n; i++) a_p[i][i]=std::conj(a_p[i][i]);
     343             :             return *this;
     344             :         }
     345             : //      case General: 
     346             :         default: {
     347             :             for (Int i=0; i<n; i++)
     348             :                 for (Int j=0; j<n; j++) a_p[i][j]=std::conj(a_p[i][j]);
     349             :             return *this;
     350             :         }
     351             :     }
     352             : }
     353             : 
     354             : template <class T, Int n> 
     355             : SquareMatrix<T,n>& SquareMatrix<T,n>::adjoint() {
     356             :     switch (type_p) {
     357             :         case ScalarId: {
     358             :             a_p[0][0]=std::conj(a_p[0][0]);
     359             :             return *this;
     360             :         }
     361             :         case Diagonal: {
     362             :             for (Int i=0; i<n; i++) a_p[i][i]=std::conj(a_p[i][i]);
     363             :             return *this;
     364             :         }
     365             :         case General: {
     366             :             for (Int i=0; i<n; i++) {
     367             :                 a_p[i][i]=std::conj(a_p[i][i]);
     368             :                 for (Int j=i+1; j<n; j++) {
     369             :                     T tmp=std::conj(a_p[i][j]);
     370             :                     a_p[i][j]=std::conj(a_p[j][i]);
     371             :                     a_p[j][i]=tmp;
     372             :                 }
     373             :             }
     374             :             return *this;
     375             :         }
     376             :     }
     377             :     return *this;
     378             : }
     379             : 
     380             : template <class T, Int n> 
     381             : SquareMatrix<T,n>& SquareMatrix<T,n>::conj(SquareMatrix<T,n>& result) {
     382             :   result = *this;
     383             :   result.conj();
     384             :   return result;
     385             : }
     386             : 
     387             : template <class T, Int n> 
     388             : SquareMatrix<T,n>& SquareMatrix<T,n>::adjoint(SquareMatrix<T,n>& result) {
     389             :   result = *this;
     390             :   result.adjoint();
     391             :   return result;
     392             : }
     393             : 
     394             : template <class T, Int n> 
     395             : SquareMatrix<T,n>& SquareMatrix<T,n>::inverse(SquareMatrix<T,n>& result) const {
     396             :   switch (type_p) {
     397             :     case ScalarId: {
     398             :       result.a_p[0][0]=T(1)/a_p[0][0];
     399             :       result.type_p=ScalarId;
     400             :       return result;
     401             :     }
     402             :     case Diagonal: {
     403             :       for (Int i=0; i<n; i++) result.a_p[i][i]=T(1)/a_p[i][i];
     404             :       result.type_p=Diagonal;
     405             :       return result;
     406             :     }
     407             : //  case General: 
     408             :     default: {
     409             :       switch (n) {
     410             :         case 2: {
     411             :           T det=a_p[0][0]*a_p[1][1]-a_p[1][0]*a_p[0][1];
     412             :           result.a_p[0][0]=a_p[1][1]/det;
     413             :           result.a_p[0][1]=-a_p[0][1]/det;
     414             :           result.a_p[1][0]=-a_p[1][0]/det;
     415             :           result.a_p[1][1]=a_p[0][0]/det;
     416             :           result.type_p=General;
     417             :           return result;
     418             :         }
     419             :         default: {
     420             :           //                return result=invert(matrix());
     421             :           Matrix<T> mat=invert(matrix());
     422             :           if (mat.nelements()==0) {
     423             :             cerr<< "invert of singular matrix attempted:"<< 
     424             :               matrix()
     425             :                 << endl;
     426             :             result=T(1);
     427             :           }
     428             :           else result=mat;
     429             :           return result;
     430             :         }
     431             :       }
     432             :     }
     433             :   }                 
     434             : }               
     435             : 
     436             : template <class T, Int n> 
     437           0 : Matrix<T>& SquareMatrix<T,n>::matrix(Matrix<T>& result) const {
     438           0 :     result.resize(n,n);
     439           0 :     switch (type_p) {
     440           0 :         case ScalarId: {
     441           0 :             result=T();
     442           0 :             for (Int i=0; i<n; i++) result(i,i)=a_p[0][0];
     443           0 :             return result;
     444             :         }
     445           0 :         case Diagonal: {
     446           0 :             result=T();
     447           0 :             for (Int i=0; i<n; i++) result(i,i)=a_p[i][i];
     448           0 :             return result;
     449             :         }
     450             : //      case General: 
     451           0 :         default: {
     452           0 :             for (Int i=0; i<n; i++)
     453           0 :                 for (Int j=0; j<n; j++) result(i,j)=a_p[i][j];
     454           0 :             return result;
     455             :         }
     456             :     }
     457             : }
     458             : 
     459             : template <class T, Int n>
     460           0 : T& SquareMatrix<T,n>::throwInvAccess() {
     461             :     throw(AipsError("SquareMatrix - attempt to change element that is "
     462           0 :                     "not available for this type of matrix"));
     463             :     // following just to make signature ok.
     464             :     return a_p[0][0];
     465             : }
     466             : 
     467             : } //# NAMESPACE CASACORE - END
     468             : 
     469             : 
     470             : #endif

Generated by: LCOV version 1.16