$search
00001 // Copyright (C) 2008-2011 NICTA (www.nicta.com.au) 00002 // Copyright (C) 2008-2011 Conrad Sanderson 00003 // 00004 // This file is part of the Armadillo C++ library. 00005 // It is provided without any warranty of fitness 00006 // for any purpose. You can redistribute this file 00007 // and/or modify it under the terms of the GNU 00008 // Lesser General Public License (LGPL) as published 00009 // by the Free Software Foundation, either version 3 00010 // of the License or (at your option) any later version. 00011 // (see http://www.opensource.org/licenses for more info) 00012 00013 00016 00017 00018 template<typename eT> 00019 inline 00020 diagview<eT>::~diagview() 00021 { 00022 arma_extra_debug_sigprint(); 00023 } 00024 00025 00026 template<typename eT> 00027 arma_inline 00028 diagview<eT>::diagview(const Mat<eT>& in_m, const uword in_row_offset, const uword in_col_offset, const uword in_len) 00029 : m(in_m) 00030 , m_ptr(0) 00031 , row_offset(in_row_offset) 00032 , col_offset(in_col_offset) 00033 , n_rows(in_len) 00034 , n_elem(in_len) 00035 { 00036 arma_extra_debug_sigprint(); 00037 } 00038 00039 00040 00041 template<typename eT> 00042 arma_inline 00043 diagview<eT>::diagview(Mat<eT>& in_m, const uword in_row_offset, const uword in_col_offset, const uword in_len) 00044 : m(in_m) 00045 , m_ptr(&in_m) 00046 , row_offset(in_row_offset) 00047 , col_offset(in_col_offset) 00048 , n_rows(in_len) 00049 , n_elem(in_len) 00050 { 00051 arma_extra_debug_sigprint(); 00052 } 00053 00054 00055 00057 template<typename eT> 00058 inline 00059 void 00060 diagview<eT>::operator= (const diagview<eT>& x) 00061 { 00062 arma_extra_debug_sigprint(); 00063 00064 diagview<eT>& t = *this; 00065 00066 arma_debug_check( (t.n_elem != x.n_elem), "diagview: diagonals have incompatible lengths"); 00067 00068 Mat<eT>& t_m = *(t.m_ptr); 00069 const Mat<eT>& x_m = x.m; 00070 00071 if(&t_m != &x_m) 00072 { 00073 const uword t_n_elem = t.n_elem; 00074 const uword t_row_offset = t.row_offset; 00075 const uword t_col_offset = t.col_offset; 00076 00077 const uword x_row_offset = x.row_offset; 00078 const uword x_col_offset = x.col_offset; 00079 00080 uword i,j; 00081 for(i=0, j=1; j < t_n_elem; i+=2, j+=2) 00082 { 00083 const eT tmp_i = x_m.at(i + x_row_offset, i + x_col_offset); 00084 const eT tmp_j = x_m.at(j + x_row_offset, j + x_col_offset); 00085 00086 t_m.at(i + t_row_offset, i + t_col_offset) = tmp_i; 00087 t_m.at(j + t_row_offset, j + t_col_offset) = tmp_j; 00088 } 00089 00090 if(i < t_n_elem) 00091 { 00092 t_m.at(i + t_row_offset, i + t_col_offset) = x_m.at(i + x_row_offset, i + x_col_offset); 00093 } 00094 } 00095 else 00096 { 00097 const Mat<eT> tmp = x; 00098 00099 (*this).operator=(tmp); 00100 } 00101 } 00102 00103 00104 00105 template<typename eT> 00106 inline 00107 void 00108 diagview<eT>::operator+=(const eT val) 00109 { 00110 arma_extra_debug_sigprint(); 00111 00112 Mat<eT>& t_m = (*m_ptr); 00113 00114 const uword t_n_elem = n_elem; 00115 const uword t_row_offset = row_offset; 00116 const uword t_col_offset = col_offset; 00117 00118 for(uword i=0; i<t_n_elem; ++i) 00119 { 00120 t_m.at( i + t_row_offset, i + t_col_offset) += val; 00121 } 00122 } 00123 00124 00125 00126 template<typename eT> 00127 inline 00128 void 00129 diagview<eT>::operator-=(const eT val) 00130 { 00131 arma_extra_debug_sigprint(); 00132 00133 Mat<eT>& t_m = (*m_ptr); 00134 00135 const uword t_n_elem = n_elem; 00136 const uword t_row_offset = row_offset; 00137 const uword t_col_offset = col_offset; 00138 00139 for(uword i=0; i<t_n_elem; ++i) 00140 { 00141 t_m.at( i + t_row_offset, i + t_col_offset) -= val; 00142 } 00143 } 00144 00145 00146 00147 template<typename eT> 00148 inline 00149 void 00150 diagview<eT>::operator*=(const eT val) 00151 { 00152 arma_extra_debug_sigprint(); 00153 00154 Mat<eT>& t_m = (*m_ptr); 00155 00156 const uword t_n_elem = n_elem; 00157 const uword t_row_offset = row_offset; 00158 const uword t_col_offset = col_offset; 00159 00160 for(uword i=0; i<t_n_elem; ++i) 00161 { 00162 t_m.at( i + t_row_offset, i + t_col_offset) *= val; 00163 } 00164 } 00165 00166 00167 00168 template<typename eT> 00169 inline 00170 void 00171 diagview<eT>::operator/=(const eT val) 00172 { 00173 arma_extra_debug_sigprint(); 00174 00175 Mat<eT>& t_m = (*m_ptr); 00176 00177 const uword t_n_elem = n_elem; 00178 const uword t_row_offset = row_offset; 00179 const uword t_col_offset = col_offset; 00180 00181 for(uword i=0; i<t_n_elem; ++i) 00182 { 00183 t_m.at( i + t_row_offset, i + t_col_offset) /= val; 00184 } 00185 } 00186 00187 00188 00190 template<typename eT> 00191 template<typename T1> 00192 inline 00193 void 00194 diagview<eT>::operator= (const Base<eT,T1>& o) 00195 { 00196 arma_extra_debug_sigprint(); 00197 00198 const unwrap<T1> tmp(o.get_ref()); 00199 const Mat<eT>& x = tmp.M; 00200 00201 diagview<eT>& t = *this; 00202 00203 arma_debug_check 00204 ( 00205 ( (t.n_elem != x.n_elem) || (x.is_vec() == false) ), 00206 "diagview: given object has incompatible size" 00207 ); 00208 00209 Mat<eT>& t_m = *(t.m_ptr); 00210 00211 const uword t_n_elem = t.n_elem; 00212 const uword t_row_offset = t.row_offset; 00213 const uword t_col_offset = t.col_offset; 00214 00215 const eT* x_mem = x.memptr(); 00216 00217 uword i,j; 00218 for(i=0, j=1; j < t_n_elem; i+=2, j+=2) 00219 { 00220 const eT tmp_i = x_mem[i]; 00221 const eT tmp_j = x_mem[j]; 00222 00223 t_m.at( i + t_row_offset, i + t_col_offset) = tmp_i; 00224 t_m.at( j + t_row_offset, j + t_col_offset) = tmp_j; 00225 } 00226 00227 if(i < t_n_elem) 00228 { 00229 t_m.at( i + t_row_offset, i + t_col_offset) = x_mem[i]; 00230 } 00231 } 00232 00233 00234 00235 template<typename eT> 00236 template<typename T1> 00237 inline 00238 void 00239 diagview<eT>::operator+=(const Base<eT,T1>& o) 00240 { 00241 arma_extra_debug_sigprint(); 00242 00243 const unwrap<T1> tmp(o.get_ref()); 00244 const Mat<eT>& x = tmp.M; 00245 00246 diagview<eT>& t = *this; 00247 00248 arma_debug_check 00249 ( 00250 ( (t.n_elem != x.n_elem) || (x.is_vec() == false) ), 00251 "diagview: given object has incompatible size" 00252 ); 00253 00254 Mat<eT>& t_m = *(t.m_ptr); 00255 00256 const uword t_n_elem = t.n_elem; 00257 const uword t_row_offset = t.row_offset; 00258 const uword t_col_offset = t.col_offset; 00259 00260 const eT* x_mem = x.memptr(); 00261 00262 uword i,j; 00263 for(i=0, j=1; j < t_n_elem; i+=2, j+=2) 00264 { 00265 const eT tmp_i = x_mem[i]; 00266 const eT tmp_j = x_mem[j]; 00267 00268 t_m.at( i + t_row_offset, i + t_col_offset) += tmp_i; 00269 t_m.at( j + t_row_offset, j + t_col_offset) += tmp_j; 00270 } 00271 00272 if(i < t_n_elem) 00273 { 00274 t_m.at( i + t_row_offset, i + t_col_offset) += x_mem[i]; 00275 } 00276 } 00277 00278 00279 00280 template<typename eT> 00281 template<typename T1> 00282 inline 00283 void 00284 diagview<eT>::operator-=(const Base<eT,T1>& o) 00285 { 00286 arma_extra_debug_sigprint(); 00287 00288 const unwrap<T1> tmp(o.get_ref()); 00289 const Mat<eT>& x = tmp.M; 00290 00291 diagview<eT>& t = *this; 00292 00293 arma_debug_check 00294 ( 00295 ( (t.n_elem != x.n_elem) || (x.is_vec() == false) ), 00296 "diagview: given object has incompatible size" 00297 ); 00298 00299 Mat<eT>& t_m = *(t.m_ptr); 00300 00301 const uword t_n_elem = t.n_elem; 00302 const uword t_row_offset = t.row_offset; 00303 const uword t_col_offset = t.col_offset; 00304 00305 const eT* x_mem = x.memptr(); 00306 00307 uword i,j; 00308 for(i=0, j=1; j < t_n_elem; i+=2, j+=2) 00309 { 00310 const eT tmp_i = x_mem[i]; 00311 const eT tmp_j = x_mem[j]; 00312 00313 t_m.at( i + t_row_offset, i + t_col_offset) -= tmp_i; 00314 t_m.at( j + t_row_offset, j + t_col_offset) -= tmp_j; 00315 } 00316 00317 if(i < t_n_elem) 00318 { 00319 t_m.at( i + t_row_offset, i + t_col_offset) -= x_mem[i]; 00320 } 00321 } 00322 00323 00324 00325 template<typename eT> 00326 template<typename T1> 00327 inline 00328 void 00329 diagview<eT>::operator%=(const Base<eT,T1>& o) 00330 { 00331 arma_extra_debug_sigprint(); 00332 00333 const unwrap<T1> tmp(o.get_ref()); 00334 const Mat<eT>& x = tmp.M; 00335 00336 diagview<eT>& t = *this; 00337 00338 arma_debug_check 00339 ( 00340 ( (t.n_elem != x.n_elem) || (x.is_vec() == false) ), 00341 "diagview: given object has incompatible size" 00342 ); 00343 00344 Mat<eT>& t_m = *(t.m_ptr); 00345 00346 const uword t_n_elem = t.n_elem; 00347 const uword t_row_offset = t.row_offset; 00348 const uword t_col_offset = t.col_offset; 00349 00350 const eT* x_mem = x.memptr(); 00351 00352 uword i,j; 00353 for(i=0, j=1; j < t_n_elem; i+=2, j+=2) 00354 { 00355 const eT tmp_i = x_mem[i]; 00356 const eT tmp_j = x_mem[j]; 00357 00358 t_m.at( i + t_row_offset, i + t_col_offset) *= tmp_i; 00359 t_m.at( j + t_row_offset, j + t_col_offset) *= tmp_j; 00360 } 00361 00362 if(i < t_n_elem) 00363 { 00364 t_m.at( i + t_row_offset, i + t_col_offset) *= x_mem[i]; 00365 } 00366 } 00367 00368 00369 00370 template<typename eT> 00371 template<typename T1> 00372 inline 00373 void 00374 diagview<eT>::operator/=(const Base<eT,T1>& o) 00375 { 00376 arma_extra_debug_sigprint(); 00377 00378 const unwrap<T1> tmp(o.get_ref()); 00379 const Mat<eT>& x = tmp.M; 00380 00381 diagview<eT>& t = *this; 00382 00383 arma_debug_check 00384 ( 00385 ( (t.n_elem != x.n_elem) || (x.is_vec() == false) ), 00386 "diagview: given object has incompatible size" 00387 ); 00388 00389 Mat<eT>& t_m = *(t.m_ptr); 00390 00391 const uword t_n_elem = t.n_elem; 00392 const uword t_row_offset = t.row_offset; 00393 const uword t_col_offset = t.col_offset; 00394 00395 const eT* x_mem = x.memptr(); 00396 00397 uword i,j; 00398 for(i=0, j=1; j < t_n_elem; i+=2, j+=2) 00399 { 00400 const eT tmp_i = x_mem[i]; 00401 const eT tmp_j = x_mem[j]; 00402 00403 t_m.at( i + t_row_offset, i + t_col_offset) /= tmp_i; 00404 t_m.at( j + t_row_offset, j + t_col_offset) /= tmp_j; 00405 } 00406 00407 if(i < t_n_elem) 00408 { 00409 t_m.at( i + t_row_offset, i + t_col_offset) /= x_mem[i]; 00410 } 00411 } 00412 00413 00414 00416 template<typename eT> 00417 inline 00418 void 00419 diagview<eT>::extract(Mat<eT>& out, const diagview<eT>& in) 00420 { 00421 arma_extra_debug_sigprint(); 00422 00423 // NOTE: we're assuming that the matrix has already been set to the correct size and there is no aliasing; 00424 // size setting and alias checking is done by either the Mat contructor or operator=() 00425 00426 const Mat<eT>& in_m = in.m; 00427 00428 const uword in_n_elem = in.n_elem; 00429 const uword in_row_offset = in.row_offset; 00430 const uword in_col_offset = in.col_offset; 00431 00432 eT* out_mem = out.memptr(); 00433 00434 uword i,j; 00435 for(i=0, j=1; j < in_n_elem; i+=2, j+=2) 00436 { 00437 const eT tmp_i = in_m.at( i + in_row_offset, i + in_col_offset ); 00438 const eT tmp_j = in_m.at( j + in_row_offset, j + in_col_offset ); 00439 00440 out_mem[i] = tmp_i; 00441 out_mem[j] = tmp_j; 00442 } 00443 00444 if(i < in_n_elem) 00445 { 00446 out_mem[i] = in_m.at( i + in_row_offset, i + in_col_offset ); 00447 } 00448 } 00449 00450 00451 00453 template<typename eT> 00454 inline 00455 void 00456 diagview<eT>::plus_inplace(Mat<eT>& out, const diagview<eT>& in) 00457 { 00458 arma_extra_debug_sigprint(); 00459 00460 arma_debug_assert_same_size(out.n_rows, out.n_cols, in.n_rows, in.n_cols, "addition"); 00461 00462 const Mat<eT>& in_m = in.m; 00463 00464 const uword in_n_elem = in.n_elem; 00465 const uword in_row_offset = in.row_offset; 00466 const uword in_col_offset = in.col_offset; 00467 00468 eT* out_mem = out.memptr(); 00469 00470 uword i,j; 00471 for(i=0, j=1; j < in_n_elem; i+=2, j+=2) 00472 { 00473 const eT tmp_i = in_m.at( i + in_row_offset, i + in_col_offset ); 00474 const eT tmp_j = in_m.at( j + in_row_offset, j + in_col_offset ); 00475 00476 out_mem[i] += tmp_i; 00477 out_mem[j] += tmp_j; 00478 } 00479 00480 if(i < in_n_elem) 00481 { 00482 out_mem[i] += in_m.at( i + in_row_offset, i + in_col_offset ); 00483 } 00484 } 00485 00486 00487 00489 template<typename eT> 00490 inline 00491 void 00492 diagview<eT>::minus_inplace(Mat<eT>& out, const diagview<eT>& in) 00493 { 00494 arma_extra_debug_sigprint(); 00495 00496 arma_debug_assert_same_size(out.n_rows, out.n_cols, in.n_rows, in.n_cols, "subtraction"); 00497 00498 const Mat<eT>& in_m = in.m; 00499 00500 const uword in_n_elem = in.n_elem; 00501 const uword in_row_offset = in.row_offset; 00502 const uword in_col_offset = in.col_offset; 00503 00504 eT* out_mem = out.memptr(); 00505 00506 uword i,j; 00507 for(i=0, j=1; j < in_n_elem; i+=2, j+=2) 00508 { 00509 const eT tmp_i = in_m.at( i + in_row_offset, i + in_col_offset ); 00510 const eT tmp_j = in_m.at( j + in_row_offset, j + in_col_offset ); 00511 00512 out_mem[i] -= tmp_i; 00513 out_mem[j] -= tmp_j; 00514 } 00515 00516 if(i < in_n_elem) 00517 { 00518 out_mem[i] -= in_m.at( i + in_row_offset, i + in_col_offset ); 00519 } 00520 } 00521 00522 00523 00525 template<typename eT> 00526 inline 00527 void 00528 diagview<eT>::schur_inplace(Mat<eT>& out, const diagview<eT>& in) 00529 { 00530 arma_extra_debug_sigprint(); 00531 00532 arma_debug_assert_same_size(out.n_rows, out.n_cols, in.n_rows, in.n_cols, "element-wise multiplication"); 00533 00534 const Mat<eT>& in_m = in.m; 00535 00536 const uword in_n_elem = in.n_elem; 00537 const uword in_row_offset = in.row_offset; 00538 const uword in_col_offset = in.col_offset; 00539 00540 eT* out_mem = out.memptr(); 00541 00542 uword i,j; 00543 for(i=0, j=1; j < in_n_elem; i+=2, j+=2) 00544 { 00545 const eT tmp_i = in_m.at( i + in_row_offset, i + in_col_offset ); 00546 const eT tmp_j = in_m.at( j + in_row_offset, j + in_col_offset ); 00547 00548 out_mem[i] *= tmp_i; 00549 out_mem[j] *= tmp_j; 00550 } 00551 00552 if(i < in_n_elem) 00553 { 00554 out_mem[i] *= in_m.at( i + in_row_offset, i + in_col_offset ); 00555 } 00556 } 00557 00558 00559 00561 template<typename eT> 00562 inline 00563 void 00564 diagview<eT>::div_inplace(Mat<eT>& out, const diagview<eT>& in) 00565 { 00566 arma_extra_debug_sigprint(); 00567 00568 arma_debug_assert_same_size(out.n_rows, out.n_cols, in.n_rows, in.n_cols, "element-wise division"); 00569 00570 const Mat<eT>& in_m = in.m; 00571 00572 const uword in_n_elem = in.n_elem; 00573 const uword in_row_offset = in.row_offset; 00574 const uword in_col_offset = in.col_offset; 00575 00576 eT* out_mem = out.memptr(); 00577 00578 uword i,j; 00579 for(i=0, j=1; j < in_n_elem; i+=2, j+=2) 00580 { 00581 const eT tmp_i = in_m.at( i + in_row_offset, i + in_col_offset ); 00582 const eT tmp_j = in_m.at( j + in_row_offset, j + in_col_offset ); 00583 00584 out_mem[i] /= tmp_i; 00585 out_mem[j] /= tmp_j; 00586 } 00587 00588 if(i < in_n_elem) 00589 { 00590 out_mem[i] /= in_m.at( i + in_row_offset, i + in_col_offset ); 00591 } 00592 } 00593 00594 00595 00596 template<typename eT> 00597 arma_inline 00598 eT& 00599 diagview<eT>::operator[](const uword i) 00600 { 00601 return (*m_ptr).at(i+row_offset, i+col_offset); 00602 } 00603 00604 00605 00606 template<typename eT> 00607 arma_inline 00608 eT 00609 diagview<eT>::operator[](const uword i) const 00610 { 00611 return m.at(i+row_offset, i+col_offset); 00612 } 00613 00614 00615 00616 template<typename eT> 00617 arma_inline 00618 eT& 00619 diagview<eT>::at(const uword i) 00620 { 00621 return (*m_ptr).at(i+row_offset, i+col_offset); 00622 } 00623 00624 00625 00626 template<typename eT> 00627 arma_inline 00628 eT 00629 diagview<eT>::at(const uword i) const 00630 { 00631 return m.at(i+row_offset, i+col_offset); 00632 } 00633 00634 00635 00636 template<typename eT> 00637 arma_inline 00638 eT& 00639 diagview<eT>::operator()(const uword i) 00640 { 00641 arma_debug_check( (i >= n_elem), "diagview::operator(): out of bounds" ); 00642 00643 return (*m_ptr).at(i+row_offset, i+col_offset); 00644 } 00645 00646 00647 00648 template<typename eT> 00649 arma_inline 00650 eT 00651 diagview<eT>::operator()(const uword i) const 00652 { 00653 arma_debug_check( (i >= n_elem), "diagview::operator(): out of bounds" ); 00654 00655 return m.at(i+row_offset, i+col_offset); 00656 } 00657 00658 00659 00660 template<typename eT> 00661 arma_inline 00662 eT& 00663 diagview<eT>::at(const uword row, const uword col) 00664 { 00665 return (*m_ptr).at(row+row_offset, row+col_offset); 00666 } 00667 00668 00669 00670 template<typename eT> 00671 arma_inline 00672 eT 00673 diagview<eT>::at(const uword row, const uword col) const 00674 { 00675 return m.at(row+row_offset, row+col_offset); 00676 } 00677 00678 00679 00680 template<typename eT> 00681 arma_inline 00682 eT& 00683 diagview<eT>::operator()(const uword row, const uword col) 00684 { 00685 arma_debug_check( ((row >= n_elem) || (col > 0)), "diagview::operator(): out of bounds" ); 00686 00687 return (*m_ptr).at(row+row_offset, row+col_offset); 00688 } 00689 00690 00691 00692 template<typename eT> 00693 arma_inline 00694 eT 00695 diagview<eT>::operator()(const uword row, const uword col) const 00696 { 00697 arma_debug_check( ((row >= n_elem) || (col > 0)), "diagview::operator(): out of bounds" ); 00698 00699 return m.at(row+row_offset, row+col_offset); 00700 } 00701 00702 00703 00704 template<typename eT> 00705 inline 00706 void 00707 diagview<eT>::fill(const eT val) 00708 { 00709 arma_extra_debug_sigprint(); 00710 00711 Mat<eT>& x = (*m_ptr); 00712 00713 for(uword i=0; i<n_elem; ++i) 00714 { 00715 x.at(i+row_offset, i+col_offset) = val; 00716 } 00717 } 00718 00719 00720 00721 template<typename eT> 00722 inline 00723 void 00724 diagview<eT>::zeros() 00725 { 00726 arma_extra_debug_sigprint(); 00727 00728 (*this).fill(eT(0)); 00729 } 00730 00731 00732 00733 template<typename eT> 00734 inline 00735 void 00736 diagview<eT>::ones() 00737 { 00738 arma_extra_debug_sigprint(); 00739 00740 (*this).fill(eT(1)); 00741 } 00742 00743 00744