latmpl.h

Go to the documentation of this file.
00001 /*-*-c++-*-****************************************************************
00002  *                     latmpl.h C++ Templates for lapackpp classes
00003                        -------------------
00004  begin                : 2005-12-29
00005  copyright            : (C) 2005 by Christian Stimming
00006  email                : stimming@tuhh.de
00007 ***************************************************************************/
00008 
00009 // This library is free software; you can redistribute it and/or
00010 // modify it under the terms of the GNU Lesser General Public License as
00011 // published by the Free Software Foundation; either version 2, or (at
00012 // your option) any later version.
00013 
00014 // This library is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU Lesser General Public License for more details.
00018 
00019 // You should have received a copy of the GNU Lesser General Public License along
00020 // with this library; see the file COPYING.  If not, write to the Free
00021 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
00022 // USA.
00023 
00024 #ifndef _LATMPL_H
00025 #define _LATMPL_H
00026 
00034 #include <cstdlib>
00035 #include <cmath>
00036 #include <lafnames.h>
00037 #include LA_EXCEPTION_H
00038 
00039 // Watch out: Only some compilers correctly implement the C++
00040 // standard specifications, where type names from inside template
00041 // classes need to be preceded by the "typename" keyword. Other
00042 // compilers do not accept the keyword "typename". For those we
00043 // define it as empty here.
00044 #ifndef __GNUC__
00045    // Non-gcc compiler
00046 #  ifdef _MSC_VER
00047      // This is Microsoft Visual C++.
00048      //  Microsoft Visual C++ 7.1  _MSC_VER = 1310
00049      //  Microsoft Visual C++ 7.0  _MSC_VER = 1300
00050      //  Microsoft Visual C++ 6.0  _MSC_VER = 1200
00051      //  Microsoft Visual C++ 5.0  _MSC_VER = 1100
00052 #    if _MSC_VER <= 1300
00053        // This is Microsoft Visual C++ 7.0 or older, so define the
00054        // keyword as empty
00055 #      define typename
00056 #    else
00057        // Microsoft Visual C++ 7.1 or newer. typename should be ok.
00058 #    endif
00059 #  else
00060      // Compiler unknown
00061 #  endif
00062 #endif
00063 
00064 namespace la {
00065 
00069 template <class matT>
00070 bool is_zero(const matT& mat)
00071 {
00072   int i, j,  M=mat.rows(), N=mat.cols();
00073 
00074   // If your compiler gives an error in this line, please see the
00075   // note above on "typename".
00076   typename matT::value_type zero(0);
00077 
00078   for (j=0;j<N;j++)
00079     for (i=0;i<M; i++)
00080       if (mat(i, j) != zero)
00081         return false;
00082   return true;
00083 }
00084 
00087 template <class matT>
00088 bool equal(const matT& mat1, const matT& mat2)
00089 {
00090   int i, j,  M=mat1.rows(), N=mat1.cols();
00091   if (mat1.rows() != mat2.rows() || mat1.cols() != mat2.cols())
00092     throw LaException("equal<matT>(const matT&, const matT)",
00093                       "Both matrices have unequal sizes");
00094   for (j=0;j<N;j++)
00095     for (i=0;i<M; i++)
00096       if (mat1(i, j) != mat2(i, j))
00097         return false;
00098   return true;
00099 }
00101 
00102 
00108 template <class matT> 
00109 void zeros(matT& mat, int N, int M=0)
00110 {
00111   mat.resize(N, M == 0 ? N : M);
00112   mat = typename matT::value_type(0);
00113 }
00114 
00118 template <class matT> 
00119 void ones(matT& mat, int N, int M=0)
00120 {
00121   mat.resize(N, M == 0 ? N : M);
00122   mat = typename matT::value_type(1);
00123 }
00124 
00129 template <class matT> 
00130 void eye(matT& mat, int N, int M=0)
00131 {
00132   int nmin = (M == 0 ? N : (M < N ? M : N));
00133   mat.resize(N, M == 0 ? N : M);
00134   mat = typename matT::value_type(0);
00135   typename matT::value_type one(1);
00136   for (int k = 0; k < nmin; ++k)
00137     mat(k, k) = one;
00138 }
00139 
00147 template <class matT>
00148 void rand(matT &A, typename matT::value_type low = 0,
00149           typename matT::value_type high = 1)
00150 {
00151    int i, j,  M = A.rows(), N = A.cols();
00152    typename matT::value_type scale = high - low;
00153    for (j=0; j<N; ++j)
00154       for (i=0; i<M; ++i)
00155          A(i,j) = low + 
00156             scale * double(std::rand()) / double(RAND_MAX);
00157 }
00158 
00168 template <class matT>
00169 void int_rand(matT &A, typename matT::value_type low = 0,
00170               typename matT::value_type high = 1)
00171 {
00172    int i, j,  M = A.rows(), N = A.cols();
00173    double bins = high - low + 1;
00174    for (j=0; j<N; ++j)
00175       for (i=0; i<M; ++i)
00176          A(i,j) = low + 
00177             typename matT::value_type(
00178                std::floor(bins * double(std::rand()) / 
00179                           double(RAND_MAX)));
00180 }
00181 
00188 template <class matT>
00189 void from_diag(matT& mat, const matT& vect)
00190 {
00191   int nmin = (mat.rows() < mat.cols() ? mat.rows() : mat.cols());
00192   mat = typename matT::value_type(0);
00193   if (vect.rows() != 1 && vect.cols() != 1)
00194     throw LaException("diag<matT>(const matT& vect, matT& mat)",
00195                       "The argument 'vect' is not a vector: "
00196                       "neither dimension is equal to one");
00197   if (vect.rows() * vect.cols() != nmin)
00198     throw LaException("diag<matT>(const matT& vect, matT& mat)",
00199                       "The size of the vector is unequal to the matrix diagonal");
00200   if (vect.rows() == 1)
00201     for (int k = 0; k < nmin; ++k)
00202       mat(k, k) = vect(0, k);
00203   else
00204     for (int k = 0; k < nmin; ++k)
00205       mat(k, k) = vect(k, 0);
00206 }
00207 
00209 
00210 
00216 template <class matT>
00217 matT zeros(int N, int M=0)
00218 {
00219   matT mat;
00220   zeros(mat, N, M);
00221   return mat.shallow_assign();
00222 }
00223 
00227 template <class matT>
00228 matT ones(int N, int M=0)
00229 {
00230   matT mat;
00231   ones(mat, N, M);
00232   return mat.shallow_assign();
00233 }
00234 
00238 template <class matT>
00239 matT eye(int N, int M=0)
00240 {
00241   matT mat;
00242   eye(mat, N, M);
00243   return mat.shallow_assign();
00244 }
00245 
00254 template <class matT>
00255 matT rand(int N, int M,
00256           typename matT::value_type low = 0,
00257           typename matT::value_type high = 1)
00258 {
00259    matT mat(N, M);
00260    rand(mat, low, high);
00261    return mat.shallow_assign();
00262 }
00263 
00273 template <class matT>
00274 matT int_rand(int N, int M,
00275           typename matT::value_type low = 0,
00276           typename matT::value_type high = 1)
00277 {
00278    matT mat(N, M);
00279    int_rand(mat, low, high);
00280    return mat.shallow_assign();
00281 }
00282 
00288 template <class matT>
00289 matT from_diag(const matT& vect)
00290 {
00291   if (vect.rows() != 1 && vect.cols() != 1)
00292     throw LaException("diag<matT>(const matT& vect, matT& mat)",
00293                       "The argument 'vect' is not a vector: "
00294                       "neither dimension is equal to one");
00295   int nmax(vect.rows() > vect.cols() ? vect.rows() : vect.cols());
00296   matT mat(nmax, nmax);
00297   from_diag(mat, vect);
00298   return mat.shallow_assign();
00299 }
00300 
00317 template<class destT, class srcT>
00318 destT convert_mat(const srcT& src)
00319 {
00320    destT res(src.rows(), src.cols());
00321    // optimize later; for now use the correct but slow implementation
00322    int i, j,  M=src.rows(), N=src.cols();
00323    for (j=0; j<N; ++j)
00324       for (i=0; i<M; ++i)
00325          res(i, j) = typename destT::value_type ( src(i, j) );
00326    return res.shallow_assign();
00327 }
00328 
00332 template <class matT>
00333 matT linspace(typename matT::value_type start, 
00334               typename matT::value_type end,
00335               int nr_points)
00336 {
00337    matT mat(nr_points, 1);
00338    typename matT::value_type stepsize = 
00339       (end - start) / typename matT::value_type (nr_points - 1);
00340    for (int k = 0; k < nr_points; ++k)
00341    {
00342       mat(k, 0) = start;
00343       start += stepsize;
00344    }
00345    return mat.shallow_assign();
00346 }
00347 
00351 template <class matT>
00352 matT repmat(const matT& A, int M, int N)
00353 {
00354    int i, j, origM = A.rows(), origN = A.cols();
00355    matT mat(origM * M, origN * N);
00356    for (j = 0; j < N; ++j)
00357       for (i = 0; i < M; ++i)
00358          mat(LaIndex(i * origM, (i+1) * origM - 1),
00359              LaIndex(j * origN, (j+1) * origN - 1))
00360             .inject(A);
00361 
00362    return mat.shallow_assign();
00363 }
00365 
00371 template <class matT>
00372 typename matT::value_type trace(const matT& mat)
00373 {
00374   int nmin = (mat.rows() < mat.cols() ? mat.rows() : mat.cols());
00375   typename matT::value_type result(0);
00376   for (int k = 0; k < nmin; ++k)
00377     result += mat(k, k);
00378   return result;
00379 }
00380 
00384 template <class matT>
00385 matT diag(const matT& mat)
00386 {
00387   int nmin = (mat.rows() < mat.cols() ? mat.rows() : mat.cols());
00388   matT vect(nmin, 1);
00389   for (int k = 0; k < nmin; ++k)
00390       vect(k, 0) = mat(k, k);
00391   return vect.shallow_assign();
00392 }
00393 
00395 
00396 } // namespace la
00397 
00398 #endif // _LATMPL_H

Generated on Sat Jul 14 11:40:36 2007 for Lapack++ by  doxygen 1.5.0