Compare commits

...
72 Commits
Author SHA1 Message Date
conrad bc2e8d5fcc patch bump 2026-07-23 23:23:18 +10:00
conrad c8b3ac8df1 fix speed regression for diagmat(glue_times) 2026-07-21 14:58:50 +10:00
conrad fef5c5954d fix speed regression for diagvec(glue_times) 2026-07-21 14:24:50 +10:00
conrad 9ce600b03b patch bump 2026-07-09 14:34:39 +10:00
conrad 37744f9a3c fix: unwrap the given object 2026-07-09 13:56:55 +10:00
conrad 1954f4a1d8 minor cleanup 2026-07-08 11:31:26 +10:00
conrad 9d731a6565 workaround for false positive warnings in GCC 15 2026-07-06 12:52:44 +10:00
conrad c7ffb88d54 more efficient handling of aliasing 2026-07-02 22:34:59 +10:00
conrad fe2930b966 fix: unwrap the given object 2026-07-02 21:23:15 +10:00
conrad 25aca17550 remove redundant code 2026-07-01 15:04:22 +10:00
conrad 23f652e542 simplification + speedup 2026-07-01 14:45:17 +10:00
conrad c6f4af01d8 more efficient handling of aliasing 2026-06-29 23:12:20 +10:00
conrad 1441e9f1a0 fix for handling .is_alias() 2026-06-29 23:07:24 +10:00
conrad f41149d528 more efficient handling of aliasing 2026-06-29 12:51:40 +10:00
conrad 3d7fd53b53 fill only non-integer matrices with NaN 2026-06-26 12:27:57 +10:00
conrad 340a1b3592 expand Mat::fixed with .row() and .col() specialisations 2026-06-25 12:04:18 +10:00
conrad 07414596d4 version bump 2026-06-18 13:21:37 +10:00
conrad 585b369988 fix layout 2026-06-18 12:56:19 +10:00
conrad a957b25a29 explicitly ignore unused value 2026-06-17 12:18:45 +10:00
conrad 61bb3e0ae8 change fill::pos_inf to shorter fill::inf 2026-06-17 11:36:30 +10:00
conrad d5f00fd4a8 mark as RC1 2026-06-16 14:42:41 +10:00
conrad 4dc011f5d3 keep requested mem_state even if n_elem is zero 2026-06-16 14:12:08 +10:00
conrad 922ccf9154 rearrange 2026-06-16 13:24:10 +10:00
conrad ba33c24e8a simpler conversion of std::vector 2026-06-16 13:19:00 +10:00
conrad fea46c6f84 more robust handling of aux_mem 2026-06-16 13:02:05 +10:00
conrad 033c93196c more robust handling of aux_mem 2026-06-16 12:33:54 +10:00
conrad 453bef9283 update list of changes 2026-06-15 15:37:28 +10:00
conrad 598df0100e minor cleanup 2026-06-15 15:35:38 +10:00
conrad 45347ce825 avoid copying when element types are the same 2026-06-15 15:12:11 +10:00
conrad 3318e018d0 faster initial vector growth 2026-06-15 12:07:45 +10:00
conrad 8d350a1534 remove unused code 2026-06-15 11:52:45 +10:00
conrad 11b885085a update list of changes 2026-06-13 00:56:07 +10:00
conrad 724dc98eb8 speedp for contiguous subcubes 2026-06-13 00:51:39 +10:00
conrad 452a6c1b49 use partially unrolled loops 2026-06-13 00:29:21 +10:00
conrad 5c2892a2b5 add specialised handling of find() within .elem() 2026-06-13 00:26:17 +10:00
conrad 88003f8ab8 obtain memory pointers earlier 2026-06-13 00:20:14 +10:00
conrad 248ce5fe7f use same variable name for definition and implementation 2026-06-13 00:14:14 +10:00
conrad e493eb3b34 simplify bounds checks 2026-06-13 00:11:16 +10:00
conrad 03411c40a6 add stored_type typedef to quasi_unwrap<> 2026-06-13 00:06:27 +10:00
conrad 3c6c443be6 more precise alias check 2026-06-12 23:54:07 +10:00
conrad a638683e6f remove unnecessary alignment attribute 2026-06-12 22:02:22 +10:00
conrad e299f5e189 simplify by reusing extract_noalias() 2026-06-12 21:59:36 +10:00
conrad 053de98101 rename unwrap objects 2026-06-12 21:56:57 +10:00
conrad 6b1ce2116b remove rarely used specialisations 2026-06-12 21:48:17 +10:00
conrad b7afc7e5fb add has_subview trait 2026-06-12 20:25:01 +10:00
conrad 1e61d46e5b rename op_find to op_find_generic; rename op_find_simple to op_find_default 2026-06-12 20:13:50 +10:00
conrad 139d9f4d62 user better name and constexpr variable to indicate half threshold 2026-06-12 20:09:12 +10:00
conrad f123904e82 add docs for .push_back() 2026-06-12 20:04:24 +10:00
conrad 6e224f38bd add .push_back() 2026-06-12 20:02:11 +10:00
conrad c088151876 remove unnecessary forced inlines 2026-06-12 19:52:15 +10:00
conrad a839bc49d3 expand deprecation notices 2026-06-12 19:45:34 +10:00
conrad c13b71fc69 rename unwrap<> to plain_unwrap<> for consistency with bandicoot 2026-06-12 19:08:54 +10:00
conrad 69fc9f29a0 mark as experimental 2026-06-12 16:17:33 +10:00
conrad 730594f6da mark as experimental 2026-06-12 16:17:20 +10:00
conrad 80087a3a55 patch bump 2026-05-28 15:12:21 +10:00
conrad d0b07c02a3 skip alias checks when extracting subfield into a fresh field 2026-05-26 22:58:36 +10:00
conrad 1716a6b531 more efficient alias checks 2026-05-26 15:08:10 +10:00
conrad a86cfc932b don't strip const 2026-05-26 12:37:27 +10:00
conrad 8ce3f3aa7d skip alias checks when extracting subview_elem2 into a fresh matrix 2026-05-25 12:49:06 +10:00
conrad 89158f7777 skip alias checks when extracting subview_elem1 into a fresh matrix 2026-05-25 12:29:45 +10:00
conrad cedbd0eb89 simplifications 2026-04-27 10:46:05 +10:00
conrad fd38c47657 better wording 2026-04-27 10:40:02 +10:00
conrad bb5c4469b3 minor fix in error message 2026-04-21 13:50:08 +10:00
conrad 36b0cd37ec patch bump 2026-04-20 00:15:11 +10:00
conrad 59fbefc095 simplifications 2026-04-19 22:59:46 +10:00
conrad b1f3a185bf distinguish between default and user supplied tolerance 2026-04-18 23:48:32 +10:00
conrad adcbf1380a ensure intermediate results are not NaN 2026-04-18 17:45:48 +10:00
conrad 733533f089 ensure intermediate results are not NaN 2026-04-18 17:09:20 +10:00
conrad ae6f216a82 ensure suppled tolerances are not NaN 2026-04-18 17:08:51 +10:00
conrad 417bb37042 ensure default tolerances are not NaN 2026-04-18 16:45:02 +10:00
conrad 95cad27904 ensure default tolerance is finite 2026-04-18 14:13:49 +10:00
conrad 3e66e7b1f0 cleanup 2026-04-16 21:39:49 +10:00
121 changed files with 2421 additions and 1295 deletions
+68 -8
View File
@@ -159,7 +159,7 @@ hr.greyline
<a class="noprint" style="display:scroll; position:fixed; bottom:5px; right:5px;" href="#top"><font size=-1>[top]</font></a>
<a name="top"></a>
<big><b>API Documentation for Armadillo 15.2</b></big>
<big><b>API Documentation for Armadillo 15.4</b></big>
<br>
<br>
<br>
@@ -271,6 +271,7 @@ Conrad Sanderson and Ryan Curtin.
<table>
<tbody>
<tr><td><a href="#attributes">attributes</a></td><td>&nbsp;</td><td>.n_rows, .n_cols, .n_elem, .n_slices, ...</td></tr>
<tr><td><small><small>&nbsp;</small></small></td><td><small><small>&nbsp;</small></small></td><td><small><small>&nbsp;</small></small></td></tr>
<tr><td><a href="#element_access">element&nbsp;access</a></td><td>&nbsp;</td><td>element/object access via (), [] and .at()</td></tr>
<tr><td><a href="#element_initialisation">element&nbsp;initialisation</a></td><td>&nbsp;</td><td>set elements via initialiser lists</td></tr>
<tr><td><small><small>&nbsp;</small></small></td><td><small><small>&nbsp;</small></small></td><td><small><small>&nbsp;</small></small></td></tr>
@@ -281,6 +282,7 @@ Conrad Sanderson and Ryan Curtin.
<tr><td><small><small>&nbsp;</small></small></td><td><small><small>&nbsp;</small></small></td><td><small><small>&nbsp;</small></small></td></tr>
<tr><td><a href="#fill">.fill</a></td><td>&nbsp;</td><td>set all elements to specified value</td></tr>
<tr><td><a href="#imbue">.imbue</a></td><td>&nbsp;</td><td>imbue (fill) with values provided by functor or lambda function</td></tr>
<tr><td><a href="#push_back">.push_back</a></td><td>&nbsp;</td><td>append elements to vectors</td></tr>
<tr><td><small><small>&nbsp;</small></small></td><td><small><small>&nbsp;</small></small></td><td><small><small>&nbsp;</small></small></td></tr>
<tr><td><a href="#clean">.clean</a></td><td>&nbsp;</td><td>replace elements below a threshold with zeros</td></tr>
<tr><td><a href="#replace_member">.replace</a></td><td>&nbsp;</td><td>replace specific elements with a new value</td></tr>
@@ -793,9 +795,9 @@ which is one of:
<tr><td><code>fill::none</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>do not initialise the elements &nbsp; (matrix may have garbage values)</td></tr>
<tr><td><code>fill::zeros</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to 0 &nbsp; (default operation)</td></tr>
<tr><td><code>fill::ones</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to 1</td></tr>
<!-- <tr><td><code>fill::nan</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to NaN</td></tr> -->
<!-- <tr><td><code>fill::pos_inf</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to +infinity</td></tr> -->
<!-- <tr><td><code>fill::neg_inf</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to -infinity</td></tr> -->
<tr><td><code>fill::nan</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to NaN</td></tr>
<tr><td><code>fill::inf</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to +infinity</td></tr>
<tr><td><code>fill::neg_inf</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to -infinity</td></tr>
<tr><td><code>fill::value(scalar)</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to the specified scalar</td></tr>
<tr><td><code>fill::eye</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set elements on the main diagonal to 1 and off-diagonal elements to 0</td></tr>
<tr><td><code>fill::randu</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set elements to random values from a uniform distribution in the [0,1] interval</td></tr>
@@ -1752,9 +1754,9 @@ which is one of:
<tr><td><code>fill::none</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>do not initialise the elements &nbsp; (cube may have garbage values)</td></tr>
<tr><td><code>fill::zeros</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to 0 &nbsp; (default operation)</td></tr>
<tr><td><code>fill::ones</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to 1</td></tr>
<!-- <tr><td><code>fill::nan</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to NaN</td></tr> -->
<!-- <tr><td><code>fill::pos_inf</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to +infinity</td></tr> -->
<!-- <tr><td><code>fill::neg_inf</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to -infinity</td></tr> -->
<tr><td><code>fill::nan</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to NaN</td></tr>
<tr><td><code>fill::inf</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to +infinity</td></tr>
<tr><td><code>fill::neg_inf</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to -infinity</td></tr>
<tr><td><code>fill::value(scalar)</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to the specified scalar</td></tr>
<tr><td><code>fill::randu</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set elements to random values from a uniform distribution in the [0,1] interval</td></tr>
<tr><td><code>fill::randn</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set elements to random values from a normal/Gaussian distribution with mean&thinsp;=&thinsp;0 and variance&thinsp;=&thinsp;1</td></tr>
@@ -2716,6 +2718,7 @@ double y = v(0);
<ul>
<li><a href="#in_range">.in_range()</a></li>
<li><a href="#element_initialisation">element initialisation</a></li>
<li><a href="#push_back">.push_back()</a></li>
<li><a href="#ind2sub">ind2sub()</a></li>
<li><a href="#sub2ind">sub2ind()</a></li>
<li><a href="#index_min_and_index_max_member">.index_min()&nbsp;/&nbsp;.index_max()</a></li>
@@ -2755,6 +2758,7 @@ mat A = { {1, 3, 5},
See also:
<ul>
<li><a href="#element_access">element access</a></li>
<li><a href="#push_back">.push_back()</a></li>
<li><a href="#reshape_member">.reshape()</a></li>
<li><a href="#print">.print()</a></li>
<li><a href="#save_load_mat">saving &amp; loading matrices</a></li>
@@ -3168,6 +3172,7 @@ mat C(5, 6, fill::value(123.0));
See also:
<ul>
<li><a href="#imbue">.imbue()</a></li>
<li><a href="#push_back">.push_back()</a></li>
<li><a href="#zeros_member">.zeros()</a></li>
<li><a href="#ones_member">.ones()</a></li>
<li><a href="#eye_member">.eye()</a></li>
@@ -3222,6 +3227,7 @@ A.imbue( [&amp;]() { return distr(engine); } );
See also:
<ul>
<li><a href="#fill">.fill()</a></li>
<li><a href="#push_back">.push_back()</a></li>
<li><a href="#transform">.transform()</a></li>
<li><a href="#element_access">element access</a></li>
<li><a href="https://en.wikipedia.org/wiki/Function_object">function object</a> at Wikipedia</li>
@@ -3232,6 +3238,48 @@ See also:
<br>
</ul>
<div class="pagebreak"></div><div class="noprint"><hr class="greyline"><br></div>
<a name="push_back"></a>
<b>.push_back(&nbsp;value&nbsp;)</b>
<ul>
<li>
Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i>
</li>
<br>
<li>
Append the given <i>value</i> to the end of the object,
under the assumption of a column or row vector layout
</li>
<br>
<li>
<b>Caveat:</b> it is faster to directly set the elements via <a href="#element_access">element accessors</a>
or <a href="#element_initialisation">braced initialiser lists</a>
</li>
<br>
<li>
Examples:
<ul>
<pre>
vec v;
v.push_back(1.23);
v.push_back(4.56);
v.push_back(7.89);
</pre>
</ul>
</li>
<br>
<li>See also:
<ul>
<li><a href="#element_access">element accessors</a></li>
<li><a href="#element_initialisation">element initialisation</a></li>
<li><a href="#fill">.fill()</a></li>
<li><a href="#imbue">.imbue()</a></li>
</ul>
</li>
<br>
</ul>
<div class="pagebreak"></div><div class="noprint"><hr class="greyline"><br></div>
<a name="clean"></a>
<b>.clean(&nbsp;</b>threshold<b>&nbsp;)</b>
@@ -5825,6 +5873,7 @@ See also:
<li><a href="#iterators_cube">iterators (cubes)</a></li>
<li><a href="#iterators_spmat">iterators (sparse matrices)</a></li>
<li><a href="#attributes">matrix and vector attributes</a></li>
<li><a href="#push_back">.push_back()</a></li>
<li><a href="#is_empty">.is_empty()</a></li>
<li><a href="#reset">.reset()</a></li>
</ul>
@@ -9655,7 +9704,7 @@ vec b = diff(a);
</li>
<br>
<li>
<b>Caveat:</b> <a href="#norm">norm()</a> is preferred for calculating the 2-norm, as it reduces the incidence of numerical underflows and overflows
<b>Caveat:</b> to obtain the Euclidean norm, use the more robust <a href="#norm">norm(x)</a> instead of <i>sqrt(dot(x,x))</i>
</li>
<br>
<li>
@@ -20720,6 +20769,17 @@ List of additions and changes for each version:
<a name="version_154"></a>
<li>Version 15.4:
<ul>
<li>added <i>fill::nan</i>, <i>fill::inf</i>, <i>fill::neg_inf</i> as optional fill forms for the <a href="#Mat">Mat</a> class</li>
<li>added <a href="#push_back">.push_back()</a> for appending elements to vectors</li>
<li>faster handling of <a href="#find">find()</a> within <a href="#submat">.elem()</a></li>
<li>faster element-wise <a href="#min_and_max">min()</a> and <a href="#min_and_max">max()</a></li>
<li>faster <a href="#conv_to">conv_to</a> when element types of input and output objects are the same</li>
</ul>
</li>
<br>
<a name="version_152"></a>
<li>Version 15.2:
<ul>
+2
View File
@@ -306,6 +306,7 @@ namespace arma
#include "armadillo_bits/op_orth_null_bones.hpp"
#include "armadillo_bits/op_relational_bones.hpp"
#include "armadillo_bits/op_find_bones.hpp"
#include "armadillo_bits/op_find_aux_bones.hpp"
#include "armadillo_bits/op_find_unique_bones.hpp"
#include "armadillo_bits/op_chol_bones.hpp"
#include "armadillo_bits/op_cx_scalar_bones.hpp"
@@ -765,6 +766,7 @@ namespace arma
#include "armadillo_bits/op_orth_null_meat.hpp"
#include "armadillo_bits/op_relational_meat.hpp"
#include "armadillo_bits/op_find_meat.hpp"
#include "armadillo_bits/op_find_aux_meat.hpp"
#include "armadillo_bits/op_find_unique_meat.hpp"
#include "armadillo_bits/op_chol_meat.hpp"
#include "armadillo_bits/op_cx_scalar_meat.hpp"
+12 -2
View File
@@ -352,7 +352,7 @@ Base<elem_type,derived>::is_symmetric(const typename get_pod_type<elem_type>::re
if(tol == T(0)) { return (*this).is_symmetric(); }
arma_conform_check( ((tol >= T(0)) == false), "is_symmetric(): parameter 'tol' must be >= 0" );
arma_conform_check( ((tol >= T(0)) == false), "is_symmetric(): parameter 'tol' must be > 0" );
const quasi_unwrap<derived> U( (*this).get_ref() );
@@ -365,8 +365,12 @@ Base<elem_type,derived>::is_symmetric(const typename get_pod_type<elem_type>::re
if(norm_A == T(0)) { return true; }
if(arma_isnan(norm_A)) { return false; }
const T norm_A_Ast = as_scalar( arma::max(sum(abs(A - A.st()), 1), 0) );
if(arma_isnan(norm_A_Ast)) { return false; }
return ( (norm_A_Ast / norm_A) <= tol );
}
@@ -435,7 +439,7 @@ Base<elem_type,derived>::is_hermitian(const typename get_pod_type<elem_type>::re
if(tol == T(0)) { return (*this).is_hermitian(); }
arma_conform_check( ((tol >= T(0)) == false), "is_hermitian(): parameter 'tol' must be >= 0" );
arma_conform_check( ((tol >= T(0)) == false), "is_hermitian(): parameter 'tol' must be > 0" );
const quasi_unwrap<derived> U( (*this).get_ref() );
@@ -448,8 +452,12 @@ Base<elem_type,derived>::is_hermitian(const typename get_pod_type<elem_type>::re
if(norm_A == T(0)) { return true; }
if(arma_isnan(norm_A)) { return false; }
const T norm_A_At = as_scalar( arma::max(sum(abs(A - A.t()), 1), 0) );
if(arma_isnan(norm_A_At)) { return false; }
return ( (norm_A_At / norm_A) <= tol );
}
@@ -927,6 +935,8 @@ Base_extra_yes<elem_type,derived>::is_sympd() const
// default value for tol
const T tol = T(100) * std::numeric_limits<T>::epsilon() * norm(X, "fro");
if(arma_isnan(tol)) { return false; }
if(X.is_hermitian(tol) == false) { return false; }
if(X.is_empty()) { return false; }
+7 -3
View File
@@ -33,6 +33,8 @@ class Col : public Mat<eT>
static constexpr bool is_row = false;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = false;
inline Col();
inline Col(const Col<eT>& X);
@@ -67,9 +69,6 @@ class Col : public Mat<eT>
inline Col(Col&& m);
inline Col& operator=(Col&& m);
// inline Col(Mat<eT>&& m);
// inline Col& operator=(Mat<eT>&& m);
inline Col& operator=(const eT val);
inline Col& operator=(const Col& m);
@@ -153,6 +152,7 @@ class Col : public Mat<eT>
arma_warn_unused arma_inline eT& at(const uword in_row, const uword in_col);
arma_warn_unused arma_inline const eT& at(const uword in_row, const uword in_col) const;
inline void push_back(const eT val);
inline constexpr bool is_vec() const { return true; }
inline constexpr bool is_rowvec() const { return false; }
@@ -210,6 +210,8 @@ class Col<eT>::fixed : public Col<eT>
static constexpr bool is_row = false;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = false;
static const uword n_rows; // value provided below the class definition
static const uword n_cols; // value provided below the class definition
static const uword n_elem; // value provided below the class definition
@@ -265,6 +267,8 @@ class Col<eT>::fixed : public Col<eT>
arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col);
arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col) const;
inline void push_back(const eT) = delete;
arma_warn_unused arma_inline eT* memptr();
arma_warn_unused arma_inline const eT* memptr() const;
+19 -58
View File
@@ -431,64 +431,6 @@ Col<eT>::operator=(Col<eT>&& X)
// template<typename eT>
// inline
// Col<eT>::Col(Mat<eT>&& X)
// : Mat<eT>(arma_vec_indicator(), 1)
// {
// arma_debug_sigprint(arma_str::format("this: %x; X: %x") % this % &X);
//
// if(X.n_cols != 1) { const Mat<eT>& XX = X; Mat<eT>::operator=(XX); return; }
//
// access::rw(Mat<eT>::n_rows) = X.n_rows;
// access::rw(Mat<eT>::n_cols) = 1;
// access::rw(Mat<eT>::n_elem) = X.n_elem;
// access::rw(Mat<eT>::n_alloc) = X.n_alloc;
//
// if( (X.n_alloc > arma_config::mat_prealloc) || (X.mem_state == 1) || (X.mem_state == 2) )
// {
// access::rw(Mat<eT>::mem_state) = X.mem_state;
// access::rw(Mat<eT>::mem) = X.mem;
//
// access::rw(X.n_rows) = 0;
// access::rw(X.n_elem) = 0;
// access::rw(X.n_alloc) = 0;
// access::rw(X.mem_state) = 0;
// access::rw(X.mem) = nullptr;
// }
// else // condition: (X.n_alloc <= arma_config::mat_prealloc) || (X.mem_state == 0) || (X.mem_state == 3)
// {
// (*this).init_cold();
//
// arrayops::copy( (*this).memptr(), X.mem, X.n_elem );
//
// if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) )
// {
// access::rw(X.n_rows) = 0;
// access::rw(X.n_elem) = 0;
// access::rw(X.mem) = nullptr;
// }
// }
// }
//
//
//
// template<typename eT>
// inline
// Col<eT>&
// Col<eT>::operator=(Mat<eT>&& X)
// {
// arma_debug_sigprint(arma_str::format("this: %x; X: %x") % this % &X);
//
// if(X.n_cols != 1) { const Mat<eT>& XX = X; Mat<eT>::operator=(XX); return *this; }
//
// (*this).steal_mem(X, true);
//
// return *this;
// }
template<typename eT>
inline
Col<eT>&
@@ -1208,6 +1150,25 @@ Col<eT>::at(const uword in_row, const uword) const
template<typename eT>
inline
void
Col<eT>::push_back(const eT val)
{
arma_debug_sigprint();
if(Mat<eT>::mem_state != 0)
{
arma_conform_check(true, "Col::push_back(): unsupported operation as auxiliary memory is in use");
return;
}
Mat<eT>::vec_push_back(val, arma_colvec_indicator());
}
template<typename eT>
inline
typename Col<eT>::row_iterator
@@ -40,6 +40,8 @@ struct CubeToMatOp : public Base< typename T1::elem_type, CubeToMatOp<T1, op_typ
static constexpr bool is_row = op_type::template traits<T1>::is_row;
static constexpr bool is_col = op_type::template traits<T1>::is_col;
static constexpr bool is_xvec = op_type::template traits<T1>::is_xvec;
static constexpr bool has_subview = T1::has_subview;
};
+2
View File
@@ -82,6 +82,8 @@ class Cube : public BaseCube< eT, Cube<eT> >
public:
static constexpr bool has_subview = false;
inline ~Cube();
inline Cube();
+28 -3
View File
@@ -807,11 +807,29 @@ Cube<eT>::Cube(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, cons
{
init_cold();
arrayops::copy( memptr(), aux_mem, n_elem );
if(aux_mem == nullptr)
{
arrayops::fill_zeros(memptr(), n_elem);
}
else
{
arrayops::copy( memptr(), aux_mem, n_elem );
}
}
else
{
create_mat();
if(aux_mem == nullptr)
{
access::rw(mem_state) = 0;
init_cold();
arrayops::fill_zeros(memptr(), n_elem);
}
else
{
create_mat();
}
}
}
@@ -835,7 +853,14 @@ Cube<eT>::Cube(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols
init_cold();
arrayops::copy( memptr(), aux_mem, n_elem );
if(aux_mem == nullptr)
{
arrayops::fill_zeros(memptr(), n_elem);
}
else
{
arrayops::copy( memptr(), aux_mem, n_elem );
}
}
+3 -2
View File
@@ -28,8 +28,9 @@ struct GenCube
typedef eT elem_type;
typedef typename get_pod_type<elem_type>::result pod_type;
static constexpr bool use_at = false;
static constexpr bool is_simple = (is_same_type<gen_type, gen_ones>::value) || (is_same_type<gen_type, gen_zeros>::value);
static constexpr bool use_at = false;
static constexpr bool is_simple = (is_same_type<gen_type, gen_ones>::value) || (is_same_type<gen_type, gen_zeros>::value);
static constexpr bool has_subview = false;
const uword n_rows;
const uword n_cols;
+2
View File
@@ -35,6 +35,8 @@ struct Gen
static constexpr bool is_col = T1::is_col;
static constexpr bool is_xvec = T1::is_xvec;
static constexpr bool has_subview = false;
const uword n_rows;
const uword n_cols;
@@ -28,6 +28,8 @@ struct GlueCube : public BaseCube< typename T1::elem_type, GlueCube<T1, T2, glue
typedef typename T1::elem_type elem_type;
typedef typename get_pod_type<elem_type>::result pod_type;
static constexpr bool has_subview = T1::has_subview || T2::has_subview;
inline GlueCube(const BaseCube<typename T1::elem_type, T1>& in_A, const BaseCube<typename T1::elem_type, T2>& in_B);
inline ~GlueCube();
+2
View File
@@ -50,6 +50,8 @@ struct Glue
typedef typename T1::elem_type elem_type;
typedef typename get_pod_type<elem_type>::result pod_type;
static constexpr bool has_subview = T1::has_subview || T2::has_subview;
inline Glue(const T1& in_A, const T2& in_B);
inline Glue(const T1& in_A, const T2& in_B, const uword in_aux_uword);
inline ~Glue();
+17 -1
View File
@@ -57,6 +57,8 @@ class Mat : public Base< eT, Mat<eT> >
static constexpr bool is_row = false;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = false;
inline ~Mat();
inline Mat();
@@ -452,6 +454,8 @@ class Mat : public Base< eT, Mat<eT> >
arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col);
arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col) const;
inline void push_back(const eT val);
arma_inline const Mat& operator++();
arma_inline void operator++(int);
@@ -819,6 +823,8 @@ class Mat : public Base< eT, Mat<eT> >
inline Mat(const arma_fixed_indicator&, const uword in_n_rows, const uword in_n_cols, const uhword in_vec_state, const eT* in_mem);
template<int vec_mode> inline void vec_push_back(const eT val, const arma_vec_mode_indicator<vec_mode>&);
friend class Cube<eT>;
friend class subview_cube<eT>;
@@ -830,7 +836,7 @@ class Mat : public Base< eT, Mat<eT> >
friend struct op_mean;
friend struct op_max;
friend struct op_min;
public:
@@ -866,6 +872,8 @@ class Mat<eT>::fixed : public Mat<eT>
static constexpr bool is_row = (fixed_n_rows == 1);
static constexpr bool is_xvec = false;
static constexpr bool has_subview = false;
static const uword n_rows; // value provided below the class definition
static const uword n_cols; // value provided below the class definition
static const uword n_elem; // value provided below the class definition
@@ -922,12 +930,20 @@ class Mat<eT>::fixed : public Mat<eT>
arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col);
arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col) const;
inline void push_back(const eT) = delete;
arma_warn_unused arma_inline eT* colptr(const uword in_col);
arma_warn_unused arma_inline const eT* colptr(const uword in_col) const;
arma_warn_unused arma_inline eT* memptr();
arma_warn_unused arma_inline const eT* memptr() const;
arma_inline subview_row<eT> row(const uword row_num);
arma_inline const subview_row<eT> row(const uword row_num) const;
arma_inline subview_col<eT> col(const uword col_num);
arma_inline const subview_col<eT> col(const uword col_num) const;
arma_warn_unused arma_inline bool is_vec() const;
inline const Mat<eT>& fill(const eT val);
+253 -32
View File
@@ -1369,7 +1369,23 @@ Mat<eT>::Mat(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const
{
init_cold();
arrayops::copy( memptr(), aux_mem, n_elem );
if(aux_mem == nullptr)
{
arrayops::fill_zeros(memptr(), n_elem);
}
else
{
arrayops::copy( memptr(), aux_mem, n_elem );
}
}
else
if(aux_mem == nullptr)
{
access::rw(mem_state) = 0;
init_cold();
arrayops::fill_zeros(memptr(), n_elem);
}
}
@@ -1392,7 +1408,14 @@ Mat<eT>::Mat(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols)
init_cold();
arrayops::copy( memptr(), aux_mem, n_elem );
if(aux_mem == nullptr)
{
arrayops::fill_zeros(memptr(), n_elem);
}
else
{
arrayops::copy( memptr(), aux_mem, n_elem );
}
}
@@ -2544,7 +2567,7 @@ Mat<eT>::Mat(const subview_elem1<eT,T1>& X, const arma_vec_indicator&, const uhw
{
arma_debug_sigprint_this(this);
(*this).operator=(X);
subview_elem1<eT,T1>::extract_noalias(*this, X);
}
@@ -2563,7 +2586,7 @@ Mat<eT>::Mat(const subview_elem1<eT,T1>& X)
{
arma_debug_sigprint_this(this);
(*this).operator=(X);
subview_elem1<eT,T1>::extract_noalias(*this, X);
}
@@ -2591,9 +2614,9 @@ Mat<eT>::operator+=(const subview_elem1<eT,T1>& X)
{
arma_debug_sigprint();
subview_elem1<eT,T1>::plus_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator+=(tmp);
}
@@ -2606,9 +2629,9 @@ Mat<eT>::operator-=(const subview_elem1<eT,T1>& X)
{
arma_debug_sigprint();
subview_elem1<eT,T1>::minus_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator-=(tmp);
}
@@ -2621,9 +2644,9 @@ Mat<eT>::operator*=(const subview_elem1<eT,T1>& X)
{
arma_debug_sigprint();
glue_times::apply_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator*=(tmp);
}
@@ -2636,9 +2659,9 @@ Mat<eT>::operator%=(const subview_elem1<eT,T1>& X)
{
arma_debug_sigprint();
subview_elem1<eT,T1>::schur_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator%=(tmp);
}
@@ -2651,9 +2674,9 @@ Mat<eT>::operator/=(const subview_elem1<eT,T1>& X)
{
arma_debug_sigprint();
subview_elem1<eT,T1>::div_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator/=(tmp);
}
@@ -2672,7 +2695,7 @@ Mat<eT>::Mat(const subview_elem2<eT,T1,T2>& X, const arma_vec_indicator&, const
{
arma_debug_sigprint_this(this);
(*this).operator=(X);
subview_elem2<eT,T1,T2>::extract_noalias(*this, X);
}
@@ -2691,7 +2714,7 @@ Mat<eT>::Mat(const subview_elem2<eT,T1,T2>& X)
{
arma_debug_sigprint_this(this);
(*this).operator=(X);
subview_elem2<eT,T1,T2>::extract_noalias(*this, X);
}
@@ -2719,9 +2742,9 @@ Mat<eT>::operator+=(const subview_elem2<eT,T1,T2>& X)
{
arma_debug_sigprint();
subview_elem2<eT,T1,T2>::plus_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator+=(tmp);
}
@@ -2734,9 +2757,9 @@ Mat<eT>::operator-=(const subview_elem2<eT,T1,T2>& X)
{
arma_debug_sigprint();
subview_elem2<eT,T1,T2>::minus_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator-=(tmp);
}
@@ -2749,9 +2772,9 @@ Mat<eT>::operator*=(const subview_elem2<eT,T1,T2>& X)
{
arma_debug_sigprint();
glue_times::apply_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator*=(tmp);
}
@@ -2764,9 +2787,9 @@ Mat<eT>::operator%=(const subview_elem2<eT,T1,T2>& X)
{
arma_debug_sigprint();
subview_elem2<eT,T1,T2>::schur_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator%=(tmp);
}
@@ -2779,9 +2802,9 @@ Mat<eT>::operator/=(const subview_elem2<eT,T1,T2>& X)
{
arma_debug_sigprint();
subview_elem2<eT,T1,T2>::div_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator/=(tmp);
}
@@ -4980,8 +5003,8 @@ Mat<eT>::insert_rows(const uword row_num, const Base<eT,T1>& X)
{
arma_debug_sigprint();
const unwrap<T1> tmp(X.get_ref());
const Mat<eT>& C = tmp.M;
const plain_unwrap<T1> tmp(X.get_ref());
const Mat<eT>& C = tmp.M;
const uword C_n_rows = C.n_rows;
const uword C_n_cols = C.n_cols;
@@ -5056,8 +5079,8 @@ Mat<eT>::insert_cols(const uword col_num, const Base<eT,T1>& X)
{
arma_debug_sigprint();
const unwrap<T1> tmp(X.get_ref());
const Mat<eT>& C = tmp.M;
const plain_unwrap<T1> tmp(X.get_ref());
const Mat<eT>& C = tmp.M;
const uword C_n_rows = C.n_rows;
const uword C_n_cols = C.n_cols;
@@ -7037,6 +7060,31 @@ Mat<eT>::at(const uword in_row, const uword in_col) const
template<typename eT>
inline
void
Mat<eT>::push_back(const eT val)
{
arma_debug_sigprint();
if(mem_state != 0)
{
arma_conform_check(true, "Mat::push_back(): unsupported operation as auxiliary memory is in use");
return;
}
const uword t_n_rows = n_rows;
const uword t_n_cols = n_cols;
if( (vec_state == 1) || (t_n_cols == 1) || ((t_n_cols == 0) && (t_n_rows == 0)) ) { (*this).vec_push_back(val, arma_colvec_indicator()); return; }
if( (vec_state == 2) || (t_n_rows == 1) ) { (*this).vec_push_back(val, arma_rowvec_indicator()); return; }
arma_conform_check(true, "Mat::push_back(): column or row vector layout required");
}
//! prefix ++
template<typename eT>
arma_inline
@@ -10047,6 +10095,119 @@ Mat<eT>::back() const
template<typename eT>
template<int vec_mode>
inline
void
Mat<eT>::vec_push_back(const eT val, const arma_vec_mode_indicator<vec_mode>&)
{
arma_debug_sigprint( arma_str::format("n_elem: %u; n_alloc: %u") % n_elem % n_alloc );
// vec_mode = 1 means col vector layout
// vec_mode = 2 means row vector layout
const uword old_n_elem = n_elem;
const uword new_n_elem = old_n_elem + 1;
if(old_n_elem <= arma_config::mat_prealloc)
{
if(old_n_elem == 0)
{
mem_local[0] = val;
access::rw(mem ) = mem_local;
access::rw(n_rows) = 1;
access::rw(n_cols) = 1;
access::rw(n_elem) = 1;
}
else
if(old_n_elem < arma_config::mat_prealloc)
{
// condition: (old_n_elem >= 1) && (old_n_elem < arma_config::mat_prealloc)
mem_local[old_n_elem] = val;
if(vec_mode == 1) { access::rw(n_rows) = new_n_elem; }
if(vec_mode == 2) { access::rw(n_cols) = new_n_elem; }
access::rw(n_elem) = new_n_elem;
}
else
{
// condition: old_n_elem == arma_config::mat_prealloc
const uword new_n_alloc = (std::max)(uword(64), uword(arma_config::mat_prealloc + arma_config::mat_prealloc/2));
arma_debug_print( arma_str::format("acquiring new memory; new_n_alloc: %u") % new_n_alloc );
eT* new_mem_ptr = memory::acquire<eT>(new_n_alloc);
if(new_mem_ptr == nullptr) { return; }
arma_debug_print("copying memory");
arrayops::copy(new_mem_ptr, mem_local, arma_config::mat_prealloc);
new_mem_ptr[old_n_elem] = val;
access::rw(mem) = new_mem_ptr;
if(vec_mode == 1) { access::rw(n_rows) = new_n_elem; }
if(vec_mode == 2) { access::rw(n_cols) = new_n_elem; }
access::rw(n_elem) = new_n_elem;
access::rw(n_alloc) = new_n_alloc;
}
}
else
{
// condition: old_n_elem > arma_config::mat_prealloc
if(n_alloc >= new_n_elem)
{
access::rw(mem[old_n_elem]) = val;
if(vec_mode == 1) { access::rw(n_rows) = new_n_elem; }
if(vec_mode == 2) { access::rw(n_cols) = new_n_elem; }
access::rw(n_elem) = new_n_elem;
}
else
{
// condition: n_alloc < new_n_elem
const uword new_n_alloc = (std::max)(uword(256), uword(n_alloc + n_alloc/2));
arma_debug_print( arma_str::format("acquiring new memory; new_n_alloc: %u") % new_n_alloc );
const eT* old_mem_ptr = mem;
eT* new_mem_ptr = memory::acquire<eT>(new_n_alloc);
if(new_mem_ptr == nullptr) { return; }
arma_debug_print("copying memory");
arrayops::copy(new_mem_ptr, old_mem_ptr, n_elem);
new_mem_ptr[old_n_elem] = val;
access::rw(mem) = new_mem_ptr;
if(vec_mode == 1) { access::rw(n_rows) = new_n_elem; }
if(vec_mode == 2) { access::rw(n_cols) = new_n_elem; }
access::rw(n_elem ) = new_n_elem;
access::rw(n_alloc) = new_n_alloc;
arma_debug_print("releasing old memory");
memory::release(old_mem_ptr);
}
}
}
template<typename eT>
template<uword fixed_n_rows, uword fixed_n_cols>
arma_inline
@@ -10585,6 +10746,66 @@ Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::memptr() const
template<typename eT>
template<uword fixed_n_rows, uword fixed_n_cols>
arma_inline
subview_row<eT>
Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::row(const uword row_num)
{
arma_debug_sigprint();
arma_conform_check_bounds( row_num >= fixed_n_rows, "Mat::row(): index out of bounds" );
return subview_row<eT>(*this, row_num);
}
template<typename eT>
template<uword fixed_n_rows, uword fixed_n_cols>
arma_inline
const subview_row<eT>
Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::row(const uword row_num) const
{
arma_debug_sigprint();
arma_conform_check_bounds( row_num >= fixed_n_rows, "Mat::row(): index out of bounds" );
return subview_row<eT>(*this, row_num);
}
template<typename eT>
template<uword fixed_n_rows, uword fixed_n_cols>
arma_inline
subview_col<eT>
Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::col(const uword col_num)
{
arma_debug_sigprint();
arma_conform_check_bounds( col_num >= fixed_n_cols, "Mat::col(): index out of bounds" );
return subview_col<eT>(*this, col_num);
}
template<typename eT>
template<uword fixed_n_rows, uword fixed_n_cols>
arma_inline
const subview_col<eT>
Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::col(const uword col_num) const
{
arma_debug_sigprint();
arma_conform_check_bounds( col_num >= fixed_n_cols, "Mat::col(): index out of bounds" );
return subview_col<eT>(*this, col_num);
}
template<typename eT>
template<uword fixed_n_rows, uword fixed_n_cols>
arma_inline
@@ -10798,8 +11019,8 @@ Mat_aux::set_real(Mat<eT>& out, const Base<eT,T1>& X)
{
arma_debug_sigprint();
const unwrap<T1> tmp(X.get_ref());
const Mat<eT>& A = tmp.M;
const plain_unwrap<T1> tmp(X.get_ref());
const Mat<eT>& A = tmp.M;
arma_conform_assert_same_size( out, A, "Mat::set_real()" );
+2
View File
@@ -26,6 +26,8 @@ struct OpCube : public BaseCube< typename T1::elem_type, OpCube<T1, op_type> >
typedef typename T1::elem_type elem_type;
typedef typename get_pod_type<elem_type>::result pod_type;
static constexpr bool has_subview = T1::has_subview;
inline explicit OpCube(const BaseCube<typename T1::elem_type, T1>& in_m);
inline OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const elem_type in_aux);
inline OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c);
+2
View File
@@ -50,6 +50,8 @@ struct Op
typedef typename T1::elem_type elem_type;
typedef typename get_pod_type<elem_type>::result pod_type;
static constexpr bool has_subview = T1::has_subview;
inline explicit Op(const T1& in_m);
inline Op(const T1& in_m, const elem_type in_aux);
inline Op(const T1& in_m, const elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b);
+7 -7
View File
@@ -1523,7 +1523,7 @@ struct Proxy_xtrans_default< Op<T1, op_htrans> >
static constexpr bool is_col = false;
static constexpr bool is_xvec = false;
const unwrap<T1> U;
const plain_unwrap<T1> U;
const xtrans_mat<elem_type,true> Q;
inline explicit Proxy_xtrans_default(const Op<T1, op_htrans>& A)
@@ -1537,7 +1537,7 @@ struct Proxy_xtrans_default< Op<T1, op_htrans> >
arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
template<typename eT2>
arma_inline bool is_alias(const Mat<eT2>& X) const { return void_ptr(&(U.M)) == void_ptr(&X); }
arma_inline bool is_alias(const Mat<eT2>& X) const { return U.is_alias(X); }
template<typename eT2>
arma_inline bool has_overlap(const subview<eT2>& X) const { return is_alias(X.m); }
@@ -1564,7 +1564,7 @@ struct Proxy_xtrans_default< Op<T1, op_strans> >
static constexpr bool is_col = false;
static constexpr bool is_xvec = false;
const unwrap<T1> U;
const plain_unwrap<T1> U;
const xtrans_mat<elem_type,false> Q;
inline explicit Proxy_xtrans_default(const Op<T1, op_strans>& A)
@@ -1578,7 +1578,7 @@ struct Proxy_xtrans_default< Op<T1, op_strans> >
arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
template<typename eT2>
arma_inline bool is_alias(const Mat<eT2>& X) const { return void_ptr(&(U.M)) == void_ptr(&X); }
arma_inline bool is_alias(const Mat<eT2>& X) const { return U.is_alias(X); }
template<typename eT2>
arma_inline bool has_overlap(const subview<eT2>& X) const { return is_alias(X.m); }
@@ -2419,8 +2419,8 @@ struct Proxy_vectorise_col_mat< Op<T1, op_vectorise_col> >
static constexpr bool is_col = true;
static constexpr bool is_xvec = false;
const unwrap<T1> U;
const Mat<elem_type> Q;
const plain_unwrap<T1> U;
const Mat<elem_type> Q;
inline explicit Proxy_vectorise_col_mat(const Op<T1, op_vectorise_col>& A)
: U(A.m)
@@ -2441,7 +2441,7 @@ struct Proxy_vectorise_col_mat< Op<T1, op_vectorise_col> >
arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
template<typename eT2>
arma_inline bool is_alias(const Mat<eT2>& X) const { return ( void_ptr(&X) == void_ptr(&(U.M)) ); }
arma_inline bool is_alias(const Mat<eT2>& X) const { return U.is_alias(X); }
template<typename eT2>
arma_inline bool has_overlap(const subview<eT2>& X) const { return is_alias(X.m); }
+7 -3
View File
@@ -33,6 +33,8 @@ class Row : public Mat<eT>
static constexpr bool is_row = true;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = false;
inline Row();
inline Row(const Row<eT>& X);
@@ -67,9 +69,6 @@ class Row : public Mat<eT>
inline Row(Row&& m);
inline Row& operator=(Row&& m);
// inline Row(Mat<eT>&& m);
// inline Row& operator=(Mat<eT>&& m);
inline Row& operator=(const eT val);
inline Row& operator=(const Row& X);
@@ -153,6 +152,7 @@ class Row : public Mat<eT>
arma_warn_unused arma_inline eT& at(const uword in_row, const uword in_col);
arma_warn_unused arma_inline const eT& at(const uword in_row, const uword in_col) const;
inline void push_back(const eT val);
inline constexpr bool is_vec() const { return true; }
inline constexpr bool is_rowvec() const { return true; }
@@ -213,6 +213,8 @@ class Row<eT>::fixed : public Row<eT>
static constexpr bool is_row = true;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = false;
static const uword n_rows; // value provided below the class definition
static const uword n_cols; // value provided below the class definition
static const uword n_elem; // value provided below the class definition
@@ -268,6 +270,8 @@ class Row<eT>::fixed : public Row<eT>
arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col);
arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col) const;
inline void push_back(const eT) = delete;
arma_warn_unused arma_inline eT* memptr();
arma_warn_unused arma_inline const eT* memptr() const;
+19 -58
View File
@@ -431,64 +431,6 @@ Row<eT>::operator=(Row<eT>&& X)
// template<typename eT>
// inline
// Row<eT>::Row(Mat<eT>&& X)
// : Mat<eT>(arma_vec_indicator(), 2)
// {
// arma_debug_sigprint(arma_str::format("this: %x; X: %x") % this % &X);
//
// if(X.n_rows != 1) { const Mat<eT>& XX = X; Mat<eT>::operator=(XX); return; }
//
// access::rw(Mat<eT>::n_rows) = 1;
// access::rw(Mat<eT>::n_cols) = X.n_cols;
// access::rw(Mat<eT>::n_elem) = X.n_elem;
// access::rw(Mat<eT>::n_alloc) = X.n_alloc;
//
// if( (X.n_alloc > arma_config::mat_prealloc) || (X.mem_state == 1) || (X.mem_state == 2) )
// {
// access::rw(Mat<eT>::mem_state) = X.mem_state;
// access::rw(Mat<eT>::mem) = X.mem;
//
// access::rw(X.n_cols) = 0;
// access::rw(X.n_elem) = 0;
// access::rw(X.n_alloc) = 0;
// access::rw(X.mem_state) = 0;
// access::rw(X.mem) = nullptr;
// }
// else // condition: (X.n_alloc <= arma_config::mat_prealloc) || (X.mem_state == 0) || (X.mem_state == 3)
// {
// (*this).init_cold();
//
// arrayops::copy( (*this).memptr(), X.mem, X.n_elem );
//
// if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) )
// {
// access::rw(X.n_cols) = 0;
// access::rw(X.n_elem) = 0;
// access::rw(X.mem) = nullptr;
// }
// }
// }
//
//
//
// template<typename eT>
// inline
// Row<eT>&
// Row<eT>::operator=(Mat<eT>&& X)
// {
// arma_debug_sigprint(arma_str::format("this: %x; X: %x") % this % &X);
//
// if(X.n_rows != 1) { const Mat<eT>& XX = X; Mat<eT>::operator=(XX); return *this; }
//
// (*this).steal_mem(X, true);
//
// return *this;
// }
template<typename eT>
inline
Row<eT>&
@@ -1208,6 +1150,25 @@ Row<eT>::at(const uword, const uword in_col) const
template<typename eT>
inline
void
Row<eT>::push_back(const eT val)
{
arma_debug_sigprint();
if(Mat<eT>::mem_state != 0)
{
arma_conform_check(true, "Row::push_back(): unsupported operation as auxiliary memory is in use");
return;
}
Mat<eT>::vec_push_back(val, arma_rowvec_indicator());
}
template<typename eT>
inline
typename Row<eT>::row_iterator
-2
View File
@@ -52,8 +52,6 @@ struct SpBase
{
arma_inline const derived& get_ref() const;
arma_inline bool is_alias(const SpMat<elem_type>& X) const;
arma_warn_unused inline const SpOp<derived,spop_htrans> t() const; //!< Hermitian transpose
arma_warn_unused inline const SpOp<derived,spop_htrans> ht() const; //!< Hermitian transpose
arma_warn_unused inline const SpOp<derived,spop_strans> st() const; //!< simple transpose
-10
View File
@@ -31,16 +31,6 @@ SpBase<elem_type,derived>::get_ref() const
template<typename elem_type, typename derived>
arma_inline
bool
SpBase<elem_type,derived>::is_alias(const SpMat<elem_type>& X) const
{
return (*this).get_ref().is_alias(X);
}
template<typename elem_type, typename derived>
inline
const SpOp<derived, spop_htrans>
+4 -1
View File
@@ -31,11 +31,14 @@ struct SpGlue : public SpBase< typename T1::elem_type, SpGlue<T1, T2, spglue_typ
static constexpr bool is_col = spglue_type::template traits<T1,T2>::is_col;
static constexpr bool is_xvec = spglue_type::template traits<T1,T2>::is_xvec;
static constexpr bool has_subview = T1::has_subview || T2::has_subview;
inline SpGlue(const T1& in_A, const T2& in_B);
inline SpGlue(const T1& in_A, const T2& in_B, const elem_type in_aux);
inline ~SpGlue();
arma_inline bool is_alias(const SpMat<elem_type>& X) const;
template<typename eT2>
arma_inline bool is_alias(const SpMat<eT2>& X) const;
const T1& A; //!< first operand; must be derived from SpBase
const T2& B; //!< second operand; must be derived from SpBase
+2 -1
View File
@@ -54,9 +54,10 @@ SpGlue<T1,T2,spglue_type>::~SpGlue()
template<typename T1, typename T2, typename spglue_type>
template<typename eT2>
arma_inline
bool
SpGlue<T1,T2,spglue_type>::is_alias(const SpMat<typename T1::elem_type>& X) const
SpGlue<T1,T2,spglue_type>::is_alias(const SpMat<eT2>& X) const
{
return (A.is_alias(X) || B.is_alias(X));
}
+4 -1
View File
@@ -33,6 +33,8 @@ class SpMat : public SpBase< eT, SpMat<eT> >
static constexpr bool is_col = false;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = false;
const uword n_rows; //!< number of rows (read-only)
const uword n_cols; //!< number of columns (read-only)
const uword n_elem; //!< number of elements (read-only)
@@ -647,7 +649,8 @@ class SpMat : public SpBase< eT, SpMat<eT> >
template<typename eT2, typename T1, typename Functor> inline void init_xform_mt(const SpBase<eT2,T1>& x, const Functor& func);
//! don't use this unless you're writing internal Armadillo code
arma_inline bool is_alias(const SpMat<eT>& X) const;
template<typename eT2>
arma_inline bool is_alias(const SpMat<eT2>& X) const;
protected:
+15 -4
View File
@@ -3565,7 +3565,7 @@ SpMat<eT>::is_symmetric(const typename get_pod_type<elem_type>::result tol) cons
if(tol == T(0)) { return (*this).is_symmetric(); }
arma_conform_check( ((tol >= T(0)) == false), "is_symmetric(): parameter 'tol' must be >= 0" );
arma_conform_check( ((tol >= T(0)) == false), "is_symmetric(): parameter 'tol' must be > 0" );
const SpMat<eT>& A = (*this);
@@ -3575,8 +3575,12 @@ SpMat<eT>::is_symmetric(const typename get_pod_type<elem_type>::result tol) cons
if(norm_A == T(0)) { return true; }
if(arma_isnan(norm_A)) { return false; }
const T norm_A_Ast = as_scalar( arma::max(sum(abs(A - A.st()), 1), 0) );
if(arma_isnan(norm_A_Ast)) { return false; }
return ( (norm_A_Ast / norm_A) <= tol );
}
@@ -3611,7 +3615,7 @@ SpMat<eT>::is_hermitian(const typename get_pod_type<elem_type>::result tol) cons
if(tol == T(0)) { return (*this).is_hermitian(); }
arma_conform_check( ((tol >= T(0)) == false), "is_hermitian(): parameter 'tol' must be >= 0" );
arma_conform_check( ((tol >= T(0)) == false), "is_hermitian(): parameter 'tol' must be > 0" );
const SpMat<eT>& A = (*this);
@@ -3621,8 +3625,12 @@ SpMat<eT>::is_hermitian(const typename get_pod_type<elem_type>::result tol) cons
if(norm_A == T(0)) { return true; }
if(arma_isnan(norm_A)) { return false; }
const T norm_A_At = as_scalar( arma::max(sum(abs(A - A.t()), 1), 0) );
if(arma_isnan(norm_A_At)) { return false; }
return ( (norm_A_At / norm_A) <= tol );
}
@@ -6007,11 +6015,14 @@ SpMat<eT>::init_xform_mt(const SpBase<eT2,T1>& A, const Functor& func)
template<typename eT>
template<typename eT2>
arma_inline
bool
SpMat<eT>::is_alias(const SpMat<eT>& X) const
SpMat<eT>::is_alias(const SpMat<eT2>& X) const
{
return (&X == this);
arma_debug_sigprint();
return (is_same_type<eT,eT2>::yes) && (void_ptr(this) == void_ptr(&X));
}
+4 -1
View File
@@ -31,12 +31,15 @@ struct SpOp : public SpBase< typename T1::elem_type, SpOp<T1, op_type> >
static constexpr bool is_col = op_type::template traits<T1>::is_col;
static constexpr bool is_xvec = op_type::template traits<T1>::is_xvec;
static constexpr bool has_subview = T1::has_subview;
inline explicit SpOp(const T1& in_m);
inline SpOp(const T1& in_m, const elem_type in_aux);
inline SpOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
inline ~SpOp();
arma_inline bool is_alias(const SpMat<elem_type>& X) const;
template<typename eT2>
arma_inline bool is_alias(const SpMat<eT2>& X) const;
const T1& m; //!< the operand; must be derived from SpBase
elem_type aux; //!< auxiliary data, using the element type as used by T1
+2 -1
View File
@@ -64,9 +64,10 @@ SpOp<T1, op_type>::~SpOp()
template<typename T1, typename op_type>
template<typename eT2>
arma_inline
bool
SpOp<T1, op_type>::is_alias(const SpMat<typename T1::elem_type>& X) const
SpOp<T1, op_type>::is_alias(const SpMat<eT2>& X) const
{
return m.is_alias(X);
}
+8 -1
View File
@@ -34,6 +34,8 @@ class SpSubview : public SpBase< eT, SpSubview<eT> >
static constexpr bool is_col = false;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = true;
const uword aux_row1;
const uword aux_col1;
const uword n_rows;
@@ -321,7 +323,8 @@ class SpSubview : public SpBase< eT, SpSubview<eT> >
inline const_row_iterator end_row(const uword row_num) const;
//! don't use this unless you're writing internal Armadillo code
arma_inline bool is_alias(const SpMat<eT>& X) const;
template<typename eT2>
arma_inline bool is_alias(const SpMat<eT2>& X) const;
private:
@@ -351,6 +354,8 @@ class SpSubview_col : public SpSubview<eT>
static constexpr bool is_col = true;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = true;
inline void operator= (const SpSubview<eT>& x);
inline void operator= (const SpSubview_col& x);
@@ -391,6 +396,8 @@ class SpSubview_row : public SpSubview<eT>
static constexpr bool is_col = false;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = true;
inline void operator= (const SpSubview<eT>& x);
inline void operator= (const SpSubview_row& x);
@@ -33,6 +33,8 @@ class SpSubview_col_list : public SpBase< eT, SpSubview_col_list<eT,T1> >
static constexpr bool is_col = false;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = true;
const SpMat<eT>& m;
const quasi_unwrap<T1> U_ci;
@@ -87,6 +89,8 @@ class SpSubview_col_list : public SpBase< eT, SpSubview_col_list<eT,T1> >
inline static void schur_inplace(SpMat<eT>& out, const SpSubview_col_list& in);
inline static void div_inplace(SpMat<eT>& out, const SpSubview_col_list& in);
template<typename eT2>
arma_inline bool is_alias(const SpMat<eT2>& X) const;
friend class SpMat<eT>;
};
@@ -714,4 +714,15 @@ SpSubview_col_list<eT,T1>::div_inplace(SpMat<eT>& out, const SpSubview_col_list&
template<typename eT, typename T1>
template<typename eT2>
arma_inline
bool
SpSubview_col_list<eT,T1>::is_alias(const SpMat<eT2>& X) const
{
return m.is_alias(X);
}
//! @}
+2 -1
View File
@@ -1786,9 +1786,10 @@ SpSubview<eT>::end_row(const uword row_num) const
template<typename eT>
template<typename eT2>
arma_inline
bool
SpSubview<eT>::is_alias(const SpMat<eT>& X) const
SpSubview<eT>::is_alias(const SpMat<eT2>& X) const
{
return m.is_alias(X);
}
@@ -31,6 +31,8 @@ struct SpToDGlue : public Base< typename T1::elem_type, SpToDGlue<T1, T2, glue_t
static constexpr bool is_col = glue_type::template traits<T1,T2>::is_col;
static constexpr bool is_xvec = glue_type::template traits<T1,T2>::is_xvec;
static constexpr bool has_subview = T1::has_subview || T2::has_subview;
inline explicit SpToDGlue(const T1& in_A, const T2& in_B);
inline ~SpToDGlue();
+2
View File
@@ -32,6 +32,8 @@ struct SpToDOp : public Base< typename T1::elem_type, SpToDOp<T1, op_type> >
static constexpr bool is_col = op_type::template traits<T1>::is_col;
static constexpr bool is_xvec = op_type::template traits<T1>::is_xvec;
static constexpr bool has_subview = T1::has_subview;
inline explicit SpToDOp(const T1& in_m);
inline SpToDOp(const T1& in_m, const elem_type in_aux);
inline SpToDOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
+8 -1
View File
@@ -286,8 +286,9 @@ template<typename T1> struct ProxyCube;
template<typename T1> struct diagmat_proxy;
template<typename T1> struct unwrap;
template<typename T1> struct plain_unwrap;
template<typename T1> struct quasi_unwrap;
template<typename T1> struct unwrap_cube;
template<typename T1> struct unwrap_spmat;
@@ -365,6 +366,12 @@ struct arma_zeros_indicator : public arma_initmode_indicator<true > {};
struct arma_nozeros_indicator : public arma_initmode_indicator<false> {};
template<int vec_mode> struct arma_vec_mode_indicator {};
struct arma_colvec_indicator : public arma_vec_mode_indicator<1> {};
struct arma_rowvec_indicator : public arma_vec_mode_indicator<2> {};
//! \addtogroup injector
//! @{
+3 -3
View File
@@ -22,9 +22,9 @@
#define ARMA_VERSION_MAJOR 15
#define ARMA_VERSION_MINOR 2
#define ARMA_VERSION_PATCH 5
#define ARMA_VERSION_NAME "Medium Roast Deluxe"
#define ARMA_VERSION_MINOR 4
#define ARMA_VERSION_PATCH 2
#define ARMA_VERSION_NAME "Medium Roast Agave"
+10 -10
View File
@@ -2932,8 +2932,8 @@ auxlib::qr_econ(Mat<eT>& Q, Mat<eT>& R, const Base<eT,T1>& X)
{
if(is_Mat<T1>::value)
{
const unwrap<T1> tmp(X.get_ref());
const Mat<eT>& M = tmp.M;
const plain_unwrap<T1> tmp(X.get_ref());
const Mat<eT>& M = tmp.M;
if(M.n_rows < M.n_cols) { return auxlib::qr(Q, R, X); }
}
@@ -5160,8 +5160,8 @@ auxlib::solve_rect_fast(Mat<typename T1::elem_type>& out, Mat<typename T1::elem_
{
typedef typename T1::elem_type eT;
const unwrap<T1> U(B_expr.get_ref());
const Mat<eT>& B = U.M;
const plain_unwrap<T1> U(B_expr.get_ref());
const Mat<eT>& B = U.M;
arma_conform_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" );
@@ -5254,8 +5254,8 @@ auxlib::solve_rect_rcond(Mat<typename T1::elem_type>& out, typename T1::pod_type
out_rcond = T(0);
const unwrap<T1> U(B_expr.get_ref());
const Mat<eT>& B = U.M;
const plain_unwrap<T1> U(B_expr.get_ref());
const Mat<eT>& B = U.M;
arma_conform_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" );
@@ -5387,8 +5387,8 @@ auxlib::solve_approx_svd(Mat<typename T1::pod_type>& out, Mat<typename T1::pod_t
{
typedef typename T1::pod_type eT;
const unwrap<T1> U(B_expr.get_ref());
const Mat<eT>& B = U.M;
const plain_unwrap<T1> U(B_expr.get_ref());
const Mat<eT>& B = U.M;
arma_conform_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" );
@@ -5509,8 +5509,8 @@ auxlib::solve_approx_svd(Mat< std::complex<typename T1::pod_type> >& out, Mat< s
typedef typename T1::pod_type T;
typedef typename std::complex<T> eT;
const unwrap<T1> U(B_expr.get_ref());
const Mat<eT>& B = U.M;
const plain_unwrap<T1> U(B_expr.get_ref());
const Mat<eT>& B = U.M;
arma_conform_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" );
@@ -35,6 +35,8 @@ class diagview : public Base< eT, diagview<eT> >
static constexpr bool is_col = true;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = true;
const uword row_offset;
const uword col_offset;
+4 -3
View File
@@ -399,9 +399,10 @@ diskio::gen_tmp_name(const std::string& x)
for(std::size_t i=0; i < suffix1_length; ++i, ++count) { out[count] = suffix1[i]; }
local_distr(local_engine); // ignore first random number
const std::size_t junk = local_distr(local_engine); // ignore first random number
arma_ignore(junk);
for(std::size_t i=0; i < suffix2_length; ++i, ++count) { out[count] = charlist[ local_distr(local_engine)]; }
for(std::size_t i=0; i < suffix2_length; ++i, ++count) { out[count] = charlist[ local_distr(local_engine) ]; }
return out;
}
@@ -1864,7 +1865,7 @@ diskio::load_csv_ascii(Mat<eT>& x, std::istream& f, std::string& err_msg, const
try { x.zeros(f_n_rows, f_n_cols); } catch(...) { err_msg = "not enough memory"; return false; }
if(strict) { x.fill(Datum<eT>::nan); } // take into account that each row may have a unique number of columns
if(strict && is_real<eT>::yes) { x.fill(Datum<eT>::nan); } // take into account that each row may have a unique number of columns
const bool use_mp = (arma_config::openmp) && (f_n_rows >= 2) && (f_n_cols >= 64);
+30 -20
View File
@@ -265,6 +265,7 @@ eglue_core<eglue_type>::apply(outT& out, const eGlue<T1, T2, eglue_type>& x)
constexpr bool use_at = (Proxy<T1>::use_at || Proxy<T2>::use_at);
constexpr bool use_mp = (Proxy<T1>::use_mp || Proxy<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (Proxy<T1>::use_mp && Proxy<T2>::use_mp);
// NOTE: we're assuming that the matrix has already been set to the correct size and there is no aliasing;
// size setting and alias checking is done by either the Mat constructor or operator=()
@@ -276,7 +277,7 @@ eglue_core<eglue_type>::apply(outT& out, const eGlue<T1, T2, eglue_type>& x)
{
const uword n_elem = x.get_n_elem();
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
@@ -333,7 +334,7 @@ eglue_core<eglue_type>::apply(outT& out, const eGlue<T1, T2, eglue_type>& x)
const Proxy<T1>& P1 = x.P1;
const Proxy<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_2_mp(=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_2_mp(=, -); }
@@ -371,12 +372,13 @@ eglue_core<eglue_type>::apply_inplace_plus(Mat<typename T1::elem_type>& out, con
constexpr bool use_at = (Proxy<T1>::use_at || Proxy<T2>::use_at);
constexpr bool use_mp = (Proxy<T1>::use_mp || Proxy<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (Proxy<T1>::use_mp && Proxy<T2>::use_mp);
if(use_at == false)
{
const uword n_elem = x.get_n_elem();
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
@@ -430,7 +432,7 @@ eglue_core<eglue_type>::apply_inplace_plus(Mat<typename T1::elem_type>& out, con
const Proxy<T1>& P1 = x.P1;
const Proxy<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_2_mp(+=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_2_mp(+=, -); }
@@ -468,12 +470,13 @@ eglue_core<eglue_type>::apply_inplace_minus(Mat<typename T1::elem_type>& out, co
constexpr bool use_at = (Proxy<T1>::use_at || Proxy<T2>::use_at);
constexpr bool use_mp = (Proxy<T1>::use_mp || Proxy<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (Proxy<T1>::use_mp && Proxy<T2>::use_mp);
if(use_at == false)
{
const uword n_elem = x.get_n_elem();
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
@@ -527,7 +530,7 @@ eglue_core<eglue_type>::apply_inplace_minus(Mat<typename T1::elem_type>& out, co
const Proxy<T1>& P1 = x.P1;
const Proxy<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_2_mp(-=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_2_mp(-=, -); }
@@ -565,12 +568,13 @@ eglue_core<eglue_type>::apply_inplace_schur(Mat<typename T1::elem_type>& out, co
constexpr bool use_at = (Proxy<T1>::use_at || Proxy<T2>::use_at);
constexpr bool use_mp = (Proxy<T1>::use_mp || Proxy<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (Proxy<T1>::use_mp && Proxy<T2>::use_mp);
if(use_at == false)
{
const uword n_elem = x.get_n_elem();
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
@@ -624,7 +628,7 @@ eglue_core<eglue_type>::apply_inplace_schur(Mat<typename T1::elem_type>& out, co
const Proxy<T1>& P1 = x.P1;
const Proxy<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_2_mp(*=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_2_mp(*=, -); }
@@ -662,12 +666,13 @@ eglue_core<eglue_type>::apply_inplace_div(Mat<typename T1::elem_type>& out, cons
constexpr bool use_at = (Proxy<T1>::use_at || Proxy<T2>::use_at);
constexpr bool use_mp = (Proxy<T1>::use_mp || Proxy<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (Proxy<T1>::use_mp && Proxy<T2>::use_mp);
if(use_at == false)
{
const uword n_elem = x.get_n_elem();
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
@@ -721,7 +726,7 @@ eglue_core<eglue_type>::apply_inplace_div(Mat<typename T1::elem_type>& out, cons
const Proxy<T1>& P1 = x.P1;
const Proxy<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_2_mp(/=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_2_mp(/=, -); }
@@ -757,6 +762,7 @@ eglue_core<eglue_type>::apply(Cube<typename T1::elem_type>& out, const eGlueCube
constexpr bool use_at = (ProxyCube<T1>::use_at || ProxyCube<T2>::use_at);
constexpr bool use_mp = (ProxyCube<T1>::use_mp || ProxyCube<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp);
// NOTE: we're assuming that the cube has already been set to the correct size and there is no aliasing;
// size setting and alias checking is done by either the Cube constructor or operator=()
@@ -768,7 +774,7 @@ eglue_core<eglue_type>::apply(Cube<typename T1::elem_type>& out, const eGlueCube
{
const uword n_elem = out.n_elem;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
@@ -826,7 +832,7 @@ eglue_core<eglue_type>::apply(Cube<typename T1::elem_type>& out, const eGlueCube
const ProxyCube<T1>& P1 = x.P1;
const ProxyCube<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_3_mp(=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_3_mp(=, -); }
@@ -865,12 +871,13 @@ eglue_core<eglue_type>::apply_inplace_plus(Cube<typename T1::elem_type>& out, co
constexpr bool use_at = (ProxyCube<T1>::use_at || ProxyCube<T2>::use_at);
constexpr bool use_mp = (ProxyCube<T1>::use_mp || ProxyCube<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp);
if(use_at == false)
{
const uword n_elem = out.n_elem;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
@@ -924,7 +931,7 @@ eglue_core<eglue_type>::apply_inplace_plus(Cube<typename T1::elem_type>& out, co
const ProxyCube<T1>& P1 = x.P1;
const ProxyCube<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_3_mp(+=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_3_mp(+=, -); }
@@ -963,12 +970,13 @@ eglue_core<eglue_type>::apply_inplace_minus(Cube<typename T1::elem_type>& out, c
constexpr bool use_at = (ProxyCube<T1>::use_at || ProxyCube<T2>::use_at);
constexpr bool use_mp = (ProxyCube<T1>::use_mp || ProxyCube<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp);
if(use_at == false)
{
const uword n_elem = out.n_elem;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
@@ -1022,7 +1030,7 @@ eglue_core<eglue_type>::apply_inplace_minus(Cube<typename T1::elem_type>& out, c
const ProxyCube<T1>& P1 = x.P1;
const ProxyCube<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_3_mp(-=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_3_mp(-=, -); }
@@ -1061,12 +1069,13 @@ eglue_core<eglue_type>::apply_inplace_schur(Cube<typename T1::elem_type>& out, c
constexpr bool use_at = (ProxyCube<T1>::use_at || ProxyCube<T2>::use_at);
constexpr bool use_mp = (ProxyCube<T1>::use_mp || ProxyCube<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp);
if(use_at == false)
{
const uword n_elem = out.n_elem;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
@@ -1120,7 +1129,7 @@ eglue_core<eglue_type>::apply_inplace_schur(Cube<typename T1::elem_type>& out, c
const ProxyCube<T1>& P1 = x.P1;
const ProxyCube<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_3_mp(*=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_3_mp(*=, -); }
@@ -1159,12 +1168,13 @@ eglue_core<eglue_type>::apply_inplace_div(Cube<typename T1::elem_type>& out, con
constexpr bool use_at = (ProxyCube<T1>::use_at || ProxyCube<T2>::use_at);
constexpr bool use_mp = (ProxyCube<T1>::use_mp || ProxyCube<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp);
if(use_at == false)
{
const uword n_elem = out.n_elem;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
@@ -1218,7 +1228,7 @@ eglue_core<eglue_type>::apply_inplace_div(Cube<typename T1::elem_type>& out, con
const ProxyCube<T1>& P1 = x.P1;
const ProxyCube<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_3_mp(/=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_3_mp(/=, -); }
+17 -2
View File
@@ -94,7 +94,9 @@ field<oT>::field(const subview_field<oT>& X)
{
arma_debug_sigprint_this(this);
(*this).operator=(X);
init(X.n_rows, X.n_cols, X.n_slices);
subview_field<oT>::extract(*this, X);
}
@@ -107,7 +109,20 @@ field<oT>::operator=(const subview_field<oT>& X)
{
arma_debug_sigprint();
subview_field<oT>::extract(*this, X);
const bool alias = (this == &(X.f));
if(alias == false)
{
(*this).init(X.n_rows, X.n_cols, X.n_slices);
subview_field<oT>::extract(*this, X);
}
else
{
field<oT> tmp(X);
(*this).operator=(std::move(tmp));
}
return *this;
}
+2 -2
View File
@@ -281,8 +281,8 @@ as_scalar_diag(const Base<typename T1::elem_type,T1>& X)
typedef typename T1::elem_type eT;
const unwrap<T1> tmp(X.get_ref());
const Mat<eT>& A = tmp.M;
const plain_unwrap<T1> tmp(X.get_ref());
const Mat<eT>& A = tmp.M;
arma_conform_check_bounds( (A.n_elem != 1), "as_scalar(): expected 1x1 matrix" );
+282 -52
View File
@@ -21,6 +21,276 @@
template<typename in_eT>
struct conv_to_helper_Mat_same_type
{
template<typename T1>
inline
static
Mat<in_eT>
apply(const Base<in_eT, T1>& in)
{
arma_debug_sigprint();
return Mat<in_eT>(in.get_ref());
}
inline
static
Mat<in_eT>
apply(const std::vector<in_eT>& in)
{
arma_debug_sigprint();
const uword N = uword( in.size() );
const in_eT* in_memptr = (N > 0) ? &(in[0]) : nullptr;
return Mat<in_eT>(in_memptr, N, 1);
}
};
template<typename out_eT, typename in_eT>
struct conv_to_helper_Mat_diff_type
{
template<typename T1>
inline
static
Mat<out_eT>
apply(const Base<in_eT, T1>& in)
{
arma_debug_sigprint();
const quasi_unwrap<T1> tmp(in.get_ref());
const Mat<in_eT>& X = tmp.M;
Mat<out_eT> out(X.n_rows, X.n_cols, arma_nozeros_indicator());
arrayops::convert( out.memptr(), X.memptr(), X.n_elem );
return out;
}
inline
static
Mat<out_eT>
apply(const std::vector<in_eT>& in)
{
arma_debug_sigprint();
const uword N = uword( in.size() );
Mat<out_eT> out(N, 1, arma_nozeros_indicator());
if(N > 0) { arrayops::convert( out.memptr(), &(in[0]), N ); }
return out;
}
};
template<typename out_eT, typename in_eT, bool condition>
struct conv_to_helper_Mat_redirect {};
template<typename out_eT, typename in_eT>
struct conv_to_helper_Mat_redirect<out_eT, in_eT, true > { typedef conv_to_helper_Mat_same_type<in_eT> result; };
template<typename out_eT, typename in_eT>
struct conv_to_helper_Mat_redirect<out_eT, in_eT, false> { typedef conv_to_helper_Mat_diff_type<out_eT, in_eT> result; };
template<typename in_eT>
struct conv_to_helper_Row_same_type
{
template<typename T1>
inline
static
Row<in_eT>
apply(const Base<in_eT, T1>& in)
{
arma_debug_sigprint();
Mat<in_eT> X(in.get_ref());
arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" );
access::rw(X.n_rows ) = uword(1);
access::rw(X.n_cols ) = X.n_elem;
access::rw(X.vec_state) = uword(2);
Row<in_eT> out; out.steal_mem(X);
return out;
}
inline
static
Row<in_eT>
apply(const std::vector<in_eT>& in)
{
arma_debug_sigprint();
const uword N = uword( in.size() );
const in_eT* in_memptr = (N > 0) ? &(in[0]) : nullptr;
return Row<in_eT>(in_memptr, N);
}
};
template<typename out_eT, typename in_eT>
struct conv_to_helper_Row_diff_type
{
template<typename T1>
inline
static
Row<out_eT>
apply(const Base<in_eT, T1>& in)
{
arma_debug_sigprint();
const quasi_unwrap<T1> tmp(in.get_ref());
const Mat<in_eT>& X = tmp.M;
arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" );
Row<out_eT> out(X.n_elem, arma_nozeros_indicator());
arrayops::convert( out.memptr(), X.memptr(), X.n_elem );
return out;
}
inline
static
Row<out_eT>
apply(const std::vector<in_eT>& in)
{
arma_debug_sigprint();
const uword N = uword( in.size() );
Row<out_eT> out(N, arma_nozeros_indicator());
if(N > 0) { arrayops::convert( out.memptr(), &(in[0]), N ); }
return out;
}
};
template<typename out_eT, typename in_eT, bool condition>
struct conv_to_helper_Row_redirect {};
template<typename out_eT, typename in_eT>
struct conv_to_helper_Row_redirect<out_eT, in_eT, true > { typedef conv_to_helper_Row_same_type<in_eT> result; };
template<typename out_eT, typename in_eT>
struct conv_to_helper_Row_redirect<out_eT, in_eT, false> { typedef conv_to_helper_Row_diff_type<out_eT, in_eT> result; };
template<typename in_eT>
struct conv_to_helper_Col_same_type
{
template<typename T1>
inline
static
Col<in_eT>
apply(const Base<in_eT, T1>& in)
{
arma_debug_sigprint();
Mat<in_eT> X(in.get_ref());
arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" );
access::rw(X.n_rows ) = X.n_elem;
access::rw(X.n_cols ) = uword(1);
access::rw(X.vec_state) = uword(1);
Col<in_eT> out; out.steal_mem(X);
return out;
}
inline
static
Col<in_eT>
apply(const std::vector<in_eT>& in)
{
arma_debug_sigprint();
const uword N = uword( in.size() );
const in_eT* in_memptr = (N > 0) ? &(in[0]) : nullptr;
return Col<in_eT>(in_memptr, N);
}
};
template<typename out_eT, typename in_eT>
struct conv_to_helper_Col_diff_type
{
template<typename T1>
inline
static
Col<out_eT>
apply(const Base<in_eT, T1>& in)
{
arma_debug_sigprint();
const quasi_unwrap<T1> tmp(in.get_ref());
const Mat<in_eT>& X = tmp.M;
arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" );
Col<out_eT> out(X.n_elem, arma_nozeros_indicator());
arrayops::convert( out.memptr(), X.memptr(), X.n_elem );
return out;
}
inline
static
Col<out_eT>
apply(const std::vector<in_eT>& in)
{
arma_debug_sigprint();
const uword N = uword( in.size() );
Col<out_eT> out(N, arma_nozeros_indicator());
if(N > 0) { arrayops::convert( out.memptr(), &(in[0]), N ); }
return out;
}
};
template<typename out_eT, typename in_eT, bool condition>
struct conv_to_helper_Col_redirect {};
template<typename out_eT, typename in_eT>
struct conv_to_helper_Col_redirect<out_eT, in_eT, true > { typedef conv_to_helper_Col_same_type<in_eT> result; };
template<typename out_eT, typename in_eT>
struct conv_to_helper_Col_redirect<out_eT, in_eT, false> { typedef conv_to_helper_Col_diff_type<out_eT, in_eT> result; };
//! conversion from Armadillo Base and BaseCube objects to scalars
//! NOTE: use as_scalar() instead; this functionality is kept only for compatibility with old user code
template<typename out_eT>
@@ -195,14 +465,9 @@ conv_to< Mat<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_not_
arma_debug_sigprint();
arma_ignore(junk);
const quasi_unwrap<T1> tmp(in.get_ref());
const Mat<in_eT>& X = tmp.M;
typedef typename conv_to_helper_Mat_redirect<out_eT, in_eT, is_same_type<out_eT, in_eT>::value>::result helper_type;
Mat<out_eT> out(X.n_rows, X.n_cols, arma_nozeros_indicator());
arrayops::convert( out.memptr(), X.memptr(), X.n_elem );
return out;
return helper_type::apply(in.get_ref());
}
@@ -297,16 +562,9 @@ conv_to< Mat<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_n
arma_debug_sigprint();
arma_ignore(junk);
const uword N = uword( in.size() );
typedef typename conv_to_helper_Mat_redirect<out_eT, in_eT, is_same_type<out_eT, in_eT>::value>::result helper_type;
Mat<out_eT> out(N, 1, arma_nozeros_indicator());
if(N > 0)
{
arrayops::convert( out.memptr(), &(in[0]), N );
}
return out;
return helper_type::apply(in);
}
@@ -366,16 +624,9 @@ conv_to< Row<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_not_
arma_debug_sigprint();
arma_ignore(junk);
const quasi_unwrap<T1> tmp(in.get_ref());
const Mat<in_eT>& X = tmp.M;
typedef typename conv_to_helper_Row_redirect<out_eT, in_eT, is_same_type<out_eT, in_eT>::value>::result helper_type;
arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" );
Row<out_eT> out(X.n_elem, arma_nozeros_indicator());
arrayops::convert( out.memptr(), X.memptr(), X.n_elem );
return out;
return helper_type::apply(in.get_ref());
}
@@ -414,16 +665,9 @@ conv_to< Row<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_n
arma_debug_sigprint();
arma_ignore(junk);
const uword N = uword( in.size() );
typedef typename conv_to_helper_Row_redirect<out_eT, in_eT, is_same_type<out_eT, in_eT>::value>::result helper_type;
Row<out_eT> out(N, arma_nozeros_indicator());
if(N > 0)
{
arrayops::convert( out.memptr(), &(in[0]), N );
}
return out;
return helper_type::apply(in);
}
@@ -483,16 +727,9 @@ conv_to< Col<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_not_
arma_debug_sigprint();
arma_ignore(junk);
const quasi_unwrap<T1> tmp(in.get_ref());
const Mat<in_eT>& X = tmp.M;
typedef typename conv_to_helper_Col_redirect<out_eT, in_eT, is_same_type<out_eT, in_eT>::value>::result helper_type;
arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" );
Col<out_eT> out(X.n_elem, arma_nozeros_indicator());
arrayops::convert( out.memptr(), X.memptr(), X.n_elem );
return out;
return helper_type::apply(in.get_ref());
}
@@ -531,16 +768,9 @@ conv_to< Col<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_n
arma_debug_sigprint();
arma_ignore(junk);
const uword N = uword( in.size() );
typedef typename conv_to_helper_Col_redirect<out_eT, in_eT, is_same_type<out_eT, in_eT>::value>::result helper_type;
Col<out_eT> out(N, arma_nozeros_indicator());
if(N > 0)
{
arrayops::convert( out.memptr(), &(in[0]), N );
}
return out;
return helper_type::apply(in);
}
+4 -4
View File
@@ -28,13 +28,13 @@ typename
enable_if2
<
is_arma_type<T1>::value,
const mtOp<uword, T1, op_find_simple>
const mtOp<uword, T1, op_find_default>
>::result
find(const T1& X)
{
arma_debug_sigprint();
return mtOp<uword, T1, op_find_simple>(X);
return mtOp<uword, T1, op_find_default>(X);
}
@@ -42,7 +42,7 @@ find(const T1& X)
template<typename T1>
arma_warn_unused
inline
const mtOp<uword, T1, op_find>
const mtOp<uword, T1, op_find_generic>
find(const Base<typename T1::elem_type,T1>& X, const uword k, const char* direction = "first")
{
arma_debug_sigprint();
@@ -57,7 +57,7 @@ find(const Base<typename T1::elem_type,T1>& X, const uword k, const char* direct
const uword type = ( (sig == 'f') || (sig == 'F') ) ? 0 : 1;
return mtOp<uword, T1, op_find>(X.get_ref(), k, type);
return mtOp<uword, T1, op_find_generic>(X.get_ref(), k, type);
}
+1 -1
View File
@@ -63,7 +63,7 @@ inv
template<typename T1>
arma_warn_unused
arma_inline
inline
typename enable_if2< is_blas_type<typename T1::elem_type>::value, const Op<T1, op_inv_gen_full> >::result
inv
(
+1 -1
View File
@@ -63,7 +63,7 @@ inv_sympd
template<typename T1>
arma_warn_unused
arma_inline
inline
typename enable_if2< is_blas_type<typename T1::elem_type>::value, const Op<T1, op_inv_spd_full> >::result
inv_sympd
(
+2 -2
View File
@@ -78,7 +78,7 @@ pow
template<typename eT, typename T2>
[[deprecated]]
[[deprecated("refactor your code to use pow() in conjunction with repcube()")]]
inline
Cube<eT>
pow
@@ -160,7 +160,7 @@ pow
template<typename T, typename T2>
[[deprecated]]
[[deprecated("refactor your code to use pow() in conjunction with repcube()")]]
inline
Cube< std::complex<T> >
pow
+3 -3
View File
@@ -97,9 +97,9 @@ sylvester
typedef typename T1::elem_type eT;
const unwrap<T1> tmp_A( in_A.get_ref() );
const unwrap<T2> tmp_B( in_B.get_ref() );
const unwrap<T3> tmp_C( in_C.get_ref() );
const plain_unwrap<T1> tmp_A( in_A.get_ref() );
const plain_unwrap<T2> tmp_B( in_B.get_ref() );
const plain_unwrap<T3> tmp_C( in_C.get_ref() );
const Mat<eT>& A = tmp_A.M;
const Mat<eT>& B = tmp_B.M;
+6 -6
View File
@@ -48,7 +48,7 @@ trimatl(const Base<typename T1::elem_type,T1>& X)
template<typename T1>
arma_warn_unused
arma_inline
inline
const SpOp<T1, spop_trimat>
trimatu(const SpBase<typename T1::elem_type,T1>& X)
{
@@ -61,7 +61,7 @@ trimatu(const SpBase<typename T1::elem_type,T1>& X)
template<typename T1>
arma_warn_unused
arma_inline
inline
const SpOp<T1, spop_trimat>
trimatl(const SpBase<typename T1::elem_type,T1>& X)
{
@@ -78,7 +78,7 @@ trimatl(const SpBase<typename T1::elem_type,T1>& X)
template<typename T1>
arma_warn_unused
arma_inline
inline
const Op<T1, op_trimatl_ext>
trimatl(const Base<typename T1::elem_type,T1>& X, const sword k)
{
@@ -94,7 +94,7 @@ trimatl(const Base<typename T1::elem_type,T1>& X, const sword k)
template<typename T1>
arma_warn_unused
arma_inline
inline
const Op<T1, op_trimatu_ext>
trimatu(const Base<typename T1::elem_type,T1>& X, const sword k)
{
@@ -110,7 +110,7 @@ trimatu(const Base<typename T1::elem_type,T1>& X, const sword k)
template<typename T1>
arma_warn_unused
arma_inline
inline
const SpOp<T1, spop_trimatu_ext>
trimatu(const SpBase<typename T1::elem_type,T1>& X, const sword k)
{
@@ -126,7 +126,7 @@ trimatu(const SpBase<typename T1::elem_type,T1>& X, const sword k)
template<typename T1>
arma_warn_unused
arma_inline
inline
const SpOp<T1, spop_trimatl_ext>
trimatl(const SpBase<typename T1::elem_type,T1>& X, const sword k)
{
+2 -2
View File
@@ -103,8 +103,8 @@ glue_atan2::apply_noalias(Mat<typename T1::elem_type>& out, const Proxy<T1>& P1,
{
if(use_mp)
{
const unwrap<typename Proxy<T1>::stored_type> U1(P1.Q);
const unwrap<typename Proxy<T2>::stored_type> U2(P2.Q);
const plain_unwrap<typename Proxy<T1>::stored_type> U1(P1.Q);
const plain_unwrap<typename Proxy<T2>::stored_type> U2(P2.Q);
out = arma::atan2(U1.M, U2.M);
}
+2 -2
View File
@@ -32,8 +32,8 @@ glue_cor::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_cor>& X)
const uword norm_type = X.aux_uword;
const unwrap<T1> UA(X.A);
const unwrap<T2> UB(X.B);
const plain_unwrap<T1> UA(X.A);
const plain_unwrap<T2> UB(X.B);
const Mat<eT>& A = UA.M;
const Mat<eT>& B = UB.M;
+2 -2
View File
@@ -32,8 +32,8 @@ glue_cov::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_cov>& X)
const uword norm_type = X.aux_uword;
const unwrap<T1> UA(X.A);
const unwrap<T2> UB(X.B);
const plain_unwrap<T1> UA(X.A);
const plain_unwrap<T2> UB(X.B);
const Mat<eT>& A = UA.M;
const Mat<eT>& B = UB.M;
+33 -5
View File
@@ -75,13 +75,41 @@ glue_max::apply(Mat<eT>& out, const Proxy<T1>& PA, const Proxy<T2>& PB)
const uword N = PA.get_n_elem();
for(uword i=0; i<N; ++i)
#if defined(ARMA_SIMPLE_LOOPS)
{
const eT Ai = A[i];
const eT Bi = B[i];
out_mem[i] = comparator(Ai,Bi) ? Ai : Bi;
for(uword i=0; i<N; ++i)
{
const eT Ai = A[i];
const eT Bi = B[i];
out_mem[i] = comparator(Ai,Bi) ? Ai : Bi;
}
}
#else
{
uword i,j;
for(i=0, j=1; j < N; i+=2, j+=2)
{
const eT Ai = A[i];
const eT Aj = A[j];
const eT Bi = B[i];
const eT Bj = B[j];
(*out_mem) = comparator(Ai,Bi) ? Ai : Bi; ++out_mem;
(*out_mem) = comparator(Aj,Bj) ? Aj : Bj; ++out_mem;
}
if(i < N)
{
const eT Ai = A[i];
const eT Bi = B[i];
(*out_mem) = comparator(Ai,Bi) ? Ai : Bi;
}
}
#endif
}
else
{
+33 -5
View File
@@ -75,13 +75,41 @@ glue_min::apply(Mat<eT>& out, const Proxy<T1>& PA, const Proxy<T2>& PB)
const uword N = PA.get_n_elem();
for(uword i=0; i<N; ++i)
#if defined(ARMA_SIMPLE_LOOPS)
{
const eT Ai = A[i];
const eT Bi = B[i];
out_mem[i] = comparator(Ai,Bi) ? Ai : Bi;
for(uword i=0; i<N; ++i)
{
const eT Ai = A[i];
const eT Bi = B[i];
out_mem[i] = comparator(Ai,Bi) ? Ai : Bi;
}
}
#else
{
uword i,j;
for(i=0, j=1; j < N; i+=2, j+=2)
{
const eT Ai = A[i];
const eT Aj = A[j];
const eT Bi = B[i];
const eT Bj = B[j];
(*out_mem) = comparator(Ai,Bi) ? Ai : Bi; ++out_mem;
(*out_mem) = comparator(Aj,Bj) ? Aj : Bj; ++out_mem;
}
if(i < N)
{
const eT Ai = A[i];
const eT Bi = B[i];
(*out_mem) = comparator(Ai,Bi) ? Ai : Bi;
}
}
#endif
}
else
{
@@ -30,6 +30,7 @@ struct glue_powext
template<typename eT> inline static void apply(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B);
// TODO: deprecated; remove in next major version
template<typename parent, unsigned int mode, typename T2> inline static Mat<typename parent::elem_type> apply(const subview_each1<parent,mode>& X, const Base<typename parent::elem_type,T2>& Y);
//
@@ -38,6 +39,7 @@ struct glue_powext
template<typename eT> inline static void apply(Cube<eT>& out, const Cube<eT>& A, const Cube<eT>& B);
// TODO: deprecated; remove in next major version
template<typename eT, typename T2> inline static Cube<eT> apply(const subview_cube_each1<eT>& X, const Base<eT,T2>& Y);
};
@@ -50,6 +52,7 @@ struct glue_powext_cx
template<typename T> inline static void apply(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const Mat<T>& B);
// TODO: deprecated; remove in next major version
template<typename parent, unsigned int mode, typename T2> inline static Mat<typename parent::elem_type> apply(const subview_each1<parent,mode>& X, const Base<typename T2::elem_type,T2>& Y);
//
@@ -58,6 +61,7 @@ struct glue_powext_cx
template<typename T> inline static void apply(Cube< std::complex<T> >& out, const Cube< std::complex<T> >& A, const Cube<T>& B);
// TODO: deprecated; remove in next major version
template<typename T, typename T2> inline static Cube< std::complex<T> > apply(const subview_cube_each1< std::complex<T> >& X, const Base<T,T2>& Y);
};
@@ -97,6 +97,7 @@ glue_powext::apply(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B)
// TODO: deprecated; remove in next major version
template<typename parent, unsigned int mode, typename T2>
inline
Mat<typename parent::elem_type>
@@ -280,6 +281,7 @@ glue_powext::apply(Cube<eT>& out, const Cube<eT>& A, const Cube<eT>& B)
// TODO: deprecated; remove in next major version
template<typename eT, typename T2>
inline
Cube<eT>
@@ -426,6 +428,7 @@ glue_powext_cx::apply(Mat< std::complex<T> >& out, const Mat< std::complex<T> >&
// TODO: deprecated; remove in next major version
template<typename parent, unsigned int mode, typename T2>
inline
Mat<typename parent::elem_type>
@@ -603,6 +606,7 @@ glue_powext_cx::apply(Cube< std::complex<T> >& out, const Cube< std::complex<T>
// TODO: deprecated; remove in next major version
template<typename T, typename T2>
inline
Cube< std::complex<T> >
+4 -4
View File
@@ -109,11 +109,11 @@ glue_times_redirect2_helper<true, check_alias>::apply(Mat<typename T1::elem_type
if( (is_cx<eT>::no) && (strip_inv<T1>::do_inv_gen) && (is_Mat<T1_stripped>::value) && (is_Mat<T2>::value) )
{
const unwrap<T1_stripped> UA(A_strip.M);
const unwrap<T2 > UB(X.B);
const plain_unwrap<T1_stripped> UA(A_strip.M);
const plain_unwrap<T2 > UB(X.B);
const typename unwrap<T1_stripped>::stored_type& A = UA.M;
const typename unwrap<T2 >::stored_type& B = UB.M;
const typename plain_unwrap<T1_stripped>::stored_type& A = UA.M;
const typename plain_unwrap<T2 >::stored_type& B = UB.M;
const uword N = A.n_rows;
+14 -14
View File
@@ -137,9 +137,9 @@ gmm_diag<eT>::set_params(const Base<eT,T1>& in_means_expr, const Base<eT,T2>& in
{
arma_debug_sigprint();
const unwrap<T1> tmp1(in_means_expr.get_ref());
const unwrap<T2> tmp2(in_dcovs_expr.get_ref());
const unwrap<T3> tmp3(in_hefts_expr.get_ref());
const plain_unwrap<T1> tmp1(in_means_expr.get_ref());
const plain_unwrap<T2> tmp2(in_dcovs_expr.get_ref());
const plain_unwrap<T3> tmp3(in_hefts_expr.get_ref());
const Mat<eT>& in_means = tmp1.M;
const Mat<eT>& in_dcovs = tmp2.M;
@@ -179,7 +179,7 @@ gmm_diag<eT>::set_means(const Base<eT,T1>& in_means_expr)
{
arma_debug_sigprint();
const unwrap<T1> tmp(in_means_expr.get_ref());
const plain_unwrap<T1> tmp(in_means_expr.get_ref());
const Mat<eT>& in_means = tmp.M;
@@ -199,7 +199,7 @@ gmm_diag<eT>::set_dcovs(const Base<eT,T1>& in_dcovs_expr)
{
arma_debug_sigprint();
const unwrap<T1> tmp(in_dcovs_expr.get_ref());
const plain_unwrap<T1> tmp(in_dcovs_expr.get_ref());
const Mat<eT>& in_dcovs = tmp.M;
@@ -222,7 +222,7 @@ gmm_diag<eT>::set_hefts(const Base<eT,T1>& in_hefts_expr)
{
arma_debug_sigprint();
const unwrap<T1> tmp(in_hefts_expr.get_ref());
const plain_unwrap<T1> tmp(in_hefts_expr.get_ref());
const Mat<eT>& in_hefts = tmp.M;
@@ -602,8 +602,8 @@ gmm_diag<eT>::raw_hist(const Base<eT,T1>& expr, const gmm_dist_mode& dist_mode)
{
arma_debug_sigprint();
const unwrap<T1> tmp(expr.get_ref());
const Mat<eT>& X = tmp.M;
const plain_unwrap<T1> tmp(expr.get_ref());
const Mat<eT>& X = tmp.M;
arma_conform_check( (X.n_rows != means.n_rows), "gmm_diag::raw_hist(): incompatible dimensions" );
@@ -626,8 +626,8 @@ gmm_diag<eT>::norm_hist(const Base<eT,T1>& expr, const gmm_dist_mode& dist_mode)
{
arma_debug_sigprint();
const unwrap<T1> tmp(expr.get_ref());
const Mat<eT>& X = tmp.M;
const plain_unwrap<T1> tmp(expr.get_ref());
const Mat<eT>& X = tmp.M;
arma_conform_check( (X.n_rows != means.n_rows), "gmm_diag::norm_hist(): incompatible dimensions" );
@@ -687,8 +687,8 @@ gmm_diag<eT>::learn
arma_conform_check( (seed_mode_ok == false), "gmm_diag::learn(): unknown seed_mode" );
arma_conform_check( ((var_floor >= eT(0)) == false), "gmm_diag::learn(): variance floor must be > 0" );
const unwrap<T1> tmp_X(data.get_ref());
const Mat<eT>& X = tmp_X.M;
const plain_unwrap<T1> tmp_X(data.get_ref());
const Mat<eT>& X = tmp_X.M;
if(X.is_empty() ) { arma_warn(3, "gmm_diag::learn(): given matrix is empty" ); return false; }
if(X.internal_has_nonfinite()) { arma_warn(3, "gmm_diag::learn(): given matrix has non-finite values"); return false; }
@@ -815,8 +815,8 @@ gmm_diag<eT>::kmeans_wrapper
arma_conform_check( (seed_mode_ok == false), "kmeans(): unknown seed_mode" );
const unwrap<T1> tmp_X(data.get_ref());
const Mat<eT>& X = tmp_X.M;
const plain_unwrap<T1> tmp_X(data.get_ref());
const Mat<eT>& X = tmp_X.M;
if(X.is_empty() ) { arma_warn(3, "kmeans(): given matrix is empty" ); return false; }
if(X.internal_has_nonfinite()) { arma_warn(3, "kmeans(): given matrix has non-finite values"); return false; }
+11 -11
View File
@@ -137,9 +137,9 @@ gmm_full<eT>::set_params(const Base<eT,T1>& in_means_expr, const BaseCube<eT,T2>
{
arma_debug_sigprint();
const unwrap <T1> tmp1(in_means_expr.get_ref());
const unwrap_cube<T2> tmp2(in_fcovs_expr.get_ref());
const unwrap <T3> tmp3(in_hefts_expr.get_ref());
const plain_unwrap <T1> tmp1(in_means_expr.get_ref());
const unwrap_cube<T2> tmp2(in_fcovs_expr.get_ref());
const plain_unwrap <T3> tmp3(in_hefts_expr.get_ref());
const Mat <eT>& in_means = tmp1.M;
const Cube<eT>& in_fcovs = tmp2.M;
@@ -183,7 +183,7 @@ gmm_full<eT>::set_means(const Base<eT,T1>& in_means_expr)
{
arma_debug_sigprint();
const unwrap<T1> tmp(in_means_expr.get_ref());
const plain_unwrap<T1> tmp(in_means_expr.get_ref());
const Mat<eT>& in_means = tmp.M;
@@ -230,7 +230,7 @@ gmm_full<eT>::set_hefts(const Base<eT,T1>& in_hefts_expr)
{
arma_debug_sigprint();
const unwrap<T1> tmp(in_hefts_expr.get_ref());
const plain_unwrap<T1> tmp(in_hefts_expr.get_ref());
const Mat<eT>& in_hefts = tmp.M;
@@ -641,8 +641,8 @@ gmm_full<eT>::raw_hist(const Base<eT,T1>& expr, const gmm_dist_mode& dist_mode)
{
arma_debug_sigprint();
const unwrap<T1> tmp(expr.get_ref());
const Mat<eT>& X = tmp.M;
const plain_unwrap<T1> tmp(expr.get_ref());
const Mat<eT>& X = tmp.M;
arma_conform_check( (X.n_rows != means.n_rows), "gmm_full::raw_hist(): incompatible dimensions" );
@@ -665,8 +665,8 @@ gmm_full<eT>::norm_hist(const Base<eT,T1>& expr, const gmm_dist_mode& dist_mode)
{
arma_debug_sigprint();
const unwrap<T1> tmp(expr.get_ref());
const Mat<eT>& X = tmp.M;
const plain_unwrap<T1> tmp(expr.get_ref());
const Mat<eT>& X = tmp.M;
arma_conform_check( (X.n_rows != means.n_rows), "gmm_full::norm_hist(): incompatible dimensions" );
@@ -726,8 +726,8 @@ gmm_full<eT>::learn
arma_conform_check( (seed_mode_ok == false), "gmm_full::learn(): unknown seed_mode" );
arma_conform_check( ((var_floor >= eT(0)) == false), "gmm_full::learn(): variance floor must be > 0" );
const unwrap<T1> tmp_X(data.get_ref());
const Mat<eT>& X = tmp_X.M;
const plain_unwrap<T1> tmp_X(data.get_ref());
const Mat<eT>& X = tmp_X.M;
if(X.is_empty() ) { arma_warn(3, "gmm_full::learn(): given matrix is empty" ); return false; }
if(X.internal_has_nonfinite()) { arma_warn(3, "gmm_full::learn(): given matrix has non-finite values"); return false; }
+5 -5
View File
@@ -22,9 +22,8 @@
struct memory
{
template<typename eT> arma_malloc inline static eT* acquire(const uword n_elem);
template<typename eT> arma_inline static void release(eT* mem);
template<typename eT> arma_inline static eT* acquire(const uword n_elem);
template<typename eT> arma_inline static void release( eT* mem );
template<typename eT> arma_inline static bool is_aligned(const eT* mem);
template<typename eT> arma_inline static void mark_as_aligned( eT*& mem);
@@ -33,9 +32,10 @@ struct memory
// NOTE: arma_inline is used as a partial workaround for bugs in GCC 15:
// NOTE: false positive warnings from -Wmismatched-new-delete and -Wmaybe-uninitialized
template<typename eT>
arma_malloc
inline
arma_inline
eT*
memory::acquire(const uword n_elem)
{
+2 -2
View File
@@ -22,7 +22,7 @@
template<typename eT, const bool use_smaller_thresh = false>
template<typename eT, const bool use_half_threshold = false>
struct mp_gate
{
arma_inline
@@ -32,7 +32,7 @@ struct mp_gate
{
#if defined(ARMA_USE_OPENMP)
{
const bool length_ok = (is_cx<eT>::yes || use_smaller_thresh) ? (n_elem >= (arma_config::mp_threshold/uword(2))) : (n_elem >= arma_config::mp_threshold);
const bool length_ok = (is_cx<eT>::yes || use_half_threshold) ? (n_elem >= (arma_config::mp_threshold/uword(2))) : (n_elem >= arma_config::mp_threshold);
return (length_ok) ? (bool(omp_in_parallel()) == false) : false;
}
@@ -27,6 +27,8 @@ struct mtGlueCube : public BaseCube< out_eT, mtGlueCube<out_eT, T1, T2, glue_typ
typedef out_eT elem_type;
typedef typename get_pod_type<out_eT>::result pod_type;
static constexpr bool has_subview = T1::has_subview || T2::has_subview;
arma_inline mtGlueCube(const T1& in_A, const T2& in_B);
arma_inline mtGlueCube(const T1& in_A, const T2& in_B, const uword in_aux_uword);
arma_inline ~mtGlueCube();
+2
View File
@@ -31,6 +31,8 @@ struct mtGlue : public Base< out_eT, mtGlue<out_eT, T1, T2, glue_type> >
static constexpr bool is_col = glue_type::template traits<T1,T2>::is_col;
static constexpr bool is_xvec = glue_type::template traits<T1,T2>::is_xvec;
static constexpr bool has_subview = T1::has_subview || T2::has_subview;
arma_inline mtGlue(const T1& in_A, const T2& in_B);
arma_inline mtGlue(const T1& in_A, const T2& in_B, const uword in_aux_uword);
arma_inline ~mtGlue();
@@ -32,6 +32,8 @@ struct mtOpCube : public BaseCube< out_eT, mtOpCube<out_eT, T1, op_type> >
typedef typename T1::elem_type in_eT;
static constexpr bool has_subview = T1::has_subview;
inline explicit mtOpCube(const T1& in_m);
inline mtOpCube(const T1& in_m, const in_eT in_aux);
inline mtOpCube(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c);
+2
View File
@@ -35,6 +35,8 @@ struct mtOp : public Base< out_eT, mtOp<out_eT, T1, op_type> >
static constexpr bool is_col = op_type::template traits<T1>::is_col;
static constexpr bool is_xvec = op_type::template traits<T1>::is_xvec;
static constexpr bool has_subview = T1::has_subview;
inline explicit mtOp(const T1& in_m);
inline mtOp(const T1& in_m, const in_eT in_aux);
inline mtOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
@@ -31,6 +31,8 @@ struct mtSpGlue : public SpBase< out_eT, mtSpGlue<out_eT, T1, T2, spglue_type> >
static constexpr bool is_col = spglue_type::template traits<T1,T2>::is_col;
static constexpr bool is_xvec = spglue_type::template traits<T1,T2>::is_xvec;
static constexpr bool has_subview = T1::has_subview || T2::has_subview;
inline mtSpGlue(const T1& in_A, const T2& in_B);
inline ~mtSpGlue();
+2
View File
@@ -36,6 +36,8 @@ struct mtSpOp : public SpBase< out_eT, mtSpOp<out_eT, T1, spop_type> >
static constexpr bool is_col = spop_type::template traits<T1>::is_col;
static constexpr bool is_xvec = spop_type::template traits<T1>::is_xvec;
static constexpr bool has_subview = T1::has_subview;
inline explicit mtSpOp(const T1& in_m);
inline mtSpOp(const T1& in_m, const in_eT in_aux);
inline mtSpOp(const T1& in_m, const uword aux_uword_a, const uword aux_uword_b);
+1 -1
View File
@@ -94,7 +94,7 @@ arma_inline
bool
mtSpOp<out_eT, T1, op_type>::is_alias(const SpMat<eT2>& X) const
{
return (void_ptr(&X) == void_ptr(&m));
return m.is_alias(X);
}
@@ -46,10 +46,15 @@ struct mtSpReduceOp : public SpBase< out_eT, mtSpReduceOp<out_eT, T1, op_type> >
static constexpr bool is_col = op_type::template traits<T1>::is_col;
static constexpr bool is_xvec = op_type::template traits<T1>::is_xvec;
static constexpr bool has_subview = T1::has_subview;
inline explicit mtSpReduceOp(const T1& in_m);
inline mtSpReduceOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
inline ~mtSpReduceOp();
template<typename eT2>
arma_inline bool is_alias(const SpMat<eT2>& X) const;
const T1& m; //!< the operand; must be derived from SpBase
uword aux_uword_a; //!< auxiliary data, uword format
uword aux_uword_b; //!< auxiliary data, uword format
@@ -52,4 +52,15 @@ mtSpReduceOp<out_eT, T1, op_type>::~mtSpReduceOp()
template<typename out_eT, typename T1, typename op_type>
template<typename eT2>
arma_inline
bool
mtSpReduceOp<out_eT, T1, op_type>::is_alias(const SpMat<eT2>& X) const
{
return m.is_alias(X);
}
//! @}
+2 -2
View File
@@ -38,7 +38,7 @@ op_clamp::apply(Mat<typename T1::elem_type>& out, const mtOp<typename T1::elem_t
if(is_Mat<T1>::value)
{
const unwrap<T1> U(in.m);
const plain_unwrap<T1> U(in.m);
// detect in-place operation
if(&out == &(U.M))
@@ -310,7 +310,7 @@ op_clamp_cx::apply(Mat<typename T1::elem_type>& out, const mtOp<typename T1::ele
if(is_Mat<T1>::value)
{
const unwrap<T1> U(in.m);
const plain_unwrap<T1> U(in.m);
op_clamp_cx::apply_direct(out, U.M, in.aux, in.aux_out_eT);
}
+4 -4
View File
@@ -33,8 +33,8 @@ op_cor::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cor>& in)
const uword norm_type = in.aux_uword_a;
const unwrap<T1> U(in.m);
const Mat<eT>& A = U.M;
const plain_unwrap<T1> U(in.m);
const Mat<eT>& A = U.M;
if(A.n_elem == 0)
{
@@ -87,8 +87,8 @@ op_cor::apply(Mat<typename T1::elem_type>& out, const Op< Op<T1,op_htrans>, op_c
}
else
{
const unwrap<T1> U(in.m.m);
const Mat<eT>& A = U.M;
const plain_unwrap<T1> U(in.m.m);
const Mat<eT>& A = U.M;
if(A.n_elem == 0)
{
+4 -4
View File
@@ -33,8 +33,8 @@ op_cov::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cov>& in)
const uword norm_type = in.aux_uword_a;
const unwrap<T1> U(in.m);
const Mat<eT>& A = U.M;
const plain_unwrap<T1> U(in.m);
const Mat<eT>& A = U.M;
if(A.n_elem == 0)
{
@@ -76,8 +76,8 @@ op_cov::apply(Mat<typename T1::elem_type>& out, const Op< Op<T1,op_htrans>, op_c
}
else
{
const unwrap<T1> U(in.m.m);
const Mat<eT>& A = U.M;
const plain_unwrap<T1> U(in.m.m);
const Mat<eT>& A = U.M;
if(A.n_elem == 0)
{
@@ -27,12 +27,20 @@ struct op_diagmat
template<typename T1>
inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_diagmat>& X);
template<typename T1>
inline static void apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1,op_diagmat>& X);
template<typename T1>
inline static void apply(Mat<typename T1::elem_type>& out, const Proxy<T1>& P);
//
template<typename T1, typename T2>
inline static void apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagmat>& X);
template<typename T1, typename T2>
inline static void apply(Mat_noalias<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagmat>& X);
template<typename T1, typename T2>
inline static void apply_times(Mat<typename T1::elem_type>& out, const T1& X, const T2& Y, const typename arma_not_cx<typename T1::elem_type>::result* junk = nullptr);
@@ -48,6 +56,9 @@ struct op_diagmat2
template<typename T1>
inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_diagmat2>& X);
template<typename T1>
inline static void apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1,op_diagmat2>& X);
template<typename T1>
inline static void apply(Mat<typename T1::elem_type>& out, const Proxy<T1>& P, const uword row_offset, const uword col_offset);
};
+76 -34
View File
@@ -34,8 +34,8 @@ op_diagmat::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagmat>& X)
{
// allow detection of in-place operation
const unwrap<T1> U(X.m);
const Mat<eT>& A = U.M;
const plain_unwrap<T1> U(X.m);
const Mat<eT>& A = U.M;
if(&out != &A) // no aliasing
{
@@ -104,6 +104,20 @@ op_diagmat::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagmat>& X)
template<typename T1>
inline
void
op_diagmat::apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1, op_diagmat>& X)
{
arma_debug_sigprint();
const Proxy<T1> P(X.m);
op_diagmat::apply(out, P);
}
template<typename T1>
inline
void
@@ -160,6 +174,31 @@ op_diagmat::apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_ti
{
arma_debug_sigprint();
typedef typename T1::elem_type eT;
if(X.m.is_alias(out))
{
Mat<eT> tmp;
op_diagmat::apply_times(tmp, X.m.A, X.m.B);
out.steal_mem(tmp);
}
else
{
op_diagmat::apply_times(out, X.m.A, X.m.B);
}
}
template<typename T1, typename T2>
inline
void
op_diagmat::apply(Mat_noalias<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagmat>& X)
{
arma_debug_sigprint();
op_diagmat::apply_times(out, X.m.A, X.m.B);
}
@@ -168,7 +207,7 @@ op_diagmat::apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_ti
template<typename T1, typename T2>
inline
void
op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, const T2& Y, const typename arma_not_cx<typename T1::elem_type>::result* junk)
op_diagmat::apply_times(Mat<typename T1::elem_type>& out, const T1& X, const T2& Y, const typename arma_not_cx<typename T1::elem_type>::result* junk)
{
arma_debug_sigprint();
arma_ignore(junk);
@@ -204,9 +243,9 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
const eT* C_mem = C.memptr();
const uword N = C.n_elem;
actual_out.zeros(N,N);
out.zeros(N,N);
for(uword i=0; i<N; ++i) { actual_out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
for(uword i=0; i<N; ++i) { out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
return;
}
@@ -222,9 +261,9 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
const eT* C_mem = C.memptr();
const uword N = C.n_elem;
actual_out.zeros(N,N);
out.zeros(N,N);
for(uword i=0; i<N; ++i) { actual_out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
for(uword i=0; i<N; ++i) { out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
return;
}
@@ -240,9 +279,9 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
const eT* C_mem = C.memptr();
const uword N = C.n_elem;
actual_out.zeros(N,N);
out.zeros(N,N);
for(uword i=0; i<N; ++i) { actual_out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
for(uword i=0; i<N; ++i) { out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
return;
}
@@ -258,20 +297,15 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
const eT* C_mem = C.memptr();
const uword N = C.n_elem;
actual_out.zeros(N,N);
out.zeros(N,N);
for(uword i=0; i<N; ++i) { actual_out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
for(uword i=0; i<N; ++i) { out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
return;
}
}
// if we got to this point, the multiplication results in a matrix
const bool is_alias = (UA.is_alias(actual_out) || UB.is_alias(actual_out));
Mat<eT> tmp;
Mat<eT>& out = (is_alias) ? tmp : actual_out;
if( (partial_unwrap<T1>::do_trans == false) && (partial_unwrap<T2>::do_trans == false) )
{
@@ -384,8 +418,6 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
out.at(k,k) = (use_alpha) ? eT(alpha * acc) : eT(acc);
}
}
if(is_alias) { actual_out.steal_mem(tmp); }
}
@@ -393,7 +425,7 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
template<typename T1, typename T2>
inline
void
op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, const T2& Y, const typename arma_cx_only<typename T1::elem_type>::result* junk)
op_diagmat::apply_times(Mat<typename T1::elem_type>& out, const T1& X, const T2& Y, const typename arma_cx_only<typename T1::elem_type>::result* junk)
{
arma_debug_sigprint();
arma_ignore(junk);
@@ -430,9 +462,9 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
const eT* C_mem = C.memptr();
const uword N = C.n_elem;
actual_out.zeros(N,N);
out.zeros(N,N);
for(uword i=0; i<N; ++i) { actual_out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
for(uword i=0; i<N; ++i) { out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
return;
}
@@ -448,9 +480,9 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
const eT* C_mem = C.memptr();
const uword N = C.n_elem;
actual_out.zeros(N,N);
out.zeros(N,N);
for(uword i=0; i<N; ++i) { actual_out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
for(uword i=0; i<N; ++i) { out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
return;
}
@@ -466,9 +498,9 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
const eT* C_mem = C.memptr();
const uword N = C.n_elem;
actual_out.zeros(N,N);
out.zeros(N,N);
for(uword i=0; i<N; ++i) { actual_out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
for(uword i=0; i<N; ++i) { out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
return;
}
@@ -484,20 +516,15 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
const eT* C_mem = C.memptr();
const uword N = C.n_elem;
actual_out.zeros(N,N);
out.zeros(N,N);
for(uword i=0; i<N; ++i) { actual_out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
for(uword i=0; i<N; ++i) { out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
return;
}
}
// if we got to this point, the multiplication results in a matrix
const bool is_alias = (UA.is_alias(actual_out) || UB.is_alias(actual_out));
Mat<eT> tmp;
Mat<eT>& out = (is_alias) ? tmp : actual_out;
if( (partial_unwrap<T1>::do_trans == false) && (partial_unwrap<T2>::do_trans == false) )
{
@@ -659,8 +686,6 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
out.at(k,k) = (use_alpha) ? eT(alpha * acc) : eT(acc);
}
}
if(is_alias) { actual_out.steal_mem(tmp); }
}
@@ -701,6 +726,23 @@ op_diagmat2::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagmat2>&
template<typename T1>
inline
void
op_diagmat2::apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1, op_diagmat2>& X)
{
arma_debug_sigprint();
const uword row_offset = X.aux_uword_a;
const uword col_offset = X.aux_uword_b;
const Proxy<T1> P(X.m);
op_diagmat2::apply(out, P, row_offset, col_offset);
}
template<typename T1>
inline
void
+17 -3
View File
@@ -27,14 +27,25 @@ struct op_diagvec
template<typename T1>
inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_diagvec>& X);
template<typename T1>
inline static void apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1,op_diagvec>& X);
template<typename T1>
inline static void apply_proxy(Mat<typename T1::elem_type>& out, const Proxy<T1>& P);
template<typename T1, typename T2>
inline static void apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagvec>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = nullptr);
//
template<typename T1, typename T2>
inline static void apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagvec>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk = nullptr);
inline static void apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagvec>& X);
template<typename T1, typename T2>
inline static void apply(Mat_noalias<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagvec>& X);
template<typename T1, typename T2>
inline static void apply_glue_times(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = nullptr);
template<typename T1, typename T2>
inline static void apply_glue_times(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk = nullptr);
};
@@ -45,6 +56,9 @@ struct op_diagvec2
template<typename T1>
inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_diagvec2>& X);
template<typename T1>
inline static void apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1,op_diagvec2>& X);
template<typename T1>
inline static void apply_proxy(Mat<typename T1::elem_type>& out, const Proxy<T1>& P, const uword row_offset, const uword col_offset);
};
+79 -22
View File
@@ -48,6 +48,20 @@ op_diagvec::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagvec>& X)
template<typename T1>
inline
void
op_diagvec::apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1, op_diagvec>& X)
{
arma_debug_sigprint();
const Proxy<T1> P(X.m);
op_diagvec::apply_proxy(out, P);
}
template<typename T1>
inline
void
@@ -87,31 +101,63 @@ op_diagvec::apply_proxy(Mat<typename T1::elem_type>& out, const Proxy<T1>& P)
template<typename T1, typename T2>
inline
void
op_diagvec::apply(Mat<typename T1::elem_type>& actual_out, const Op< Glue<T1,T2,glue_times>, op_diagvec>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk)
op_diagvec::apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagvec>& X)
{
arma_debug_sigprint();
typedef typename T1::elem_type eT;
if(X.m.is_alias(out))
{
Mat<eT> tmp;
op_diagvec::apply_glue_times(tmp, X.m);
out.steal_mem(tmp);
}
else
{
op_diagvec::apply_glue_times(out, X.m);
}
}
template<typename T1, typename T2>
inline
void
op_diagvec::apply(Mat_noalias<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagvec>& X)
{
arma_debug_sigprint();
op_diagvec::apply_glue_times(out, X.m);
}
template<typename T1, typename T2>
inline
void
op_diagvec::apply_glue_times(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk)
{
arma_debug_sigprint();
arma_ignore(junk);
typedef typename T1::elem_type eT;
const partial_unwrap<T1> UA(X.m.A);
const partial_unwrap<T2> UB(X.m.B);
const partial_unwrap<T1> UA(X.A);
const partial_unwrap<T2> UB(X.B);
const typename partial_unwrap<T1>::stored_type& A = UA.M;
const typename partial_unwrap<T2>::stored_type& B = UB.M;
arma_conform_assert_trans_mul_size< partial_unwrap<T1>::do_trans, partial_unwrap<T2>::do_trans >(A.n_rows, A.n_cols, B.n_rows, B.n_cols, "matrix multiplication");
if( (A.n_elem == 0) || (B.n_elem == 0) ) { actual_out.reset(); return; }
if( (A.n_elem == 0) || (B.n_elem == 0) ) { out.reset(); return; }
constexpr bool use_alpha = partial_unwrap<T1>::do_times || partial_unwrap<T2>::do_times;
const eT alpha = use_alpha ? (UA.get_val() * UB.get_val()) : eT(0);
const bool is_alias = (UA.is_alias(actual_out) || UB.is_alias(actual_out));
Mat<eT> tmp;
Mat<eT>& out = (is_alias) ? tmp : actual_out;
const uword A_n_rows = A.n_rows;
const uword A_n_cols = A.n_cols;
@@ -237,8 +283,6 @@ op_diagvec::apply(Mat<typename T1::elem_type>& actual_out, const Op< Glue<T1,T2,
out_mem[k] = (use_alpha) ? eT(alpha * acc) : eT(acc);
}
}
if(is_alias) { actual_out.steal_mem(tmp); }
}
@@ -246,7 +290,7 @@ op_diagvec::apply(Mat<typename T1::elem_type>& actual_out, const Op< Glue<T1,T2,
template<typename T1, typename T2>
inline
void
op_diagvec::apply(Mat<typename T1::elem_type>& actual_out, const Op< Glue<T1,T2,glue_times>, op_diagvec>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk)
op_diagvec::apply_glue_times(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk)
{
arma_debug_sigprint();
arma_ignore(junk);
@@ -254,24 +298,19 @@ op_diagvec::apply(Mat<typename T1::elem_type>& actual_out, const Op< Glue<T1,T2,
typedef typename T1::pod_type T;
typedef typename T1::elem_type eT;
const partial_unwrap<T1> UA(X.m.A);
const partial_unwrap<T2> UB(X.m.B);
const partial_unwrap<T1> UA(X.A);
const partial_unwrap<T2> UB(X.B);
const typename partial_unwrap<T1>::stored_type& A = UA.M;
const typename partial_unwrap<T2>::stored_type& B = UB.M;
arma_conform_assert_trans_mul_size< partial_unwrap<T1>::do_trans, partial_unwrap<T2>::do_trans >(A.n_rows, A.n_cols, B.n_rows, B.n_cols, "matrix multiplication");
if( (A.n_elem == 0) || (B.n_elem == 0) ) { actual_out.reset(); return; }
if( (A.n_elem == 0) || (B.n_elem == 0) ) { out.reset(); return; }
constexpr bool use_alpha = partial_unwrap<T1>::do_times || partial_unwrap<T2>::do_times;
const eT alpha = use_alpha ? (UA.get_val() * UB.get_val()) : eT(0);
const bool is_alias = (UA.is_alias(actual_out) || UB.is_alias(actual_out));
Mat<eT> tmp;
Mat<eT>& out = (is_alias) ? tmp : actual_out;
const uword A_n_rows = A.n_rows;
const uword A_n_cols = A.n_cols;
@@ -446,8 +485,6 @@ op_diagvec::apply(Mat<typename T1::elem_type>& actual_out, const Op< Glue<T1,T2,
out_mem[k] = (use_alpha) ? eT(alpha * acc) : eT(acc);
}
}
if(is_alias) { actual_out.steal_mem(tmp); }
}
@@ -491,6 +528,26 @@ op_diagvec2::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagvec2>&
template<typename T1>
inline
void
op_diagvec2::apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1, op_diagvec2>& X)
{
arma_debug_sigprint();
const uword a = X.aux_uword_a;
const uword b = X.aux_uword_b;
const uword row_offset = (b > 0) ? a : 0;
const uword col_offset = (b == 0) ? a : 0;
const Proxy<T1> P(X.m);
op_diagvec2::apply_proxy(out, P, row_offset, col_offset);
}
template<typename T1>
inline
void
+2 -2
View File
@@ -601,8 +601,8 @@ op_cdot::apply_unwrap(const T1& X, const T2& Y)
typedef typename T1::elem_type eT;
const unwrap<T1> tmp1(X);
const unwrap<T2> tmp2(Y);
const plain_unwrap<T1> tmp1(X);
const plain_unwrap<T2> tmp2(Y);
const Mat<eT>& A = tmp1.M;
const Mat<eT>& B = tmp2.M;
+2 -2
View File
@@ -200,8 +200,8 @@ op_expmat_sym::apply_direct(Mat<typename T1::elem_type>& out, const Base<typenam
typedef typename T1::elem_type eT;
typedef typename T1::pod_type T;
const unwrap<T1> U(expr.get_ref());
const Mat<eT>& X = U.M;
const plain_unwrap<T1> U(expr.get_ref());
const Mat<eT>& X = U.M;
arma_conform_check( (X.is_square() == false), "expmat_sym(): given matrix must be square sized" );
@@ -0,0 +1,81 @@
// SPDX-License-Identifier: Apache-2.0
//
// Copyright 2008-2016 Conrad Sanderson (https://conradsanderson.id.au)
// Copyright 2008-2016 National ICT Australia (NICTA)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
//! \addtogroup op_find_aux
//! @{
struct op_find_aux
: public traits_op_default
{
template<typename functor, typename T1>
inline static void
apply
(
functor element_processor,
const Base<typename T1::elem_type, T1>& X
);
template<typename functor, typename T1, typename op_type>
inline static void
apply
(
functor element_processor,
const mtOp<uword, T1, op_type>& X,
const typename arma_op_rel_only<op_type>::result* junk1 = nullptr,
const typename arma_not_cx<typename T1::elem_type>::result* junk2 = nullptr
);
template<typename functor, typename T1, typename op_type>
inline static void
apply
(
functor element_processor,
const mtOp<uword, T1, op_type>& X,
const typename arma_op_rel_only<op_type>::result* junk1 = nullptr,
const typename arma_cx_only<typename T1::elem_type>::result* junk2 = nullptr
);
template<typename functor, typename T1, typename T2, typename glue_type>
inline static void
apply
(
functor element_processor,
const mtGlue<uword, T1, T2, glue_type>& X,
const typename arma_glue_rel_only<glue_type>::result* junk1 = nullptr,
const typename arma_not_cx<typename T1::elem_type>::result* junk2 = nullptr,
const typename arma_not_cx<typename T2::elem_type>::result* junk3 = nullptr
);
template<typename functor, typename T1, typename T2, typename glue_type>
inline static void
apply
(
functor element_processor,
const mtGlue<uword, T1, T2, glue_type>& X,
const typename arma_glue_rel_only<glue_type>::result* junk1 = nullptr,
const typename arma_cx_only<typename T1::elem_type>::result* junk2 = nullptr,
const typename arma_cx_only<typename T2::elem_type>::result* junk3 = nullptr
);
};
//! @}
+425
View File
@@ -0,0 +1,425 @@
// SPDX-License-Identifier: Apache-2.0
//
// Copyright 2008-2016 Conrad Sanderson (https://conradsanderson.id.au)
// Copyright 2008-2016 National ICT Australia (NICTA)
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ------------------------------------------------------------------------
//! \addtogroup op_find_aux
//! @{
template<typename functor, typename T1>
inline
void
op_find_aux::apply
(
functor element_processor,
const Base<typename T1::elem_type, T1>& X
)
{
arma_debug_sigprint();
typedef typename T1::elem_type eT;
const Proxy<T1> A(X.get_ref());
const uword n_elem = A.get_n_elem();
if(Proxy<T1>::use_at == false)
{
typename Proxy<T1>::ea_type PA = A.get_ea();
for(uword i=0; i<n_elem; ++i)
{
if(PA[i] != eT(0)) { element_processor(i); }
}
}
else
{
const uword n_rows = A.get_n_rows();
const uword n_cols = A.get_n_cols();
uword i = 0;
for(uword col=0; col < n_cols; ++col)
for(uword row=0; row < n_rows; ++row)
{
if(A.at(row,col) != eT(0)) { element_processor(i); }
++i;
}
}
}
template<typename functor, typename T1, typename op_type>
inline
void
op_find_aux::apply
(
functor element_processor,
const mtOp<uword, T1, op_type>& X,
const typename arma_op_rel_only<op_type>::result* junk1,
const typename arma_not_cx<typename T1::elem_type>::result* junk2
)
{
arma_debug_sigprint();
arma_ignore(junk1);
arma_ignore(junk2);
typedef typename T1::elem_type eT;
const eT val = X.aux;
if((is_same_type<op_type, op_rel_eq>::yes || is_same_type<op_type, op_rel_noteq>::yes) && arma_config::check_conform && arma_isnan(val))
{
arma_warn(1, "find(): NaN is not equal to anything; suggest to use find_nonfinite() instead");
}
const Proxy<T1> A(X.m);
const uword n_elem = A.get_n_elem();
if(Proxy<T1>::use_at == false)
{
typename Proxy<T1>::ea_type PA = A.get_ea();
uword i,j;
for(i=0, j=1; j < n_elem; i+=2, j+=2)
{
const eT tpi = PA[i];
const eT tpj = PA[j];
bool not_zero_i;
bool not_zero_j;
if(is_same_type<op_type, op_rel_lt_pre >::yes) { not_zero_i = (val < tpi); }
else if(is_same_type<op_type, op_rel_lt_post >::yes) { not_zero_i = (tpi < val); }
else if(is_same_type<op_type, op_rel_gt_pre >::yes) { not_zero_i = (val > tpi); }
else if(is_same_type<op_type, op_rel_gt_post >::yes) { not_zero_i = (tpi > val); }
else if(is_same_type<op_type, op_rel_lteq_pre >::yes) { not_zero_i = (val <= tpi); }
else if(is_same_type<op_type, op_rel_lteq_post>::yes) { not_zero_i = (tpi <= val); }
else if(is_same_type<op_type, op_rel_gteq_pre >::yes) { not_zero_i = (val >= tpi); }
else if(is_same_type<op_type, op_rel_gteq_post>::yes) { not_zero_i = (tpi >= val); }
else if(is_same_type<op_type, op_rel_eq >::yes) { not_zero_i = (tpi == val); }
else if(is_same_type<op_type, op_rel_noteq >::yes) { not_zero_i = (tpi != val); }
else { not_zero_i = false; }
if(is_same_type<op_type, op_rel_lt_pre >::yes) { not_zero_j = (val < tpj); }
else if(is_same_type<op_type, op_rel_lt_post >::yes) { not_zero_j = (tpj < val); }
else if(is_same_type<op_type, op_rel_gt_pre >::yes) { not_zero_j = (val > tpj); }
else if(is_same_type<op_type, op_rel_gt_post >::yes) { not_zero_j = (tpj > val); }
else if(is_same_type<op_type, op_rel_lteq_pre >::yes) { not_zero_j = (val <= tpj); }
else if(is_same_type<op_type, op_rel_lteq_post>::yes) { not_zero_j = (tpj <= val); }
else if(is_same_type<op_type, op_rel_gteq_pre >::yes) { not_zero_j = (val >= tpj); }
else if(is_same_type<op_type, op_rel_gteq_post>::yes) { not_zero_j = (tpj >= val); }
else if(is_same_type<op_type, op_rel_eq >::yes) { not_zero_j = (tpj == val); }
else if(is_same_type<op_type, op_rel_noteq >::yes) { not_zero_j = (tpj != val); }
else { not_zero_j = false; }
if(not_zero_i) { element_processor(i); }
if(not_zero_j) { element_processor(j); }
}
if(i < n_elem)
{
bool not_zero;
const eT tmp = PA[i];
if(is_same_type<op_type, op_rel_lt_pre >::yes) { not_zero = (val < tmp); }
else if(is_same_type<op_type, op_rel_lt_post >::yes) { not_zero = (tmp < val); }
else if(is_same_type<op_type, op_rel_gt_pre >::yes) { not_zero = (val > tmp); }
else if(is_same_type<op_type, op_rel_gt_post >::yes) { not_zero = (tmp > val); }
else if(is_same_type<op_type, op_rel_lteq_pre >::yes) { not_zero = (val <= tmp); }
else if(is_same_type<op_type, op_rel_lteq_post>::yes) { not_zero = (tmp <= val); }
else if(is_same_type<op_type, op_rel_gteq_pre >::yes) { not_zero = (val >= tmp); }
else if(is_same_type<op_type, op_rel_gteq_post>::yes) { not_zero = (tmp >= val); }
else if(is_same_type<op_type, op_rel_eq >::yes) { not_zero = (tmp == val); }
else if(is_same_type<op_type, op_rel_noteq >::yes) { not_zero = (tmp != val); }
else { not_zero = false; }
if(not_zero) { element_processor(i); }
}
}
else
{
const uword n_rows = A.get_n_rows();
const uword n_cols = A.get_n_cols();
uword i = 0;
for(uword col=0; col < n_cols; ++col)
for(uword row=0; row < n_rows; ++row)
{
const eT tmp = A.at(row,col);
bool not_zero;
if(is_same_type<op_type, op_rel_lt_pre >::yes) { not_zero = (val < tmp); }
else if(is_same_type<op_type, op_rel_lt_post >::yes) { not_zero = (tmp < val); }
else if(is_same_type<op_type, op_rel_gt_pre >::yes) { not_zero = (val > tmp); }
else if(is_same_type<op_type, op_rel_gt_post >::yes) { not_zero = (tmp > val); }
else if(is_same_type<op_type, op_rel_lteq_pre >::yes) { not_zero = (val <= tmp); }
else if(is_same_type<op_type, op_rel_lteq_post>::yes) { not_zero = (tmp <= val); }
else if(is_same_type<op_type, op_rel_gteq_pre >::yes) { not_zero = (val >= tmp); }
else if(is_same_type<op_type, op_rel_gteq_post>::yes) { not_zero = (tmp >= val); }
else if(is_same_type<op_type, op_rel_eq >::yes) { not_zero = (tmp == val); }
else if(is_same_type<op_type, op_rel_noteq >::yes) { not_zero = (tmp != val); }
else { not_zero = false; }
if(not_zero) { element_processor(i); }
++i;
}
}
}
template<typename functor, typename T1, typename op_type>
inline
void
op_find_aux::apply
(
functor element_processor,
const mtOp<uword, T1, op_type>& X,
const typename arma_op_rel_only<op_type>::result* junk1,
const typename arma_cx_only<typename T1::elem_type>::result* junk2
)
{
arma_debug_sigprint();
arma_ignore(junk1);
arma_ignore(junk2);
typedef typename T1::elem_type eT;
typedef typename Proxy<T1>::ea_type ea_type;
const eT val = X.aux;
if((is_same_type<op_type, op_rel_eq>::yes || is_same_type<op_type, op_rel_noteq>::yes) && arma_config::check_conform && arma_isnan(val))
{
arma_warn(1, "find(): NaN is not equal to anything; suggest to use find_nonfinite() instead");
}
const Proxy<T1> A(X.m);
const uword n_elem = A.get_n_elem();
if(Proxy<T1>::use_at == false)
{
ea_type PA = A.get_ea();
for(uword i=0; i<n_elem; ++i)
{
const eT tmp = PA[i];
bool not_zero;
if(is_same_type<op_type, op_rel_eq >::yes) { not_zero = (tmp == val); }
else if(is_same_type<op_type, op_rel_noteq>::yes) { not_zero = (tmp != val); }
else { not_zero = false; }
if(not_zero) { element_processor(i); }
}
}
else
{
const uword n_rows = A.get_n_rows();
const uword n_cols = A.get_n_cols();
uword i = 0;
for(uword col=0; col<n_cols; ++col)
for(uword row=0; row<n_rows; ++row)
{
const eT tmp = A.at(row,col);
bool not_zero;
if(is_same_type<op_type, op_rel_eq >::yes) { not_zero = (tmp == val); }
else if(is_same_type<op_type, op_rel_noteq>::yes) { not_zero = (tmp != val); }
else { not_zero = false; }
if(not_zero) { element_processor(i); }
i++;
}
}
}
template<typename functor, typename T1, typename T2, typename glue_type>
inline
void
op_find_aux::apply
(
functor element_processor,
const mtGlue<uword, T1, T2, glue_type>& X,
const typename arma_glue_rel_only<glue_type>::result* junk1,
const typename arma_not_cx<typename T1::elem_type>::result* junk2,
const typename arma_not_cx<typename T2::elem_type>::result* junk3
)
{
arma_debug_sigprint();
arma_ignore(junk1);
arma_ignore(junk2);
arma_ignore(junk3);
typedef typename T1::elem_type eT1;
typedef typename T2::elem_type eT2;
typedef typename Proxy<T1>::ea_type ea_type1;
typedef typename Proxy<T2>::ea_type ea_type2;
const Proxy<T1> A(X.A);
const Proxy<T2> B(X.B);
arma_conform_assert_same_size(A, B, "relational operator");
const uword n_elem = A.get_n_elem();
if((Proxy<T1>::use_at == false) && (Proxy<T2>::use_at == false))
{
ea_type1 PA = A.get_ea();
ea_type2 PB = B.get_ea();
for(uword i=0; i<n_elem; ++i)
{
const eT1 tmp1 = PA[i];
const eT2 tmp2 = PB[i];
bool not_zero;
if(is_same_type<glue_type, glue_rel_lt >::yes) { not_zero = (tmp1 < tmp2); }
else if(is_same_type<glue_type, glue_rel_gt >::yes) { not_zero = (tmp1 > tmp2); }
else if(is_same_type<glue_type, glue_rel_lteq >::yes) { not_zero = (tmp1 <= tmp2); }
else if(is_same_type<glue_type, glue_rel_gteq >::yes) { not_zero = (tmp1 >= tmp2); }
else if(is_same_type<glue_type, glue_rel_eq >::yes) { not_zero = (tmp1 == tmp2); }
else if(is_same_type<glue_type, glue_rel_noteq >::yes) { not_zero = (tmp1 != tmp2); }
else if(is_same_type<glue_type, glue_rel_and >::yes) { not_zero = (tmp1 && tmp2); }
else if(is_same_type<glue_type, glue_rel_or >::yes) { not_zero = (tmp1 || tmp2); }
else { not_zero = false; }
if(not_zero) { element_processor(i); }
}
}
else
{
const uword n_rows = A.get_n_rows();
const uword n_cols = A.get_n_cols();
uword i = 0;
for(uword col=0; col < n_cols; ++col)
for(uword row=0; row < n_rows; ++row)
{
const eT1 tmp1 = A.at(row,col);
const eT2 tmp2 = B.at(row,col);
bool not_zero;
if(is_same_type<glue_type, glue_rel_lt >::yes) { not_zero = (tmp1 < tmp2); }
else if(is_same_type<glue_type, glue_rel_gt >::yes) { not_zero = (tmp1 > tmp2); }
else if(is_same_type<glue_type, glue_rel_lteq >::yes) { not_zero = (tmp1 <= tmp2); }
else if(is_same_type<glue_type, glue_rel_gteq >::yes) { not_zero = (tmp1 >= tmp2); }
else if(is_same_type<glue_type, glue_rel_eq >::yes) { not_zero = (tmp1 == tmp2); }
else if(is_same_type<glue_type, glue_rel_noteq >::yes) { not_zero = (tmp1 != tmp2); }
else if(is_same_type<glue_type, glue_rel_and >::yes) { not_zero = (tmp1 && tmp2); }
else if(is_same_type<glue_type, glue_rel_or >::yes) { not_zero = (tmp1 || tmp2); }
else { not_zero = false; }
if(not_zero) { element_processor(i); }
i++;
}
}
}
template<typename functor, typename T1, typename T2, typename glue_type>
inline
void
op_find_aux::apply
(
functor element_processor,
const mtGlue<uword, T1, T2, glue_type>& X,
const typename arma_glue_rel_only<glue_type>::result* junk1,
const typename arma_cx_only<typename T1::elem_type>::result* junk2,
const typename arma_cx_only<typename T2::elem_type>::result* junk3
)
{
arma_debug_sigprint();
arma_ignore(junk1);
arma_ignore(junk2);
arma_ignore(junk3);
typedef typename Proxy<T1>::ea_type ea_type1;
typedef typename Proxy<T2>::ea_type ea_type2;
const Proxy<T1> A(X.A);
const Proxy<T2> B(X.B);
arma_conform_assert_same_size(A, B, "relational operator");
const uword n_elem = A.get_n_elem();
if((Proxy<T1>::use_at == false) && (Proxy<T2>::use_at == false))
{
ea_type1 PA = A.get_ea();
ea_type2 PB = B.get_ea();
for(uword i=0; i<n_elem; ++i)
{
bool not_zero;
if(is_same_type<glue_type, glue_rel_eq >::yes) { not_zero = (PA[i] == PB[i]); }
else if(is_same_type<glue_type, glue_rel_noteq >::yes) { not_zero = (PA[i] != PB[i]); }
else { not_zero = false; }
if(not_zero) { element_processor(i); }
}
}
else
{
const uword n_rows = A.get_n_rows();
const uword n_cols = A.get_n_cols();
uword i = 0;
for(uword col=0; col<n_cols; ++col)
for(uword row=0; row<n_rows; ++row)
{
bool not_zero;
if(is_same_type<glue_type, glue_rel_eq >::yes) { not_zero = (A.at(row,col) == B.at(row,col)); }
else if(is_same_type<glue_type, glue_rel_noteq >::yes) { not_zero = (A.at(row,col) != B.at(row,col)); }
else { not_zero = false; }
if(not_zero) { element_processor(i); }
i++;
}
}
}
//! @}
+4 -4
View File
@@ -22,7 +22,7 @@
struct op_find
struct op_find_generic
: public traits_op_col
{
template<typename T1>
@@ -76,16 +76,16 @@ struct op_find
);
template<typename T1>
inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_find>& X);
inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_find_generic>& X);
};
struct op_find_simple
struct op_find_default
: public traits_op_col
{
template<typename T1>
inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_find_simple>& X);
inline static void apply(Mat<uword>& out, const mtOp<uword, T1, op_find_default>& X);
};
+9 -9
View File
@@ -25,7 +25,7 @@
template<typename T1>
inline
uword
op_find::helper
op_find_generic::helper
(
Mat<uword>& indices,
const Base<typename T1::elem_type, T1>& X
@@ -77,7 +77,7 @@ op_find::helper
template<typename T1, typename op_type>
inline
uword
op_find::helper
op_find_generic::helper
(
Mat<uword>& indices,
const mtOp<uword, T1, op_type>& X,
@@ -209,7 +209,7 @@ op_find::helper
template<typename T1, typename op_type>
inline
uword
op_find::helper
op_find_generic::helper
(
Mat<uword>& indices,
const mtOp<uword, T1, op_type>& X,
@@ -290,7 +290,7 @@ op_find::helper
template<typename T1, typename T2, typename glue_type>
inline
uword
op_find::helper
op_find_generic::helper
(
Mat<uword>& indices,
const mtGlue<uword, T1, T2, glue_type>& X,
@@ -386,7 +386,7 @@ op_find::helper
template<typename T1, typename T2, typename glue_type>
inline
uword
op_find::helper
op_find_generic::helper
(
Mat<uword>& indices,
const mtGlue<uword, T1, T2, glue_type>& X,
@@ -461,7 +461,7 @@ op_find::helper
template<typename T1>
inline
void
op_find::apply(Mat<uword>& out, const mtOp<uword, T1, op_find>& X)
op_find_generic::apply(Mat<uword>& out, const mtOp<uword, T1, op_find_generic>& X)
{
arma_debug_sigprint();
@@ -469,7 +469,7 @@ op_find::apply(Mat<uword>& out, const mtOp<uword, T1, op_find>& X)
const uword type = X.aux_uword_b;
Mat<uword> indices;
const uword n_nz = op_find::helper(indices, X.m);
const uword n_nz = op_find_generic::helper(indices, X.m);
if(n_nz > 0)
{
@@ -497,12 +497,12 @@ op_find::apply(Mat<uword>& out, const mtOp<uword, T1, op_find>& X)
template<typename T1>
inline
void
op_find_simple::apply(Mat<uword>& out, const mtOp<uword, T1, op_find_simple>& X)
op_find_default::apply(Mat<uword>& out, const mtOp<uword, T1, op_find_default>& X)
{
arma_debug_sigprint();
Mat<uword> indices;
const uword n_nz = op_find::helper(indices, X.m);
const uword n_nz = op_find_generic::helper(indices, X.m);
out.steal_mem_col(indices, n_nz);
}
+2 -2
View File
@@ -32,7 +32,7 @@ op_flipud::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_flipud>& in)
if(is_Mat<T1>::value)
{
const unwrap<T1> U(in.m);
const plain_unwrap<T1> U(in.m);
if(&out == &(U.M)) { op_flipud::apply_mat_inplace(out); return; }
@@ -166,7 +166,7 @@ op_fliplr::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_fliplr>& in)
if(is_Mat<T1>::value)
{
const unwrap<T1> U(in.m);
const plain_unwrap<T1> U(in.m);
if(&out == &(U.M)) { op_fliplr::apply_mat_inplace(out); return; }
+1 -1
View File
@@ -309,7 +309,7 @@ op_htrans::apply_direct(Mat<typename T1::elem_type>& out, const T1& X)
// allow detection of in-place transpose
if(is_Mat<T1>::value)
{
const unwrap<T1> U(X);
const plain_unwrap<T1> U(X);
op_htrans::apply_mat(out, U.M);
}
+2 -2
View File
@@ -500,8 +500,8 @@ op_logmat_sympd::apply_direct(Mat<typename T1::elem_type>& out, const Base<typen
typedef typename T1::pod_type T;
typedef typename T1::elem_type eT;
const unwrap<T1> U(expr.get_ref());
const Mat<eT>& X = U.M;
const plain_unwrap<T1> U(expr.get_ref());
const Mat<eT>& X = U.M;
arma_conform_check( (X.is_square() == false), "logmat_sympd(): given matrix must be square sized" );
@@ -87,6 +87,8 @@ op_orth::apply_direct(Mat<typename T1::elem_type>& out, const Base<typename T1::
// set tolerance to default if it hasn't been specified
if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * s_mem[0] * std::numeric_limits<T>::epsilon(); }
if(arma_isnan(tol)) { return false; }
uword count = 0;
for(uword i=0; i < s_n_elem; ++i) { count += (s_mem[i] > tol) ? uword(1) : uword(0); }
@@ -174,6 +176,8 @@ op_null::apply_direct(Mat<typename T1::elem_type>& out, const Base<typename T1::
// set tolerance to default if it hasn't been specified
if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * s_mem[0] * std::numeric_limits<T>::epsilon(); }
if(arma_isnan(tol)) { return false; }
uword count = 0;
for(uword i=0; i < s_n_elem; ++i) { count += (s_mem[i] > tol) ? uword(1) : uword(0); }
+6
View File
@@ -176,6 +176,8 @@ op_pinv::apply_diag(Mat<eT>& out, const Mat<eT>& A, typename get_pod_type<eT>::r
if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * max_abs_Aii * std::numeric_limits<T>::epsilon(); }
if(arma_isnan(tol)) { return false; }
for(uword i=0; i<N; ++i)
{
if(diag_abs_vals[i] >= tol)
@@ -236,6 +238,8 @@ op_pinv::apply_sym(Mat<eT>& out, const Mat<eT>& A, typename get_pod_type<eT>::re
// set tolerance to default if it hasn't been specified
if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * abs_eigval[0] * std::numeric_limits<T>::epsilon(); }
if(arma_isnan(tol)) { return false; }
uword count = 0;
for(uword i=0; i < abs_eigval.n_elem; ++i) { count += (abs_eigval[i] >= tol) ? uword(1) : uword(0); }
@@ -310,6 +314,8 @@ op_pinv::apply_gen(Mat<eT>& out, Mat<eT>& A, typename get_pod_type<eT>::result t
// set tolerance to default if it hasn't been specified
if( (tol == T(0)) && (s.n_elem > 0) ) { tol = (std::max)(n_rows, n_cols) * s[0] * std::numeric_limits<T>::epsilon(); }
if(arma_isnan(tol)) { return false; }
uword count = 0;
for(uword i=0; i < s.n_elem; ++i) { count += (s[i] >= tol) ? uword(1) : uword(0); }
+2 -2
View File
@@ -268,8 +268,8 @@ op_princomp::direct_princomp
typedef typename T1::elem_type eT;
typedef typename T1::pod_type T;
const unwrap<T1> Y( X.get_ref() );
const Mat<eT>& in = Y.M;
const plain_unwrap<T1> Y( X.get_ref() );
const Mat<eT>& in = Y.M;
if(in.n_elem != 0)
{
+18 -6
View File
@@ -87,6 +87,8 @@ op_rank::apply_diag(uword& out, Mat<eT>& A, typename get_pod_type<eT>::result to
typedef typename get_pod_type<eT>::result T;
out = uword(0);
const uword N = (std::min)(A.n_rows, A.n_cols);
podarray<T> diag_abs_vals(N);
@@ -98,7 +100,7 @@ op_rank::apply_diag(uword& out, Mat<eT>& A, typename get_pod_type<eT>::result to
const eT Aii = A.at(i,i);
const T abs_Aii = std::abs(Aii);
if(arma_isnan(Aii)) { out = uword(0); return false; }
if(arma_isnan(Aii)) { return false; }
diag_abs_vals[i] = abs_Aii;
@@ -108,6 +110,8 @@ op_rank::apply_diag(uword& out, Mat<eT>& A, typename get_pod_type<eT>::result to
// set tolerance to default if it hasn't been specified
if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * max_abs_Aii * std::numeric_limits<T>::epsilon(); }
if(arma_isnan(tol)) { return false; }
uword count = 0;
for(uword i=0; i<N; ++i) { count += (diag_abs_vals[i] > tol) ? uword(1) : uword(0); }
@@ -128,18 +132,20 @@ op_rank::apply_sym(uword& out, Mat<eT>& A, typename get_pod_type<eT>::result tol
typedef typename get_pod_type<eT>::result T;
if(A.is_square() == false) { out = uword(0); return false; }
out = uword(0);
if(A.is_square() == false) { return false; }
Col<T> v;
const bool status = auxlib::eig_sym(v, A);
if(status == false) { out = uword(0); return false; }
if(status == false) { return false; }
const uword v_n_elem = v.n_elem;
T* v_mem = v.memptr();
if(v_n_elem == 0) { out = uword(0); return true; }
if(v_n_elem == 0) { return true; }
T max_abs_v = T(0);
@@ -148,6 +154,8 @@ op_rank::apply_sym(uword& out, Mat<eT>& A, typename get_pod_type<eT>::result tol
// set tolerance to default if it hasn't been specified
if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * max_abs_v * std::numeric_limits<T>::epsilon(); }
if(arma_isnan(tol)) { return false; }
uword count = 0;
for(uword i=0; i < v_n_elem; ++i) { count += (v_mem[i] > tol) ? uword(1) : uword(0); }
@@ -168,20 +176,24 @@ op_rank::apply_gen(uword& out, Mat<eT>& A, typename get_pod_type<eT>::result tol
typedef typename get_pod_type<eT>::result T;
out = uword(0);
Col<T> s;
const bool status = auxlib::svd_dc(s, A);
if(status == false) { out = uword(0); return false; }
if(status == false) { return false; }
const uword s_n_elem = s.n_elem;
const T* s_mem = s.memptr();
if(s_n_elem == 0) { out = uword(0); return true; }
if(s_n_elem == 0) { return true; }
// set tolerance to default if it hasn't been specified
if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * s_mem[0] * std::numeric_limits<T>::epsilon(); }
if(arma_isnan(tol)) { return false; }
uword count = 0;
for(uword i=0; i < s_n_elem; ++i) { count += (s_mem[i] > tol) ? uword(1) : uword(0); }
@@ -28,6 +28,8 @@ struct op_repelem
template<typename obj> inline static void apply_noalias(Mat<typename obj::elem_type>& out, const obj& X, const uword copies_per_row, const uword copies_per_col);
template<typename T1> inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_repelem>& in);
template<typename T1> inline static void apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1,op_repelem>& in);
};
@@ -100,4 +100,21 @@ op_repelem::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_repelem>& in)
template<typename T1>
inline
void
op_repelem::apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1,op_repelem>& in)
{
arma_debug_sigprint();
const uword copies_per_row = in.aux_uword_a;
const uword copies_per_col = in.aux_uword_b;
const quasi_unwrap<T1> U(in.m);
op_repelem::apply_noalias(out, U.M, copies_per_row, copies_per_col);
}
//! @}
+2 -2
View File
@@ -36,8 +36,8 @@ op_reshape::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_reshape>& in)
if(is_Mat<T1>::value)
{
const unwrap<T1> U(in.m);
const Mat<eT>& A = U.M;
const plain_unwrap<T1> U(in.m);
const Mat<eT>& A = U.M;
if(&out == &A)
{
+2 -2
View File
@@ -36,8 +36,8 @@ op_resize::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_resize>& in)
if(is_Mat<T1>::value)
{
const unwrap<T1> U(in.m);
const Mat<eT>& A = U.M;
const plain_unwrap<T1> U(in.m);
const Mat<eT>& A = U.M;
if(&out == &A)
{
+2 -2
View File
@@ -36,7 +36,7 @@ op_reverse::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_reverse>& in)
if(is_Mat<T1>::value)
{
const unwrap<T1> U(in.m);
const plain_unwrap<T1> U(in.m);
if(&out == &(U.M))
{
@@ -101,7 +101,7 @@ op_reverse_vec::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_reverse_v
if(is_Mat<T1>::value)
{
const unwrap<T1> U(in.m);
const plain_unwrap<T1> U(in.m);
if(&out == &(U.M))
{
+2 -2
View File
@@ -213,7 +213,7 @@ op_shuffle::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_shuffle>& in)
{
arma_debug_sigprint();
const unwrap<T1> U(in.m);
const plain_unwrap<T1> U(in.m);
const uword dim = in.aux_uword_a;
@@ -231,7 +231,7 @@ op_shuffle_vec::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_shuffle_v
{
arma_debug_sigprint();
const unwrap<T1> U(in.m);
const plain_unwrap<T1> U(in.m);
const uword dim = (T1::is_xvec) ? uword(U.M.is_rowvec() ? 1 : 0) : uword((T1::is_row) ? 1 : 0);
+2 -2
View File
@@ -264,8 +264,8 @@ op_sort_vec::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_sort_vec>& i
typedef typename T1::elem_type eT;
const unwrap<T1> U(in.m); // not using quasi_unwrap, to ensure there is no aliasing with subviews
const Mat<eT>& X = U.M;
const plain_unwrap<T1> U(in.m); // not using quasi_unwrap, to ensure there is no aliasing with subviews
const Mat<eT>& X = U.M;
const uword sort_mode = in.aux_uword_a;
+2 -2
View File
@@ -477,8 +477,8 @@ op_sqrtmat_sympd::apply_direct(Mat<typename T1::elem_type>& out, const Base<type
typedef typename T1::elem_type eT;
typedef typename T1::pod_type T;
const unwrap<T1> U(expr.get_ref());
const Mat<eT>& X = U.M;
const plain_unwrap<T1> U(expr.get_ref());
const Mat<eT>& X = U.M;
arma_conform_check( (X.is_square() == false), "sqrtmat_sympd(): given matrix must be square sized" );
+1 -1
View File
@@ -389,7 +389,7 @@ op_strans::apply_direct(Mat<typename T1::elem_type>& out, const T1& X)
// allow detection of in-place transpose
if(is_Mat<T1>::value)
{
const unwrap<T1> U(X);
const plain_unwrap<T1> U(X);
op_strans::apply_mat(out, U.M);
}
+8 -8
View File
@@ -30,8 +30,8 @@ op_symmatu::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_symmatu>& in)
typedef typename T1::elem_type eT;
const unwrap<T1> tmp(in.m);
const Mat<eT>& A = tmp.M;
const plain_unwrap<T1> tmp(in.m);
const Mat<eT>& A = tmp.M;
arma_conform_check( (A.is_square() == false), "symmatu(): given matrix must be square sized" );
@@ -81,8 +81,8 @@ op_symmatl::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_symmatl>& in)
typedef typename T1::elem_type eT;
const unwrap<T1> tmp(in.m);
const Mat<eT>& A = tmp.M;
const plain_unwrap<T1> tmp(in.m);
const Mat<eT>& A = tmp.M;
arma_conform_check( (A.is_square() == false), "symmatl(): given matrix must be square sized" );
@@ -136,8 +136,8 @@ op_symmatu_cx::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_symmatu_cx
typedef typename T1::elem_type eT;
const unwrap<T1> tmp(in.m);
const Mat<eT>& A = tmp.M;
const plain_unwrap<T1> tmp(in.m);
const Mat<eT>& A = tmp.M;
arma_conform_check( (A.is_square() == false), "symmatu(): given matrix must be square sized" );
@@ -210,8 +210,8 @@ op_symmatl_cx::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_symmatl_cx
typedef typename T1::elem_type eT;
const unwrap<T1> tmp(in.m);
const Mat<eT>& A = tmp.M;
const plain_unwrap<T1> tmp(in.m);
const Mat<eT>& A = tmp.M;
arma_conform_check( (A.is_square() == false), "symmatl(): given matrix must be square sized" );
+5 -5
View File
@@ -70,7 +70,7 @@ op_trimat::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_trimat>& in)
// allow detection of in-place operation
if(is_Mat<T1>::value)
{
const unwrap<T1> U(in.m);
const plain_unwrap<T1> U(in.m);
if(&out == &(U.M))
{
@@ -236,8 +236,8 @@ op_trimatu_ext::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_trimatu_e
typedef typename T1::elem_type eT;
const unwrap<T1> tmp(in.m);
const Mat<eT>& A = tmp.M;
const plain_unwrap<T1> tmp(in.m);
const Mat<eT>& A = tmp.M;
arma_conform_check( (A.is_square() == false), "trimatu(): given matrix must be square sized" );
@@ -327,8 +327,8 @@ op_trimatl_ext::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_trimatl_e
typedef typename T1::elem_type eT;
const unwrap<T1> tmp(in.m);
const Mat<eT>& A = tmp.M;
const plain_unwrap<T1> tmp(in.m);
const Mat<eT>& A = tmp.M;
arma_conform_check( (A.is_square() == false), "trimatl(): given matrix must be square sized" );

Some files were not shown because too many files have changed in this diff Show More