IT++ Logo

specmat.cpp

Go to the documentation of this file.
00001 
00030 #include <itpp/base/specmat.h>
00031 #include <itpp/base/math/elem_math.h>
00032 #include <itpp/base/math/log_exp.h>
00033 #include <itpp/base/matfunc.h>
00034 
00035 
00036 namespace itpp
00037 {
00038 
00039 ivec find(const bvec &invector)
00040 {
00041   it_assert(invector.size() > 0, "find(): vector cannot be empty");
00042   ivec temp(invector.size());
00043   int pos = 0;
00044   for (int i = 0;i < invector.size();i++) {
00045     if (invector(i) == bin(1)) {
00046       temp(pos) = i;
00047       pos++;
00048     }
00049   }
00050   temp.set_size(pos, true);
00051   return temp;
00052 }
00053 
00055 
00056 #define CREATE_SET_FUNS(typef,typem,name,value) \
00057   typef name(int size)    \
00058   {      \
00059     typef t(size);    \
00060     t = value;     \
00061     return t;     \
00062   }      \
00063       \
00064     typem name(int rows, int cols)  \
00065     {      \
00066       typem t(rows, cols);   \
00067       t = value;    \
00068       return t;     \
00069     }
00070 
00071 #define CREATE_EYE_FUN(type,name,zero,one) \
00072   type name(int size) {    \
00073     type t(size,size);    \
00074     t = zero;     \
00075     for (int i=0; i<size; i++)   \
00076       t(i,i) = one;    \
00077     return t;     \
00078   }
00079 
00080 CREATE_SET_FUNS(vec, mat, ones, 1.0)
00081 CREATE_SET_FUNS(bvec, bmat, ones_b, bin(1))
00082 CREATE_SET_FUNS(ivec, imat, ones_i, 1)
00083 CREATE_SET_FUNS(cvec, cmat, ones_c, std::complex<double>(1.0))
00084 
00085 CREATE_SET_FUNS(vec, mat, zeros, 0.0)
00086 CREATE_SET_FUNS(bvec, bmat, zeros_b, bin(0))
00087 CREATE_SET_FUNS(ivec, imat, zeros_i, 0)
00088 CREATE_SET_FUNS(cvec, cmat, zeros_c, std::complex<double>(0.0))
00089 
00090 CREATE_EYE_FUN(mat, eye, 0.0, 1.0)
00091 CREATE_EYE_FUN(bmat, eye_b, bin(0), bin(1))
00092 CREATE_EYE_FUN(imat, eye_i, 0, 1)
00093 CREATE_EYE_FUN(cmat, eye_c, std::complex<double>(0.0), std::complex<double>(1.0))
00094 
00095 template <class T>
00096 void eye(int size, Mat<T> &m)
00097 {
00098   m.set_size(size, size, false);
00099   m = T(0);
00100   for (int i = size - 1; i >= 0; i--)
00101     m(i, i) = T(1);
00102 }
00103 
00105 
00106 vec impulse(int size)
00107 {
00108   vec t(size);
00109   t.clear();
00110   t[0] = 1.0;
00111   return t;
00112 }
00113 
00114 vec linspace(double from, double to, int points)
00115 {
00116   if (points < 2) {
00117     // This is the "Matlab definition" of linspace
00118     vec output(1);
00119     output(0) = to;
00120     return output;
00121   }
00122   else {
00123     vec output(points);
00124     double step = (to - from) / double(points - 1);
00125     int i;
00126     for (i = 0; i < points; i++)
00127       output(i) = from + i * step;
00128     return output;
00129   }
00130 }
00131 
00132 vec zigzag_space(double t0, double t1, int K)
00133 {
00134   it_assert(K > 0, "zigzag_space:() K must be positive");
00135   ivec N = "0 1";
00136 
00137   int n = 2;
00138   for (int k = 0; k < K; k++) {
00139     ivec Nn = 2 * N;
00140     for (int i = 1; i < length(Nn); i += 2)  {
00141       Nn = concat(Nn, i);
00142       n++;
00143     }
00144     N = Nn;
00145   }
00146 
00147   vec T0 = linspace(t0, t1, n);
00148   vec Tt = zeros(n);
00149   for (int i = 0; i < n; i++) {
00150     Tt(i) = T0(N(i));
00151   }
00152   return Tt;
00153 }
00154 
00155 // Construct a Hadamard-imat of size "size"
00156 imat hadamard(int size)
00157 {
00158   it_assert(size > 0, "hadamard(): size is not a power of 2");
00159   int logsize = ceil_i(::log2(static_cast<double>(size)));
00160   it_assert(pow2i(logsize) == size, "hadamard(): size is not a power of 2");
00161 
00162   imat H(size, size);
00163   H(0, 0) = 1;
00164 
00165   for (int i = 0; i < logsize; ++i) {
00166     int pow2 = 1 << i;
00167     for (int k = 0; k < pow2; ++k) {
00168       for (int l = 0; l < pow2; ++l) {
00169         H(k, l) = H(k, l);
00170         H(k + pow2, l) = H(k, l);
00171         H(k, l + pow2) = H(k, l);
00172         H(k + pow2, l + pow2) = (-1) * H(k, l);
00173       }
00174     }
00175   }
00176   return H;
00177 }
00178 
00179 imat jacobsthal(int p)
00180 {
00181   int quadratic_residue;
00182   imat out(p, p);
00183   int i, j;
00184 
00185   out = -1; // start with all elements equal to "-1"
00186 
00187   // Generate a complete list of quadratic residues
00188   for (i = 0; i < (p - 1) / 2; i++) {
00189     quadratic_residue = ((i + 1) * (i + 1)) % p;
00190     // set this element in all rows (col-row) = quadratic_residue
00191     for (j = 0; j < p; j++) {
00192       out(j, (j + quadratic_residue) % p) = 1;
00193     }
00194   }
00195 
00196   // set diagonal elements to zero
00197   for (i = 0; i < p; i++) {
00198     out(i, i) = 0;
00199   }
00200   return out;
00201 }
00202 
00203 imat conference(int n)
00204 {
00205   it_assert_debug(n % 4 == 2, "conference(int n); wrong size");
00206   int pm = n - 1; // p must be odd prime, not checked
00207   imat out(n, n);
00208 
00209   out.set_submatrix(1, n - 1, 1, n - 1, jacobsthal(pm));
00210   out.set_submatrix(0, 0, 1, n - 1, 1);
00211   out.set_submatrix(1, n - 1, 0, 0, 1);
00212   out(0, 0) = 0;
00213 
00214   return out;
00215 }
00216 
00217 cmat toeplitz(const cvec &c, const cvec &r)
00218 {
00219   int size = c.size();
00220   it_assert(size == r.size(),
00221             "toeplitz(): Incorrect sizes of input vectors.");
00222   cmat output(size, size);
00223   cvec c_conj = conj(c);
00224   c_conj[0] = conj(c_conj[0]);
00225 
00226   for (int i = 0; i < size; i++) {
00227     cmat tmp = reshape(c_conj(0, size - 1 - i), size - i, 1);
00228     output.set_submatrix(i, size - 1, i, i, tmp);
00229   }
00230   for (int i = 0; i < size - 1; i++) {
00231     cmat tmp = reshape(r(1, size - 1 - i), 1, size - 1 - i);
00232     output.set_submatrix(i, i, i + 1, size - 1, tmp);
00233   }
00234 
00235   return output;
00236 }
00237 
00238 cmat toeplitz(const cvec &c)
00239 {
00240   int size = c.size();
00241   cmat output(size, size);
00242   cvec c_conj = conj(c);
00243   c_conj[0] = conj(c_conj[0]);
00244 
00245   for (int i = 0; i < size; i++) {
00246     cmat tmp = reshape(c_conj(0, size - 1 - i), size - i, 1);
00247     output.set_submatrix(i, size - 1, i, i, tmp);
00248   }
00249   for (int i = 0; i < size - 1; i++) {
00250     cmat tmp = reshape(c(1, size - 1 - i), 1, size - 1 - i);
00251     output.set_submatrix(i, i, i + 1, size - 1, tmp);
00252   }
00253 
00254   return output;
00255 }
00256 
00257 mat toeplitz(const vec &c, const vec &r)
00258 {
00259 
00260   mat output(c.size(), r.size());
00261 
00262   for (int i = 0; i < c.size(); i++) {
00263     for (int j = 0; j < std::min(r.size(), c.size() - i); j++)
00264       output(i + j, j) = c(i);
00265   }
00266 
00267   for (int j = 1; j < r.size(); j++) {
00268     for (int i = 0; i < std::min(c.size(), r.size() - j); i++)
00269       output(i, i + j) = r(j);
00270   }
00271 
00272   return output;
00273 }
00274 
00275 mat toeplitz(const vec &c)
00276 {
00277   mat output(c.size(), c.size());
00278 
00279   for (int i = 0; i < c.size(); i++) {
00280     for (int j = 0; j < c.size() - i; j++)
00281       output(i + j, j) = c(i);
00282   }
00283 
00284   for (int j = 1; j < c.size(); j++) {
00285     for (int i = 0; i < c.size() - j; i++)
00286       output(i, i + j) = c(j);
00287   }
00288 
00289   return output;
00290 }
00291 
00292 mat rotation_matrix(int dim, int plane1, int plane2, double angle)
00293 {
00294   mat m;
00295   double c = std::cos(angle), s = std::sin(angle);
00296 
00297   it_assert(plane1 >= 0 && plane2 >= 0 &&
00298             plane1 < dim && plane2 < dim && plane1 != plane2,
00299             "Invalid arguments to rotation_matrix()");
00300 
00301   m.set_size(dim, dim, false);
00302   m = 0.0;
00303   for (int i = 0; i < dim; i++)
00304     m(i, i) = 1.0;
00305 
00306   m(plane1, plane1) = c;
00307   m(plane1, plane2) = -s;
00308   m(plane2, plane1) = s;
00309   m(plane2, plane2) = c;
00310 
00311   return m;
00312 }
00313 
00314 void house(const vec &x, vec &v, double &beta)
00315 {
00316   double sigma, mu;
00317   int n = x.size();
00318 
00319   v = x;
00320   if (n == 1) {
00321     v(0) = 1.0;
00322     beta = 0.0;
00323     return;
00324   }
00325   sigma = sum(sqr(x(1, n - 1)));
00326   v(0) = 1.0;
00327   if (sigma == 0.0)
00328     beta = 0.0;
00329   else {
00330     mu = std::sqrt(sqr(x(0)) + sigma);
00331     if (x(0) <= 0.0)
00332       v(0) = x(0) - mu;
00333     else
00334       v(0) = -sigma / (x(0) + mu);
00335     beta = 2 * sqr(v(0)) / (sigma + sqr(v(0)));
00336     v /= v(0);
00337   }
00338 }
00339 
00340 void givens(double a, double b, double &c, double &s)
00341 {
00342   double t;
00343 
00344   if (b == 0) {
00345     c = 1.0;
00346     s = 0.0;
00347   }
00348   else {
00349     if (fabs(b) > fabs(a)) {
00350       t = -a / b;
00351       s = -1.0 / std::sqrt(1 + t * t);
00352       c = s * t;
00353     }
00354     else {
00355       t = -b / a;
00356       c = 1.0 / std::sqrt(1 + t * t);
00357       s = c * t;
00358     }
00359   }
00360 }
00361 
00362 void givens(double a, double b, mat &m)
00363 {
00364   double t, c, s;
00365 
00366   m.set_size(2, 2);
00367 
00368   if (b == 0) {
00369     m(0, 0) = 1.0;
00370     m(1, 1) = 1.0;
00371     m(1, 0) = 0.0;
00372     m(0, 1) = 0.0;
00373   }
00374   else {
00375     if (fabs(b) > fabs(a)) {
00376       t = -a / b;
00377       s = -1.0 / std::sqrt(1 + t * t);
00378       c = s * t;
00379     }
00380     else {
00381       t = -b / a;
00382       c = 1.0 / std::sqrt(1 + t * t);
00383       s = c * t;
00384     }
00385     m(0, 0) = c;
00386     m(1, 1) = c;
00387     m(0, 1) = s;
00388     m(1, 0) = -s;
00389   }
00390 }
00391 
00392 mat givens(double a, double b)
00393 {
00394   mat m(2, 2);
00395   givens(a, b, m);
00396   return m;
00397 }
00398 
00399 
00400 void givens_t(double a, double b, mat &m)
00401 {
00402   double t, c, s;
00403 
00404   m.set_size(2, 2);
00405 
00406   if (b == 0) {
00407     m(0, 0) = 1.0;
00408     m(1, 1) = 1.0;
00409     m(1, 0) = 0.0;
00410     m(0, 1) = 0.0;
00411   }
00412   else {
00413     if (fabs(b) > fabs(a)) {
00414       t = -a / b;
00415       s = -1.0 / std::sqrt(1 + t * t);
00416       c = s * t;
00417     }
00418     else {
00419       t = -b / a;
00420       c = 1.0 / std::sqrt(1 + t * t);
00421       s = c * t;
00422     }
00423     m(0, 0) = c;
00424     m(1, 1) = c;
00425     m(0, 1) = -s;
00426     m(1, 0) = s;
00427   }
00428 }
00429 
00430 mat givens_t(double a, double b)
00431 {
00432   mat m(2, 2);
00433   givens_t(a, b, m);
00434   return m;
00435 }
00436 
00438 template void eye(int, mat &);
00440 template void eye(int, bmat &);
00442 template void eye(int, imat &);
00444 template void eye(int, cmat &);
00445 
00446 } // namespace itpp
SourceForge Logo

Generated on Fri Jul 25 12:42:58 2008 for IT++ by Doxygen 1.5.4