| SpMat_bones.hpp | | SpMat_bones.hpp | |
| | | | |
| skipping to change at line 80 | | skipping to change at line 80 | |
| inline SpMat(const std::string& text); | | inline SpMat(const std::string& text); | |
| inline const SpMat& operator=(const std::string& text); | | inline const SpMat& operator=(const std::string& text); | |
| inline SpMat(const SpMat<eT>& x); | | inline SpMat(const SpMat<eT>& x); | |
| | | | |
| #if defined(ARMA_USE_CXX11) | | #if defined(ARMA_USE_CXX11) | |
| inline SpMat(SpMat&& m); | | inline SpMat(SpMat&& m); | |
| inline const SpMat& operator=(SpMat&& m); | | inline const SpMat& operator=(SpMat&& m); | |
| #endif | | #endif | |
| | | | |
| template<typename T1, typename T2> inline SpMat(const Base<uword,T1>& loc
ations, const Base<eT,T2>& values, const bool sort_locations = true); | | template<typename T1, typename T2> inline SpMat(const Base<uword,T1>& loc
ations, const Base<eT,T2>& values, const bool sort_locations = true); | |
|
| template<typename T1, typename T2> inline SpMat(const Base<uword,T1>& loc
ations, const Base<eT,T2>& values, const uword n_rows, const uword n_cols,
const bool sort_locations = true); | | template<typename T1, typename T2> inline SpMat(const Base<uword,T1>& loc
ations, const Base<eT,T2>& values, const uword n_rows, const uword n_cols,
const bool sort_locations = true, const bool check_for_zeros = true); | |
| | | | |
| template<typename T1, typename T2, typename T3> inline SpMat(const Base<u
word,T1>& rowind, const Base<uword,T2>& colptr, const Base<eT,T3>& values,
const uword n_rows, const uword n_cols); | | template<typename T1, typename T2, typename T3> inline SpMat(const Base<u
word,T1>& rowind, const Base<uword,T2>& colptr, const Base<eT,T3>& values,
const uword n_rows, const uword n_cols); | |
| | | | |
| inline const SpMat& operator=(const eT val); //! Sets size to 1x1. | | inline const SpMat& operator=(const eT val); //! Sets size to 1x1. | |
| inline const SpMat& operator*=(const eT val); | | inline const SpMat& operator*=(const eT val); | |
| inline const SpMat& operator/=(const eT val); | | inline const SpMat& operator/=(const eT val); | |
| // operator+=(val) and operator-=(val) are not defined as they don't make
sense for sparse matrices | | // operator+=(val) and operator-=(val) are not defined as they don't make
sense for sparse matrices | |
| | | | |
| /** | | /** | |
| * Operators on other sparse matrices. These work as though you would ex
pect. | | * Operators on other sparse matrices. These work as though you would ex
pect. | |
| | | | |
| skipping to change at line 513 | | skipping to change at line 513 | |
| inline row_iterator end_row(); | | inline row_iterator end_row(); | |
| inline const_row_iterator end_row() const; | | inline const_row_iterator end_row() const; | |
| | | | |
| inline row_iterator end_row(const uword row_num); | | inline row_iterator end_row(const uword row_num); | |
| inline const_row_iterator end_row(const uword row_num) const; | | inline const_row_iterator end_row(const uword row_num) const; | |
| | | | |
| inline void clear(); | | inline void clear(); | |
| inline bool empty() const; | | inline bool empty() const; | |
| inline uword size() const; | | inline uword size() const; | |
| | | | |
|
| inline void remove_zeros(); | | | |
| | | | |
| /** | | /** | |
| * Resize memory. You are responsible for updating the column pointers a
nd | | * Resize memory. You are responsible for updating the column pointers a
nd | |
| * filling the new memory (if the new size is larger). If the new size i
s | | * filling the new memory (if the new size is larger). If the new size i
s | |
| * smaller, the first new_n_nonzero elements will be copied. n_nonzero i
s | | * smaller, the first new_n_nonzero elements will be copied. n_nonzero i
s | |
| * updated. | | * updated. | |
| */ | | */ | |
| inline void mem_resize(const uword new_n_nonzero); | | inline void mem_resize(const uword new_n_nonzero); | |
| | | | |
| //! don't use this unless you're writing internal Armadillo code | | //! don't use this unless you're writing internal Armadillo code | |
| inline void steal_mem(SpMat& X); | | inline void steal_mem(SpMat& X); | |
| | | | |
End of changes. 2 change blocks. |
| 3 lines changed or deleted | | 1 lines changed or added | |
|
| SpMat_meat.hpp | | SpMat_meat.hpp | |
| | | | |
| skipping to change at line 211 | | skipping to change at line 211 | |
| const Mat<uword>& locs = locs_tmp.M; | | const Mat<uword>& locs = locs_tmp.M; | |
| const Mat<eT>& vals = vals_tmp.M; | | const Mat<eT>& vals = vals_tmp.M; | |
| | | | |
| arma_debug_check( (vals.is_vec() == false), "SpMat::SpMat(): given 'v
alues' object is not a vector" ); | | arma_debug_check( (vals.is_vec() == false), "SpMat::SpMat(): given 'v
alues' object is not a vector" ); | |
| arma_debug_check( (locs.n_rows != 2), "SpMat::SpMat(): location
s matrix must have two rows" ); | | arma_debug_check( (locs.n_rows != 2), "SpMat::SpMat(): location
s matrix must have two rows" ); | |
| arma_debug_check( (locs.n_cols != vals.n_elem), "SpMat::SpMat(): number o
f locations is different than number of values" ); | | arma_debug_check( (locs.n_cols != vals.n_elem), "SpMat::SpMat(): number o
f locations is different than number of values" ); | |
| | | | |
| // If there are no elements in the list, max() will fail. | | // If there are no elements in the list, max() will fail. | |
| if(locs.n_cols == 0) { init(0, 0); return; } | | if(locs.n_cols == 0) { init(0, 0); return; } | |
| | | | |
|
| // Automatically determine size | | // Automatically determine size before pruning zeros. | |
| uvec bounds = arma::max(locs, 1); | | uvec bounds = arma::max(locs, 1); | |
| init(bounds[0] + 1, bounds[1] + 1); | | init(bounds[0] + 1, bounds[1] + 1); | |
| | | | |
|
| init_batch(locs, vals, sort_locations); | | // Ensure that there are no zeros | |
| | | const uword N_old = vals.n_elem; | |
| | | uword N_new = 0; | |
| | | | |
| | | for(uword i = 0; i < N_old; ++i) | |
| | | { | |
| | | if(vals[i] != eT(0)) { ++N_new; } | |
| | | } | |
| | | | |
| | | if(N_new != N_old) | |
| | | { | |
| | | Col<eT> filtered_vals(N_new); | |
| | | Mat<uword> filtered_locs(2, N_new); | |
| | | | |
| | | uword index = 0; | |
| | | for(uword i = 0; i < N_old; ++i) | |
| | | { | |
| | | if(vals[i] != eT(0)) | |
| | | { | |
| | | filtered_vals[index] = vals[i]; | |
| | | | |
| | | filtered_locs.at(0, index) = locs.at(0, i); | |
| | | filtered_locs.at(1, index) = locs.at(1, i); | |
| | | | |
| | | ++index; | |
| | | } | |
| | | } | |
| | | | |
| | | init_batch(filtered_locs, filtered_vals, sort_locations); | |
| | | } | |
| | | else | |
| | | { | |
| | | init_batch(locs, vals, sort_locations); | |
| | | } | |
| } | | } | |
| | | | |
| //! Insert a large number of values at once. | | //! Insert a large number of values at once. | |
| //! locations.row[0] should be row indices, locations.row[1] should be colu
mn indices, | | //! locations.row[0] should be row indices, locations.row[1] should be colu
mn indices, | |
| //! and values should be the corresponding values. | | //! and values should be the corresponding values. | |
| //! If sort_locations is false, then it is assumed that the locations and v
alues | | //! If sort_locations is false, then it is assumed that the locations and v
alues | |
| //! are already sorted in column-major ordering. | | //! are already sorted in column-major ordering. | |
| //! In this constructor the size is explicitly given. | | //! In this constructor the size is explicitly given. | |
| template<typename eT> | | template<typename eT> | |
| template<typename T1, typename T2> | | template<typename T1, typename T2> | |
| inline | | inline | |
|
| SpMat<eT>::SpMat(const Base<uword,T1>& locations_expr, const Base<eT,T2>& v
als_expr, const uword in_n_rows, const uword in_n_cols, const bool sort_loc
ations) | | SpMat<eT>::SpMat(const Base<uword,T1>& locations_expr, const Base<eT,T2>& v
als_expr, const uword in_n_rows, const uword in_n_cols, const bool sort_loc
ations, const bool check_for_zeros) | |
| : n_rows(0) | | : n_rows(0) | |
| , n_cols(0) | | , n_cols(0) | |
| , n_elem(0) | | , n_elem(0) | |
| , n_nonzero(0) | | , n_nonzero(0) | |
| , vec_state(0) | | , vec_state(0) | |
| , values(NULL) | | , values(NULL) | |
| , row_indices(NULL) | | , row_indices(NULL) | |
| , col_ptrs(NULL) | | , col_ptrs(NULL) | |
| { | | { | |
| arma_extra_debug_sigprint_this(this); | | arma_extra_debug_sigprint_this(this); | |
| | | | |
| skipping to change at line 251 | | skipping to change at line 284 | |
| | | | |
| const Mat<uword>& locs = locs_tmp.M; | | const Mat<uword>& locs = locs_tmp.M; | |
| const Mat<eT>& vals = vals_tmp.M; | | const Mat<eT>& vals = vals_tmp.M; | |
| | | | |
| arma_debug_check( (vals.is_vec() == false), "SpMat::SpMat(): given 'v
alues' object is not a vector" ); | | arma_debug_check( (vals.is_vec() == false), "SpMat::SpMat(): given 'v
alues' object is not a vector" ); | |
| arma_debug_check( (locs.n_rows != 2), "SpMat::SpMat(): location
s matrix must have two rows" ); | | arma_debug_check( (locs.n_rows != 2), "SpMat::SpMat(): location
s matrix must have two rows" ); | |
| arma_debug_check( (locs.n_cols != vals.n_elem), "SpMat::SpMat(): number o
f locations is different than number of values" ); | | arma_debug_check( (locs.n_cols != vals.n_elem), "SpMat::SpMat(): number o
f locations is different than number of values" ); | |
| | | | |
| init(in_n_rows, in_n_cols); | | init(in_n_rows, in_n_cols); | |
| | | | |
|
| init_batch(locs, vals, sort_locations); | | // Ensure that there are no zeros, unless the user asked not to. | |
| | | if(check_for_zeros) | |
| | | { | |
| | | const uword N_old = vals.n_elem; | |
| | | uword N_new = 0; | |
| | | | |
| | | for(uword i = 0; i < N_old; ++i) | |
| | | { | |
| | | if(vals[i] != eT(0)) { ++N_new; } | |
| | | } | |
| | | | |
| | | if(N_new != N_old) | |
| | | { | |
| | | Col<eT> filtered_vals(N_new); | |
| | | Mat<uword> filtered_locs(2, N_new); | |
| | | | |
| | | uword index = 0; | |
| | | for(uword i = 0; i < N_old; ++i) | |
| | | { | |
| | | if(vals[i] != eT(0)) | |
| | | { | |
| | | filtered_vals[index] = vals[i]; | |
| | | | |
| | | filtered_locs.at(0, index) = locs.at(0, i); | |
| | | filtered_locs.at(1, index) = locs.at(1, i); | |
| | | | |
| | | ++index; | |
| | | } | |
| | | } | |
| | | | |
| | | init_batch(filtered_locs, filtered_vals, sort_locations); | |
| | | } | |
| | | else | |
| | | { | |
| | | init_batch(locs, vals, sort_locations); | |
| | | } | |
| | | } | |
| | | else | |
| | | { | |
| | | init_batch(locs, vals, sort_locations); | |
| | | } | |
| } | | } | |
| | | | |
| //! Insert a large number of values at once. | | //! Insert a large number of values at once. | |
| //! Per CSC format, rowind_expr should be row indices, | | //! Per CSC format, rowind_expr should be row indices, | |
| //! colptr_expr should column ptr indices locations, | | //! colptr_expr should column ptr indices locations, | |
| //! and values should be the corresponding values. | | //! and values should be the corresponding values. | |
| //! In this constructor the size is explicitly given. | | //! In this constructor the size is explicitly given. | |
| //! Values are assumed to be sorted, and the size | | //! Values are assumed to be sorted, and the size | |
| //! information is trusted | | //! information is trusted | |
| template<typename eT> | | template<typename eT> | |
| | | | |
| skipping to change at line 3816 | | skipping to change at line 3889 | |
| | | | |
| access::rw(col_ptrs[ locs_i[1] + 1 ])++; | | access::rw(col_ptrs[ locs_i[1] + 1 ])++; | |
| } | | } | |
| } | | } | |
| | | | |
| // Now fix the column pointers. | | // Now fix the column pointers. | |
| for (uword i = 0; i <= n_cols; ++i) | | for (uword i = 0; i <= n_cols; ++i) | |
| { | | { | |
| access::rw(col_ptrs[i + 1]) += col_ptrs[i]; | | access::rw(col_ptrs[i + 1]) += col_ptrs[i]; | |
| } | | } | |
|
| | | | |
| remove_zeros(); | | | |
| } | | | |
| | | | |
| template<typename eT> | | | |
| inline | | | |
| void | | | |
| SpMat<eT>::remove_zeros() | | | |
| { | | | |
| arma_extra_debug_sigprint(); | | | |
| | | | |
| uword zeros_count = 0; | | | |
| | | | |
| for(uword i=0; i<n_nonzero; ++i) | | | |
| { | | | |
| if(values[i] == eT(0)) { zeros_count++; } | | | |
| } | | | |
| | | | |
| if(zeros_count == 0) | | | |
| { | | | |
| return; | | | |
| } | | | |
| | | | |
| const uword actual_n_nonzero = n_nonzero - zeros_count; | | | |
| | | | |
| SpMat<eT> out(n_rows, n_cols); | | | |
| | | | |
| out.mem_resize(actual_n_nonzero); | | | |
| | | | |
| const SpMat<eT>& x = (*this); | | | |
| | | | |
| typename SpMat<eT>::const_iterator x_it = x.begin(); | | | |
| typename SpMat<eT>::const_iterator x_end = x.end(); | | | |
| | | | |
| uword cur_val = 0; | | | |
| while(x_it != x_end) | | | |
| { | | | |
| const eT val = (*x_it); | | | |
| | | | |
| if(val != eT(0)) | | | |
| { | | | |
| access::rw(out.values[cur_val]) = val; | | | |
| access::rw(out.row_indices[cur_val]) = x_it.row(); | | | |
| | | | |
| ++access::rw(out.col_ptrs[x_it.col() + 1]); | | | |
| ++cur_val; | | | |
| } | | | |
| | | | |
| ++x_it; | | | |
| } | | | |
| | | | |
| const uword out_n_cols = out.n_cols; | | | |
| uword* out_col_ptrs = access::rwp(out.col_ptrs); | | | |
| | | | |
| for(uword c = 1; c <= out_n_cols; ++c) | | | |
| { | | | |
| out_col_ptrs[c] += out_col_ptrs[c - 1]; | | | |
| } | | | |
| | | | |
| steal_mem(out); | | | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| inline | | inline | |
| void | | void | |
| SpMat<eT>::mem_resize(const uword new_n_nonzero) | | SpMat<eT>::mem_resize(const uword new_n_nonzero) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| if(n_nonzero != new_n_nonzero) | | if(n_nonzero != new_n_nonzero) | |
| | | | |
End of changes. 5 change blocks. |
| 64 lines changed or deleted | | 77 lines changed or added | |
|
| arma_cmath.hpp | | arma_cmath.hpp | |
|
| // Copyright (C) 2008-2013 Conrad Sanderson | | // Copyright (C) 2008-2014 Conrad Sanderson | |
| // Copyright (C) 2008-2013 NICTA (www.nicta.com.au) | | // Copyright (C) 2008-2014 NICTA (www.nicta.com.au) | |
| // | | // | |
| // This Source Code Form is subject to the terms of the Mozilla Public | | // This Source Code Form is subject to the terms of the Mozilla Public | |
| // License, v. 2.0. If a copy of the MPL was not distributed with this | | // License, v. 2.0. If a copy of the MPL was not distributed with this | |
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | | // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| | | | |
| //! \addtogroup arma_cmath | | //! \addtogroup arma_cmath | |
| //! @{ | | //! @{ | |
| | | | |
| // | | // | |
| // wrappers for isfinite | | // wrappers for isfinite | |
| | | | |
| skipping to change at line 43 | | skipping to change at line 43 | |
| #elif defined(ARMA_HAVE_TR1) | | #elif defined(ARMA_HAVE_TR1) | |
| { | | { | |
| return std::tr1::isfinite(x); | | return std::tr1::isfinite(x); | |
| } | | } | |
| #elif defined(ARMA_HAVE_ISFINITE) | | #elif defined(ARMA_HAVE_ISFINITE) | |
| { | | { | |
| return (std::isfinite(x) != 0); | | return (std::isfinite(x) != 0); | |
| } | | } | |
| #else | | #else | |
| { | | { | |
|
| const bool x_is_inf = ( (x == x) && ((x - x) != float(0)) ); | | const float y = (std::numeric_limits<float>::max)(); | |
| const bool x_is_nan = (x != x); | | | |
| | | | |
|
| return ( (x_is_inf == false) && (x_is_nan == false) ); | | return (x == x) && (x >= -y) && (x <= y); | |
| } | | } | |
| #endif | | #endif | |
| } | | } | |
| | | | |
| template<> | | template<> | |
| arma_inline | | arma_inline | |
| bool | | bool | |
| arma_isfinite(double x) | | arma_isfinite(double x) | |
| { | | { | |
| #if defined(ARMA_USE_CXX11) | | #if defined(ARMA_USE_CXX11) | |
| | | | |
| skipping to change at line 70 | | skipping to change at line 69 | |
| #elif defined(ARMA_HAVE_TR1) | | #elif defined(ARMA_HAVE_TR1) | |
| { | | { | |
| return std::tr1::isfinite(x); | | return std::tr1::isfinite(x); | |
| } | | } | |
| #elif defined(ARMA_HAVE_ISFINITE) | | #elif defined(ARMA_HAVE_ISFINITE) | |
| { | | { | |
| return (std::isfinite(x) != 0); | | return (std::isfinite(x) != 0); | |
| } | | } | |
| #else | | #else | |
| { | | { | |
|
| const bool x_is_inf = ( (x == x) && ((x - x) != double(0)) ); | | const double y = (std::numeric_limits<double>::max)(); | |
| const bool x_is_nan = (x != x); | | | |
| | | | |
|
| return ( (x_is_inf == false) && (x_is_nan == false) ); | | return (x == x) && (x >= -y) && (x <= y); | |
| } | | } | |
| #endif | | #endif | |
| } | | } | |
| | | | |
| template<typename T> | | template<typename T> | |
| arma_inline | | arma_inline | |
| bool | | bool | |
| arma_isfinite(const std::complex<T>& x) | | arma_isfinite(const std::complex<T>& x) | |
| { | | { | |
| if( (arma_isfinite(x.real()) == false) || (arma_isfinite(x.imag()) == fal
se) ) | | if( (arma_isfinite(x.real()) == false) || (arma_isfinite(x.imag()) == fal
se) ) | |
| { | | { | |
| return false; | | return false; | |
| } | | } | |
| else | | else | |
| { | | { | |
| return true; | | return true; | |
| } | | } | |
| } | | } | |
| | | | |
|
| | | // rudimentary wrappers for log1p() | |
| | | | |
| | | arma_inline | |
| | | float | |
| | | arma_log1p(const float x) | |
| | | { | |
| | | #if defined(ARMA_USE_CXX11) | |
| | | { | |
| | | return std::log1p(x); | |
| | | } | |
| | | #else | |
| | | { | |
| | | if((x >= float(0)) && (x < std::numeric_limits<float>::epsilon())) | |
| | | { | |
| | | return x; | |
| | | } | |
| | | else | |
| | | if((x < float(0)) && (-x < std::numeric_limits<float>::epsilon())) | |
| | | { | |
| | | return x; | |
| | | } | |
| | | else | |
| | | { | |
| | | return std::log(float(1) + x); | |
| | | } | |
| | | } | |
| | | #endif | |
| | | } | |
| | | | |
| | | arma_inline | |
| | | double | |
| | | arma_log1p(const double x) | |
| | | { | |
| | | #if defined(ARMA_USE_CXX11) | |
| | | { | |
| | | return std::log1p(x); | |
| | | } | |
| | | #elif defined(ARMA_HAVE_LOG1P) | |
| | | { | |
| | | return log1p(x); | |
| | | } | |
| | | #else | |
| | | { | |
| | | if((x >= double(0)) && (x < std::numeric_limits<double>::epsilon())) | |
| | | { | |
| | | return x; | |
| | | } | |
| | | else | |
| | | if((x < double(0)) && (-x < std::numeric_limits<double>::epsilon())) | |
| | | { | |
| | | return x; | |
| | | } | |
| | | else | |
| | | { | |
| | | return std::log(double(1) + x); | |
| | | } | |
| | | } | |
| | | #endif | |
| | | } | |
| | | | |
| // | | // | |
| // wrappers for trigonometric functions | | // wrappers for trigonometric functions | |
| // | | // | |
| // wherever possible, try to use C++11 or TR1 versions of the following fun
ctions: | | // wherever possible, try to use C++11 or TR1 versions of the following fun
ctions: | |
| // | | // | |
| // complex acos | | // complex acos | |
| // complex asin | | // complex asin | |
| // complex atan | | // complex atan | |
| // | | // | |
| // real acosh | | // real acosh | |
| | | | |
End of changes. 6 change blocks. |
| 8 lines changed or deleted | | 66 lines changed or added | |
|
| fn_eig_sym.hpp | | fn_eig_sym.hpp | |
|
| // Copyright (C) 2008-2013 Conrad Sanderson | | // Copyright (C) 2008-2014 Conrad Sanderson | |
| // Copyright (C) 2008-2013 NICTA (www.nicta.com.au) | | // Copyright (C) 2008-2014 NICTA (www.nicta.com.au) | |
| // Copyright (C) 2011 Stanislav Funiak | | // Copyright (C) 2011 Stanislav Funiak | |
| // | | // | |
| // This Source Code Form is subject to the terms of the Mozilla Public | | // This Source Code Form is subject to the terms of the Mozilla Public | |
| // License, v. 2.0. If a copy of the MPL was not distributed with this | | // License, v. 2.0. If a copy of the MPL was not distributed with this | |
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | | // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| | | | |
| //! \addtogroup fn_eig_sym | | //! \addtogroup fn_eig_sym | |
| //! @{ | | //! @{ | |
| | | | |
| //! Eigenvalues of real/complex symmetric/hermitian matrix X | | //! Eigenvalues of real/complex symmetric/hermitian matrix X | |
| | | | |
| skipping to change at line 81 | | skipping to change at line 81 | |
| Col<typename T1::pod_type>& eigval, | | Col<typename T1::pod_type>& eigval, | |
| Mat<typename T1::elem_type>& eigvec, | | Mat<typename T1::elem_type>& eigvec, | |
| const Base<typename T1::elem_type,T1>& X, | | const Base<typename T1::elem_type,T1>& X, | |
| const char* method = "dc", | | const char* method = "dc", | |
| const typename arma_blas_type_only<typename T1::elem_type>::result* junk
= 0 | | const typename arma_blas_type_only<typename T1::elem_type>::result* junk
= 0 | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| arma_ignore(junk); | | arma_ignore(junk); | |
| | | | |
|
| arma_debug_check( void_ptr(&eigval) == void_ptr(&eigvec), "eig_sym(): eig
val is an alias of eigvec" ); | | typedef typename T1::elem_type eT; | |
| | | | |
| const char sig = (method != NULL) ? method[0] : char(0); | | const char sig = (method != NULL) ? method[0] : char(0); | |
| | | | |
|
| arma_debug_check( ((sig != 's') && (sig != 'd')), "eig_sym(): unknown met | | arma_debug_check( ((sig != 's') && (sig != 'd')), "eig_sym(): unk | |
| hod specified" ); | | nown method specified" ); | |
| | | arma_debug_check( void_ptr(&eigval) == void_ptr(&eigvec), "eig_sym(): eig | |
| | | val is an alias of eigvec" ); | |
| | | | |
| | | const Proxy<T1> P(X.get_ref()); | |
| | | | |
| | | const bool is_alias = P.is_alias(eigvec); | |
| | | | |
| | | Mat<eT> eigvec_tmp; | |
| | | Mat<eT>& eigvec_out = (is_alias == false) ? eigvec : eigvec_tmp; | |
| | | | |
|
| const bool status = (sig == 'd') ? auxlib::eig_sym_dc(eigval, eigvec, X) | | bool status = false; | |
| : auxlib::eig_sym(eigval, eigvec, X); | | | |
| | | if(sig == 'd') { status = auxlib::eig_sym_dc(eigval, eigvec_out, P. | |
| | | Q); } | |
| | | | |
| | | if(status == false) { status = auxlib::eig_sym(eigval, eigvec_out, P.Q); | |
| | | } | |
| | | | |
| if(status == false) | | if(status == false) | |
| { | | { | |
| eigval.reset(); | | eigval.reset(); | |
| eigvec.reset(); | | eigvec.reset(); | |
| arma_bad("eig_sym(): failed to converge", false); | | arma_bad("eig_sym(): failed to converge", false); | |
| } | | } | |
|
| | | else | |
| | | { | |
| | | if(is_alias) { eigvec.steal_mem(eigvec_tmp); } | |
| | | } | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| | | | |
| //! @} | | //! @} | |
| | | | |
End of changes. 5 change blocks. |
| 7 lines changed or deleted | | 25 lines changed or added | |
|
| fn_eigs_gen.hpp | | fn_eigs_gen.hpp | |
| | | | |
| skipping to change at line 21 | | skipping to change at line 21 | |
| | | | |
| //! eigenvalues of general sparse matrix X | | //! eigenvalues of general sparse matrix X | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| Col< std::complex<typename T1::pod_type> > | | Col< std::complex<typename T1::pod_type> > | |
| eigs_gen | | eigs_gen | |
| ( | | ( | |
| const SpBase<typename T1::elem_type, T1>& X, | | const SpBase<typename T1::elem_type, T1>& X, | |
| const uword n_eigvals, | | const uword n_eigvals, | |
| const char* form = "lm", | | const char* form = "lm", | |
|
| | | const typename T1::elem_type tol = 0.0, | |
| const typename arma_blas_type_only<typename T1::elem_type>::result* junk
= 0 | | const typename arma_blas_type_only<typename T1::elem_type>::result* junk
= 0 | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| arma_ignore(junk); | | arma_ignore(junk); | |
| | | | |
| typedef typename T1::pod_type T; | | typedef typename T1::pod_type T; | |
| | | | |
| Mat< std::complex<T> > eigvec; | | Mat< std::complex<T> > eigvec; | |
| Col< std::complex<T> > eigval; | | Col< std::complex<T> > eigval; | |
| | | | |
|
| const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, for
m); | | const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, for
m, tol); | |
| | | | |
| if(status == false) | | if(status == false) | |
| { | | { | |
| eigval.reset(); | | eigval.reset(); | |
| arma_bad("eigs_gen(): failed to converge"); | | arma_bad("eigs_gen(): failed to converge"); | |
| } | | } | |
| | | | |
| return eigval; | | return eigval; | |
| } | | } | |
| | | | |
| //! eigenvalues of general sparse matrix X | | //! eigenvalues of general sparse matrix X | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| bool | | bool | |
| eigs_gen | | eigs_gen | |
| ( | | ( | |
| Col< std::complex<typename T1::pod_type> >& eigval, | | Col< std::complex<typename T1::pod_type> >& eigval, | |
| const SpBase<typename T1::elem_type, T1>& X, | | const SpBase<typename T1::elem_type, T1>& X, | |
| const uword n_eigvals, | | const uword n_eigvals, | |
| const char* form = "lm", | | const char* form = "lm", | |
|
| | | const typename T1::pod_type tol = 0.0, | |
| const typename arma_blas_type_only<typename T1::elem_type>::result* junk
= 0 | | const typename arma_blas_type_only<typename T1::elem_type>::result* junk
= 0 | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| arma_ignore(junk); | | arma_ignore(junk); | |
| | | | |
| typedef typename T1::pod_type T; | | typedef typename T1::pod_type T; | |
| | | | |
| Mat< std::complex<T> > eigvec; | | Mat< std::complex<T> > eigvec; | |
| | | | |
|
| const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, for
m); | | const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, for
m, tol); | |
| | | | |
| if(status == false) | | if(status == false) | |
| { | | { | |
| eigval.reset(); | | eigval.reset(); | |
| arma_bad("eigs_gen(): failed to converge", false); | | arma_bad("eigs_gen(): failed to converge", false); | |
| } | | } | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 85 | | skipping to change at line 87 | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| bool | | bool | |
| eigs_gen | | eigs_gen | |
| ( | | ( | |
| Col< std::complex<typename T1::pod_type> >& eigval, | | Col< std::complex<typename T1::pod_type> >& eigval, | |
| Mat< std::complex<typename T1::pod_type> >& eigvec, | | Mat< std::complex<typename T1::pod_type> >& eigvec, | |
| const SpBase<typename T1::elem_type, T1>& X, | | const SpBase<typename T1::elem_type, T1>& X, | |
| const uword n_eigvals, | | const uword n_eigvals, | |
| const char* form = "lm", | | const char* form = "lm", | |
|
| | | const typename T1::pod_type tol = 0.0, | |
| const typename arma_blas_type_only<typename T1::elem_type>::result* junk
= 0 | | const typename arma_blas_type_only<typename T1::elem_type>::result* junk
= 0 | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| arma_ignore(junk); | | arma_ignore(junk); | |
| | | | |
| arma_debug_check( void_ptr(&eigval) == void_ptr(&eigvec), "eigs_gen(): ei
gval is an alias of eigvec" ); | | arma_debug_check( void_ptr(&eigval) == void_ptr(&eigvec), "eigs_gen(): ei
gval is an alias of eigvec" ); | |
| | | | |
|
| const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, for
m); | | const bool status = sp_auxlib::eigs_gen(eigval, eigvec, X, n_eigvals, for
m, tol); | |
| | | | |
| if(status == false) | | if(status == false) | |
| { | | { | |
| eigval.reset(); | | eigval.reset(); | |
| eigvec.reset(); | | eigvec.reset(); | |
| arma_bad("eigs_gen(): failed to converge", false); | | arma_bad("eigs_gen(): failed to converge", false); | |
| } | | } | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| | | | |
End of changes. 6 change blocks. |
| 3 lines changed or deleted | | 6 lines changed or added | |
|
| fn_eigs_sym.hpp | | fn_eigs_sym.hpp | |
| | | | |
| skipping to change at line 21 | | skipping to change at line 21 | |
| | | | |
| //! eigenvalues of symmetric real sparse matrix X | | //! eigenvalues of symmetric real sparse matrix X | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| Col<typename T1::pod_type> | | Col<typename T1::pod_type> | |
| eigs_sym | | eigs_sym | |
| ( | | ( | |
| const SpBase<typename T1::elem_type,T1>& X, | | const SpBase<typename T1::elem_type,T1>& X, | |
| const uword n_eigvals, | | const uword n_eigvals, | |
| const char* form = "lm", | | const char* form = "lm", | |
|
| | | const typename T1::elem_type tol = 0.0, | |
| const typename arma_real_only<typename T1::elem_type>::result* junk = 0 | | const typename arma_real_only<typename T1::elem_type>::result* junk = 0 | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| arma_ignore(junk); | | arma_ignore(junk); | |
| | | | |
| Mat<typename T1::elem_type> eigvec; | | Mat<typename T1::elem_type> eigvec; | |
| Col<typename T1::pod_type > eigval; | | Col<typename T1::pod_type > eigval; | |
| | | | |
|
| const bool status = sp_auxlib::eigs_sym(eigval, eigvec, X, n_eigvals, for
m); | | const bool status = sp_auxlib::eigs_sym(eigval, eigvec, X, n_eigvals, for
m, tol); | |
| | | | |
| if(status == false) | | if(status == false) | |
| { | | { | |
| eigval.reset(); | | eigval.reset(); | |
| arma_bad("eigs_sym(): failed to converge"); | | arma_bad("eigs_sym(): failed to converge"); | |
| } | | } | |
| | | | |
| return eigval; | | return eigval; | |
| } | | } | |
| | | | |
| //! eigenvalues of symmetric real sparse matrix X | | //! eigenvalues of symmetric real sparse matrix X | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| bool | | bool | |
| eigs_sym | | eigs_sym | |
| ( | | ( | |
| Col<typename T1::pod_type >& eigval, | | Col<typename T1::pod_type >& eigval, | |
| const SpBase<typename T1::elem_type,T1>& X, | | const SpBase<typename T1::elem_type,T1>& X, | |
| const uword n_eigvals, | | const uword n_eigvals, | |
| const char* form = "lm", | | const char* form = "lm", | |
|
| | | const typename T1::elem_type tol = 0.0, | |
| const typename arma_real_only<typename T1::elem_type>::result* junk = 0 | | const typename arma_real_only<typename T1::elem_type>::result* junk = 0 | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| arma_ignore(junk); | | arma_ignore(junk); | |
| | | | |
| Mat<typename T1::elem_type> eigvec; | | Mat<typename T1::elem_type> eigvec; | |
| | | | |
|
| const bool status = sp_auxlib::eigs_sym(eigval, eigvec, X, n_eigvals, for
m); | | const bool status = sp_auxlib::eigs_sym(eigval, eigvec, X, n_eigvals, for
m, tol); | |
| | | | |
| if(status == false) | | if(status == false) | |
| { | | { | |
| eigval.reset(); | | eigval.reset(); | |
| arma_bad("eigs_sym(): failed to converge", false); | | arma_bad("eigs_sym(): failed to converge", false); | |
| } | | } | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| | | | |
| | | | |
| skipping to change at line 81 | | skipping to change at line 83 | |
| template<typename T1> | | template<typename T1> | |
| inline | | inline | |
| bool | | bool | |
| eigs_sym | | eigs_sym | |
| ( | | ( | |
| Col<typename T1::pod_type >& eigval, | | Col<typename T1::pod_type >& eigval, | |
| Mat<typename T1::elem_type>& eigvec, | | Mat<typename T1::elem_type>& eigvec, | |
| const SpBase<typename T1::elem_type,T1>& X, | | const SpBase<typename T1::elem_type,T1>& X, | |
| const uword n_eigvals, | | const uword n_eigvals, | |
| const char* form = "lm", | | const char* form = "lm", | |
|
| | | const typename T1::elem_type tol = 0.0, | |
| const typename arma_real_only<typename T1::elem_type>::result* junk = 0 | | const typename arma_real_only<typename T1::elem_type>::result* junk = 0 | |
| ) | | ) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| arma_ignore(junk); | | arma_ignore(junk); | |
| | | | |
| arma_debug_check( void_ptr(&eigval) == void_ptr(&eigvec), "eigs_sym(): ei
gval is an alias of eigvec" ); | | arma_debug_check( void_ptr(&eigval) == void_ptr(&eigvec), "eigs_sym(): ei
gval is an alias of eigvec" ); | |
| | | | |
|
| const bool status = sp_auxlib::eigs_sym(eigval, eigvec, X, n_eigvals, for
m); | | const bool status = sp_auxlib::eigs_sym(eigval, eigvec, X, n_eigvals, for
m, tol); | |
| | | | |
| if(status == false) | | if(status == false) | |
| { | | { | |
| eigval.reset(); | | eigval.reset(); | |
| arma_bad("eigs_sym(): failed to converge", false); | | arma_bad("eigs_sym(): failed to converge", false); | |
| } | | } | |
| | | | |
| return status; | | return status; | |
| } | | } | |
| | | | |
| | | | |
End of changes. 6 change blocks. |
| 3 lines changed or deleted | | 6 lines changed or added | |
|
| sp_auxlib_meat.hpp | | sp_auxlib_meat.hpp | |
| | | | |
| skipping to change at line 47 | | skipping to change at line 47 | |
| if(c2 == 'i') { return form_si; } | | if(c2 == 'i') { return form_si; } | |
| } | | } | |
| | | | |
| return form_none; | | return form_none; | |
| } | | } | |
| | | | |
| //! immediate eigendecomposition of symmetric real sparse object | | //! immediate eigendecomposition of symmetric real sparse object | |
| template<typename eT, typename T1> | | template<typename eT, typename T1> | |
| inline | | inline | |
| bool | | bool | |
|
| sp_auxlib::eigs_sym(Col<eT>& eigval, Mat<eT>& eigvec, const SpBase<eT, T1>&
X, const uword n_eigvals, const char* form_str) | | sp_auxlib::eigs_sym(Col<eT>& eigval, Mat<eT>& eigvec, const SpBase<eT, T1>&
X, const uword n_eigvals, const char* form_str, const eT default_tol) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| #if defined(ARMA_USE_ARPACK) | | #if defined(ARMA_USE_ARPACK) | |
| { | | { | |
| const form_type form_val = sp_auxlib::interpret_form_str(form_str); | | const form_type form_val = sp_auxlib::interpret_form_str(form_str); | |
| | | | |
| arma_debug_check( (form_val != form_lm) && (form_val != form_sm), "eigs
_sym(): unknown form specified" ); | | arma_debug_check( (form_val != form_lm) && (form_val != form_sm), "eigs
_sym(): unknown form specified" ); | |
| | | | |
| char which_sm[3] = "SM"; | | char which_sm[3] = "SM"; | |
| char which_lm[3] = "LM"; | | char which_lm[3] = "LM"; | |
| char* which = (form_val == form_sm) ? which_sm : which_lm; // sel
ect which eigenvalues we want: smallest magnitude or largest magnitude | | char* which = (form_val == form_sm) ? which_sm : which_lm; // sel
ect which eigenvalues we want: smallest magnitude or largest magnitude | |
| | | | |
| // Make a sparse proxy object. | | // Make a sparse proxy object. | |
| SpProxy<T1> p(X.get_ref()); | | SpProxy<T1> p(X.get_ref()); | |
| | | | |
| // Make sure it's square. | | // Make sure it's square. | |
| arma_debug_check( (p.get_n_rows() != p.get_n_cols()), "eigs_sym(): give
n sparse matrix is not square"); | | arma_debug_check( (p.get_n_rows() != p.get_n_cols()), "eigs_sym(): give
n sparse matrix is not square"); | |
| | | | |
| // Make sure we aren't asking for every eigenvalue. | | // Make sure we aren't asking for every eigenvalue. | |
|
| arma_debug_check( (n_eigvals >= p.get_n_rows()), "eigs_sym(): n_eigvals
must be less than the number of rows in the matrix"); | | arma_debug_check( (n_eigvals + 1 >= p.get_n_rows()), "eigs_sym(): n_eig
vals + 1 must be less than the number of rows in the matrix"); | |
| | | | |
| // If the matrix is empty, the case is trivial. | | // If the matrix is empty, the case is trivial. | |
| if(p.get_n_cols() == 0) // We already know n_cols == n_rows. | | if(p.get_n_cols() == 0) // We already know n_cols == n_rows. | |
| { | | { | |
| eigval.reset(); | | eigval.reset(); | |
| eigvec.reset(); | | eigvec.reset(); | |
| return true; | | return true; | |
| } | | } | |
| | | | |
| // Set up variables that get used for neupd(). | | // Set up variables that get used for neupd(). | |
| blas_int n, ncv, ldv, lworkl, info; | | blas_int n, ncv, ldv, lworkl, info; | |
|
| eT tol; | | eT tol = default_tol; | |
| podarray<eT> resid, v, workd, workl; | | podarray<eT> resid, v, workd, workl; | |
| podarray<blas_int> iparam, ipntr; | | podarray<blas_int> iparam, ipntr; | |
| podarray<eT> rwork; // Not used in this case. | | podarray<eT> rwork; // Not used in this case. | |
| | | | |
| run_aupd(n_eigvals, which, p, true /* sym, not gen */, n, tol, resid, n
cv, v, ldv, iparam, ipntr, workd, workl, lworkl, rwork, info); | | run_aupd(n_eigvals, which, p, true /* sym, not gen */, n, tol, resid, n
cv, v, ldv, iparam, ipntr, workd, workl, lworkl, rwork, info); | |
| | | | |
| if(info != 0) | | if(info != 0) | |
| { | | { | |
| return false; | | return false; | |
| } | | } | |
| | | | |
| skipping to change at line 135 | | skipping to change at line 135 | |
| arma_stop("eigs_sym(): use of ARPACK needs to be enabled"); | | arma_stop("eigs_sym(): use of ARPACK needs to be enabled"); | |
| return false; | | return false; | |
| } | | } | |
| #endif | | #endif | |
| } | | } | |
| | | | |
| //! immediate eigendecomposition of non-symmetric real sparse object | | //! immediate eigendecomposition of non-symmetric real sparse object | |
| template<typename T, typename T1> | | template<typename T, typename T1> | |
| inline | | inline | |
| bool | | bool | |
|
| sp_auxlib::eigs_gen(Col< std::complex<T> >& eigval, Mat< std::complex<T> >&
eigvec, const SpBase<T, T1>& X, const uword n_eigvals, const char* form_st
r) | | sp_auxlib::eigs_gen(Col< std::complex<T> >& eigval, Mat< std::complex<T> >&
eigvec, const SpBase<T, T1>& X, const uword n_eigvals, const char* form_st
r, const T default_tol) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| #if defined(ARMA_USE_ARPACK) | | #if defined(ARMA_USE_ARPACK) | |
| { | | { | |
| const form_type form_val = sp_auxlib::interpret_form_str(form_str); | | const form_type form_val = sp_auxlib::interpret_form_str(form_str); | |
| | | | |
| arma_debug_check( (form_val == form_none), "eigs_gen(): unknown form sp
ecified" ); | | arma_debug_check( (form_val == form_none), "eigs_gen(): unknown form sp
ecified" ); | |
| | | | |
| char which_lm[3] = "LM"; | | char which_lm[3] = "LM"; | |
| | | | |
| skipping to change at line 173 | | skipping to change at line 173 | |
| default: which = which_lm; | | default: which = which_lm; | |
| } | | } | |
| | | | |
| // Make a sparse proxy object. | | // Make a sparse proxy object. | |
| SpProxy<T1> p(X.get_ref()); | | SpProxy<T1> p(X.get_ref()); | |
| | | | |
| // Make sure it's square. | | // Make sure it's square. | |
| arma_debug_check( (p.get_n_rows() != p.get_n_cols()), "eigs_gen(): give
n sparse matrix is not square"); | | arma_debug_check( (p.get_n_rows() != p.get_n_cols()), "eigs_gen(): give
n sparse matrix is not square"); | |
| | | | |
| // Make sure we aren't asking for every eigenvalue. | | // Make sure we aren't asking for every eigenvalue. | |
|
| arma_debug_check( (n_eigvals >= p.get_n_rows()), "eigs_gen(): n_eigvals
must be less than the number of rows in the matrix"); | | arma_debug_check( (n_eigvals + 1 >= p.get_n_rows()), "eigs_gen(): n_eig
vals + 1 must be less than the number of rows in the matrix"); | |
| | | | |
| // If the matrix is empty, the case is trivial. | | // If the matrix is empty, the case is trivial. | |
| if(p.get_n_cols() == 0) // We already know n_cols == n_rows. | | if(p.get_n_cols() == 0) // We already know n_cols == n_rows. | |
| { | | { | |
| eigval.reset(); | | eigval.reset(); | |
| eigvec.reset(); | | eigvec.reset(); | |
| return true; | | return true; | |
| } | | } | |
| | | | |
| // Set up variables that get used for neupd(). | | // Set up variables that get used for neupd(). | |
| blas_int n, ncv, ldv, lworkl, info; | | blas_int n, ncv, ldv, lworkl, info; | |
|
| T tol; | | T tol = default_tol; | |
| podarray<T> resid, v, workd, workl; | | podarray<T> resid, v, workd, workl; | |
| podarray<blas_int> iparam, ipntr; | | podarray<blas_int> iparam, ipntr; | |
| podarray<T> rwork; // Not used in the real case. | | podarray<T> rwork; // Not used in the real case. | |
| | | | |
| run_aupd(n_eigvals, which, p, false /* gen, not sym */, n, tol, resid,
ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, rwork, info); | | run_aupd(n_eigvals, which, p, false /* gen, not sym */, n, tol, resid,
ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, rwork, info); | |
| | | | |
| if(info != 0) | | if(info != 0) | |
| { | | { | |
| return false; | | return false; | |
| } | | } | |
| | | | |
| skipping to change at line 282 | | skipping to change at line 282 | |
| arma_stop("eigs_gen(): use of ARPACK needs to be enabled"); | | arma_stop("eigs_gen(): use of ARPACK needs to be enabled"); | |
| return false; | | return false; | |
| } | | } | |
| #endif | | #endif | |
| } | | } | |
| | | | |
| //! immediate eigendecomposition of non-symmetric complex sparse object | | //! immediate eigendecomposition of non-symmetric complex sparse object | |
| template<typename T, typename T1> | | template<typename T, typename T1> | |
| inline | | inline | |
| bool | | bool | |
|
| sp_auxlib::eigs_gen(Col< std::complex<T> >& eigval, Mat< std::complex<T> >&
eigvec, const SpBase< std::complex<T>, T1>& X, const uword n_eigvals, cons
t char* form_str) | | sp_auxlib::eigs_gen(Col< std::complex<T> >& eigval, Mat< std::complex<T> >&
eigvec, const SpBase< std::complex<T>, T1>& X, const uword n_eigvals, cons
t char* form_str, const T default_tol) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| #if defined(ARMA_USE_ARPACK) | | #if defined(ARMA_USE_ARPACK) | |
| { | | { | |
| const form_type form_val = sp_auxlib::interpret_form_str(form_str); | | const form_type form_val = sp_auxlib::interpret_form_str(form_str); | |
| | | | |
| arma_debug_check( (form_val == form_none), "eigs_gen(): unknown form sp
ecified" ); | | arma_debug_check( (form_val == form_none), "eigs_gen(): unknown form sp
ecified" ); | |
| | | | |
| char which_lm[3] = "LM"; | | char which_lm[3] = "LM"; | |
| | | | |
| skipping to change at line 320 | | skipping to change at line 320 | |
| default: which = which_lm; | | default: which = which_lm; | |
| } | | } | |
| | | | |
| // Make a sparse proxy object. | | // Make a sparse proxy object. | |
| SpProxy<T1> p(X.get_ref()); | | SpProxy<T1> p(X.get_ref()); | |
| | | | |
| // Make sure it's square. | | // Make sure it's square. | |
| arma_debug_check( (p.get_n_rows() != p.get_n_cols()), "eigs_gen(): give
n sparse matrix is not square"); | | arma_debug_check( (p.get_n_rows() != p.get_n_cols()), "eigs_gen(): give
n sparse matrix is not square"); | |
| | | | |
| // Make sure we aren't asking for every eigenvalue. | | // Make sure we aren't asking for every eigenvalue. | |
|
| arma_debug_check( (n_eigvals >= p.get_n_rows()), "eigs_gen(): n_eigvals
must be less than the number of rows in the matrix"); | | arma_debug_check( (n_eigvals + 1 >= p.get_n_rows()), "eigs_gen(): n_eig
vals + 1 must be less than the number of rows in the matrix"); | |
| | | | |
| // If the matrix is empty, the case is trivial. | | // If the matrix is empty, the case is trivial. | |
| if(p.get_n_cols() == 0) // We already know n_cols == n_rows. | | if(p.get_n_cols() == 0) // We already know n_cols == n_rows. | |
| { | | { | |
| eigval.reset(); | | eigval.reset(); | |
| eigvec.reset(); | | eigvec.reset(); | |
| return true; | | return true; | |
| } | | } | |
| | | | |
| // Set up variables that get used for neupd(). | | // Set up variables that get used for neupd(). | |
| blas_int n, ncv, ldv, lworkl, info; | | blas_int n, ncv, ldv, lworkl, info; | |
|
| T tol; | | T tol = default_tol; | |
| podarray< std::complex<T> > resid, v, workd, workl; | | podarray< std::complex<T> > resid, v, workd, workl; | |
| podarray<blas_int> iparam, ipntr; | | podarray<blas_int> iparam, ipntr; | |
| podarray<T> rwork; | | podarray<T> rwork; | |
| | | | |
| run_aupd(n_eigvals, which, p, false /* gen, not sym */, n, tol, resid,
ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, rwork, info); | | run_aupd(n_eigvals, which, p, false /* gen, not sym */, n, tol, resid,
ncv, v, ldv, iparam, ipntr, workd, workl, lworkl, rwork, info); | |
| | | | |
| if(info != 0) | | if(info != 0) | |
| { | | { | |
| return false; | | return false; | |
| } | | } | |
| | | | |
| skipping to change at line 414 | | skipping to change at line 414 | |
| // entertainingly archaic FORTRAN software engineering technique that | | // entertainingly archaic FORTRAN software engineering technique that | |
| // basically means that we call saupd()/naupd() and it tells us with so
me | | // basically means that we call saupd()/naupd() and it tells us with so
me | |
| // return code what we need to do next (usually a matrix-vector product
) and | | // return code what we need to do next (usually a matrix-vector product
) and | |
| // then call it again. So this results in some type of iterative proce
ss | | // then call it again. So this results in some type of iterative proce
ss | |
| // where we call saupd()/naupd() many times. | | // where we call saupd()/naupd() many times. | |
| blas_int ido = 0; // This must be 0 for the first call. | | blas_int ido = 0; // This must be 0 for the first call. | |
| char bmat = 'I'; // We are considering the standard eigenvalue problem. | | char bmat = 'I'; // We are considering the standard eigenvalue problem. | |
| n = p.get_n_rows(); // The size of the matrix. | | n = p.get_n_rows(); // The size of the matrix. | |
| blas_int nev = n_eigvals; | | blas_int nev = n_eigvals; | |
| | | | |
|
| tol = std::numeric_limits<eT>::epsilon(); // Machine epsilon as toleran
ce. | | | |
| resid.set_size(n); | | resid.set_size(n); | |
| | | | |
| // "NCV must satisfy the two inequalities 2 <= NCV-NEV and NCV <= N". | | // "NCV must satisfy the two inequalities 2 <= NCV-NEV and NCV <= N". | |
| // "It is recommended that NCV >= 2 * NEV". | | // "It is recommended that NCV >= 2 * NEV". | |
|
| ncv = (2 * nev < n) ? 2 * nev : ((nev + 2 < n) ? nev + 2 : n); | | ncv = 2 + nev; | |
| | | if (ncv < 2 * nev) { ncv = 2 * nev; } | |
| | | if (ncv > n) { ncv = n; } | |
| v.set_size(n * ncv); // Array N by NCV (output). | | v.set_size(n * ncv); // Array N by NCV (output). | |
| rwork.set_size(ncv); // Work array of size NCV for complex calls. | | rwork.set_size(ncv); // Work array of size NCV for complex calls. | |
| ldv = n; // "Leading dimension of V exactly as declared in the calling
program." | | ldv = n; // "Leading dimension of V exactly as declared in the calling
program." | |
| | | | |
| // IPARAM: integer array of length 11. | | // IPARAM: integer array of length 11. | |
| iparam.zeros(11); | | iparam.zeros(11); | |
| iparam(0) = 1; // Exact shifts (not provided by us). | | iparam(0) = 1; // Exact shifts (not provided by us). | |
| iparam(2) = 1000; // Maximum iterations; all the examples use 300, but
they were written in the ancient times. | | iparam(2) = 1000; // Maximum iterations; all the examples use 300, but
they were written in the ancient times. | |
| iparam(6) = 1; // Mode 1: A * x = lambda * x. | | iparam(6) = 1; // Mode 1: A * x = lambda * x. | |
| | | | |
| | | | |
End of changes. 11 change blocks. |
| 11 lines changed or deleted | | 12 lines changed or added | |
|
| subview_bones.hpp | | subview_bones.hpp | |
|
| // Copyright (C) 2008-2013 Conrad Sanderson | | // Copyright (C) 2008-2014 Conrad Sanderson | |
| // Copyright (C) 2008-2013 NICTA (www.nicta.com.au) | | // Copyright (C) 2008-2014 NICTA (www.nicta.com.au) | |
| // Copyright (C) 2011 James Sanders | | // Copyright (C) 2011 James Sanders | |
| // | | // | |
| // This Source Code Form is subject to the terms of the Mozilla Public | | // This Source Code Form is subject to the terms of the Mozilla Public | |
| // License, v. 2.0. If a copy of the MPL was not distributed with this | | // License, v. 2.0. If a copy of the MPL was not distributed with this | |
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | | // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| | | | |
| //! \addtogroup subview | | //! \addtogroup subview | |
| //! @{ | | //! @{ | |
| | | | |
| //! Class for storing data required to construct or apply operations to a s
ubmatrix | | //! Class for storing data required to construct or apply operations to a s
ubmatrix | |
| | | | |
| skipping to change at line 67 | | skipping to change at line 67 | |
| template<typename T1> inline void operator-=(const SpBase<eT, T1>& x); | | template<typename T1> inline void operator-=(const SpBase<eT, T1>& x); | |
| template<typename T1> inline void operator%=(const SpBase<eT, T1>& x); | | template<typename T1> inline void operator%=(const SpBase<eT, T1>& x); | |
| template<typename T1> inline void operator/=(const SpBase<eT, T1>& x); | | template<typename T1> inline void operator/=(const SpBase<eT, T1>& x); | |
| | | | |
| inline void operator= (const subview& x); | | inline void operator= (const subview& x); | |
| inline void operator+= (const subview& x); | | inline void operator+= (const subview& x); | |
| inline void operator-= (const subview& x); | | inline void operator-= (const subview& x); | |
| inline void operator%= (const subview& x); | | inline void operator%= (const subview& x); | |
| inline void operator/= (const subview& x); | | inline void operator/= (const subview& x); | |
| | | | |
|
| | | template<typename T1, typename gen_type> | |
| | | inline typename enable_if2< is_same_type<typename T1::elem_type, eT>::val | |
| | | ue, void>::result operator=(const Gen<T1,gen_type>& x); | |
| | | | |
| inline static void extract(Mat<eT>& out, const subview& in); | | inline static void extract(Mat<eT>& out, const subview& in); | |
| | | | |
| inline static void plus_inplace(Mat<eT>& out, const subview& in); | | inline static void plus_inplace(Mat<eT>& out, const subview& in); | |
| inline static void minus_inplace(Mat<eT>& out, const subview& in); | | inline static void minus_inplace(Mat<eT>& out, const subview& in); | |
| inline static void schur_inplace(Mat<eT>& out, const subview& in); | | inline static void schur_inplace(Mat<eT>& out, const subview& in); | |
| inline static void div_inplace(Mat<eT>& out, const subview& in); | | inline static void div_inplace(Mat<eT>& out, const subview& in); | |
| | | | |
| template<typename functor> inline void transform(functor F); | | template<typename functor> inline void transform(functor F); | |
| template<typename functor> inline void imbue(functor F); | | template<typename functor> inline void imbue(functor F); | |
| | | | |
| | | | |
| skipping to change at line 200 | | skipping to change at line 203 | |
| | | | |
| const eT* colmem; | | const eT* colmem; | |
| | | | |
| inline void operator= (const subview<eT>& x); | | inline void operator= (const subview<eT>& x); | |
| inline void operator= (const subview_col& x); | | inline void operator= (const subview_col& x); | |
| inline void operator= (const eT val); | | inline void operator= (const eT val); | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline void operator= (const Base<eT,T1>& x); | | inline void operator= (const Base<eT,T1>& x); | |
| | | | |
|
| | | template<typename T1, typename gen_type> | |
| | | inline typename enable_if2< is_same_type<typename T1::elem_type, eT>::val | |
| | | ue, void>::result operator=(const Gen<T1,gen_type>& x); | |
| | | | |
| arma_inline const Op<subview_col<eT>,op_htrans> t() const; | | arma_inline const Op<subview_col<eT>,op_htrans> t() const; | |
| arma_inline const Op<subview_col<eT>,op_htrans> ht() const; | | arma_inline const Op<subview_col<eT>,op_htrans> ht() const; | |
| arma_inline const Op<subview_col<eT>,op_strans> st() const; | | arma_inline const Op<subview_col<eT>,op_strans> st() const; | |
| | | | |
| inline void fill(const eT val); | | inline void fill(const eT val); | |
| inline void zeros(); | | inline void zeros(); | |
| inline void ones(); | | inline void ones(); | |
| | | | |
| arma_inline eT at_alt (const uword i) const; | | arma_inline eT at_alt (const uword i) const; | |
| | | | |
| | | | |
| skipping to change at line 265 | | skipping to change at line 271 | |
| static const bool is_row = true; | | static const bool is_row = true; | |
| static const bool is_col = false; | | static const bool is_col = false; | |
| | | | |
| inline void operator= (const subview<eT>& x); | | inline void operator= (const subview<eT>& x); | |
| inline void operator= (const subview_row& x); | | inline void operator= (const subview_row& x); | |
| inline void operator= (const eT val); | | inline void operator= (const eT val); | |
| | | | |
| template<typename T1> | | template<typename T1> | |
| inline void operator= (const Base<eT,T1>& x); | | inline void operator= (const Base<eT,T1>& x); | |
| | | | |
|
| | | template<typename T1, typename gen_type> | |
| | | inline typename enable_if2< is_same_type<typename T1::elem_type, eT>::val | |
| | | ue, void>::result operator=(const Gen<T1,gen_type>& x); | |
| | | | |
| arma_inline const Op<subview_row<eT>,op_htrans> t() const; | | arma_inline const Op<subview_row<eT>,op_htrans> t() const; | |
| arma_inline const Op<subview_row<eT>,op_htrans> ht() const; | | arma_inline const Op<subview_row<eT>,op_htrans> ht() const; | |
| arma_inline const Op<subview_row<eT>,op_strans> st() const; | | arma_inline const Op<subview_row<eT>,op_strans> st() const; | |
| | | | |
| inline eT at_alt (const uword i) const; | | inline eT at_alt (const uword i) const; | |
| | | | |
| inline eT& operator[](const uword i); | | inline eT& operator[](const uword i); | |
| inline eT operator[](const uword i) const; | | inline eT operator[](const uword i) const; | |
| | | | |
| inline eT& operator()(const uword i); | | inline eT& operator()(const uword i); | |
| | | | |
End of changes. 4 change blocks. |
| 2 lines changed or deleted | | 14 lines changed or added | |
|
| subview_meat.hpp | | subview_meat.hpp | |
|
| // Copyright (C) 2008-2013 Conrad Sanderson | | // Copyright (C) 2008-2014 Conrad Sanderson | |
| // Copyright (C) 2008-2013 NICTA (www.nicta.com.au) | | // Copyright (C) 2008-2014 NICTA (www.nicta.com.au) | |
| // Copyright (C) 2011 James Sanders | | // Copyright (C) 2011 James Sanders | |
| // Copyright (C) 2013 Ryan Curtin | | // Copyright (C) 2013 Ryan Curtin | |
| // | | // | |
| // This Source Code Form is subject to the terms of the Mozilla Public | | // This Source Code Form is subject to the terms of the Mozilla Public | |
| // License, v. 2.0. If a copy of the MPL was not distributed with this | | // License, v. 2.0. If a copy of the MPL was not distributed with this | |
| // file, You can obtain one at http://mozilla.org/MPL/2.0/. | | // file, You can obtain one at http://mozilla.org/MPL/2.0/. | |
| | | | |
| //! \addtogroup subview | | //! \addtogroup subview | |
| //! @{ | | //! @{ | |
| | | | |
| | | | |
| skipping to change at line 1155 | | skipping to change at line 1155 | |
| } | | } | |
| | | | |
| if(overlap) | | if(overlap) | |
| { | | { | |
| delete tmp_subview; | | delete tmp_subview; | |
| delete tmp_mat; | | delete tmp_mat; | |
| } | | } | |
| | | | |
| } | | } | |
| | | | |
|
| | | template<typename eT> | |
| | | template<typename T1, typename gen_type> | |
| | | inline | |
| | | typename enable_if2< is_same_type<typename T1::elem_type, eT>::value, void> | |
| | | ::result | |
| | | subview<eT>::operator= (const Gen<T1,gen_type>& in) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | arma_debug_assert_same_size(n_rows, n_cols, in.n_rows, in.n_cols, "copy i | |
| | | nto submatrix"); | |
| | | | |
| | | in.apply(*this); | |
| | | } | |
| | | | |
| //! transform each element in the subview using a functor | | //! transform each element in the subview using a functor | |
| template<typename eT> | | template<typename eT> | |
| template<typename functor> | | template<typename functor> | |
| inline | | inline | |
| void | | void | |
| subview<eT>::transform(functor F) | | subview<eT>::transform(functor F) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| const uword local_n_cols = n_cols; | | const uword local_n_cols = n_cols; | |
| | | | |
| skipping to change at line 2503 | | skipping to change at line 2516 | |
| inline | | inline | |
| void | | void | |
| subview_col<eT>::operator=(const Base<eT,T1>& X) | | subview_col<eT>::operator=(const Base<eT,T1>& X) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| subview<eT>::operator=(X); | | subview<eT>::operator=(X); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
|
| | | template<typename T1, typename gen_type> | |
| | | inline | |
| | | typename enable_if2< is_same_type<typename T1::elem_type, eT>::value, void> | |
| | | ::result | |
| | | subview_col<eT>::operator= (const Gen<T1,gen_type>& in) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | arma_debug_assert_same_size(subview<eT>::n_rows, uword(1), in.n_rows, (in | |
| | | .is_col ? uword(1) : in.n_cols), "copy into submatrix"); | |
| | | | |
| | | in.apply(*this); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| arma_inline | | arma_inline | |
| const Op<subview_col<eT>,op_htrans> | | const Op<subview_col<eT>,op_htrans> | |
| subview_col<eT>::t() const | | subview_col<eT>::t() const | |
| { | | { | |
| return Op<subview_col<eT>,op_htrans>(*this); | | return Op<subview_col<eT>,op_htrans>(*this); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| arma_inline | | arma_inline | |
| const Op<subview_col<eT>,op_htrans> | | const Op<subview_col<eT>,op_htrans> | |
| | | | |
| skipping to change at line 2781 | | skipping to change at line 2807 | |
| inline | | inline | |
| void | | void | |
| subview_row<eT>::operator=(const Base<eT,T1>& X) | | subview_row<eT>::operator=(const Base<eT,T1>& X) | |
| { | | { | |
| arma_extra_debug_sigprint(); | | arma_extra_debug_sigprint(); | |
| | | | |
| subview<eT>::operator=(X); | | subview<eT>::operator=(X); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
|
| | | template<typename T1, typename gen_type> | |
| | | inline | |
| | | typename enable_if2< is_same_type<typename T1::elem_type, eT>::value, void> | |
| | | ::result | |
| | | subview_row<eT>::operator= (const Gen<T1,gen_type>& in) | |
| | | { | |
| | | arma_extra_debug_sigprint(); | |
| | | | |
| | | arma_debug_assert_same_size(uword(1), subview<eT>::n_cols, (in.is_row ? u | |
| | | word(1) : in.n_rows), in.n_cols, "copy into submatrix"); | |
| | | | |
| | | in.apply(*this); | |
| | | } | |
| | | | |
| | | template<typename eT> | |
| arma_inline | | arma_inline | |
| const Op<subview_row<eT>,op_htrans> | | const Op<subview_row<eT>,op_htrans> | |
| subview_row<eT>::t() const | | subview_row<eT>::t() const | |
| { | | { | |
| return Op<subview_row<eT>,op_htrans>(*this); | | return Op<subview_row<eT>,op_htrans>(*this); | |
| } | | } | |
| | | | |
| template<typename eT> | | template<typename eT> | |
| arma_inline | | arma_inline | |
| const Op<subview_row<eT>,op_htrans> | | const Op<subview_row<eT>,op_htrans> | |
| | | | |
End of changes. 4 change blocks. |
| 2 lines changed or deleted | | 47 lines changed or added | |
|