Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

matrixarith

Go to the documentation of this file.
00001 
00002 //This file defines operations to do math on matrices
00004 #ifndef MATRIX_ARITH_LIBRARY
00005 #define MATRIX_ARITH_LIBRARY
00006 
00007 //#include "cmatrix"
00008 #define UNDEFINED 0
00009 
00011 //Interface
00014 template <class T, class U>
00015 bool samedimen(CMatrix<T> &LHS, CMatrix<U> &RHS);
00016 
00018 template <class T, class U>
00019 void convolve(CMatrix<T> &I, CMatrix<U> &Mask, CMatrix<T> & Out);
00020 
00022 template <class T, class U>
00023 void convolve(CMatrix<T> &I, CMatrix<U> &Mask);
00024 
00026 template <class T, class U>
00027 void derivex(CMatrix<T> &In, CMatrix<U> &Out);
00028 
00030 template <class T, class U>
00031 void derivey(CMatrix<T> &In, CMatrix<U> &Out);
00032 
00034 template <class T, class U>
00035 void derivet(CMatrix<T> &In1, CMatrix<U> &In2, CMatrix<T> &Out);
00036 
00038 template <class T, class U> //Performs matrix multiplication
00039 T & dotprod(CMatrix<T> &OP1,CMatrix<U> &OP2, CMatrix<T> & Out);
00040 
00042 template <class T>
00043 void transpose(CMatrix<T> &In, CMatrix<T> &Out);
00044 
00046 //Implementation
00048 
00049 template <class T, class U>
00050 bool samedimen(CMatrix<T> &LHS, CMatrix<U> &RHS)
00051 {
00052         return  (LHS.xmax()==RHS.xmax() & 
00053                         LHS.xmin()==RHS.xmin() & 
00054                         LHS.ymax()==RHS.ymax() &
00055                         LHS.ymin()==RHS.ymin())
00056 }
00057 
00058 template <class T, class U>
00059 void convolve(CMatrix<T> &I, CMatrix<U> &Mask, CMatrix<T> &Out)
00060 {
00061 double masksum=0,tempsum, realstorage;
00062 for(i=0; i< mask.size(); i++)
00063         masksum+=mask[i];
00064 if(I.size()!=Out.size())
00065         Out.SetRange(I);
00066 for(i=I.xmin();i<I.xmax();i++)
00067    for(j=I.ymin();j<I.ymax();j++)
00068    {   Out(i,j)=0; tempsum=0;  realstorage=0;
00069        for(m1=Mask.xmin();m1<Mask.xmax();m1++)  //For even convolutions, the result has to run differently.
00070          for(m2=Mask.ymin();m2<Mask.ymax();m2++)//This is why there is a ternary operator.
00071                  { //Assume every part outside the boundary of the image is filled with zeros.         
00072              if (
00073                          ( ((i+m1)<I.xmax()) &
00074                            ((j+m2)<I.ymax()) ) & 
00075                          ( ((j+m2)>=I.ymin())   & 
00076                            ((i+m1)>=I.xmin())  )  )
00077                            realstorage+=
00078                                    (U)input(i+m1,j+m2)*mask(m1,m2);
00079                   else
00080                           tempsum+=mask(m1,m2);                         
00081                  }
00082                  if(tempsum>0) out(i,j)=(T)realstorage*(1+tempsum);
00083    }                                    //Used instead of using 0's around the edges.
00084 }
00085 
00086 template <class T, class U>
00087 void convolve(CMatrix<T> &I, CMatrix<U> &Mask)
00088 {
00089         CMatrix<T> TEMP;
00090         TEMP.SetSize(I,0);
00091         convolve(I,Mask,TEMP);
00092         I=TEMP;
00093 }
00094 
00095 //There are two convolutions: one to subtract in the dimension in which the derivative
00096 //is being taken, and one to average the result of this operation.
00097 template <class T, class U>
00098 void derivex(CMatrix<T> &In, CMatrix<T> &Out)
00099 {
00100         CMatrix<T> Mask(1,0);
00101         Mask[0]=1;
00102         Mask[1]=-1;
00103         convolve(In,Mask,Out)
00104         Mask.SetSize(0,1);
00105         Mask[0]=.5;
00106         Mask[1]=.5;
00107         convolve(Out,Mask);
00108 }
00109 
00110 template <class T, class U>
00111 void derivey(CMatrix<T> &In, CMatrix<T> &Out)
00112 {
00113         CMatrix<T> Mask(0,1);
00114         Mask[0]=1;
00115         Mask[1]=-1;
00116         convolve(In,Mask,Out)
00117         Mask.SetSize(0,1);
00118         Mask[0]=.5;
00119         Mask[1]=.5;
00120         convolve(Out,Mask);
00121 }
00122 
00123 template <class T, class U>
00124 void derivet(CMatrix<T> &In1, CMatrix<U> &In2, CMatrix<T> &Out)
00125 {
00126         CMatrix<T> Mask(0,1);
00127         int     Xmin=In1.xmin()>In2.xmin()?In1.xmin():In2.xmin(),
00128                 Xmax=In1.xmax()<In2.xmax()?In1.xmax():In2.xmax(),
00129                 Ymin=In1.ymin()>In2.ymin()?In1.ymin():in2.ymin(),
00130                 Ymax=In1.ymax()>In2.ymax()?In1.ymax():In2.ymax();
00131         for(i=Xmin;i<Xmax; i++)
00132                 for(j=Ymin; j<Ymax; j++)
00133                         Out=In1(i,j)-In2(i,j);
00134         //Usually, the differences are averaged slightly.  We'll do that.
00135         Mask[0]=.5;
00136         Mask[1]=.5;
00137         convolve(Out,Mask);
00138         Mask.SetSize(1,0);
00139         Mask[0]=.5;
00140         Mask[1]=.5;
00141         convolve(Out,Mask);
00142 }
00143 
00144 template <class T, class U> //Performs matrix multiplication
00145 T & dotprod(CMatrix<T> &OP1,CMatrix<U> &OP2, CMatrix<T> & Out)
00146 {
00147         int i=0,j=0,k;
00148         if(OP1.xmin()!=OP2.ymin()||OP1.xmax()!=OP2.ymax())
00149         {
00150                 cerr << "Multiplication is not possible for these matrices.  Perhaps you must transpose one of them." << endl;
00151                 exit(0);
00152         }
00153         if((OP1.y()!=Out.y()) || (OP2.x()!=Out.x()) )
00154                 out.initialize(OP2.x(),OP1.y());
00155         for(k=0; k<rhs.x(); k++)
00156                 for(j=0; j<lhs.y(); j++)
00157                 {
00158                         out(k,j)=0;
00159                         for(i=0; i<lhs.x(); i++)
00160                                 Out(k,j)+=OP1(i,j)*OP2(k,i);
00161                 };
00162                 return out;
00163 }
00164 
00165 template <class T>
00166 void transpose(CMatrix<T> &In,CMatrix<T> & Out)
00167 {
00168         Out.SetSize(In.ymin(),In.xmin(),In.ymax(),In.xmax());
00169         int i=0, j=0;
00170         for(i=0; i<xmax; i++)
00171                 for(j=0; j<ymax; j++)
00172                         Out(j,i)=OP1(i,j);
00173                 
00174 }
00175 
00176 
00177 #endif //MATRIX_ARITH_LIBRARY

Generated at Thu Apr 25 20:30:41 2002 for SuperParr by doxygen1.2.9.1 written by Dimitri van Heesch, © 1997-2001