|
STK++ 1.0
|
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