Gen_bones.hpp | Gen_bones.hpp | |||
---|---|---|---|---|
// Copyright (C) 2011-2013 Conrad Sanderson | // Copyright (C) 2011-2014 Conrad Sanderson | |||
// Copyright (C) 2011-2013 NICTA (www.nicta.com.au) | // Copyright (C) 2011-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 Gen | //! \addtogroup Gen | |||
//! @{ | //! @{ | |||
//! support class for generator functions (eg. zeros, randu, randn, ...) | //! support class for generator functions (eg. zeros, randu, randn, ...) | |||
template<typename T1, typename gen_type> | template<typename T1, typename gen_type> | |||
skipping to change at line 43 | skipping to change at line 43 | |||
arma_inline elem_type operator[] (const uword ii) const ; | arma_inline elem_type operator[] (const uword ii) const ; | |||
arma_inline elem_type at (const uword row, const uword col) const ; | arma_inline elem_type at (const uword row, const uword col) const ; | |||
arma_inline elem_type at_alt (const uword ii) const ; | arma_inline elem_type at_alt (const uword ii) const ; | |||
inline void apply (Mat<elem_type>& out) const; | inline void apply (Mat<elem_type>& out) const; | |||
inline void apply_inplace_plus (Mat<elem_type>& out) const; | inline void apply_inplace_plus (Mat<elem_type>& out) const; | |||
inline void apply_inplace_minus(Mat<elem_type>& out) const; | inline void apply_inplace_minus(Mat<elem_type>& out) const; | |||
inline void apply_inplace_schur(Mat<elem_type>& out) const; | inline void apply_inplace_schur(Mat<elem_type>& out) const; | |||
inline void apply_inplace_div (Mat<elem_type>& out) const; | inline void apply_inplace_div (Mat<elem_type>& out) const; | |||
inline void apply(subview<elem_type>& out) const; | ||||
}; | }; | |||
//! @} | //! @} | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 4 lines changed or added | |||
Gen_meat.hpp | Gen_meat.hpp | |||
---|---|---|---|---|
// Copyright (C) 2011-2013 Conrad Sanderson | // Copyright (C) 2011-2014 Conrad Sanderson | |||
// Copyright (C) 2011-2013 NICTA (www.nicta.com.au) | // Copyright (C) 2011-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 Gen | //! \addtogroup Gen | |||
//! @{ | //! @{ | |||
template<typename T1, typename gen_type> | template<typename T1, typename gen_type> | |||
arma_inline | arma_inline | |||
skipping to change at line 276 | skipping to change at line 276 | |||
} | } | |||
if(iq < n_elem) | if(iq < n_elem) | |||
{ | { | |||
out_mem[iq] /= Gen<T1, gen_type>::generate(); | out_mem[iq] /= Gen<T1, gen_type>::generate(); | |||
} | } | |||
} | } | |||
} | } | |||
template<typename T1, typename gen_type> | ||||
inline | ||||
void | ||||
Gen<T1, gen_type>::apply(subview<typename T1::elem_type>& out) const | ||||
{ | ||||
arma_extra_debug_sigprint(); | ||||
// NOTE: we're assuming that the submatrix has the same dimensions as the | ||||
Gen object | ||||
// this is checked by subview::operator=() | ||||
if(is_same_type<gen_type, gen_ones_diag>::yes) { out.eye(); } | ||||
else if(is_same_type<gen_type, gen_ones_full>::yes) { out.ones(); } | ||||
else if(is_same_type<gen_type, gen_zeros >::yes) { out.zeros(); } | ||||
else if(is_same_type<gen_type, gen_randu >::yes) { out.randu(); } | ||||
else if(is_same_type<gen_type, gen_randn >::yes) { out.randn(); } | ||||
} | ||||
//! @} | //! @} | |||
End of changes. 2 change blocks. | ||||
2 lines changed or deleted | 20 lines changed or added | |||
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_iterators_meat.hpp | SpMat_iterators_meat.hpp | |||
---|---|---|---|---|
skipping to change at line 336 | skipping to change at line 336 | |||
, actual_pos(0) | , actual_pos(0) | |||
{ | { | |||
// Corner case for empty matrix. | // Corner case for empty matrix. | |||
if(in_M.n_nonzero == 0) | if(in_M.n_nonzero == 0) | |||
{ | { | |||
iterator_base::internal_col = 0; | iterator_base::internal_col = 0; | |||
internal_row = in_M.n_rows; | internal_row = in_M.n_rows; | |||
return; | return; | |||
} | } | |||
// We don't count zeroes in our position count, so we have to find the no nzero | // We don't count zeros in our position count, so we have to find the non zero | |||
// value corresponding to the given initial position. We assume initial_ pos | // value corresponding to the given initial position. We assume initial_ pos | |||
// is valid. | // is valid. | |||
// This is irritating because we don't know where the elements are in eac h | // This is irritating because we don't know where the elements are in eac h | |||
// row. What we will do is loop across all columns looking for elements in | // row. What we will do is loop across all columns looking for elements in | |||
// row 0 (and add to our sum), then in row 1, and so forth, until we get to | // row 0 (and add to our sum), then in row 1, and so forth, until we get to | |||
// the desired position. | // the desired position. | |||
uword cur_pos = -1; | uword cur_pos = -1; | |||
uword cur_row = 0; | uword cur_row = 0; | |||
uword cur_col = 0; | uword cur_col = 0; | |||
End of changes. 1 change blocks. | ||||
1 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 | |||
arma_version.hpp | arma_version.hpp | |||
---|---|---|---|---|
skipping to change at line 12 | skipping to change at line 12 | |||
// Copyright (C) 2009-2014 NICTA (www.nicta.com.au) | // Copyright (C) 2009-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_version | //! \addtogroup arma_version | |||
//! @{ | //! @{ | |||
#define ARMA_VERSION_MAJOR 4 | #define ARMA_VERSION_MAJOR 4 | |||
#define ARMA_VERSION_MINOR 300 | #define ARMA_VERSION_MINOR 320 | |||
#define ARMA_VERSION_PATCH 9 | #define ARMA_VERSION_PATCH 0 | |||
#define ARMA_VERSION_NAME "Medieval Cornea Scraper" | #define ARMA_VERSION_NAME "Daintree Tea Raider" | |||
struct arma_version | struct arma_version | |||
{ | { | |||
static const unsigned int major = ARMA_VERSION_MAJOR; | static const unsigned int major = ARMA_VERSION_MAJOR; | |||
static const unsigned int minor = ARMA_VERSION_MINOR; | static const unsigned int minor = ARMA_VERSION_MINOR; | |||
static const unsigned int patch = ARMA_VERSION_PATCH; | static const unsigned int patch = ARMA_VERSION_PATCH; | |||
static | static | |||
inline | inline | |||
std::string | std::string | |||
End of changes. 1 change blocks. | ||||
3 lines changed or deleted | 3 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 | |||
fn_misc.hpp | fn_misc.hpp | |||
---|---|---|---|---|
skipping to change at line 109 | skipping to change at line 109 | |||
} | } | |||
const eT negdelta = log_b - log_a; | const eT negdelta = log_b - log_a; | |||
if( (negdelta < Datum<eT>::log_min) || (arma_isfinite(negdelta) == false) ) | if( (negdelta < Datum<eT>::log_min) || (arma_isfinite(negdelta) == false) ) | |||
{ | { | |||
return log_a; | return log_a; | |||
} | } | |||
else | else | |||
{ | { | |||
#if defined(ARMA_HAVE_LOG1P) | return (log_a + arma_log1p(std::exp(negdelta))); | |||
return (log_a + log1p(std::exp(negdelta))); | ||||
#else | ||||
return (log_a + std::log(1.0 + std::exp(negdelta))); | ||||
#endif | ||||
} | } | |||
} | } | |||
// for compatibility with earlier versions | // for compatibility with earlier versions | |||
template<typename eT> | template<typename eT> | |||
inline | inline | |||
typename arma_real_only<eT>::result | typename arma_real_only<eT>::result | |||
log_add(eT log_a, eT log_b) | log_add(eT log_a, eT log_b) | |||
{ | { | |||
return log_add_exp(log_a, log_b); | return log_add_exp(log_a, log_b); | |||
End of changes. 1 change blocks. | ||||
5 lines changed or deleted | 1 lines changed or added | |||
sp_auxlib_bones.hpp | sp_auxlib_bones.hpp | |||
---|---|---|---|---|
skipping to change at line 28 | skipping to change at line 28 | |||
{ | { | |||
form_none, form_lm, form_sm, form_lr, form_sr, form_li, form_si | form_none, form_lm, form_sm, form_lr, form_sr, form_li, form_si | |||
}; | }; | |||
inline static form_type interpret_form_str(const char* form_str); | inline static form_type interpret_form_str(const char* form_str); | |||
// | // | |||
// eigs_sym() via ARPACK | // eigs_sym() via ARPACK | |||
template<typename eT, typename T1> | template<typename eT, typename T1> | |||
inline static bool eigs_sym(Col<eT>& eigval, Mat<eT>& eigvec, const SpBas e<eT, T1>& X, const uword n_eigvals, const char* form_str); | inline static bool eigs_sym(Col<eT>& eigval, Mat<eT>& eigvec, const SpBas e<eT, T1>& X, const uword n_eigvals, const char* form_str, const eT default _tol); | |||
// | // | |||
// eigs_gen() via ARPACK | // eigs_gen() via ARPACK | |||
template<typename T, typename T1> | template<typename T, typename T1> | |||
inline static bool eigs_gen(Col< std::complex<T> >& eigval, Mat< std::com plex<T> >& eigvec, const SpBase<T, T1>& X, const uword n_eigvals, const cha r* form_str); | inline static bool eigs_gen(Col< std::complex<T> >& eigval, Mat< std::com plex<T> >& eigvec, const SpBase<T, T1>& X, const uword n_eigvals, const cha r* form_str, const T default_tol); | |||
template<typename T, typename T1> | template<typename T, typename T1> | |||
inline static bool eigs_gen(Col< std::complex<T> >& eigval, Mat< std::com plex<T> >& eigvec, const SpBase< std::complex<T>, T1>& X, const uword n_eig vals, const char* form_str); | inline static bool eigs_gen(Col< std::complex<T> >& eigval, Mat< std::com plex<T> >& eigvec, const SpBase< std::complex<T>, T1>& X, const uword n_eig vals, const char* form_str, const T default_tol); | |||
private: | private: | |||
// calls arpack saupd()/naupd() because the code is so similar for each | // calls arpack saupd()/naupd() because the code is so similar for each | |||
// all of the extra variables are later used by seupd()/neupd(), but thos e | // all of the extra variables are later used by seupd()/neupd(), but thos e | |||
// functions are very different and we can't combine their code | // functions are very different and we can't combine their code | |||
template<typename eT, typename T, typename T1> | template<typename eT, typename T, typename T1> | |||
inline static void run_aupd | inline static void run_aupd | |||
( | ( | |||
End of changes. 3 change blocks. | ||||
3 lines changed or deleted | 3 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 | |||