Compare commits

...
17 Commits
Author SHA1 Message Date
conrad df74f400b8 patch bump 2024-05-31 01:08:56 +10:00
conrad 88a07dcc24 add tests for SpSubview n_nonzero 2024-05-30 12:04:40 +10:00
conrad 442c88844b sync to handle corner cases 2024-05-29 13:12:34 +10:00
conrad 53612a37db address cmake deprecation warning 2024-05-28 14:34:24 +10:00
conrad cbbdf4d7fb update list of changes 2024-05-28 14:17:48 +10:00
conrad 0fabb6f51d extend speedup to general submatrices that span all rows 2024-05-27 11:36:06 +10:00
conrad 32f5a39b24 faster handling of sparse submatrices with one column 2024-05-23 14:05:25 +10:00
conrad 8ba668f998 postpone deprecation until next major release 2024-05-23 13:50:01 +10:00
conrad f71713434c add caveat 2024-05-23 13:45:58 +10:00
conrad 098ed292a9 deprecate superseded forms of conv_to() 2024-05-21 14:44:15 +10:00
conrad 30a996ceaf fix 2024-05-13 12:10:02 +10:00
conrad 89aac38ad0 beef up warning 2024-05-08 13:44:11 +10:00
conrad 20f999fcbd patch bump 2024-05-07 12:10:40 +10:00
conrad 79536556e2 simplification 2024-05-06 22:23:35 +10:00
conrad 7bdaea8e18 add explanatory note 2024-05-05 15:25:53 +10:00
conrad 74e9f62d46 minor fixes 2024-05-03 14:22:05 +10:00
conrad 600e6ef063 add mutex around generating FFTW3 plans 2024-05-03 14:02:28 +10:00
13 changed files with 121 additions and 25 deletions
+1 -1
View File
@@ -29,7 +29,7 @@
## NOTE: More details: https://arma.sourceforge.net/faq.html
cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR)
cmake_minimum_required(VERSION 2.8.12...3.5 FATAL_ERROR)
if(NOT (${CMAKE_MAJOR_VERSION} LESS 3))
if(POLICY CMP0025)
+6 -1
View File
@@ -4280,7 +4280,7 @@ For form 2:
<li>
For form 3:
<ul>
<li>apply the given <i>lambda_function</i> to each slice</li>
<li>apply the given <i>lambda_function</i> to each column vector or row vector</li>
<li>the function must accept a reference to a <a href="#Col">Col</a> or <a href="#Row">Row</a> object with the same element type as the underlying matrix</li>
</ul>
</li>
@@ -8873,6 +8873,10 @@ Conversion of a <i>mat</i> object into <i>colvec</i>, <i>rowvec</i> or <i>std::v
</li>
<br>
<li>
<b>Caveat:</b> to convert an expression that results in a 1x1 matrix to a pure scalar value, use <a href="#as_scalar">as_scalar()</a>
</li>
<br>
<li>
Examples:
<ul>
<pre>
@@ -20222,6 +20226,7 @@ List of additions and changes for each version:
<li>Version 12.8:
<ul>
<li>faster detection of symmetric expressions by <a href="#pinv">pinv()</a> and <a href="#rank">rank()</a></li>
<li>faster handling of sparse submatrix views</li>
<li>expanded <a href="#shift">shift()</a> to handle sparse matrices</li>
<li>expanded <a href="#conv_to">conv_to</a> for more flexible conversions between sparse and dense matrices</li>
<li>added <a href="#misc_fns">cbrt()</a></li>
+3 -3
View File
@@ -19,9 +19,9 @@
#ifndef ARMA_INCLUDES
#define ARMA_INCLUDES
// NOTE: functions that are designed to be user accessible are described in the documentation (docs.html).
// NOTE: all other functions and classes (ie. not explicitly described in the documentation)
// NOTE: are considered as internal implementation details, and may be changed or removed without notice.
// WARNING: the documentation (docs.html) describes the public API (functions, classes, constants);
// WARNING: any functionality which is _not explicitly_ described in the documentation
// WARNING: is considered as internal implementation detail, and may be changed or removed without notice.
#include "armadillo_bits/config.hpp"
#include "armadillo_bits/compiler_check.hpp"
+18 -8
View File
@@ -44,18 +44,28 @@ SpSubview<eT>::SpSubview(const SpMat<eT>& in_m, const uword in_row1, const uword
m.sync_csc();
// There must be a O(1) way to do this
uword lend = m.col_ptrs[in_col1 + in_n_cols];
uword lend_row = in_row1 + in_n_rows;
uword count = 0;
// count the number of non-zeros in the subview
uword count = 0;
for(uword i = m.col_ptrs[in_col1]; i < lend; ++i)
if(n_rows == m.n_rows)
{
const uword m_row_indices_i = m.row_indices[i];
count = m.col_ptrs[aux_col1 + n_cols] - m.col_ptrs[aux_col1];
}
else
{
arma_extra_debug_print("counting non-zeros in sparse subview");
const bool condition = (m_row_indices_i >= in_row1) && (m_row_indices_i < lend_row);
uword lend = m.col_ptrs[in_col1 + in_n_cols];
uword lend_row = in_row1 + in_n_rows;
count += condition ? uword(1) : uword(0);
for(uword i = m.col_ptrs[in_col1]; i < lend; ++i)
{
const uword m_row_indices_i = m.row_indices[i];
const bool condition = (m_row_indices_i >= in_row1) && (m_row_indices_i < lend_row);
count += condition ? uword(1) : uword(0);
}
}
access::rw(n_nonzero) = count;
+1 -1
View File
@@ -23,7 +23,7 @@
#define ARMA_VERSION_MAJOR 12
#define ARMA_VERSION_MINOR 8
#define ARMA_VERSION_PATCH 2
#define ARMA_VERSION_PATCH 4
#define ARMA_VERSION_NAME "Cortisol Injector"
@@ -377,14 +377,11 @@
#if defined(__SUNPRO_CC)
// http://www.oracle.com/technetwork/server-storage/solarisstudio/training/index-jsp-141991.html
// http://www.oracle.com/technetwork/server-storage/solarisstudio/documentation/cplusplus-faq-355066.html
#if (__SUNPRO_CC < 0x5140)
#error "*** newer compiler required ***"
#endif
#endif
+5
View File
@@ -201,6 +201,11 @@
#if defined(ARMA_EXTRA_DEBUG)
#undef ARMA_NO_DEBUG
#undef ARMA_DONT_CHECK_NONFINITE
#undef ARMA_CHECK_NONFINITE
#define ARMA_CHECK_NONFINITE
#undef ARMA_WARN_LEVEL
#define ARMA_WARN_LEVEL 3
#endif
+5
View File
@@ -201,6 +201,11 @@
#if defined(ARMA_EXTRA_DEBUG)
#undef ARMA_NO_DEBUG
#undef ARMA_DONT_CHECK_NONFINITE
#undef ARMA_CHECK_NONFINITE
#define ARMA_CHECK_NONFINITE
#undef ARMA_WARN_LEVEL
#define ARMA_WARN_LEVEL 3
#endif
+4 -4
View File
@@ -579,7 +579,7 @@ arma_assert_same_size(const uword A_n_rows, const uword A_n_cols, const uword B_
//! stop if given matrices have different sizes
//! stop if given matrices do not have the same size
template<typename eT1, typename eT2>
arma_hot
inline
@@ -600,7 +600,7 @@ arma_assert_same_size(const Mat<eT1>& A, const Mat<eT2>& B, const char* x)
//! stop if given proxies have different sizes
//! stop if given proxies do not have the same size
template<typename eT1, typename eT2>
arma_hot
inline
@@ -804,7 +804,7 @@ arma_assert_same_size(const uword A_n_rows, const uword A_n_cols, const uword A_
//! stop if given cubes have different sizes
//! stop if given cubes do not have the same size
template<typename eT1, typename eT2>
arma_hot
inline
@@ -883,7 +883,7 @@ arma_assert_same_size(const subview_cube<eT>& A, const ProxyCube<T1>& B, const c
//! stop if given cube proxies have different sizes
//! stop if given cube proxies do not have the same size
template<typename eT1, typename eT2>
arma_hot
inline
+31 -1
View File
@@ -23,6 +23,13 @@
#if defined(ARMA_USE_FFTW3)
struct fft_engine_fftw3_aux
{
#if (!defined(ARMA_DONT_USE_STD_MUTEX))
static inline std::mutex& get_plan_mutex() { static std::mutex plan_mutex; return plan_mutex; }
#endif
};
template<typename cx_type, bool inverse>
class fft_engine_fftw3
{
@@ -74,7 +81,30 @@ class fft_engine_fftw3
const int fftw3_flags = fftw3_flag_destroy | fftw3_flag_estimate;
arma_extra_debug_print("fft_engine_fftw3::constructor: generating 1D plan");
fftw3_plan = fftw3::plan_dft_1d<cx_type>(N, X_work.memptr(), Y_work.memptr(), fftw3_sign, fftw3_flags);
// only fftw3::execute() is thread safe, as per FFTW docs:
// https://www.fftw.org/fftw3_doc/Thread-safety.html
#if defined(ARMA_USE_OPENMP)
{
#pragma omp critical (arma_fft_engine_fftw3)
{
fftw3_plan = fftw3::plan_dft_1d<cx_type>(N, X_work.memptr(), Y_work.memptr(), fftw3_sign, fftw3_flags);
}
}
#elif (!defined(ARMA_DONT_USE_STD_MUTEX))
{
std::mutex& plan_mutex = fft_engine_fftw3_aux::get_plan_mutex();
const std::lock_guard<std::mutex> lock(plan_mutex);
fftw3_plan = fftw3::plan_dft_1d<cx_type>(N, X_work.memptr(), Y_work.memptr(), fftw3_sign, fftw3_flags);
}
#else
{
fftw3_plan = fftw3::plan_dft_1d<cx_type>(N, X_work.memptr(), Y_work.memptr(), fftw3_sign, fftw3_flags);
}
#endif
if(fftw3_plan == nullptr) { arma_stop_runtime_error("fft_engine_fftw3::constructor: failed to create plan"); }
}
+1 -1
View File
@@ -30,7 +30,7 @@ class conv_to
template<typename in_eT, typename T1>
inline static out_eT from(const Base<in_eT, T1>& in, const typename arma_not_cx<in_eT>::result* junk = nullptr);
template<typename in_eT, typename T1>
inline static out_eT from(const Base<in_eT, T1>& in, const typename arma_cx_only<in_eT>::result* junk = nullptr);
+22 -2
View File
@@ -289,13 +289,33 @@ dot
{
arma_extra_debug_sigprint();
typedef typename T1::elem_type eT;
if(is_SpSubview_col<T2>::value)
{
// TODO: refactor to use C++17 "if constexpr" to avoid reinterpret_cast shenanigans
const SpSubview_col<eT>& yy = reinterpret_cast< const SpSubview_col<eT>& >(y);
if(yy.n_rows == yy.m.n_rows)
{
arma_extra_debug_print("using sparse column vector specialisation");
const quasi_unwrap<T1> U(x);
arma_debug_assert_same_size(U.M.n_elem, uword(1), yy.n_elem, uword(1), "dot()");
yy.m.sync();
return dense_sparse_helper::dot(U.M.memptr(), yy.m, yy.aux_col1);
}
}
const Proxy<T1> pa(x);
const SpProxy<T2> pb(y);
arma_debug_assert_same_size(pa.get_n_rows(), pa.get_n_cols(), pb.get_n_rows(), pb.get_n_cols(), "dot()");
typedef typename T1::elem_type eT;
eT result = eT(0);
typename SpProxy<T2>::const_iterator_type it = pb.begin();
+24
View File
@@ -1538,3 +1538,27 @@ TEST_CASE("sp_subview_row_iterator_test_2")
REQUIRE( true );
}
TEST_CASE("sp_subview_n_nonzero_test")
{
sp_mat x;
x.sprandu(100, 100, 0.3);
sp_vec y = x.col(0);
REQUIRE( y.n_nonzero == x.col(0).n_nonzero );
sp_mat z = x.cols(0, 5);
REQUIRE( z.n_nonzero == x.cols(0, 5).n_nonzero );
z = x.cols(11, 74);
REQUIRE( z.n_nonzero == x.cols(11, 74).n_nonzero );
z = x.submat(12, 14, 77, 17);
REQUIRE( z.n_nonzero == x.submat(12, 14, 77, 17).n_nonzero );
}