00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
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
00040
00041
00042
00043
00044 #ifndef __GNUC__
00045
00046 # ifdef _MSC_VER
00047
00048
00049
00050
00051
00052 # if _MSC_VER <= 1300
00053
00054
00055 # define typename
00056 # else
00057
00058 # endif
00059 # else
00060
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
00075
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
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 }
00397
00398 #endif // _LATMPL_H