STK++ 1.0
STK_LinAlgebra1D.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 1D Linear Algebra methods with Real Containers
00028  * Author:   Serge Iovleff, serge.iovleff@stkpp.org
00029  *
00030  **/
00031 
00037 #ifndef STK_LINALGEBRA1D_H
00038 #define STK_LINALGEBRA1D_H
00039 
00040 #include "../../STKernel/include/STK_Real.h"
00041 #include "../../STKernel/include/STK_Misc.h"
00042 
00043 #include "../../Sdk/include/STK_ITContainer1D.h"
00044 
00045 namespace STK
00046 {
00047 
00057 template<class Container1D>
00058 Real sum( ITContainer1D<Real, Container1D> const& x)
00059 {
00060   // get dimensions
00061   const Integer first = x.first(), last = x.last();
00062   // compute the sum
00063   Real sum = 0.0;
00064   for (Integer i=first; i<=last; i++)
00065     sum += x[i];
00066   return (sum);
00067 }
00068 
00079 template<class Container1D1, class Container1D2>
00080 Real weightedSum( ITContainer1D<Real, Container1D1> const& x
00081                 , ITContainer1D<Real, Container1D2> const& w
00082                 )
00083 {
00084 #ifdef STK_DEBUG
00085     if (!x.range().isIn(w.range()))
00086       throw runtime_error("In weightedSum(x, w) "
00087                                "x.range() not include in w.range()");
00088 #endif
00089   // dimensions
00090   const Integer first = x.first(), last = x.last();
00091   // compute the weighted sum
00092   Real sum = 0.0;
00093   for (Integer i=first; i<=last; i++)
00094     sum += w[i] * x[i];
00095   return (sum);
00096 }
00097 
00106 template<class Container1D>
00107 Real normInf( ITContainer1D<Real, Container1D> const& x)
00108 {
00109   // get dimensions
00110   const Integer first = x.first(), last = x.last();
00111   // compute the maxmal value
00112   Real scale = 0.0;
00113   for (Integer i=first; i<=last; i++)
00114     scale = max(scale, abs(x[i]));
00115   return (scale);
00116 }
00117 
00127 template<class Container1D1, class Container1D2>
00128 Real weightedNormInf( ITContainer1D<Real, Container1D1> const& x
00129                     , ITContainer1D<Real, Container1D2> const& w
00130                     )
00131 {
00132 #ifdef STK_DEBUG
00133     if (!x.range().isIn(w.range()))
00134       throw runtime_error("In weightedNormInf(x, w) "
00135                                "x.range() not include in w.range()");
00136 #endif
00137   // get dimensions
00138   const Integer first = x.first(), last = x.last();
00139   // compute weighted norm inf
00140   Real scale = 0.0;
00141   for (Integer i=first; i<=last; i++)
00142     scale = max(scale, abs(w[i]*x[i]));
00143   return (scale);
00144 }
00145 
00154 template<class Container1D>
00155 Real normTwo( ITContainer1D<Real, Container1D> const& x)
00156 {
00157   // compute the maximal value of x
00158   Real scale =normInf(x), norm =0.0;
00159   if (scale)
00160   {
00161     // get dimensions
00162     const Integer first = x.first(), last = x.last();
00163     // sum squared normalized values
00164     for (Integer i = first; i<=last; i++)
00165     {
00166       const Real aux = x[i]/scale;
00167       norm += aux * aux;
00168     }
00169   }
00170   // rescale sum
00171   return (Real(sqrt(double(norm)))*scale);
00172 }
00173 
00183 template<class Container1D1, class Container1D2>
00184 Real weightedNormTwo( ITContainer1D<Real, Container1D1> const& x
00185                     , ITContainer1D<Real, Container1D2> const& w
00186                     )
00187 {
00188 #ifdef STK_DEBUG
00189     if (!x.range().isIn(w.range()))
00190       throw runtime_error("In weightedNormTwo(x, w) "
00191                                "x.range() not include in w.range()");
00192 #endif
00193   // compute the maximal value of x
00194   Real scale = weightedNormInf(x, w), norm2 =0.0;
00195   if (scale)
00196   {
00197     // get dimensions
00198     const Integer first = x.first(), last = x.last();
00199     // compute norm2
00200     for (Integer i = first; i<=last; i++)
00201     {
00202       const Real aux = (w[i]*x[i])/scale;
00203       norm2 += aux * aux;
00204     }
00205   }
00206   // rescale sum
00207   return (Real(sqrt(double(norm2)))*scale);
00208 }
00209 
00218 template<class Container1D>
00219 Real normTwo2( ITContainer1D<Real, Container1D> const& x)
00220 {
00221   Real scale =normInf(x), norm =0.0;
00222   if (scale)
00223   {
00224     // get dimensions
00225     const Integer first = x.first(), last = x.last();
00226     // sum squared normalized values
00227     for (Integer i = first; i<=last; i++)
00228     {
00229       Real aux = x[i]/scale;
00230       norm += aux * aux;
00231     }
00232   }
00233   // scale result
00234   return (norm*scale*scale);
00235 }
00236 
00247 template<class Container1D1, class Container1D2>
00248 Real weightedNormTwo2( ITContainer1D<Real, Container1D1> const& x
00249                      , ITContainer1D<Real, Container1D2> const& w
00250                      )
00251 {
00252 #ifdef STK_DEBUG
00253   if (!x.range().isIn(w.range()))
00254     throw runtime_error("In weightedNormTwo2(x, w) "
00255                              "x.range() not include in w.range()");
00256 #endif
00257   Real scale =weightedNormInf(x, w), norm =0.0;
00258   if (scale)
00259   {
00260     // get dimensions
00261     const Integer first = x.first(), last = x.last();
00262     // compute norm2
00263     for (Integer i = first; i <= last; i++)
00264     {
00265       const Real aux = x[i]/scale;
00266       norm += w[i] * aux * aux;
00267     }
00268   }
00269   // scale result
00270   return (norm*scale*scale);
00271 }
00272 
00285 template<class Container1D1, class Container1D2>
00286 Real dot( ITContainer1D<Real, Container1D1> const& x
00287         , ITContainer1D<Real, Container1D2> const& y
00288         )
00289 {
00290   // compute the valid range
00291   const Integer first = max(x.first(), y.first()) , last = min(x.last(), y.last());
00292   // compute the sum product
00293   Real sum=0.0;
00294   Integer i;
00295   for (i = first; i<last; i+=2)
00296     sum += x[i] * y[i] + x[i+1] * y[i+1];
00297   // check if the number of element is odd
00298   if (i==last) sum+=x[last]*y[last];
00299   return (sum);
00300 }
00301 
00315 template<class Container1D1, class Container1D2, class Container1D3>
00316 Real weightedDot( ITContainer1D<Real, Container1D1> const& x
00317                 , ITContainer1D<Real, Container1D2> const& y
00318                 , ITContainer1D<Real, Container1D3> const& w
00319                 )
00320 {
00321   // compute the valid range
00322   const Integer first = max(x.first(), y.first()) , last = min(x.last(), y.last());
00323 #ifdef STK_DEBUG
00324   if (!Range(first,last).isIn(w.range()))
00325     throw runtime_error("In weightedDot(x, w) "
00326                              "Range(first,last) not include in w.range()");
00327 #endif
00328   // compute the sum product
00329   Real sum=0.0;
00330   Integer i;
00331   for (i = first; i<last; i+=2)
00332     sum += w[i]*x[i] * y[i] + w[i+1]*x[i+1] * y[i+1];
00333   // check if last is odd
00334   if (i == last) sum += w[last]*x[last]*y[last];
00335   return (sum);
00336 }
00337 
00351 template<class Container1D1, class Container1D2>
00352 Real dist( ITContainer1D<Real, Container1D1> const& x
00353          , ITContainer1D<Real, Container1D2> const& y
00354          )
00355 {
00356   // compute the valid range
00357   const Integer first = max(x.first(), y.first()) , last = min(x.last(), y.last());
00358   // compute the maximal difference
00359   Real scale = 0.;
00360   for (Integer i = first; i<=last; i++)
00361     scale = max(scale, abs(x[i] - y[i]));
00362   // Compute the norm
00363   Real norm2 = 0.;
00364   if (scale)
00365   { // comp the norm^2
00366     for (Integer i = first; i<=last; i++)
00367     {
00368       const Real aux = (x[i]-y[i])/scale;
00369       norm2 += aux * aux;
00370     }
00371   }
00372   // rescale sum
00373   return (Real(sqrt(double(norm2)))*scale);
00374 }
00375 
00390 template<class Container1D1, class Container1D2, class Container1D3>
00391 Real weightedDist( ITContainer1D<Real, Container1D1> const& x
00392                  , ITContainer1D<Real, Container1D2> const& y
00393                  , ITContainer1D<Real, Container1D3> const& w
00394                  )
00395 {
00396   // compute the valid range
00397   const Integer first = max(x.first(), y.first()) , last = min(x.last(), y.last());
00398 #ifdef STK_DEBUG
00399   if (!Range(first,last).isIn(w.range()))
00400     throw runtime_error("In weightedDist(x, w) "
00401                              "Range(first,last) not include in w.range()");
00402 #endif
00403   // compute the maximal difference
00404   Real scale = 0., norm2= 0.;
00405   for (Integer i = first; i<=last; i++)
00406     scale = max(scale, abs(w[i]*(x[i] - y[i])));
00407   // Compute the norm
00408   if (scale)
00409   { // comp the norm^2
00410     for (Integer i = first; i<=last; i++)
00411     {
00412       const Real aux = (x[i]-y[i])/scale;
00413       norm2 += w[i]*aux * aux;
00414     }
00415   }
00416   // rescale sum
00417   return (Real(sqrt(double(norm2)))*scale);
00418 }
00419 
00430 template<class Container1D1, class Container1D2>
00431 void add(ITContainer1D<Real, Container1D1> const& x, ITContainer1D<Real, Container1D2>& y)
00432 {
00433   // compute the valid range
00434   const Integer first = max(x.first(), y.first()) , last = min(x.last(), y.last());
00435   for (Integer i = first; i<=last; i++)
00436   {
00437     y[i] += x[i];
00438   }
00439 }
00440 
00452 template<class Container1D1, class Container1D2, class Container1D3>
00453 void add( ITContainer1D<Real, Container1D1> const& x
00454         , ITContainer1D<Real, Container1D2> const& y
00455         , ITContainer1D<Real, Container1D3>& z
00456         )
00457 {
00458   // compute the valid range
00459   const Integer first = max(x.first(), y.first()) , last = min(x.last(), y.last());
00460   z.resize(Range(first, last));
00461   for (Integer i = first; i<=last; i++)
00462   {
00463     z[i] = x[i] + y[i];
00464   }
00465 }
00466 
00477 template<class Container1D1, class Container1D2>
00478 void diff(ITContainer1D<Real, Container1D1> const& x, ITContainer1D<Real, Container1D2>& y)
00479 {
00480   // compute the valid range
00481   const Integer first = max(x.first(), y.first()) , last = min(x.last(), y.last());
00482   for (Integer i = first; i<=last; i++)
00483   {
00484     y[i] -= x[i];
00485   }
00486 }
00487 
00499 template<class Container1D1, class Container1D2, class Container1D3>
00500 void diff( ITContainer1D<Real, Container1D1> const& x
00501          , ITContainer1D<Real, Container1D2> const& y
00502          , ITContainer1D<Real, Container1D3>& z
00503          )
00504 {
00505   // compute the valid range
00506   const Integer first = max(x.first(), y.first()) , last = min(x.last(), y.last());
00507   z.resize(Range(first, last));
00508   for (Integer i = first; i<=last; i++)
00509   {
00510     z[i] = x[i] - y[i];
00511   }
00512 }
00513 
00514 
00515 } // Namespace STK
00516 
00517 #endif // STK_LINALGEBRA1D_H