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
Generated on Fri Jul 25 12:42:58 2008 for IT++ by Doxygen 1.5.4