STK++ 1.0
STK_LinAlgebra2D.h
Go to the documentation of this file.
00001 /*--------------------------------------------------------------------*/
00002 /*     Copyright (C) 2004-2007  Serge Iovleff
00003 
00004     This program is free software; you can redistribute it and/or modify
00005     it under the terms of the GNU Lesser General Public License as
00006     published by the Free Software Foundation; either version 2 of the
00007     License, or (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU Lesser General Public License for more details.
00013 
00014     You should have received a copy of the GNU Lesser General Public
00015     License along with this program; if not, write to the
00016     Free Software Foundation, Inc.,
00017     59 Temple Place,
00018     Suite 330,
00019     Boston, MA 02111-1307
00020     USA
00021 
00022     Contact : Serge.Iovleff@stkpp.org
00023 */
00024 
00025 /*
00026  * Project:  stkpp::Algebra
00027  * Purpose:  Define 2D Linear Algebra methods with Real Containers
00028  * Author:   Serge Iovleff, serge.iovleff@stkpp.org
00029  *
00030  **/
00031 
00037 #ifndef STK_LINALGEBRA2D_H
00038 #define STK_LINALGEBRA2D_H
00039 
00040 // Point and Vector classes
00041 #include "../../Arrays/include/STK_Point.h"
00042 #include "../../Arrays/include/STK_Vector.h"
00043 #include "../../Arrays/include/STK_Matrix.h"
00044 #include "../../Arrays/include/STK_MatrixSquare.h"
00045 
00046 #include "STK_LinAlgebra1D.h"
00047 
00048 namespace STK
00049 {
00068 template < class TContainer2D , class TContainer1D>
00069 void mult( ITContainer2D<Real, TContainer2D> const& A
00070          , ITContainer1D<Real, TContainer1D> const& X
00071          , ITContainer1D<Real, TContainer1D>& Y
00072          )
00073 {
00074   // create result
00075   Y.resize(A.rangeVe());
00076   // indexes
00077   const Integer first = A.firstRow(), last = A.lastRow();
00078   for (Integer i=first; i<=last; i++)
00079   {
00080     Y[i] = dot(A.row(i), X);
00081   }
00082 }
00083 
00094 template <class Container1D>
00095 void mult( MatrixSquare const& A
00096          , ITContainer1D<Real, Container1D> const& X
00097          , ITContainer1D<Real, Container1D>& Y
00098          )
00099 {
00100   // create result
00101   Y.resize(A.range());
00102   // indexes
00103   const Integer first = A.first(), last = A.last();
00104   for (Integer i=first; i<=last; i++)
00105   {
00106     Y[i] = dot<Point, Container1D>(A.row(i), X);
00107   }
00108 }
00109 
00120 template < class TContainer2D , class TContainer1D>
00121 void multLefTranspose( ITContainer2D<Real, TContainer2D> const& A
00122                      , ITContainer1D<Real, TContainer1D> const& X
00123                      , ITContainer1D<Real, TContainer1D>& Y
00124                      )
00125 {
00126   // create result
00127   Y.resize(A.rangeHo());
00128   // indexes
00129   const Integer first = A.firstCol(), last = A.lastCol();
00130   for (Integer j=first; j<=last; j++)
00131   {
00132     Y[j] = dot(A.col(j), X);
00133   }
00134 }
00135 
00146 template <class Container1D>
00147 void multLeftTranspose( MatrixSquare const& A
00148                       , ITContainer1D<Real, Container1D> const& X
00149                       , ITContainer1D<Real, Container1D>& Y
00150                       )
00151 {
00152   // create result
00153   Y.resize(A.range());
00154   // indexes
00155   const Integer first = A.first(), last = A.last();
00156   for (Integer i=first; i<=last; i++)
00157   {
00158       Y[i] = dot<Vector, Container1D>(A[i], X);
00159   }
00160 }
00161 
00171 template < class TContainer2D >
00172 Real normInf( ITContainer2D<Real, TContainer2D> const& A)
00173 {
00174   // indexes
00175   const Integer firstCol = A.firstCol(), lastCol = A.lastCol();
00176   const Integer firstRow = A.firstRow(), lastRow = A.lastRow();
00177   // find maximal absolute value
00178   Real scale = 0.0;
00179   for (Integer j=firstRow; j<=lastRow; j++)
00180     for (Integer i=firstCol; i<=lastCol; i++)
00181       scale = STK::max(scale, STK::abs(A(i,j)));
00182   return (scale);
00183 }
00184 
00193 template < class TContainer2D1, class TContainer2D2>
00194 void transpose( ITContainer2D< Real, TContainer2D1> const& A
00195               , ITContainer2D< Real, TContainer2D2>& At
00196               )
00197 {
00198   // Resize At.
00199   At.resize(A.rangeHo(), A.rangeVe());
00200 
00201   // indexes
00202   const Integer firstCol = A.firstCol(), lastCol = A.lastCol();
00203   const Integer firstRow = A.firstRow(), lastRow = A.lastRow();
00204   // copy each column of A in each row of At
00205   for (Integer j=firstRow; j<=lastRow; j++)
00206     for (Integer i=firstCol; i<=lastCol; i++)
00207       At(i, j) = A(j, i);
00208 }
00209 
00218 template < class TContainer2D >
00219 ITContainer2D< Real, TContainer2D>& transpose(ITContainer2D< Real, TContainer2D>& Q)
00220 {
00221   // check if we have to create an auxiliary container
00222   if (Q.rangeVe() != Q.rangeVe())
00223   {
00224     // create temporary Matrix
00225     Matrix R;
00226     transpose(R, Q);
00227     Q = R;
00228     return Q;
00229   }
00230   // Square Matrix
00231   const Integer first = Q.firstRow(), last = Q.lastRow();
00232   // swap elements
00233   for (Integer  i=first; i<=last; i++)
00234   {
00235     for ( Integer j= first; j< last; j++)
00236     {
00237       Real aux(Q(i,j));
00238       Q(i,j)  = Q(j,i);
00239       Q(j,i) = aux;
00240     }
00241   }
00242   return Q;
00243 }
00244 
00251 Real trace( MatrixSquare const& A);
00252 
00253 
00265 template <class Container1D>
00266 Vector* mult( Matrix const& A, ITContainer1D<Real, Container1D> const& X)
00267 {
00268 #ifdef STK_DEBUG
00269   if (A.rangeHo() != X.range())
00270     throw runtime_error("In Vector* mult(A, X) "
00271                              "A.rangeHo() != X.range()");
00272 #endif
00273   // create result
00274   Vector* res = new Vector(A.rangeVe());
00275   // indexes
00276   const Integer firstRow = A.firstRow(), lastRow = A.lastRow();
00277   const Integer firstCol = A.firstCol(), lastCol = A.lastCol();
00278   for (Integer i=firstRow; i<=lastRow; i++)
00279   {
00280       Real sum = 0.0;
00281       for (Integer k = firstCol; k<=lastCol; k++)
00282         sum += A(i, k) * X[k];
00283       (*res)[i] = sum;
00284   }
00285   return res;
00286 }
00287 
00299 template <class Container1D>
00300 Vector* multLeftTranspose( Matrix const& A, ITContainer1D<Real, Container1D> const& X)
00301 {
00302 #ifdef STK_DEBUG
00303   if (A.rangeVe() != X.range())
00304     throw runtime_error("In Vector* multLeftTranspose(A, X) "
00305                              "A.rangeHo() != X.range()");
00306 #endif
00307   // create result
00308   Vector* res = new Vector(A.rangeHo());
00309   // indexes
00310   const Integer firstRow = A.firstRow(), lastRow = A.lastRow();
00311   const Integer firstCol = A.firstCol(), lastCol = A.lastCol();
00312 
00313   for (Integer i=firstCol; i<=lastCol; i++)
00314   {
00315       Real sum = 0.0;
00316       for (Integer k = firstRow; k<=lastRow; k++)
00317         sum += A(k, i) * X[k];
00318       (*res)[i] = sum;
00319   }
00320   return res;
00321 }
00322 
00323 } // Namespace STK
00324 
00325 #endif
00326 // STK_LINALGEBRA2D_H