Compare commits

...
61 Commits
Author SHA1 Message Date
conrad 7334664999 patch bump 2026-03-15 18:42:19 +10:00
conrad f021766215 speedups for blank sparse submatrices 2026-03-15 17:33:41 +10:00
conrad 5491a20833 simplifications 2026-03-13 12:16:51 +10:00
conrad 1cab3be4df simplifications 2026-03-13 11:52:44 +10:00
conrad 08e1cb5211 specialisation for subview::zeros() 2026-03-13 11:33:39 +10:00
conrad 70c45a2f17 workarounds for ASAN false positives 2026-03-12 18:21:38 +10:00
conrad 2dfed59b94 simplifications 2026-03-12 15:57:37 +10:00
conrad 8bf7834041 simplifications 2026-03-12 15:48:04 +10:00
conrad 1461d33045 simplifications 2026-03-12 15:32:54 +10:00
conrad e05bc82e7b speedups for empty subcubes 2026-03-12 15:30:34 +10:00
conrad 9201e8ddd0 speedups for empty cubes 2026-03-12 15:23:18 +10:00
conrad 30dd62780b speedups for empty cubes 2026-03-12 12:21:15 +10:00
conrad 5dd6c665a5 speedups for empty cubes 2026-03-12 11:55:26 +10:00
conrad 2e6b4ed0a3 speedups for empty cubes 2026-03-11 17:09:31 +10:00
conrad 08c0647e54 speedups for empty matrices 2026-03-11 16:55:26 +10:00
conrad ff7f5d63e6 speedups for empty matrices 2026-03-11 15:12:59 +10:00
conrad 2288ec1497 remove superfluous comments 2026-03-11 15:12:32 +10:00
conrad 1df5fc83b7 speedups for blank sparse matrices 2026-03-10 15:58:00 +10:00
conrad 81df0a1f93 simplifications 2026-03-10 15:51:02 +10:00
conrad bceaf09865 speedups for blank sparse submatrices 2026-03-10 13:14:08 +10:00
conrad 3992546579 speedups for blank sparse submatrices 2026-03-10 12:31:16 +10:00
conrad 602f6217e0 speedups for blank sparse submatrices 2026-03-10 12:01:54 +10:00
conrad 449e6f682f speedups for blank sparse matrices 2026-03-10 11:51:20 +10:00
conrad 03df540096 fix error message 2026-03-09 13:29:19 +10:00
conrad b21700fc85 check if sizes are the same 2026-03-09 13:25:32 +10:00
conrad 02438fff53 speedups for blank sparse submatrices 2026-03-09 13:17:36 +10:00
conrad 451d5d2cec speedups for empty submatrices 2026-03-05 15:50:01 +10:00
conrad 534f135ef5 speedups for empty submatrices 2026-03-04 15:32:54 +10:00
conrad 8bd0d6692a speedups for empty subcubes 2026-03-04 15:24:34 +10:00
conrad ad1bed2686 speedups for empty submatrices 2026-02-28 14:11:47 +10:00
conrad 36e3d67a28 speedups for empty submatrices 2026-02-27 13:35:17 +10:00
conrad e3db651df7 speedup for empty submatrices 2026-02-27 13:07:40 +10:00
conrad fa52e3f5ef speedup for empty subcubes 2026-02-25 13:11:14 +10:00
conrad e6b06b21da speedup for empty matrices 2026-02-23 17:04:55 +10:00
conrad 252708e389 get pointer to first element via dedicated function 2026-02-20 13:17:43 +10:00
conrad 4b468f5009 simplifications 2026-02-20 10:47:28 +10:00
conrad 1244651dda simpler wording 2026-02-11 17:26:57 +10:00
conrad e4b96542b3 improve docs for .col_as_mat() and .row_as_mat() 2026-02-10 12:22:25 +10:00
conrad 5701dd07a8 avoid potentially confusing debug message 2026-02-05 15:21:14 +10:00
conrad bdc89797cd improved wording 2026-02-03 12:15:10 +10:00
conrad 2110b7d82c improved wording and layout 2026-02-03 11:53:05 +10:00
conrad 3bcfde3238 avoid repetition 2026-02-02 16:51:23 +10:00
conrad 3495f87581 better wording 2026-02-02 16:49:09 +10:00
conrad 8a24c0d724 expand fill types 2026-02-02 13:33:39 +10:00
conrad ec75a6107c expand docs for .fill() with notes on element initialisation during construction 2026-01-30 13:29:45 +10:00
conrad 450e1ba8a5 use explicit initialisation 2026-01-29 13:39:36 +10:00
conrad a0dcf97054 use explicit initialisation 2026-01-28 17:11:43 +10:00
conrad cd96c0d9e2 update paper 2026-01-02 12:25:10 +10:00
conrad 5e4ce67bf4 patch bump 2025-12-16 13:25:46 +10:00
conrad 7dbe9fa6c3 add LLM prohibition section 2025-12-16 13:03:19 +10:00
conrad 7da30298dd add RSL section to head 2025-12-15 14:19:05 +10:00
conrad f347a5640e simplification 2025-12-11 19:07:05 +10:00
conrad c7433b6e60 allow memory reuse with size growth 2025-12-11 16:22:29 +10:00
conrad e712b832e8 simplification 2025-12-11 15:14:55 +10:00
conrad 8a736f85a3 reuse memory where possible 2025-12-11 15:09:16 +10:00
conrad 9f8bf056c2 simplification 2025-12-11 14:20:05 +10:00
conrad b79a7e005c use explicit initialisation 2025-12-10 18:57:17 +10:00
conrad cae3a6a4bf optimise .resize() for small vectors that fit within pre-allocated memory 2025-12-10 15:12:17 +10:00
conrad fb6278f692 return early if resized matrix is empty 2025-12-10 15:11:10 +10:00
conrad 8622e81b8a faster repcube() 2025-12-10 12:31:03 +10:00
conrad f788d4032f emit more info on linker config 2025-12-10 12:28:19 +10:00
27 changed files with 1095 additions and 532 deletions
+4 -2
View File
@@ -381,10 +381,11 @@ else()
set(ARMA_LIBS ${ARMA_LIBS} ${MKL_LIBRARIES})
message(STATUS "")
message(STATUS "*** If the MKL libraries are installed in non-standard locations such as")
message(STATUS "*** If the MKL libraries are installed in a non-standard location such as")
message(STATUS "*** /opt/intel/mkl, /opt/intel/composerxe/, /usr/local/intel/mkl")
message(STATUS "*** make sure the run-time linker can find them.")
message(STATUS "*** On Linux systems this can be done by editing /etc/ld.so.conf")
message(STATUS "*** or specifying the location through a file in /etc/ld.so.conf.d/")
message(STATUS "*** or modifying the LD_LIBRARY_PATH environment variable.")
message(STATUS "")
message(STATUS "*** On systems with SELinux enabled (eg. Fedora, RHEL),")
@@ -419,10 +420,11 @@ else()
endif()
message(STATUS "")
message(STATUS "*** If the OpenBLAS library is installed in")
message(STATUS "*** If the OpenBLAS library is installed in a location such as")
message(STATUS "*** /usr/local/lib or /usr/local/lib64")
message(STATUS "*** make sure the run-time linker can find it.")
message(STATUS "*** On Linux systems this can be done by editing /etc/ld.so.conf")
message(STATUS "*** or specifying the location through a file in /etc/ld.so.conf.d/")
message(STATUS "*** or modifying the LD_LIBRARY_PATH environment variable.")
message(STATUS "")
+14 -4
View File
@@ -38,7 +38,8 @@ Copyright 2017-2025 Data61 / CSIRO
13. [API Stability and Version Policy](#13-api-stability-and-version-policy)
14. [Bug Reports and Frequently Asked Questions](#14-bug-reports-and-frequently-asked-questions)
15. [Related Software Using Armadillo](#15-related-software-using-armadillo)
15. [Prohibition on Use of Large Language Models (LLMs)](#15-prohibition-on-use-of-large-language-models-llms)
16. [Related Software Using Armadillo](#16-related-software-using-armadillo)
---
@@ -390,8 +391,8 @@ Use a web browser to view it.
Use of the C++11 `auto` keyword is not recommended with Armadillo objects and expressions.
Armadillo has a template meta-programming framework which creates short-lived temporaries
that are not properly handled by `auto`.
Armadillo has a template meta-programming framework which creates short-lived
temporary objects that are not properly handled by `auto`.
---
@@ -451,7 +452,16 @@ https://arma.sourceforge.net/faq.html
---
### 15: Related Software Using Armadillo
### 15: Prohibition on Use of Large Language Models (LLMs)
The Armadillo codebase has been developed entirely without the use of LLMs.
We do not accept any code which has been created (directly or indirectly)
with the aid of LLMs. This is due to issues with code provenance and low quality
of LLM generated code.
---
### 16: Related Software Using Armadillo
* MLPACK: extensive library of machine learning algorithms
https://mlpack.org
Binary file not shown.
+75 -25
View File
@@ -21,6 +21,15 @@ limitations under the License.
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
<title>Armadillo: API Documentation</title>
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAARpJREFUOMtjYMABzFuiGYE4BohPA/FvIP6Phv8CMTcuzVxAvAGqeTYQT0HCd6AG3MSlmRWIdwNxLhY5MyC+ADVgLS4DyqAK2NDEBaAuiobKt+Ay4CZUgQRaeKwCYj8gTofKR+My4CNUQSSSWCYQT4ay+6HyprgMOADEs4BYFso3AOITQMwB5W+HGsCPMxCR2LxAfA6INZHE7gHxGwZCAOrvFUDcCsQqUKwFxP+A+CQxBpRgSTwwvIKQZm8gfgbEVkCsgYRToQZ049NsBtVshEUuA2pAAYpfoTQzEEcB8QsgtsdheA/UgFhkwV1AfBuIPwDxOyC2xeO6jVAD5kBd6gQS/AbEX4F4JRDLEwgbUHp4CsRboLETzkApAADMF8+Pl3d18QAAAABJRU5ErkJggg==">
<script type="application/rsl+xml">
<rsl xmlns="https://rslstandard.org/rsl">
<content url="">
<license>
<prohibits type="usage">ai-train ai-input</prohibits>
</license>
</content>
</rsl>
</script>
<style type="text/css">
<!--
body
@@ -245,8 +254,9 @@ Conrad Sanderson and Ryan Curtin.
<tr><td><a href="#Col">Col&lt;<i>type</i>&gt;, colvec, vec</a></td><td>&nbsp;</td><td>dense column vector class</td></tr>
<tr><td><a href="#Row">Row&lt;<i>type</i>&gt;, rowvec</a></td><td>&nbsp;</td><td>dense row vector class</td></tr>
<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
<tr><td><a href="#Cube">Cube&lt;<i>type</i>&gt;, cube, cx_cube</a></td><td>&nbsp;</td><td>dense cube class ("3D matrix")</td></tr>
<tr><td><a href="#Cube">Cube&lt;<i>type</i>&gt;, cube, cx_cube</a></td><td>&nbsp;</td><td>dense cube class (quasi third-order tensor, aka "3D matrix")</td></tr>
<tr><td><a href="#field">field&lt;<i>object&nbsp;type</i>&gt;</a></td><td>&nbsp;</td><td>class for storing arbitrary objects in matrix-like or cube-like layouts</td></tr>
<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
<tr><td><a href="#SpMat">SpMat&lt;<i>type</i>&gt;, sp_mat, sp_cx_mat</a></td><td>&nbsp;</td><td>sparse matrix class</td></tr>
<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
<tr><td><a href="#operators">operators</a></td><td>&nbsp;</td><td><code><big>+</big>&nbsp; <big>&minus;</big>&nbsp; <big>*</big>&nbsp; %&nbsp; /&nbsp; ==&nbsp; !=&nbsp; &lt;=&nbsp; &gt;=&nbsp; &lt;&nbsp; &gt;&nbsp; &amp;&amp;&nbsp; ||</code></td></tr>
@@ -751,6 +761,8 @@ Functions which use LAPACK (generally matrix decompositions) are only valid for
<a name="constructors_mat"></a>
<li>
Constructors:
<br>
<br>
<ul>
<table>
<tbody>
@@ -775,22 +787,27 @@ Constructors:
<li>
Matrix elements can be explicitly initialised during construction by specifying <i>fill_form</i>,
which is one of:
<br>
<br>
<ul>
<table>
<tbody>
<tr><td><code>fill::zeros</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to 0</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::eye</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set the 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 all 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 all elements to random values from a normal/Gaussian distribution with zero mean and unit variance</td></tr>
<tr><td><code>fill::value(scalar)</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to specified scalar</td></tr>
<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::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>
<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>
</tbody>
</table>
</ul>
</li>
<br>
<li>Default element initialisation is <code>fill::zeros</code> (since Armadillo 10.5)</li>
<li>If <i>fill_form</i> is not specified, <i>fill::zeros</i> is used by default (since Armadillo 10.5)</li>
<br>
<li>
For the <i>mat(string)</i> constructor, the format is elements separated by spaces, and rows denoted by semicolons;
@@ -1145,6 +1162,8 @@ main exceptions are functions which require square matrices
<br>
<li>
Constructors:
<br>
<br>
<ul>
<table>
<tbody>
@@ -1417,6 +1436,8 @@ main exceptions are functions which require square matrices
<br>
<li>
Constructors:
<br>
<br>
<ul>
<table>
<tbody>
@@ -1543,11 +1564,11 @@ rowvec z = A.row(5); // extract a row vector
<br><b>cx_cube</b>
<ul>
<li>
Classes for cubes (quasi 3rd order tensors), also known as "3D matrices"
Classes for cubes (quasi third-order tensors, aka "3D matrices")
</li>
<br>
<li>
Data is stored as a set of slices (matrices) stored contiguously within memory;
Data is stored as an ordered set of slices (matrices) placed contiguously within memory;
within each slice, elements are stored with column-major ordering (ie. column by column)
</li>
<br>
@@ -1695,6 +1716,8 @@ it is possible to use other types instead, eg. <i>fcube</i>
<a name="constructors_cube"></a>
<li>
Constructors:
<br>
<br>
<ul>
<table>
<tbody>
@@ -1713,21 +1736,26 @@ Constructors:
<li>
Cube elements can be explicitly initialised during construction by specifying <i>fill_form</i>,
which is one of:
<br>
<br>
<ul>
<table>
<tbody>
<tr><td><code>fill::zeros</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to 0</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::randu</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all 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 all elements to random values from a normal/Gaussian distribution with zero mean and unit variance</td></tr>
<tr><td><code>fill::value(scalar)</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to specified scalar</td></tr>
<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::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>
</tbody>
</table>
</ul>
</li>
<br>
<li>Default element initialisation is <code>fill::zeros</code> (since Armadillo 10.5)</li>
<li>If <i>fill_form</i> is not specified, <i>fill::zeros</i> is used by default (since Armadillo 10.5)</li>
<br>
<li>
Each instance of <i>cube</i> automatically allocates and releases internal memory.
@@ -1863,6 +1891,8 @@ Each element can have an arbitrary size (eg. in a field of matrices, each matrix
<br>
<li>
Constructors, where <i>object_type</i> is another class, eg. <i>vec</i>, <i>mat</i>, <i>std::string</i>, etc:
<br>
<br>
<ul>
<table>
<tbody>
@@ -1889,6 +1919,7 @@ mat A = randn(2,3);
mat B = randn(4,5);
field&lt;mat&gt; F(2,1);
F(0,0) = A;
F(1,0) = B;
@@ -2063,6 +2094,8 @@ it is possible to use other types instead, eg. <i>sp_fmat</i>
<a name="constructors_sp_mat"></a>
<li>
Constructors:
<br>
<br>
<ul>
<table>
<tbody>
@@ -2100,6 +2133,8 @@ for small matrices use the <a href="#Mat">Mat</a> class, even if most of the ele
<li>
<a name="batch_constructors_sp_mat"></a>
Batch insertion constructors:
<br>
<br>
<ul>
<li>form&nbsp;1: <code>sp_mat(<i>locations</i>, <i>values</i>, <i>sort_locations&thinsp;=&thinsp;true</i>)</code></li>
<li>form&nbsp;2: <code>sp_mat(<i>locations</i>, <i>values</i>, <i>n_rows</i>, <i>n_cols</i>, <i>sort_locations&thinsp;=&thinsp;true</i>, <i>check_for_zeros&thinsp;=&thinsp;true</i>)</code></li>
@@ -2153,6 +2188,8 @@ If <i>check_for_zeros</i> is set to <i>false</i>, the <i>values</i> vector is as
<br>
<li>
The following subset of operations &amp; functions is available for sparse matrices:
<br>
<br>
<ul>
<li>fundamental arithmetic <a href="#operators">operations</a> (such as addition and multiplication)</li>
<li><a href="#submat">submatrix views</a>: most contiguous forms and the non-contiguous form of <i>X.cols(vector_of_column_indices)</i></li>
@@ -2932,6 +2969,7 @@ C.eye();
<li>See also:
<ul>
<li><a href="#ones_member">.ones()</a></li>
<li><a href="#fill">.fill()</a></li>
<li><a href="#diag">.diag()</a></li>
<li><a href="#diagmat">diagmat()</a></li>
<li><a href="#diagvec">diagvec()</a></li>
@@ -3090,7 +3128,7 @@ See also:
Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i>, <i>field</i>
</li>
<br>
<li>Sets the elements to a specified value</li>
<li>Sets all elements to a specified value</li>
<br>
<li>The type of value must match the type of elements used by the container object (eg. for <i>mat</i> the type is <i>double</i>)
</li>
@@ -3101,29 +3139,38 @@ Examples:
<pre>
mat A(5, 6);
A.fill(123.0); // or: mat A(5, 6, fill::value(123.0));
A.fill(123.0);
</pre>
</ul>
</li>
<br>
<li>
<b>Note:</b> to set all elements to zero during matrix construction, use the following more compact form:
<b>Caveats:</b>
<ul>
<li>To initialise all elements during matrix construction, it is more efficient to use a <i><a href="#Mat">fill_form</a></i>:
<ul>
<pre>
mat A(5, 6, fill::zeros);
mat B(5, 6, fill::ones);
mat C(5, 6, fill::value(123.0));
</pre>
</ul>
</li>
<li>If <i>fill_form</i> is not specified, <i>fill::zeros</i> is used by default (since Armadillo 10.5)</li>
</ul>
</li>
<br>
<li>
See also:
<ul>
<li><a href="#imbue">.imbue()</a></li>
<li><a href="#ones_member">.ones()</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>
<li><a href="#randu_randn_member">.randu() &amp; .randn()</a></li>
<li><a href="#replace">.replace()</a></li>
<li><a href="#constants">constants (pi, nan, inf, ...)</a></li>
<li><a href="#Mat">matrix constructors</a></li>
</ul>
</li>
<br>
@@ -4071,8 +4118,8 @@ Instances of <i>span(a,b)</i> can be replaced by:
</li>
<br>
<li>
An individual slice, accessed via <i>.slice()</i>, is an instance of the <i>Mat</i> class
(a reference to a matrix is provided)
A single slice, accessed via <i>.slice(slice_number)</i>, is an instance of the <i>Mat</i> class (a reference to a matrix is provided);
<br>see also <i>.<a href="#col_row_as_mat">col_as_mat()</a></i> and <i>.<a href="#col_row_as_mat">row_as_mat()</a></i>
</li>
<br>
<li>
@@ -5805,6 +5852,7 @@ Examples:
<ul>
<pre>
mat X(4, 5, fill::randu);
vec v = X.as_col();
</pre>
</ul>
@@ -5858,9 +5906,11 @@ Examples:
<pre>
cube Q(5, 4, 3, fill::randu);
mat A = Q.col_as_mat(2); // size of A: 5x3
mat A = Q.slice(2); // size of A: 5x4
mat B = Q.row_as_mat(2); // size of B: 3x4
mat B = Q.col_as_mat(2); // size of B: 5x3
mat C = Q.row_as_mat(2); // size of C: 3x4
</pre>
</ul>
</li>
@@ -18427,7 +18477,7 @@ An instance of the class has the following member functions:
</td>
<td style="vertical-align: top;">
return the number of seconds since the last call to <code>.tic()</code>,
with the returned number of seconds reduced by any freeze/unfreeze durations
with the number of seconds reduced by any freeze/unfreeze durations
</td>
</tr>
<tr>
+4
View File
@@ -1344,6 +1344,10 @@ Col<eT>::fixed<fixed_n_elem>::fixed(const fill::fill_class<fill_type>&)
if(is_same_type<fill_type, fill::fill_eye >::yes) { Mat<eT>::eye(); }
if(is_same_type<fill_type, fill::fill_randu>::yes) { Mat<eT>::randu(); }
if(is_same_type<fill_type, fill::fill_randn>::yes) { Mat<eT>::randn(); }
if(is_same_type<fill_type, fill::fill_nan >::yes) { (*this).fill( priv::Datum_helper::nan <eT>() ); }
if(is_same_type<fill_type, fill::fill_pos_inf>::yes) { (*this).fill( priv::Datum_helper::pos_inf<eT>() ); }
if(is_same_type<fill_type, fill::fill_neg_inf>::yes) { (*this).fill( priv::Datum_helper::neg_inf<eT>() ); }
}
+3
View File
@@ -360,6 +360,9 @@ class Cube : public BaseCube< eT, Cube<eT> >
inline Cube& fill(const eT val);
template<typename fill_type>
inline Cube& fill(const fill::fill_class<fill_type>& f);
inline Cube& zeros();
inline Cube& zeros(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices);
inline Cube& zeros(const SizeCube& s);
+41 -32
View File
@@ -52,7 +52,7 @@ Cube<eT>::Cube()
, n_elem(0)
, n_alloc(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
}
@@ -172,7 +172,7 @@ Cube<eT>::Cube(const SizeCube& s, const arma_initmode_indicator<do_zeros>&)
template<typename eT>
template<typename fill_type>
inline
Cube<eT>::Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices, const fill::fill_class<fill_type>&)
Cube<eT>::Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices, const fill::fill_class<fill_type>& f)
: n_rows(in_n_rows)
, n_cols(in_n_cols)
, n_elem_slice(in_n_rows*in_n_cols)
@@ -186,12 +186,7 @@ Cube<eT>::Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_sl
init_cold();
if(is_same_type<fill_type, fill::fill_zeros>::yes) { (*this).zeros(); }
if(is_same_type<fill_type, fill::fill_ones >::yes) { (*this).ones(); }
if(is_same_type<fill_type, fill::fill_randu>::yes) { (*this).randu(); }
if(is_same_type<fill_type, fill::fill_randn>::yes) { (*this).randn(); }
arma_static_check( (is_same_type<fill_type, fill::fill_eye>::yes), "Cube::Cube(): unsupported fill type" );
(*this).fill(f);
}
@@ -199,7 +194,7 @@ Cube<eT>::Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_sl
template<typename eT>
template<typename fill_type>
inline
Cube<eT>::Cube(const SizeCube& s, const fill::fill_class<fill_type>&)
Cube<eT>::Cube(const SizeCube& s, const fill::fill_class<fill_type>& f)
: n_rows(s.n_rows)
, n_cols(s.n_cols)
, n_elem_slice(s.n_rows*s.n_cols)
@@ -213,12 +208,7 @@ Cube<eT>::Cube(const SizeCube& s, const fill::fill_class<fill_type>&)
init_cold();
if(is_same_type<fill_type, fill::fill_zeros>::yes) { (*this).zeros(); }
if(is_same_type<fill_type, fill::fill_ones >::yes) { (*this).ones(); }
if(is_same_type<fill_type, fill::fill_randu>::yes) { (*this).randu(); }
if(is_same_type<fill_type, fill::fill_randn>::yes) { (*this).randn(); }
arma_static_check( (is_same_type<fill_type, fill::fill_eye>::yes), "Cube::Cube(): unsupported fill type" );
(*this).fill(f);
}
@@ -934,7 +924,7 @@ Cube<eT>::Cube
, n_elem(0)
, n_alloc(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -1064,7 +1054,7 @@ Cube<eT>::Cube(const subview_cube_slices<eT,T1>& X)
, n_elem(0)
, n_alloc(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2751,7 +2741,7 @@ Cube<eT>::Cube(const OpCube<T1, op_type>& X)
, n_elem(0)
, n_alloc(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -3048,7 +3038,7 @@ Cube<eT>::Cube(const mtOpCube<eT, T1, op_type>& X)
, n_elem(0)
, n_alloc(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -3144,7 +3134,7 @@ Cube<eT>::Cube(const GlueCube<T1, T2, glue_type>& X)
, n_elem(0)
, n_alloc(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -3401,7 +3391,7 @@ Cube<eT>::Cube(const mtGlueCube<eT, T1, T2, glue_type>& X)
, n_elem(0)
, n_alloc(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -3887,7 +3877,7 @@ arma_inline
eT*
Cube<eT>::slice_memptr(const uword uslice)
{
return const_cast<eT*>( &mem[ uslice*n_elem_slice ] );
return access::rwp( mem + (uslice*n_elem_slice) );
}
@@ -3898,7 +3888,7 @@ arma_inline
const eT*
Cube<eT>::slice_memptr(const uword uslice) const
{
return &mem[ uslice*n_elem_slice ];
return mem + (uslice*n_elem_slice);
}
@@ -3909,7 +3899,7 @@ arma_inline
eT*
Cube<eT>::slice_colptr(const uword uslice, const uword col)
{
return const_cast<eT*>( &mem[ uslice*n_elem_slice + col*n_rows] );
return access::rwp( mem + (uslice*n_elem_slice + col*n_rows) );
}
@@ -3920,7 +3910,7 @@ arma_inline
const eT*
Cube<eT>::slice_colptr(const uword uslice, const uword col) const
{
return &mem[ uslice*n_elem_slice + col*n_rows ];
return mem + (uslice*n_elem_slice + col*n_rows);
}
@@ -4227,6 +4217,30 @@ Cube<eT>::fill(const eT val)
template<typename eT>
template<typename fill_type>
inline
Cube<eT>&
Cube<eT>::fill(const fill::fill_class<fill_type>&)
{
arma_debug_sigprint();
arma_static_check( (is_same_type<fill_type, fill::fill_eye>::yes), "Cube::fill(): unsupported fill type" );
if(is_same_type<fill_type, fill::fill_zeros>::yes) { (*this).zeros(); }
if(is_same_type<fill_type, fill::fill_ones >::yes) { (*this).ones(); }
if(is_same_type<fill_type, fill::fill_randu>::yes) { (*this).randu(); }
if(is_same_type<fill_type, fill::fill_randn>::yes) { (*this).randn(); }
if(is_same_type<fill_type, fill::fill_nan >::yes) { (*this).fill( priv::Datum_helper::nan <eT>() ); }
if(is_same_type<fill_type, fill::fill_pos_inf>::yes) { (*this).fill( priv::Datum_helper::pos_inf<eT>() ); }
if(is_same_type<fill_type, fill::fill_neg_inf>::yes) { (*this).fill( priv::Datum_helper::neg_inf<eT>() ); }
return *this;
}
template<typename eT>
inline
Cube<eT>&
@@ -5458,18 +5472,13 @@ template<typename eT>
template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices>
template<typename fill_type>
inline
Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::fixed(const fill::fill_class<fill_type>&)
Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::fixed(const fill::fill_class<fill_type>& f)
{
arma_debug_sigprint_this(this);
mem_setup();
if(is_same_type<fill_type, fill::fill_zeros>::yes) { Cube<eT>::zeros(); }
if(is_same_type<fill_type, fill::fill_ones >::yes) { Cube<eT>::ones(); }
if(is_same_type<fill_type, fill::fill_randu>::yes) { Cube<eT>::randu(); }
if(is_same_type<fill_type, fill::fill_randn>::yes) { Cube<eT>::randn(); }
arma_static_check( (is_same_type<fill_type, fill::fill_eye>::yes), "Cube::fixed::fixed(): unsupported fill type" );
(*this).fill(f);
}
+102 -72
View File
@@ -49,7 +49,7 @@ Mat<eT>::Mat()
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
}
@@ -255,7 +255,7 @@ Mat<eT>::Mat(const arma_vec_indicator&, const uhword in_vec_state)
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
}
@@ -312,15 +312,10 @@ Mat<eT>::init_cold()
const char* error_message = "Mat::init(): requested size is too large; suggest to enable ARMA_64BIT_WORD";
#endif
arma_conform_check
(
(
( (n_rows > ARMA_MAX_UHWORD) || (n_cols > ARMA_MAX_UHWORD) )
? ( (double(n_rows) * double(n_cols)) > double(ARMA_MAX_UWORD) )
: false
),
error_message
);
if( (n_rows > ARMA_MAX_UHWORD) || (n_cols > ARMA_MAX_UHWORD) )
{
arma_conform_check( ( (double(n_rows) * double(n_cols)) > double(ARMA_MAX_UWORD) ), error_message );
}
if(n_elem <= arma_config::mat_prealloc)
{
@@ -383,17 +378,10 @@ Mat<eT>::init_warm(uword in_n_rows, uword in_n_cols)
const char* error_message_4 = "Mat::init(): requested size is too large; suggest to enable ARMA_64BIT_WORD";
#endif
arma_conform_set_error
(
err_state,
err_msg,
(
( (in_n_rows > ARMA_MAX_UHWORD) || (in_n_cols > ARMA_MAX_UHWORD) )
? ( (double(in_n_rows) * double(in_n_cols)) > double(ARMA_MAX_UWORD) )
: false
),
error_message_4
);
if( (in_n_rows > ARMA_MAX_UHWORD) || (in_n_cols > ARMA_MAX_UHWORD) )
{
arma_conform_set_error( err_state, err_msg, ( (double(in_n_rows) * double(in_n_cols)) > double(ARMA_MAX_UWORD) ), error_message_4 );
}
arma_conform_check(err_state, err_msg);
@@ -468,7 +456,7 @@ Mat<eT>::Mat(const char* text)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -502,7 +490,7 @@ Mat<eT>::Mat(const std::string& text)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -690,7 +678,7 @@ Mat<eT>::Mat(const std::initializer_list<eT>& list)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -722,7 +710,7 @@ Mat<eT>::Mat(const std::initializer_list< std::initializer_list<eT> >& list)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -889,7 +877,7 @@ Mat<eT>::Mat(const Mat<eT>& in_mat, const arma_vec_indicator&, const uhword in_v
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint(arma_str::format("this: %x; in_mat: %x") % this % &in_mat);
@@ -1524,7 +1512,7 @@ Mat<eT>::Mat(const BaseCube<eT,T1>& X, const arma_vec_indicator&, const uhword i
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -1543,7 +1531,7 @@ Mat<eT>::Mat(const BaseCube<eT,T1>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -1990,7 +1978,7 @@ Mat<eT>::Mat(const Base<typename Mat<eT>::pod_type,T1>& A, const Base<typename M
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2010,7 +1998,7 @@ Mat<eT>::Mat(const Base<typename Mat<eT>::pod_type,T1>& A, const Base<typename M
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2055,7 +2043,7 @@ Mat<eT>::Mat(const subview<eT>& X, const arma_vec_indicator&, const uhword in_ve
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2278,7 +2266,7 @@ Mat<eT>::Mat(const subview_cube<eT>& x, const arma_vec_indicator&, const uhword
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2297,7 +2285,7 @@ Mat<eT>::Mat(const subview_cube<eT>& x)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2407,7 +2395,7 @@ Mat<eT>::Mat(const diagview<eT>& X, const arma_vec_indicator&, const uhword in_v
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2552,7 +2540,7 @@ Mat<eT>::Mat(const subview_elem1<eT,T1>& X, const arma_vec_indicator&, const uhw
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2571,7 +2559,7 @@ Mat<eT>::Mat(const subview_elem1<eT,T1>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2680,7 +2668,7 @@ Mat<eT>::Mat(const subview_elem2<eT,T1,T2>& X, const arma_vec_indicator&, const
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2699,7 +2687,7 @@ Mat<eT>::Mat(const subview_elem2<eT,T1,T2>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2808,7 +2796,7 @@ Mat<eT>::Mat(const SpBase<eT, T1>& m, const arma_vec_indicator&, const uhword in
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2827,7 +2815,7 @@ Mat<eT>::Mat(const SpBase<eT, T1>& m)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2888,6 +2876,8 @@ Mat<eT>::operator+=(const SpBase<eT, T1>& m)
arma_conform_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "addition");
if(p.get_n_nonzero() == 0) { return *this; }
typename SpProxy<T1>::const_iterator_type it = p.begin();
typename SpProxy<T1>::const_iterator_type it_end = p.end();
@@ -2910,6 +2900,8 @@ Mat<eT>::operator-=(const SpBase<eT, T1>& m)
arma_conform_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "subtraction");
if(p.get_n_nonzero() == 0) { return *this; }
typename SpProxy<T1>::const_iterator_type it = p.begin();
typename SpProxy<T1>::const_iterator_type it_end = p.end();
@@ -2928,9 +2920,9 @@ Mat<eT>::operator*=(const SpBase<eT, T1>& m)
{
arma_debug_sigprint();
Mat<eT> z = (*this) * m.get_ref();
Mat<eT> tmp = (*this) * m.get_ref();
steal_mem(z);
steal_mem(tmp);
return *this;
}
@@ -3011,7 +3003,7 @@ Mat<eT>::Mat(const SpSubview<eT>& X, const arma_vec_indicator&, const uhword in_
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -3029,7 +3021,7 @@ Mat<eT>::Mat(const SpSubview<eT>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -3212,7 +3204,7 @@ Mat<eT>::Mat(const spdiagview<eT>& X, const arma_vec_indicator&, const uhword in
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5140,7 +5132,7 @@ Mat<eT>::Mat(const Gen<T1, gen_type>& X, const arma_vec_indicator&, const uhword
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5290,7 +5282,7 @@ Mat<eT>::Mat(const Op<T1, op_type>& X, const arma_vec_indicator&, const uhword i
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5312,7 +5304,7 @@ Mat<eT>::Mat(const Op<T1, op_type>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5441,7 +5433,7 @@ Mat<eT>::Mat(const eOp<T1, eop_type>& X, const arma_vec_indicator&, const uhword
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5669,7 +5661,7 @@ Mat<eT>::Mat(const mtOp<eT, T1, op_type>& X, const arma_vec_indicator&, const uh
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5688,7 +5680,7 @@ Mat<eT>::Mat(const mtOp<eT, T1, op_type>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5797,7 +5789,7 @@ Mat<eT>::Mat(const CubeToMatOp<T1, op_type>& X, const arma_vec_indicator&, const
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5818,7 +5810,7 @@ Mat<eT>::Mat(const CubeToMatOp<T1, op_type>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5941,7 +5933,7 @@ Mat<eT>::Mat(const SpToDOp<T1, op_type>& X, const arma_vec_indicator&, const uhw
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5962,7 +5954,7 @@ Mat<eT>::Mat(const SpToDOp<T1, op_type>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6091,7 +6083,7 @@ Mat<eT>::Mat(const mtSpReduceOp<eT, T1, op_type>& X, const arma_vec_indicator&,
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6110,7 +6102,7 @@ Mat<eT>::Mat(const mtSpReduceOp<eT, T1, op_type>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6219,7 +6211,7 @@ Mat<eT>::Mat(const Glue<T1, T2, glue_type>& X, const arma_vec_indicator&, const
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6242,7 +6234,7 @@ Mat<eT>::Mat(const Glue<T1, T2, glue_type>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6408,7 +6400,7 @@ Mat<eT>::Mat(const eGlue<T1, T2, eglue_type>& X, const arma_vec_indicator&, cons
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6615,7 +6607,7 @@ Mat<eT>::Mat(const mtGlue<eT, T1, T2, glue_type>& X, const arma_vec_indicator&,
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6634,7 +6626,7 @@ Mat<eT>::Mat(const mtGlue<eT, T1, T2, glue_type>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6745,7 +6737,7 @@ Mat<eT>::Mat(const SpToDGlue<T1, T2, glue_type>& X, const arma_vec_indicator&, c
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6767,7 +6759,7 @@ Mat<eT>::Mat(const SpToDGlue<T1, T2, glue_type>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -7487,7 +7479,7 @@ arma_inline
eT*
Mat<eT>::colptr(const uword in_col)
{
return & access::rw(mem[in_col*n_rows]);
return access::rwp( mem + (in_col*n_rows) );
}
@@ -7498,7 +7490,7 @@ arma_inline
const eT*
Mat<eT>::colptr(const uword in_col) const
{
return & mem[in_col*n_rows];
return mem + (in_col*n_rows);
}
@@ -7580,10 +7572,40 @@ Mat<eT>::resize(const uword new_n_elem)
{
arma_debug_sigprint();
const uword new_n_rows = (vec_state == 2) ? uword(1 ) : uword(new_n_elem);
const uword new_n_cols = (vec_state == 2) ? uword(new_n_elem) : uword(1 );
const bool reuse_mem =
( is_vec() && (mem_state == 0) )
&&
(
( (new_n_elem <= arma_config::mat_prealloc) && (n_elem <= arma_config::mat_prealloc) && ( n_elem > 0 ) )
|| ( (new_n_elem > arma_config::mat_prealloc) && (n_elem > arma_config::mat_prealloc) && (new_n_elem <= n_alloc) )
);
return (*this).resize(new_n_rows, new_n_cols);
if(reuse_mem)
{
arma_debug_print("Mat::resize(): reusing memory");
if(new_n_elem > n_elem)
{
arma_debug_print("Mat::resize(): zeroing memory");
eT* t_mem = (*this).memptr(); // the (n_elem > 0) check above ensures that (*this).memptr() is a valid pointer
for(uword ii = n_elem; ii < new_n_elem; ++ii) { t_mem[ii] = eT(0); }
}
access::rw(n_rows) = (vec_state == 2) ? uword(1 ) : uword(new_n_elem);
access::rw(n_cols) = (vec_state == 2) ? uword(new_n_elem) : uword(1 );
access::rw(n_elem) = new_n_elem;
}
else
{
const uword new_n_rows = (vec_state == 2) ? uword(1 ) : uword(new_n_elem);
const uword new_n_cols = (vec_state == 2) ? uword(new_n_elem) : uword(1 );
(*this).resize(new_n_rows, new_n_cols);
}
return (*this);
}
@@ -7908,6 +7930,10 @@ Mat<eT>::fill(const fill::fill_class<fill_type>&)
if(is_same_type<fill_type, fill::fill_randu>::yes) { (*this).randu(); }
if(is_same_type<fill_type, fill::fill_randn>::yes) { (*this).randn(); }
if(is_same_type<fill_type, fill::fill_nan >::yes) { (*this).fill( priv::Datum_helper::nan <eT>() ); }
if(is_same_type<fill_type, fill::fill_pos_inf>::yes) { (*this).fill( priv::Datum_helper::pos_inf<eT>() ); }
if(is_same_type<fill_type, fill::fill_neg_inf>::yes) { (*this).fill( priv::Datum_helper::neg_inf<eT>() ); }
return *this;
}
@@ -10081,6 +10107,10 @@ Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const fill::fill_class<fill_ty
if(is_same_type<fill_type, fill::fill_eye >::yes) { Mat<eT>::eye(); }
if(is_same_type<fill_type, fill::fill_randu>::yes) { Mat<eT>::randu(); }
if(is_same_type<fill_type, fill::fill_randn>::yes) { Mat<eT>::randn(); }
if(is_same_type<fill_type, fill::fill_nan >::yes) { (*this).fill( priv::Datum_helper::nan <eT>() ); }
if(is_same_type<fill_type, fill::fill_pos_inf>::yes) { (*this).fill( priv::Datum_helper::pos_inf<eT>() ); }
if(is_same_type<fill_type, fill::fill_neg_inf>::yes) { (*this).fill( priv::Datum_helper::neg_inf<eT>() ); }
}
@@ -10515,7 +10545,7 @@ Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::colptr(const uword in_col)
{
eT* mem_actual = (use_extra) ? mem_local_extra : mem_local;
return & access::rw(mem_actual[in_col*fixed_n_rows]);
return access::rwp( mem_actual + (in_col*fixed_n_rows) );
}
@@ -10528,7 +10558,7 @@ Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::colptr(const uword in_col) const
{
const eT* mem_actual = (use_extra) ? mem_local_extra : mem_local;
return & mem_actual[in_col*fixed_n_rows];
return mem_actual + (in_col*fixed_n_rows);
}
+4
View File
@@ -1351,6 +1351,10 @@ Row<eT>::fixed<fixed_n_elem>::fixed(const fill::fill_class<fill_type>&)
if(is_same_type<fill_type, fill::fill_eye >::yes) { Mat<eT>::eye(); }
if(is_same_type<fill_type, fill::fill_randu>::yes) { Mat<eT>::randu(); }
if(is_same_type<fill_type, fill::fill_randn>::yes) { Mat<eT>::randn(); }
if(is_same_type<fill_type, fill::fill_nan >::yes) { (*this).fill( priv::Datum_helper::nan <eT>() ); }
if(is_same_type<fill_type, fill::fill_pos_inf>::yes) { (*this).fill( priv::Datum_helper::pos_inf<eT>() ); }
if(is_same_type<fill_type, fill::fill_neg_inf>::yes) { (*this).fill( priv::Datum_helper::neg_inf<eT>() ); }
}
+125 -77
View File
@@ -688,15 +688,22 @@ SpMat<eT>::operator=(const SpMat<eT>& x)
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator+=(const SpMat<eT>& x)
SpMat<eT>::operator+=(const SpMat<eT>& X)
{
arma_debug_sigprint();
sync_csc();
SpMat<eT> out = (*this) + x;
steal_mem(out);
if(X.n_nonzero == 0)
{
arma_conform_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "addition");
}
else
{
SpMat<eT> tmp = (*this) + X;
steal_mem(tmp);
}
return *this;
}
@@ -706,15 +713,22 @@ SpMat<eT>::operator+=(const SpMat<eT>& x)
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator-=(const SpMat<eT>& x)
SpMat<eT>::operator-=(const SpMat<eT>& X)
{
arma_debug_sigprint();
sync_csc();
SpMat<eT> out = (*this) - x;
steal_mem(out);
if(X.n_nonzero == 0)
{
arma_conform_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "subtraction");
}
else
{
SpMat<eT> tmp = (*this) - X;
steal_mem(tmp);
}
return *this;
}
@@ -724,15 +738,15 @@ SpMat<eT>::operator-=(const SpMat<eT>& x)
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator*=(const SpMat<eT>& y)
SpMat<eT>::operator*=(const SpMat<eT>& X)
{
arma_debug_sigprint();
sync_csc();
SpMat<eT> z = (*this) * y;
SpMat<eT> tmp = (*this) * X;
steal_mem(z);
steal_mem(tmp);
return *this;
}
@@ -743,15 +757,24 @@ SpMat<eT>::operator*=(const SpMat<eT>& y)
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator%=(const SpMat<eT>& y)
SpMat<eT>::operator%=(const SpMat<eT>& X)
{
arma_debug_sigprint();
sync_csc();
SpMat<eT> z = (*this) % y;
steal_mem(z);
if(X.n_nonzero == 0)
{
arma_conform_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "element-wise multiplication");
(*this).zeros();
}
else
{
SpMat<eT> tmp = (*this) % X;
steal_mem(tmp);
}
return *this;
}
@@ -1338,9 +1361,16 @@ SpMat<eT>::operator+=(const SpSubview<eT>& X)
sync_csc();
SpMat<eT> tmp = (*this) + X;
steal_mem(tmp);
if(X.n_nonzero == 0)
{
arma_conform_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "addition");
}
else
{
SpMat<eT> tmp = (*this) + X;
steal_mem(tmp);
}
return *this;
}
@@ -1356,64 +1386,82 @@ SpMat<eT>::operator-=(const SpSubview<eT>& X)
sync_csc();
SpMat<eT> tmp = (*this) - X;
steal_mem(tmp);
return *this;
}
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator*=(const SpSubview<eT>& y)
{
arma_debug_sigprint();
sync_csc();
SpMat<eT> z = (*this) * y;
steal_mem(z);
return *this;
}
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator%=(const SpSubview<eT>& x)
{
arma_debug_sigprint();
sync_csc();
SpMat<eT> tmp = (*this) % x;
steal_mem(tmp);
return *this;
}
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator/=(const SpSubview<eT>& x)
{
arma_debug_sigprint();
arma_conform_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-wise division");
// There is no pretty way to do this.
for(uword elem = 0; elem < n_elem; elem++)
if(X.n_nonzero == 0)
{
at(elem) /= x(elem);
arma_conform_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "subtraction");
}
else
{
SpMat<eT> tmp = (*this) - X;
steal_mem(tmp);
}
return *this;
}
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator*=(const SpSubview<eT>& X)
{
arma_debug_sigprint();
sync_csc();
SpMat<eT> tmp = (*this) * X;
steal_mem(tmp);
return *this;
}
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator%=(const SpSubview<eT>& X)
{
arma_debug_sigprint();
sync_csc();
if(X.n_nonzero == 0)
{
arma_conform_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "element-wise multiplication");
(*this).zeros();
}
else
{
SpMat<eT> tmp = (*this) % X;
steal_mem(tmp);
}
return *this;
}
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator/=(const SpSubview<eT>& X)
{
arma_debug_sigprint();
// NOTE: use of this function is not advised; it is implemented only for completeness
arma_conform_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "element-wise division");
for(uword c = 0; c < n_cols; ++c)
for(uword r = 0; r < n_rows; ++r)
{
at(r, c) /= X.at(r, c);
}
return *this;
@@ -1507,9 +1555,9 @@ SpMat<eT>::operator*=(const SpSubview_col_list<eT,T1>& X)
sync_csc();
SpMat<eT> z = (*this) * X;
SpMat<eT> tmp = (*this) * X;
steal_mem(z);
steal_mem(tmp);
return *this;
}
+41
View File
@@ -44,6 +44,8 @@ SpSubview<eT>::SpSubview(const SpMat<eT>& in_m, const uword in_row1, const uword
m.sync_csc();
if( (n_elem == 0) || (m.n_nonzero == 0) ) { return; } // (*this).n_nonzero already set to zero
// count the number of non-zeros in the subview
uword count = 0;
@@ -127,6 +129,8 @@ SpSubview<eT>::operator+=(const eT val)
tmp.fill(val);
if(n_nonzero == 0) { return (*this).operator=(tmp); }
return (*this).operator=( (*this) + tmp );
}
@@ -319,6 +323,15 @@ SpSubview<eT>::operator+=(const Base<eT, T1>& x)
{
arma_debug_sigprint();
if(n_nonzero == 0)
{
const quasi_unwrap<T1> U(x.get_ref());
arma_conform_assert_same_size(n_rows, n_cols, U.M.n_rows, U.M.n_cols, "addition");
return (*this).operator=(U.M);
}
return (*this).operator=( (*this) + x.get_ref() );
}
@@ -369,6 +382,8 @@ SpSubview<eT>::operator%=(const Base<eT, T1>& x)
arma_conform_assert_same_size(sv.n_rows, sv.n_cols, B.n_rows, B.n_cols, "element-wise multiplication");
if(n_nonzero == 0) { return *this; }
SpMat<eT>& sv_m = access::rw(sv.m);
sv_m.sync_csc();
@@ -555,6 +570,15 @@ SpSubview<eT>::operator+=(const SpBase<eT, T1>& x)
{
arma_debug_sigprint();
if(n_nonzero == 0)
{
const unwrap_spmat<T1> U(x.get_ref());
arma_conform_assert_same_size(n_rows, n_cols, U.M.n_rows, U.M.n_cols, "addition");
return (*this).operator_equ_common(U.M);
}
// TODO: implement dedicated machinery
return (*this).operator=( (*this) + x.get_ref() );
}
@@ -596,6 +620,15 @@ SpSubview<eT>::operator%=(const SpBase<eT, T1>& x)
{
arma_debug_sigprint();
if(n_nonzero == 0)
{
const SpProxy<T1> P(x.get_ref());
arma_conform_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(), "element-wise multiplication");
return *this;
}
// TODO: implement dedicated machinery
return (*this).operator=( (*this) % x.get_ref() );
}
@@ -648,6 +681,8 @@ SpSubview<eT>::for_each(functor F)
m.sync_csc();
m.invalidate_cache();
if(n_nonzero == 0) { return; }
const uword lstart_row = aux_row1;
const uword lend_row = aux_row1 + n_rows;
@@ -704,6 +739,8 @@ SpSubview<eT>::for_each(functor F) const
m.sync_csc();
if(n_nonzero == 0) { return; }
const uword lstart_row = aux_row1;
const uword lend_row = aux_row1 + n_rows;
@@ -743,6 +780,8 @@ SpSubview<eT>::transform(functor F)
m.sync_csc();
m.invalidate_cache();
if(n_nonzero == 0) { return; }
const uword lstart_row = aux_row1;
const uword lend_row = aux_row1 + n_rows;
@@ -813,6 +852,8 @@ SpSubview<eT>::replace(const eT old_val, const eT new_val)
m.sync_csc();
m.invalidate_cache();
if(n_nonzero == 0) { return; }
const uword lstart_row = aux_row1;
const uword lend_row = aux_row1 + n_rows;
+1 -1
View File
@@ -23,7 +23,7 @@
#define ARMA_VERSION_MAJOR 15
#define ARMA_VERSION_MINOR 2
#define ARMA_VERSION_PATCH 2
#define ARMA_VERSION_PATCH 4
#define ARMA_VERSION_NAME "Medium Roast Deluxe"
+12 -12
View File
@@ -330,18 +330,6 @@
#undef ARMA_OPTIMISE_POWEXPR
#endif
#if defined(ARMA_DONT_CHECK_CONFORMANCE)
#if defined(ARMA_CHECK_CONFORMANCE) && (ARMA_WARN_LEVEL >= 2)
#pragma message ("WARNING: conformance checks disabled")
#endif
#undef ARMA_CHECK_CONFORMANCE
#endif
#if defined(ARMA_DONT_CHECK_NONFINITE)
#undef ARMA_CHECK_NONFINITE
#endif
#if defined(ARMA_NO_DEBUG)
#undef ARMA_DEBUG
#undef ARMA_EXTRA_DEBUG
@@ -361,6 +349,18 @@
#define ARMA_WARN_LEVEL 3
#endif
#if defined(ARMA_DONT_CHECK_CONFORMANCE)
#if defined(ARMA_CHECK_CONFORMANCE) && (ARMA_WARN_LEVEL >= 2)
#pragma message ("WARNING: conformance checks disabled")
#endif
#undef ARMA_CHECK_CONFORMANCE
#endif
#if defined(ARMA_DONT_CHECK_NONFINITE)
#undef ARMA_CHECK_NONFINITE
#endif
#if defined(ARMA_DONT_PRINT_EXCEPTIONS)
#undef ARMA_PRINT_EXCEPTIONS
#endif
+12 -12
View File
@@ -330,18 +330,6 @@
#undef ARMA_OPTIMISE_POWEXPR
#endif
#if defined(ARMA_DONT_CHECK_CONFORMANCE)
#if defined(ARMA_CHECK_CONFORMANCE) && (ARMA_WARN_LEVEL >= 2)
#pragma message ("WARNING: conformance checks disabled")
#endif
#undef ARMA_CHECK_CONFORMANCE
#endif
#if defined(ARMA_DONT_CHECK_NONFINITE)
#undef ARMA_CHECK_NONFINITE
#endif
#if defined(ARMA_NO_DEBUG)
#undef ARMA_DEBUG
#undef ARMA_EXTRA_DEBUG
@@ -361,6 +349,18 @@
#define ARMA_WARN_LEVEL 3
#endif
#if defined(ARMA_DONT_CHECK_CONFORMANCE)
#if defined(ARMA_CHECK_CONFORMANCE) && (ARMA_WARN_LEVEL >= 2)
#pragma message ("WARNING: conformance checks disabled")
#endif
#undef ARMA_CHECK_CONFORMANCE
#endif
#if defined(ARMA_DONT_CHECK_NONFINITE)
#undef ARMA_CHECK_NONFINITE
#endif
#if defined(ARMA_DONT_PRINT_EXCEPTIONS)
#undef ARMA_PRINT_EXCEPTIONS
#endif
+55 -6
View File
@@ -62,11 +62,14 @@ namespace priv
}
//
template<typename eT>
static
constexpr
typename arma_real_only<eT>::result
inf(typename arma_real_only<eT>::result* junk = nullptr)
pos_inf(typename arma_real_only<eT>::result* junk = nullptr)
{
arma_ignore(junk);
@@ -78,13 +81,13 @@ namespace priv
static
constexpr
typename arma_cx_only<eT>::result
inf(typename arma_cx_only<eT>::result* junk = nullptr)
pos_inf(typename arma_cx_only<eT>::result* junk = nullptr)
{
arma_ignore(junk);
typedef typename get_pod_type<eT>::result T;
return eT( Datum_helper::inf<T>(), Datum_helper::inf<T>() );
return eT( Datum_helper::pos_inf<T>(), Datum_helper::pos_inf<T>() );
}
@@ -92,12 +95,54 @@ namespace priv
static
constexpr
typename arma_integral_only<eT>::result
inf(typename arma_integral_only<eT>::result* junk = nullptr)
pos_inf(typename arma_integral_only<eT>::result* junk = nullptr)
{
arma_ignore(junk);
return std::numeric_limits<eT>::max();
}
//
template<typename eT>
static
constexpr
typename arma_real_only<eT>::result
neg_inf(typename arma_real_only<eT>::result* junk = nullptr)
{
arma_ignore(junk);
return (std::numeric_limits<eT>::has_infinity) ? eT(-std::numeric_limits<eT>::infinity()) : eT(std::numeric_limits<eT>::lowest());
}
template<typename eT>
static
constexpr
typename arma_cx_only<eT>::result
neg_inf(typename arma_cx_only<eT>::result* junk = nullptr)
{
arma_ignore(junk);
typedef typename get_pod_type<eT>::result T;
return eT( Datum_helper::neg_inf<T>(), Datum_helper::neg_inf<T>() );
}
template<typename eT>
static
constexpr
typename arma_integral_only<eT>::result
neg_inf(typename arma_integral_only<eT>::result* junk = nullptr)
{
arma_ignore(junk);
return std::numeric_limits<eT>::lowest();
}
};
}
@@ -125,7 +170,9 @@ struct Datum
static const eT log_min; //!< log of the minimum representable value
static const eT log_max; //!< log of the maximum representable value
static const eT nan; //!< "not a number"
static const eT inf; //!< infinity
static const eT inf; //!< positive infinity
static const eT pos_inf; //!< positive infinity
static const eT neg_inf; //!< negative infinity
//
@@ -176,7 +223,9 @@ template<typename eT> const eT Datum<eT>::eps = std::numeric_limits<eT>:
template<typename eT> const eT Datum<eT>::log_min = std::log(std::numeric_limits<eT>::min());
template<typename eT> const eT Datum<eT>::log_max = std::log(std::numeric_limits<eT>::max());
template<typename eT> const eT Datum<eT>::nan = priv::Datum_helper::nan<eT>();
template<typename eT> const eT Datum<eT>::inf = priv::Datum_helper::inf<eT>();
template<typename eT> const eT Datum<eT>::inf = priv::Datum_helper::pos_inf<eT>();
template<typename eT> const eT Datum<eT>::pos_inf = priv::Datum_helper::pos_inf<eT>();
template<typename eT> const eT Datum<eT>::neg_inf = priv::Datum_helper::neg_inf<eT>();
template<typename eT> const eT Datum<eT>::m_u = eT(1.66053906892e-27);
template<typename eT> const eT Datum<eT>::N_A = eT(6.02214076e23);
+19 -12
View File
@@ -22,22 +22,29 @@
namespace fill
{
struct fill_none {};
struct fill_zeros {};
struct fill_ones {};
struct fill_eye {};
struct fill_randu {};
struct fill_randn {};
struct fill_none {};
struct fill_zeros {};
struct fill_ones {};
struct fill_eye {};
struct fill_randu {};
struct fill_randn {};
struct fill_nan {};
struct fill_pos_inf {};
struct fill_neg_inf {};
template<typename fill_type>
struct fill_class { inline constexpr fill_class() {} };
static constexpr fill_class<fill_none > none;
static constexpr fill_class<fill_zeros> zeros;
static constexpr fill_class<fill_ones > ones;
static constexpr fill_class<fill_eye > eye;
static constexpr fill_class<fill_randu> randu;
static constexpr fill_class<fill_randn> randn;
static constexpr fill_class<fill_none > none;
static constexpr fill_class<fill_zeros > zeros;
static constexpr fill_class<fill_ones > ones;
static constexpr fill_class<fill_eye > eye;
static constexpr fill_class<fill_randu > randu;
static constexpr fill_class<fill_randn > randn;
static constexpr fill_class<fill_nan > nan;
static constexpr fill_class<fill_pos_inf> inf;
static constexpr fill_class<fill_pos_inf> pos_inf;
static constexpr fill_class<fill_neg_inf> neg_inf;
//
+8
View File
@@ -80,6 +80,8 @@ op_accu_mat::apply_proxy_at(const Proxy<T1>& P)
const uword n_rows = P.get_n_rows();
const uword n_cols = P.get_n_cols();
if(n_rows == 0) { return eT(0); }
eT val = eT(0);
if(n_rows != 1)
@@ -146,6 +148,8 @@ op_accu_mat::apply_omit_helper(const Proxy<T1>& P, functor is_omitted)
const uword n_rows = P.get_n_rows();
const uword n_cols = P.get_n_cols();
if(n_rows == 0) { return eT_zero; }
for(uword c=0; c < n_cols; ++c)
for(uword r=0; r < n_rows; ++r)
{
@@ -602,6 +606,8 @@ op_accu_mat::apply(const subview<eT>& X)
const uword X_n_rows = X.n_rows;
const uword X_n_cols = X.n_cols;
if( (X_n_rows == 0) || (X_n_cols == 0) ) { return eT(0); }
if(X_n_rows == 1)
{
const uword X_m_n_rows = X.m.n_rows;
@@ -750,6 +756,8 @@ op_accu_cube::apply_proxy_at(const ProxyCube<T1>& P)
const uword n_cols = P.get_n_cols();
const uword n_slices = P.get_n_slices();
if( (n_rows == 0) || (n_cols == 0) ) { return eT(0); }
eT val1 = eT(0);
eT val2 = eT(0);
@@ -65,6 +65,7 @@ op_htrans::apply_mat_noalias(Mat<eT>& out, const Mat<eT>& A, const typename arma
op_htrans::apply_mat_noalias_large(out, A);
}
else
if( (A_n_rows != 0) && (A_n_cols != 0) )
{
eT* outptr = out.memptr();
+12 -8
View File
@@ -153,15 +153,19 @@ op_repcube::apply_noalias(Cube<eT>& out, const Cube<eT>& X, const uword copies_p
if(out.is_empty()) { return; }
// TODO: this is a rudimentary implementation
const SizeCube X_size = SizeCube(X.n_rows, X.n_cols, X.n_slices);
for(uword s = 0; s < out.n_slices; s += X.n_slices)
for(uword c = 0; c < out.n_cols; c += X.n_cols )
for(uword r = 0; r < out.n_rows; r += X.n_rows )
for(uword s=0; s < X.n_slices; ++s)
{
out.subcube(r, c, s, X_size) = X;
// avoid use of Cube::slice() to prevent generating Mat objects that the user may not need
const Mat<eT> X_slice_s(const_cast<eT*>(X.slice_memptr(s)), X.n_rows, X.n_cols, false, true);
Mat<eT> out_slice_s( out.slice_memptr(s) , out.n_rows, out.n_cols, false, true);
op_repmat::apply_noalias(out_slice_s, X_slice_s, copies_per_row, copies_per_col);
for(uword t=1; t < copies_per_slice; ++t)
{
arrayops::copy(out.slice_memptr(s + (t * X.n_slices)), out_slice_s.memptr(), out_slice_s.n_elem);
}
}
}
+1 -1
View File
@@ -81,7 +81,7 @@ op_resize::apply_mat_inplace(Mat<eT>& A, const uword new_n_rows, const uword new
arma_conform_check( (A.vec_state == 1) && (new_n_cols != 1), "resize(): requested size is not compatible with column vector layout" );
arma_conform_check( (A.vec_state == 2) && (new_n_rows != 1), "resize(): requested size is not compatible with row vector layout" );
if(A.is_empty()) { A.zeros(new_n_rows, new_n_cols); return; }
if( A.is_empty() || (new_n_rows == 0) || (new_n_cols == 0) ) { A.zeros(new_n_rows, new_n_cols); return; }
Mat<eT> B(new_n_rows, new_n_cols, arma_nozeros_indicator());
@@ -200,6 +200,7 @@ op_strans::apply_mat_noalias(Mat<eT>& out, const TA& A)
op_strans::apply_mat_noalias_large(out, A);
}
else
if( (A_n_rows != 0) && (A_n_cols != 0) )
{
eT* outptr = out.memptr();
@@ -176,6 +176,8 @@ op_vectorise_col::apply_subview(Mat<eT>& out, const subview<eT>& sv)
out.set_size(sv.n_elem, 1);
if(sv.n_elem == 0) { return; }
eT* out_mem = out.memptr();
for(uword col=0; col < sv_n_cols; ++col)
@@ -201,6 +203,8 @@ op_vectorise_col::apply_proxy(Mat<typename T1::elem_type>& out, const Proxy<T1>&
out.set_size(N, 1);
if(N == 0) { return; }
eT* outmem = out.memptr();
if(Proxy<T1>::use_at == false)
@@ -305,6 +309,8 @@ op_vectorise_row::apply_proxy(Mat<typename T1::elem_type>& out, const Proxy<T1>&
out.set_size(1, n_elem);
if(n_elem == 0) { return; }
eT* outmem = out.memptr();
if(n_cols == 1)
@@ -471,6 +477,8 @@ op_vectorise_cube_col::apply_proxy(Mat<typename T1::elem_type>& out, const T1& e
out.set_size(N, 1);
if(N == 0) { return; }
eT* outmem = out.memptr();
if(ProxyCube<T1>::use_at == false)
+3
View File
@@ -142,6 +142,9 @@ class subview : public Base< eT, subview<eT> >
arma_inline eT* colptr(const uword in_col);
arma_inline const eT* colptr(const uword in_col) const;
arma_inline eT* startptr();
arma_inline const eT* startptr() const;
template<typename eT2>
inline bool check_overlap(const subview<eT2>& x) const;
+114 -40
View File
@@ -109,6 +109,8 @@ subview_cube_each1<eT>::operator= (const Base<eT,T1>& in)
const uword p_n_slices = p.n_slices;
const uword p_n_elem_slice = p.n_elem_slice;
if(p_n_elem_slice == 0) { return; }
const eT* A_mem = A.memptr();
for(uword i=0; i < p_n_slices; ++i) { arrayops::copy( p.slice_memptr(i), A_mem, p_n_elem_slice ); }
@@ -134,6 +136,8 @@ subview_cube_each1<eT>::operator+= (const Base<eT,T1>& in)
const uword p_n_slices = p.n_slices;
const uword p_n_elem_slice = p.n_elem_slice;
if(p_n_elem_slice == 0) { return; }
const eT* A_mem = A.memptr();
for(uword i=0; i < p_n_slices; ++i) { arrayops::inplace_plus( p.slice_memptr(i), A_mem, p_n_elem_slice ); }
@@ -159,6 +163,8 @@ subview_cube_each1<eT>::operator-= (const Base<eT,T1>& in)
const uword p_n_slices = p.n_slices;
const uword p_n_elem_slice = p.n_elem_slice;
if(p_n_elem_slice == 0) { return; }
const eT* A_mem = A.memptr();
for(uword i=0; i < p_n_slices; ++i) { arrayops::inplace_minus( p.slice_memptr(i), A_mem, p_n_elem_slice ); }
@@ -184,6 +190,8 @@ subview_cube_each1<eT>::operator%= (const Base<eT,T1>& in)
const uword p_n_slices = p.n_slices;
const uword p_n_elem_slice = p.n_elem_slice;
if(p_n_elem_slice == 0) { return; }
const eT* A_mem = A.memptr();
for(uword i=0; i < p_n_slices; ++i) { arrayops::inplace_mul( p.slice_memptr(i), A_mem, p_n_elem_slice ); }
@@ -209,6 +217,8 @@ subview_cube_each1<eT>::operator/= (const Base<eT,T1>& in)
const uword p_n_slices = p.n_slices;
const uword p_n_elem_slice = p.n_elem_slice;
if(p_n_elem_slice == 0) { return; }
const eT* A_mem = A.memptr();
for(uword i=0; i < p_n_slices; ++i) { arrayops::inplace_div( p.slice_memptr(i), A_mem, p_n_elem_slice ); }
@@ -300,6 +310,8 @@ subview_cube_each2<eT,TB>::operator= (const Base<eT,T1>& in)
arma_conform_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
if(p_n_elem_slice == 0) { continue; }
arrayops::copy(p.slice_memptr(slice), A_mem, p_n_elem_slice);
}
}
@@ -339,6 +351,8 @@ subview_cube_each2<eT,TB>::operator+= (const Base<eT,T1>& in)
arma_conform_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
if(p_n_elem_slice == 0) { continue; }
arrayops::inplace_plus(p.slice_memptr(slice), A_mem, p_n_elem_slice);
}
}
@@ -378,6 +392,8 @@ subview_cube_each2<eT,TB>::operator-= (const Base<eT,T1>& in)
arma_conform_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
if(p_n_elem_slice == 0) { continue; }
arrayops::inplace_minus(p.slice_memptr(slice), A_mem, p_n_elem_slice);
}
}
@@ -417,6 +433,8 @@ subview_cube_each2<eT,TB>::operator%= (const Base<eT,T1>& in)
arma_conform_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
if(p_n_elem_slice == 0) { continue; }
arrayops::inplace_mul(p.slice_memptr(slice), A_mem, p_n_elem_slice);
}
}
@@ -456,6 +474,8 @@ subview_cube_each2<eT,TB>::operator/= (const Base<eT,T1>& in)
arma_conform_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
if(p_n_elem_slice == 0) { continue; }
arrayops::inplace_div(p.slice_memptr(slice), A_mem, p_n_elem_slice);
}
}
@@ -492,12 +512,15 @@ subview_cube_each1_aux::operator_plus
X.check_size(A);
for(uword i=0; i < p_n_slices; ++i)
if( (p_n_rows != 0) && (p_n_cols != 0) )
{
Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
out_slice = p_slice + A;
for(uword i=0; i < p_n_slices; ++i)
{
Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
out_slice = p_slice + A;
}
}
return out;
@@ -529,12 +552,15 @@ subview_cube_each1_aux::operator_minus
X.check_size(A);
for(uword i=0; i < p_n_slices; ++i)
if( (p_n_rows != 0) && (p_n_cols != 0) )
{
Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
out_slice = p_slice - A;
for(uword i=0; i < p_n_slices; ++i)
{
Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
out_slice = p_slice - A;
}
}
return out;
@@ -566,12 +592,15 @@ subview_cube_each1_aux::operator_minus
Y.check_size(A);
for(uword i=0; i < p_n_slices; ++i)
if( (p_n_rows != 0) && (p_n_cols != 0) )
{
Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
out_slice = A - p_slice;
for(uword i=0; i < p_n_slices; ++i)
{
Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
out_slice = A - p_slice;
}
}
return out;
@@ -603,12 +632,15 @@ subview_cube_each1_aux::operator_schur
X.check_size(A);
for(uword i=0; i < p_n_slices; ++i)
if( (p_n_rows != 0) && (p_n_cols != 0) )
{
Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
out_slice = p_slice % A;
for(uword i=0; i < p_n_slices; ++i)
{
Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
out_slice = p_slice % A;
}
}
return out;
@@ -640,12 +672,15 @@ subview_cube_each1_aux::operator_div
X.check_size(A);
for(uword i=0; i < p_n_slices; ++i)
if( (p_n_rows != 0) && (p_n_cols != 0) )
{
Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
out_slice = p_slice / A;
for(uword i=0; i < p_n_slices; ++i)
{
Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
out_slice = p_slice / A;
}
}
return out;
@@ -677,12 +712,15 @@ subview_cube_each1_aux::operator_div
Y.check_size(A);
for(uword i=0; i < p_n_slices; ++i)
if( (p_n_rows != 0) && (p_n_cols != 0) )
{
Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
out_slice = A / p_slice;
for(uword i=0; i < p_n_slices; ++i)
{
Mat<eT> out_slice( out.slice_memptr(i), p_n_rows, p_n_cols, false, true);
const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(i)), p_n_rows, p_n_cols, false, true);
out_slice = A / p_slice;
}
}
return out;
@@ -706,14 +744,26 @@ subview_cube_each1_aux::operator_times
const unwrap<T2> tmp(Y.get_ref());
const Mat<eT>& M = tmp.M;
if(arma_config::check_conform)
{
if(C.n_cols != M.n_rows) { arma_stop_logic_error("each_slice(): incompatible sizes for matrix multiplication"); }
}
Cube<eT> out(C.n_rows, M.n_cols, C.n_slices, arma_nozeros_indicator());
for(uword i=0; i < C.n_slices; ++i)
if( (C.n_elem == 0) || (M.n_elem == 0) )
{
Mat<eT> out_slice( out.slice_memptr(i), C.n_rows, M.n_cols, false, true);
const Mat<eT> C_slice(const_cast<eT*>(C.slice_memptr(i)), C.n_rows, C.n_cols, false, true);
out_slice = C_slice * M;
out.zeros();
}
else
{
for(uword i=0; i < C.n_slices; ++i)
{
Mat<eT> out_slice( out.slice_memptr(i), C.n_rows, M.n_cols, false, true);
const Mat<eT> C_slice(const_cast<eT*>(C.slice_memptr(i)), C.n_rows, C.n_cols, false, true);
out_slice = C_slice * M;
}
}
return out;
@@ -737,14 +787,26 @@ subview_cube_each1_aux::operator_times
const Cube<eT>& C = Y.P;
if(arma_config::check_conform)
{
if(M.n_cols != C.n_rows) { arma_stop_logic_error("each_slice(): incompatible sizes for matrix multiplication"); }
}
Cube<eT> out(M.n_rows, C.n_cols, C.n_slices, arma_nozeros_indicator());
for(uword i=0; i < C.n_slices; ++i)
if( (M.n_elem == 0) || (C.n_elem == 0) )
{
Mat<eT> out_slice( out.slice_memptr(i), M.n_rows, C.n_cols, false, true);
const Mat<eT> C_slice(const_cast<eT*>(C.slice_memptr(i)), C.n_rows, C.n_cols, false, true);
out_slice = M * C_slice;
out.zeros();
}
else
{
for(uword i=0; i < C.n_slices; ++i)
{
Mat<eT> out_slice( out.slice_memptr(i), M.n_rows, C.n_cols, false, true);
const Mat<eT> C_slice(const_cast<eT*>(C.slice_memptr(i)), C.n_rows, C.n_cols, false, true);
out_slice = M * C_slice;
}
}
return out;
@@ -795,6 +857,8 @@ subview_cube_each2_aux::operator_plus
arma_conform_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
if(p_n_elem_slice == 0) { continue; }
arrayops::inplace_plus(out.slice_memptr(slice), A_mem, p_n_elem_slice);
}
@@ -840,6 +904,8 @@ subview_cube_each2_aux::operator_minus
arma_conform_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
if(p_n_elem_slice == 0) { continue; }
arrayops::inplace_minus(out.slice_memptr(slice), A_mem, p_n_elem_slice);
}
@@ -884,6 +950,8 @@ subview_cube_each2_aux::operator_minus
arma_conform_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
if( (p_n_rows == 0) || (p_n_cols == 0) ) { continue; }
Mat<eT> out_slice( out.slice_memptr(slice), p_n_rows, p_n_cols, false, true);
const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(slice)), p_n_rows, p_n_cols, false, true);
@@ -932,6 +1000,8 @@ subview_cube_each2_aux::operator_schur
arma_conform_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
if(p_n_elem_slice == 0) { continue; }
arrayops::inplace_mul(out.slice_memptr(slice), A_mem, p_n_elem_slice);
}
@@ -977,6 +1047,8 @@ subview_cube_each2_aux::operator_div
arma_conform_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
if(p_n_elem_slice == 0) { continue; }
arrayops::inplace_div(out.slice_memptr(slice), A_mem, p_n_elem_slice);
}
@@ -1021,6 +1093,8 @@ subview_cube_each2_aux::operator_div
arma_conform_check_bounds( (slice >= p_n_slices), "each_slice(): index out of bounds" );
if( (p_n_rows == 0) || (p_n_cols == 0) ) { continue; }
Mat<eT> out_slice( out.slice_memptr(slice), p_n_rows, p_n_cols, false, true);
const Mat<eT> p_slice(const_cast<eT*>(p.slice_memptr(slice)), p_n_rows, p_n_cols, false, true);
+63 -18
View File
@@ -117,6 +117,8 @@ subview_cube<eT>::inplace_op(const eT val)
const uword t_n_cols = t.n_cols;
const uword t_n_slices = t.n_slices;
if( (t_n_rows == 0) || (t_n_cols == 0) ) { return; }
for(uword s=0; s < t_n_slices; ++s)
for(uword c=0; c < t_n_cols; ++c)
{
@@ -150,6 +152,8 @@ subview_cube<eT>::inplace_op(const BaseCube<eT,T1>& in, const char* identifier)
arma_conform_assert_same_size(t, P, identifier);
if( (t_n_rows == 0) || (t_n_cols == 0) || (t_n_slices == 0) ) { return; }
const bool use_mp = arma_config::openmp && ProxyCube<T1>::use_mp && mp_gate<eT>::eval(t.n_elem);
const bool has_overlap = P.has_overlap(t);
@@ -258,6 +262,8 @@ subview_cube<eT>::inplace_op(const subview_cube<eT>& x, const char* identifier)
const uword t_n_cols = t.n_cols;
const uword t_n_slices = t.n_slices;
if( (t_n_rows == 0) || (t_n_cols == 0) ) { return; }
for(uword s=0; s < t_n_slices; ++s)
for(uword c=0; c < t_n_cols; ++c)
{
@@ -1174,6 +1180,8 @@ subview_cube<eT>::replace(const eT old_val, const eT new_val)
const uword local_n_cols = n_cols;
const uword local_n_slices = n_slices;
if( (local_n_rows == 0) || (local_n_cols == 0) ) { return; }
for(uword slice = 0; slice < local_n_slices; ++slice)
{
for(uword col = 0; col < local_n_cols; ++col)
@@ -1196,6 +1204,8 @@ subview_cube<eT>::clean(const typename get_pod_type<eT>::result threshold)
const uword local_n_cols = n_cols;
const uword local_n_slices = n_slices;
if( (local_n_rows == 0) || (local_n_cols == 0) ) { return; }
for(uword slice = 0; slice < local_n_slices; ++slice)
{
for(uword col = 0; col < local_n_cols; ++col)
@@ -1228,6 +1238,8 @@ subview_cube<eT>::clamp(const eT min_val, const eT max_val)
const uword local_n_cols = n_cols;
const uword local_n_slices = n_slices;
if( (local_n_rows == 0) || (local_n_cols == 0) ) { return; }
for(uword slice = 0; slice < local_n_slices; ++slice)
{
for(uword col = 0; col < local_n_cols; ++col)
@@ -1250,6 +1262,8 @@ subview_cube<eT>::fill(const eT val)
const uword local_n_cols = n_cols;
const uword local_n_slices = n_slices;
if( (local_n_rows == 0) || (local_n_cols == 0) ) { return; }
for(uword slice = 0; slice < local_n_slices; ++slice)
{
for(uword col = 0; col < local_n_cols; ++col)
@@ -1272,6 +1286,8 @@ subview_cube<eT>::zeros()
const uword local_n_cols = n_cols;
const uword local_n_slices = n_slices;
if( (local_n_rows == 0) || (local_n_cols == 0) ) { return; }
for(uword slice = 0; slice < local_n_slices; ++slice)
{
for(uword col = 0; col < local_n_cols; ++col)
@@ -1306,6 +1322,8 @@ subview_cube<eT>::randu()
const uword local_n_cols = n_cols;
const uword local_n_slices = n_slices;
if( (local_n_rows == 0) || (local_n_cols == 0) ) { return; }
for(uword slice = 0; slice < local_n_slices; ++slice)
{
for(uword col = 0; col < local_n_cols; ++col)
@@ -1328,6 +1346,8 @@ subview_cube<eT>::randn()
const uword local_n_cols = n_cols;
const uword local_n_slices = n_slices;
if( (local_n_rows == 0) || (local_n_cols == 0) ) { return; }
for(uword slice = 0; slice < local_n_slices; ++slice)
{
for(uword col = 0; col < local_n_cols; ++col)
@@ -1352,11 +1372,14 @@ subview_cube<eT>::is_finite() const
const uword local_n_cols = n_cols;
const uword local_n_slices = n_slices;
for(uword slice = 0; slice < local_n_slices; ++slice)
if( (local_n_rows != 0) && (local_n_cols != 0) )
{
for(uword col = 0; col < local_n_cols; ++col)
for(uword slice = 0; slice < local_n_slices; ++slice)
{
if(arrayops::is_finite(slice_colptr(slice,col), local_n_rows) == false) { return false; }
for(uword col = 0; col < local_n_cols; ++col)
{
if(arrayops::is_finite(slice_colptr(slice,col), local_n_rows) == false) { return false; }
}
}
}
@@ -1376,11 +1399,14 @@ subview_cube<eT>::is_zero(const typename get_pod_type<eT>::result tol) const
const uword local_n_cols = n_cols;
const uword local_n_slices = n_slices;
for(uword slice = 0; slice < local_n_slices; ++slice)
if( (local_n_rows != 0) && (local_n_cols != 0) )
{
for(uword col = 0; col < local_n_cols; ++col)
for(uword slice = 0; slice < local_n_slices; ++slice)
{
if(arrayops::is_zero(slice_colptr(slice,col), local_n_rows, tol) == false) { return false; }
for(uword col = 0; col < local_n_cols; ++col)
{
if(arrayops::is_zero(slice_colptr(slice,col), local_n_rows, tol) == false) { return false; }
}
}
}
@@ -1402,11 +1428,14 @@ subview_cube<eT>::has_inf() const
const uword local_n_cols = n_cols;
const uword local_n_slices = n_slices;
for(uword slice = 0; slice < local_n_slices; ++slice)
if( (local_n_rows != 0) && (local_n_cols != 0) )
{
for(uword col = 0; col < local_n_cols; ++col)
for(uword slice = 0; slice < local_n_slices; ++slice)
{
if(arrayops::has_inf(slice_colptr(slice,col), local_n_rows)) { return true; }
for(uword col = 0; col < local_n_cols; ++col)
{
if(arrayops::has_inf(slice_colptr(slice,col), local_n_rows)) { return true; }
}
}
}
@@ -1428,11 +1457,14 @@ subview_cube<eT>::has_nan() const
const uword local_n_cols = n_cols;
const uword local_n_slices = n_slices;
for(uword slice = 0; slice < local_n_slices; ++slice)
if( (local_n_rows != 0) && (local_n_cols != 0) )
{
for(uword col = 0; col < local_n_cols; ++col)
for(uword slice = 0; slice < local_n_slices; ++slice)
{
if(arrayops::has_nan(slice_colptr(slice,col), local_n_rows)) { return true; }
for(uword col = 0; col < local_n_cols; ++col)
{
if(arrayops::has_nan(slice_colptr(slice,col), local_n_rows)) { return true; }
}
}
}
@@ -1454,11 +1486,14 @@ subview_cube<eT>::has_nonfinite() const
const uword local_n_cols = n_cols;
const uword local_n_slices = n_slices;
for(uword slice = 0; slice < local_n_slices; ++slice)
if( (local_n_rows != 0) && (local_n_cols != 0) )
{
for(uword col = 0; col < local_n_cols; ++col)
for(uword slice = 0; slice < local_n_slices; ++slice)
{
if(arrayops::is_finite(slice_colptr(slice,col), local_n_rows) == false) { return true; }
for(uword col = 0; col < local_n_cols; ++col)
{
if(arrayops::is_finite(slice_colptr(slice,col), local_n_rows) == false) { return true; }
}
}
}
@@ -1614,7 +1649,7 @@ arma_inline
eT*
subview_cube<eT>::slice_colptr(const uword in_slice, const uword in_col)
{
return & access::rw((const_cast< Cube<eT>& >(m)).mem[ (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 ]);
return access::rwp( m.mem + ( (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 ) );
}
@@ -1624,7 +1659,7 @@ arma_inline
const eT*
subview_cube<eT>::slice_colptr(const uword in_slice, const uword in_col) const
{
return & m.mem[ (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 ];
return m.mem + ( (in_slice + aux_slice1)*m.n_elem_slice + (in_col + aux_col1)*m.n_rows + aux_row1 );
}
@@ -1704,7 +1739,7 @@ void
subview_cube<eT>::extract(Cube<eT>& out, const subview_cube<eT>& in)
{
arma_debug_sigprint();
// 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=()
@@ -1714,6 +1749,8 @@ subview_cube<eT>::extract(Cube<eT>& out, const subview_cube<eT>& in)
arma_debug_print(arma_str::format("out.n_rows: %u; out.n_cols: %u; out.n_slices: %u; in.m.n_rows: %u; in.m.n_cols: %u; in.m.n_slices: %u") % out.n_rows % out.n_cols % out.n_slices % in.m.n_rows % in.m.n_cols % in.m.n_slices);
if( (n_rows == 0) || (n_cols == 0) ) { return; }
if( (in.aux_row1 == 0) && (n_rows == in.m.n_rows) )
{
for(uword s=0; s < n_slices; ++s)
@@ -1747,6 +1784,8 @@ subview_cube<eT>::plus_inplace(Cube<eT>& out, const subview_cube<eT>& in)
const uword n_cols = out.n_cols;
const uword n_slices = out.n_slices;
if( (n_rows == 0) || (n_cols == 0) ) { return; }
for(uword slice = 0; slice<n_slices; ++slice)
{
for(uword col = 0; col<n_cols; ++col)
@@ -1772,6 +1811,8 @@ subview_cube<eT>::minus_inplace(Cube<eT>& out, const subview_cube<eT>& in)
const uword n_cols = out.n_cols;
const uword n_slices = out.n_slices;
if( (n_rows == 0) || (n_cols == 0) ) { return; }
for(uword slice = 0; slice<n_slices; ++slice)
{
for(uword col = 0; col<n_cols; ++col)
@@ -1797,6 +1838,8 @@ subview_cube<eT>::schur_inplace(Cube<eT>& out, const subview_cube<eT>& in)
const uword n_cols = out.n_cols;
const uword n_slices = out.n_slices;
if( (n_rows == 0) || (n_cols == 0) ) { return; }
for(uword slice = 0; slice<n_slices; ++slice)
{
for(uword col = 0; col<n_cols; ++col)
@@ -1822,6 +1865,8 @@ subview_cube<eT>::div_inplace(Cube<eT>& out, const subview_cube<eT>& in)
const uword n_cols = out.n_cols;
const uword n_slices = out.n_slices;
if( (n_rows == 0) || (n_cols == 0) ) { return; }
for(uword slice = 0; slice<n_slices; ++slice)
{
for(uword col = 0; col<n_cols; ++col)
+164 -114
View File
@@ -157,6 +157,8 @@ subview_each1<parent,mode>::operator= (const Base<eT,T1>& in)
const uword p_n_rows = p.n_rows;
const uword p_n_cols = p.n_cols;
if(p_n_rows == 0) { return; }
if(mode == 0) // each column
{
for(uword i=0; i < p_n_cols; ++i)
@@ -194,6 +196,8 @@ subview_each1<parent,mode>::operator+= (const Base<eT,T1>& in)
const uword p_n_rows = p.n_rows;
const uword p_n_cols = p.n_cols;
if(p_n_rows == 0) { return; }
if(mode == 0) // each column
{
for(uword i=0; i < p_n_cols; ++i)
@@ -231,6 +235,8 @@ subview_each1<parent,mode>::operator-= (const Base<eT,T1>& in)
const uword p_n_rows = p.n_rows;
const uword p_n_cols = p.n_cols;
if(p_n_rows == 0) { return; }
if(mode == 0) // each column
{
for(uword i=0; i < p_n_cols; ++i)
@@ -268,6 +274,8 @@ subview_each1<parent,mode>::operator%= (const Base<eT,T1>& in)
const uword p_n_rows = p.n_rows;
const uword p_n_cols = p.n_cols;
if(p_n_rows == 0) { return; }
if(mode == 0) // each column
{
for(uword i=0; i < p_n_cols; ++i)
@@ -305,6 +313,8 @@ subview_each1<parent,mode>::operator/= (const Base<eT,T1>& in)
const uword p_n_rows = p.n_rows;
const uword p_n_cols = p.n_cols;
if(p_n_rows == 0) { return; }
if(mode == 0) // each column
{
for(uword i=0; i < p_n_cols; ++i)
@@ -400,6 +410,8 @@ subview_each2<parent,mode,TB>::operator= (const Base<eT,T1>& in)
arma_conform_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" );
if(p_n_rows == 0) { continue; }
arrayops::copy( p.colptr(col), A_mem, p_n_rows );
}
}
@@ -456,6 +468,8 @@ subview_each2<parent,mode,TB>::operator+= (const Base<eT,T1>& in)
arma_conform_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" );
if(p_n_rows == 0) { continue; }
arrayops::inplace_plus( p.colptr(col), A_mem, p_n_rows );
}
}
@@ -509,6 +523,8 @@ subview_each2<parent,mode,TB>::operator-= (const Base<eT,T1>& in)
arma_conform_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" );
if(p_n_rows == 0) { continue; }
arrayops::inplace_minus( p.colptr(col), A_mem, p_n_rows );
}
}
@@ -562,6 +578,8 @@ subview_each2<parent,mode,TB>::operator%= (const Base<eT,T1>& in)
arma_conform_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" );
if(p_n_rows == 0) { continue; }
arrayops::inplace_mul( p.colptr(col), A_mem, p_n_rows );
}
}
@@ -615,6 +633,8 @@ subview_each2<parent,mode,TB>::operator/= (const Base<eT,T1>& in)
arma_conform_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" );
if(p_n_rows == 0) { continue; }
arrayops::inplace_div( p.colptr(col), A_mem, p_n_rows );
}
}
@@ -666,32 +686,35 @@ subview_each1_aux::operator_plus
const eT* A_mem = A.memptr();
if(mode == 0) // each column
if( (p_n_rows != 0) && (p_n_cols != 0) )
{
for(uword i=0; i < p_n_cols; ++i)
if(mode == 0) // each column
{
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
for(uword row=0; row < p_n_rows; ++row)
for(uword i=0; i < p_n_cols; ++i)
{
out_mem[row] = p_mem[row] + A_mem[row];
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
for(uword row=0; row < p_n_rows; ++row)
{
out_mem[row] = p_mem[row] + A_mem[row];
}
}
}
}
if(mode == 1) // each row
{
for(uword i=0; i < p_n_cols; ++i)
if(mode == 1) // each row
{
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
const eT A_val = A_mem[i];
for(uword row=0; row < p_n_rows; ++row)
for(uword i=0; i < p_n_cols; ++i)
{
out_mem[row] = p_mem[row] + A_val;
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
const eT A_val = A_mem[i];
for(uword row=0; row < p_n_rows; ++row)
{
out_mem[row] = p_mem[row] + A_val;
}
}
}
}
@@ -728,32 +751,35 @@ subview_each1_aux::operator_minus
const eT* A_mem = A.memptr();
if(mode == 0) // each column
if( (p_n_rows != 0) && (p_n_cols != 0) )
{
for(uword i=0; i < p_n_cols; ++i)
if(mode == 0) // each column
{
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
for(uword row=0; row < p_n_rows; ++row)
for(uword i=0; i < p_n_cols; ++i)
{
out_mem[row] = p_mem[row] - A_mem[row];
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
for(uword row=0; row < p_n_rows; ++row)
{
out_mem[row] = p_mem[row] - A_mem[row];
}
}
}
}
if(mode == 1) // each row
{
for(uword i=0; i < p_n_cols; ++i)
if(mode == 1) // each row
{
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
const eT A_val = A_mem[i];
for(uword row=0; row < p_n_rows; ++row)
for(uword i=0; i < p_n_cols; ++i)
{
out_mem[row] = p_mem[row] - A_val;
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
const eT A_val = A_mem[i];
for(uword row=0; row < p_n_rows; ++row)
{
out_mem[row] = p_mem[row] - A_val;
}
}
}
}
@@ -790,32 +816,35 @@ subview_each1_aux::operator_minus
const eT* A_mem = A.memptr();
if(mode == 0) // each column
if( (p_n_rows != 0) && (p_n_cols != 0) )
{
for(uword i=0; i < p_n_cols; ++i)
if(mode == 0) // each column
{
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
for(uword row=0; row < p_n_rows; ++row)
for(uword i=0; i < p_n_cols; ++i)
{
out_mem[row] = A_mem[row] - p_mem[row];
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
for(uword row=0; row < p_n_rows; ++row)
{
out_mem[row] = A_mem[row] - p_mem[row];
}
}
}
}
if(mode == 1) // each row
{
for(uword i=0; i < p_n_cols; ++i)
if(mode == 1) // each row
{
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
const eT A_val = A_mem[i];
for(uword row=0; row < p_n_rows; ++row)
for(uword i=0; i < p_n_cols; ++i)
{
out_mem[row] = A_val - p_mem[row];
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
const eT A_val = A_mem[i];
for(uword row=0; row < p_n_rows; ++row)
{
out_mem[row] = A_val - p_mem[row];
}
}
}
}
@@ -852,32 +881,35 @@ subview_each1_aux::operator_schur
const eT* A_mem = A.memptr();
if(mode == 0) // each column
if( (p_n_rows != 0) && (p_n_cols != 0) )
{
for(uword i=0; i < p_n_cols; ++i)
if(mode == 0) // each column
{
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
for(uword row=0; row < p_n_rows; ++row)
for(uword i=0; i < p_n_cols; ++i)
{
out_mem[row] = p_mem[row] * A_mem[row];
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
for(uword row=0; row < p_n_rows; ++row)
{
out_mem[row] = p_mem[row] * A_mem[row];
}
}
}
}
if(mode == 1) // each row
{
for(uword i=0; i < p_n_cols; ++i)
if(mode == 1) // each row
{
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
const eT A_val = A_mem[i];
for(uword row=0; row < p_n_rows; ++row)
for(uword i=0; i < p_n_cols; ++i)
{
out_mem[row] = p_mem[row] * A_val;
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
const eT A_val = A_mem[i];
for(uword row=0; row < p_n_rows; ++row)
{
out_mem[row] = p_mem[row] * A_val;
}
}
}
}
@@ -914,32 +946,35 @@ subview_each1_aux::operator_div
const eT* A_mem = A.memptr();
if(mode == 0) // each column
if( (p_n_rows != 0) && (p_n_cols != 0) )
{
for(uword i=0; i < p_n_cols; ++i)
if(mode == 0) // each column
{
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
for(uword row=0; row < p_n_rows; ++row)
for(uword i=0; i < p_n_cols; ++i)
{
out_mem[row] = p_mem[row] / A_mem[row];
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
for(uword row=0; row < p_n_rows; ++row)
{
out_mem[row] = p_mem[row] / A_mem[row];
}
}
}
}
if(mode == 1) // each row
{
for(uword i=0; i < p_n_cols; ++i)
if(mode == 1) // each row
{
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
const eT A_val = A_mem[i];
for(uword row=0; row < p_n_rows; ++row)
for(uword i=0; i < p_n_cols; ++i)
{
out_mem[row] = p_mem[row] / A_val;
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
const eT A_val = A_mem[i];
for(uword row=0; row < p_n_rows; ++row)
{
out_mem[row] = p_mem[row] / A_val;
}
}
}
}
@@ -976,32 +1011,35 @@ subview_each1_aux::operator_div
const eT* A_mem = A.memptr();
if(mode == 0) // each column
if( (p_n_rows != 0) && (p_n_cols != 0) )
{
for(uword i=0; i < p_n_cols; ++i)
if(mode == 0) // each column
{
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
for(uword row=0; row < p_n_rows; ++row)
for(uword i=0; i < p_n_cols; ++i)
{
out_mem[row] = A_mem[row] / p_mem[row];
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
for(uword row=0; row < p_n_rows; ++row)
{
out_mem[row] = A_mem[row] / p_mem[row];
}
}
}
}
if(mode == 1) // each row
{
for(uword i=0; i < p_n_cols; ++i)
if(mode == 1) // each row
{
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
const eT A_val = A_mem[i];
for(uword row=0; row < p_n_rows; ++row)
for(uword i=0; i < p_n_cols; ++i)
{
out_mem[row] = A_val / p_mem[row];
const eT* p_mem = p.colptr(i);
eT* out_mem = out.colptr(i);
const eT A_val = A_mem[i];
for(uword row=0; row < p_n_rows; ++row)
{
out_mem[row] = A_val / p_mem[row];
}
}
}
}
@@ -1058,6 +1096,8 @@ subview_each2_aux::operator_plus
arma_conform_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" );
if(p_n_rows == 0) { continue; }
arrayops::inplace_plus( out.colptr(col), A_mem, p_n_rows );
}
}
@@ -1120,6 +1160,8 @@ subview_each2_aux::operator_minus
arma_conform_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" );
if(p_n_rows == 0) { continue; }
arrayops::inplace_minus( out.colptr(col), A_mem, p_n_rows );
}
}
@@ -1182,6 +1224,8 @@ subview_each2_aux::operator_minus
arma_conform_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" );
if(p_n_rows == 0) { continue; }
const eT* p_mem = p.colptr(col);
eT* out_mem = out.colptr(col);
@@ -1250,6 +1294,8 @@ subview_each2_aux::operator_schur
arma_conform_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" );
if(p_n_rows == 0) { continue; }
arrayops::inplace_mul( out.colptr(col), A_mem, p_n_rows );
}
}
@@ -1312,6 +1358,8 @@ subview_each2_aux::operator_div
arma_conform_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" );
if(p_n_rows == 0) { continue; }
arrayops::inplace_div( out.colptr(col), A_mem, p_n_rows );
}
}
@@ -1374,6 +1422,8 @@ subview_each2_aux::operator_div
arma_conform_check_bounds( (col >= p_n_cols), "each_col(): index out of bounds" );
if(p_n_rows == 0) { continue; }
const eT* p_mem = p.colptr(col);
eT* out_mem = out.colptr(col);
+208 -96
View File
@@ -95,6 +95,8 @@ subview<eT>::inplace_op(const eT val)
const uword s_n_rows = s.n_rows;
const uword s_n_cols = s.n_cols;
if( (s_n_rows == 0) || (s_n_cols == 0) ) { return; }
if(s_n_rows == 1)
{
Mat<eT>& A = const_cast< Mat<eT>& >(s.m);
@@ -151,6 +153,8 @@ subview<eT>::inplace_op(const Base<eT,T1>& in, const char* identifier)
arma_conform_assert_same_size(s, P, identifier);
if( (s_n_rows == 0) || (s_n_cols == 0) ) { return; }
const bool use_mp = arma_config::openmp && Proxy<T1>::use_mp && mp_gate<eT>::eval(s.n_elem);
const bool has_overlap = P.has_overlap(s);
@@ -348,8 +352,10 @@ subview<eT>::inplace_op(const subview<eT>& x, const char* identifier)
arma_conform_assert_same_size(s, x, identifier);
const uword s_n_cols = s.n_cols;
const uword s_n_rows = s.n_rows;
const uword s_n_cols = s.n_cols;
if( (s_n_rows == 0) || (s_n_cols == 0) ) { return; }
if(s_n_rows == 1)
{
@@ -606,7 +612,8 @@ subview<eT>::operator=(const SpBase<eT, T1>& x)
// Clear the subview.
zeros();
// Iterate through the sparse subview and set the nonzero values appropriately.
if(p.get_n_nonzero() == 0) { return; }
typename SpProxy<T1>::const_iterator_type cit = p.begin();
typename SpProxy<T1>::const_iterator_type cit_end = p.end();
@@ -631,7 +638,8 @@ subview<eT>::operator+=(const SpBase<eT, T1>& x)
arma_conform_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "addition");
// Iterate through the sparse subview and add its values.
if(p.get_n_nonzero() == 0) { return; }
typename SpProxy<T1>::const_iterator_type cit = p.begin();
typename SpProxy<T1>::const_iterator_type cit_end = p.end();
@@ -656,7 +664,8 @@ subview<eT>::operator-=(const SpBase<eT, T1>& x)
arma_conform_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "subtraction");
// Iterate through the sparse subview and subtract its values.
if(p.get_n_nonzero() == 0) { return; }
typename SpProxy<T1>::const_iterator_type cit = p.begin();
typename SpProxy<T1>::const_iterator_type cit_end = p.end();
@@ -725,13 +734,12 @@ subview<eT>::operator/=(const SpBase<eT, T1>& x)
{
arma_debug_sigprint();
// NOTE: use of this function is not advised; it is implemented only for completeness
const SpProxy<T1> p(x.get_ref());
arma_conform_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise division");
// This is probably going to fill your subview with a bunch of NaNs,
// so I'm not going to bother to implement it fast.
// You can have slow NaNs. They're fine too.
for(uword c = 0; c < n_cols; ++c)
for(uword r = 0; r < n_rows; ++r)
{
@@ -968,8 +976,10 @@ subview<eT>::replace(const eT old_val, const eT new_val)
subview<eT>& s = *this;
const uword s_n_cols = s.n_cols;
const uword s_n_rows = s.n_rows;
const uword s_n_cols = s.n_cols;
if( (s_n_rows == 0) || (s_n_cols == 0) ) { return; }
if(s_n_rows == 1)
{
@@ -1018,8 +1028,10 @@ subview<eT>::clean(const typename get_pod_type<eT>::result threshold)
subview<eT>& s = *this;
const uword s_n_cols = s.n_cols;
const uword s_n_rows = s.n_rows;
const uword s_n_cols = s.n_cols;
if(s_n_rows == 0) { return; }
for(uword ucol=0; ucol < s_n_cols; ++ucol)
{
@@ -1048,8 +1060,10 @@ subview<eT>::clamp(const eT min_val, const eT max_val)
subview<eT>& s = *this;
const uword s_n_cols = s.n_cols;
const uword s_n_rows = s.n_rows;
const uword s_n_cols = s.n_cols;
if(s_n_rows == 0) { return; }
for(uword ucol=0; ucol < s_n_cols; ++ucol)
{
@@ -1068,8 +1082,10 @@ subview<eT>::fill(const eT val)
subview<eT>& s = *this;
const uword s_n_cols = s.n_cols;
const uword s_n_rows = s.n_rows;
const uword s_n_cols = s.n_cols;
if( (s_n_rows == 0) || (s_n_cols == 0) ) { return; }
if(s_n_rows == 1)
{
@@ -1109,7 +1125,42 @@ subview<eT>::zeros()
{
arma_debug_sigprint();
(*this).fill(eT(0));
subview<eT>& s = *this;
const uword s_n_rows = s.n_rows;
const uword s_n_cols = s.n_cols;
if( (s_n_rows == 0) || (s_n_cols == 0) ) { return; }
if(s_n_rows == 1)
{
Mat<eT>& A = const_cast< Mat<eT>& >(s.m);
const uword A_n_rows = A.n_rows;
eT* Aptr = &(A.at(s.aux_row1,s.aux_col1));
constexpr eT eT_zero = eT(0);
for(uword ii=0; ii < s_n_cols; ++ii)
{
(*Aptr) = eT_zero; Aptr += A_n_rows;
}
}
else
{
if( (s.aux_row1 == 0) && (s_n_rows == s.m.n_rows) )
{
arrayops::fill_zeros( s.colptr(0), s.n_elem );
}
else
{
for(uword ucol=0; ucol < s_n_cols; ++ucol)
{
arrayops::fill_zeros( s.colptr(ucol), s_n_rows );
}
}
}
}
@@ -1157,6 +1208,8 @@ subview<eT>::randu()
const uword s_n_rows = s.n_rows;
const uword s_n_cols = s.n_cols;
if( (s_n_rows == 0) || (s_n_cols == 0) ) { return; }
if(s_n_rows == 1)
{
podarray<eT> tmp(s_n_cols);
@@ -1197,6 +1250,8 @@ subview<eT>::randn()
const uword s_n_rows = s.n_rows;
const uword s_n_cols = s.n_cols;
if( (s_n_rows == 0) || (s_n_cols == 0) ) { return; }
if(s_n_rows == 1)
{
podarray<eT> tmp(s_n_cols);
@@ -1410,7 +1465,7 @@ arma_inline
eT*
subview<eT>::colptr(const uword in_col)
{
return & access::rw((const_cast< Mat<eT>& >(m)).mem[ (in_col + aux_col1)*m.n_rows + aux_row1 ]);
return access::rwp( m.mem + ((in_col + aux_col1)*m.n_rows + aux_row1) );
}
@@ -1420,7 +1475,27 @@ arma_inline
const eT*
subview<eT>::colptr(const uword in_col) const
{
return & m.mem[ (in_col + aux_col1)*m.n_rows + aux_row1 ];
return m.mem + ((in_col + aux_col1)*m.n_rows + aux_row1);
}
template<typename eT>
arma_inline
eT*
subview<eT>::startptr()
{
return access::rwp( m.mem + (aux_col1*m.n_rows + aux_row1) );
}
template<typename eT>
arma_inline
const eT*
subview<eT>::startptr() const
{
return m.mem + (aux_col1*m.n_rows + aux_row1);
}
@@ -1483,9 +1558,12 @@ subview<eT>::is_finite() const
const uword local_n_rows = n_rows;
const uword local_n_cols = n_cols;
for(uword ii=0; ii<local_n_cols; ++ii)
if(local_n_rows != 0)
{
if(arrayops::is_finite(colptr(ii), local_n_rows) == false) { return false; }
for(uword ii=0; ii<local_n_cols; ++ii)
{
if(arrayops::is_finite(colptr(ii), local_n_rows) == false) { return false; }
}
}
return true;
@@ -1503,9 +1581,12 @@ subview<eT>::is_zero(const typename get_pod_type<eT>::result tol) const
const uword local_n_rows = n_rows;
const uword local_n_cols = n_cols;
for(uword ii=0; ii<local_n_cols; ++ii)
if(local_n_rows != 0)
{
if(arrayops::is_zero(colptr(ii), local_n_rows, tol) == false) { return false; }
for(uword ii=0; ii<local_n_cols; ++ii)
{
if(arrayops::is_zero(colptr(ii), local_n_rows, tol) == false) { return false; }
}
}
return true;
@@ -1525,9 +1606,12 @@ subview<eT>::has_inf() const
const uword local_n_rows = n_rows;
const uword local_n_cols = n_cols;
for(uword ii=0; ii<local_n_cols; ++ii)
if(local_n_rows != 0)
{
if(arrayops::has_inf(colptr(ii), local_n_rows)) { return true; }
for(uword ii=0; ii<local_n_cols; ++ii)
{
if(arrayops::has_inf(colptr(ii), local_n_rows)) { return true; }
}
}
return false;
@@ -1547,9 +1631,12 @@ subview<eT>::has_nan() const
const uword local_n_rows = n_rows;
const uword local_n_cols = n_cols;
for(uword ii=0; ii<local_n_cols; ++ii)
if(local_n_rows != 0)
{
if(arrayops::has_nan(colptr(ii), local_n_rows)) { return true; }
for(uword ii=0; ii<local_n_cols; ++ii)
{
if(arrayops::has_nan(colptr(ii), local_n_rows)) { return true; }
}
}
return false;
@@ -1569,9 +1656,12 @@ subview<eT>::has_nonfinite() const
const uword local_n_rows = n_rows;
const uword local_n_cols = n_cols;
for(uword ii=0; ii<local_n_cols; ++ii)
if(local_n_rows != 0)
{
if(arrayops::is_finite(colptr(ii), local_n_rows) == false) { return true; }
for(uword ii=0; ii<local_n_cols; ++ii)
{
if(arrayops::is_finite(colptr(ii), local_n_rows) == false) { return true; }
}
}
return false;
@@ -1590,64 +1680,66 @@ subview<eT>::extract(Mat<eT>& out, const subview<eT>& in)
// 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=()
const uword n_rows = in.n_rows; // number of rows in the subview
const uword n_cols = in.n_cols; // number of columns in the subview
arma_debug_print(arma_str::format("out.n_rows: %u; out.n_cols: %u; in.m.n_rows: %u; in.m.n_cols: %u") % out.n_rows % out.n_cols % in.m.n_rows % in.m.n_cols );
const uword n_rows = in.n_rows;
const uword n_cols = in.n_cols;
if(in.is_vec())
if( (n_rows == 0) || (n_cols == 0) ) { return; }
if(n_cols == 1)
{
if(n_cols == 1) // a column vector
{
arma_debug_print("subview::extract(): copying col");
// in.colptr(0) is the first column of the subview, taking into account any row offset
arrayops::copy( out.memptr(), in.colptr(0), n_rows );
}
else
if(n_rows == 1) // a row vector
{
arma_debug_print("subview::extract(): copying row)");
eT* out_mem = out.memptr();
const uword X_n_rows = in.m.n_rows;
const eT* Xptr = &(in.m.at(in.aux_row1,in.aux_col1));
uword j;
for(j=1; j < n_cols; j+=2)
{
const eT tmp1 = (*Xptr); Xptr += X_n_rows;
const eT tmp2 = (*Xptr); Xptr += X_n_rows;
(*out_mem) = tmp1; out_mem++;
(*out_mem) = tmp2; out_mem++;
}
if((j-1) < n_cols)
{
(*out_mem) = (*Xptr);
}
}
}
else // general submatrix
{
arma_debug_print("subview::extract(): general submatrix");
arma_debug_print("subview::extract(): copying col");
if( (in.aux_row1 == 0) && (n_rows == in.m.n_rows) )
// in.colptr(0) is the first column of the subview, taking into account any row offset
arrayops::copy( out.memptr(), in.colptr(0), n_rows );
return;
}
if(n_rows == 1)
{
arma_debug_print("subview::extract(): copying row");
eT* out_mem = out.memptr();
const uword X_n_rows = in.m.n_rows;
const eT* Xptr = &(in.m.at(in.aux_row1,in.aux_col1));
uword j;
for(j=1; j < n_cols; j+=2)
{
arrayops::copy( out.memptr(), in.colptr(0), in.n_elem );
const eT tmp1 = (*Xptr); Xptr += X_n_rows;
const eT tmp2 = (*Xptr); Xptr += X_n_rows;
(*out_mem) = tmp1; out_mem++;
(*out_mem) = tmp2; out_mem++;
}
else
if((j-1) < n_cols)
{
for(uword col=0; col < n_cols; ++col)
{
arrayops::copy( out.colptr(col), in.colptr(col), n_rows );
}
(*out_mem) = (*Xptr);
}
return;
}
if( (in.aux_row1 == 0) && (n_rows == in.m.n_rows) )
{
arma_debug_print("subview::extract(): contiguous submatrix");
arrayops::copy( out.memptr(), in.colptr(0), in.n_elem );
return;
}
arma_debug_print("subview::extract(): general submatrix");
for(uword col=0; col < n_cols; ++col)
{
arrayops::copy( out.colptr(col), in.colptr(col), n_rows );
}
}
@@ -1666,6 +1758,8 @@ subview<eT>::plus_inplace(Mat<eT>& out, const subview<eT>& in)
const uword n_rows = in.n_rows;
const uword n_cols = in.n_cols;
if( (n_rows == 0) || (n_cols == 0) ) { return; }
if(n_rows == 1)
{
eT* out_mem = out.memptr();
@@ -1714,6 +1808,8 @@ subview<eT>::minus_inplace(Mat<eT>& out, const subview<eT>& in)
const uword n_rows = in.n_rows;
const uword n_cols = in.n_cols;
if( (n_rows == 0) || (n_cols == 0) ) { return; }
if(n_rows == 1)
{
eT* out_mem = out.memptr();
@@ -1762,6 +1858,8 @@ subview<eT>::schur_inplace(Mat<eT>& out, const subview<eT>& in)
const uword n_rows = in.n_rows;
const uword n_cols = in.n_cols;
if( (n_rows == 0) || (n_cols == 0) ) { return; }
if(n_rows == 1)
{
eT* out_mem = out.memptr();
@@ -1810,6 +1908,8 @@ subview<eT>::div_inplace(Mat<eT>& out, const subview<eT>& in)
const uword n_rows = in.n_rows;
const uword n_cols = in.n_cols;
if( (n_rows == 0) || (n_cols == 0) ) { return; }
if(n_rows == 1)
{
eT* out_mem = out.memptr();
@@ -2377,9 +2477,12 @@ subview<eT>::each_col(const std::function< void(Col<eT>&) >& F)
{
arma_debug_sigprint();
for(uword ii=0; ii < n_cols; ++ii)
const uword local_n_rows = n_rows;
const uword local_n_cols = n_cols;
for(uword ii=0; ii < local_n_cols; ++ii)
{
Col<eT> tmp(colptr(ii), n_rows, false, true);
Col<eT> tmp(colptr(ii), local_n_rows, false, true);
F(tmp);
}
}
@@ -2393,9 +2496,12 @@ subview<eT>::each_col(const std::function< void(const Col<eT>&) >& F) const
{
arma_debug_sigprint();
for(uword ii=0; ii < n_cols; ++ii)
const uword local_n_rows = n_rows;
const uword local_n_cols = n_cols;
for(uword ii=0; ii < local_n_cols; ++ii)
{
const Col<eT> tmp(colptr(ii), n_rows, false, true);
const Col<eT> tmp(colptr(ii), local_n_rows, false, true);
F(tmp);
}
}
@@ -2410,20 +2516,23 @@ subview<eT>::each_row(const std::function< void(Row<eT>&) >& F)
{
arma_debug_sigprint();
podarray<eT> array1(n_cols);
podarray<eT> array2(n_cols);
const uword local_n_rows = n_rows;
const uword local_n_cols = n_cols;
Row<eT> tmp1( array1.memptr(), n_cols, false, true );
Row<eT> tmp2( array2.memptr(), n_cols, false, true );
podarray<eT> array1(local_n_cols);
podarray<eT> array2(local_n_cols);
Row<eT> tmp1( array1.memptr(), local_n_cols, false, true );
Row<eT> tmp2( array2.memptr(), local_n_cols, false, true );
eT* tmp1_mem = tmp1.memptr();
eT* tmp2_mem = tmp2.memptr();
uword ii, jj;
for(ii=0, jj=1; jj < n_rows; ii+=2, jj+=2)
for(ii=0, jj=1; jj < local_n_rows; ii+=2, jj+=2)
{
for(uword col_id = 0; col_id < n_cols; ++col_id)
for(uword col_id = 0; col_id < local_n_cols; ++col_id)
{
const eT* col_mem = colptr(col_id);
@@ -2434,7 +2543,7 @@ subview<eT>::each_row(const std::function< void(Row<eT>&) >& F)
F(tmp1);
F(tmp2);
for(uword col_id = 0; col_id < n_cols; ++col_id)
for(uword col_id = 0; col_id < local_n_cols; ++col_id)
{
eT* col_mem = colptr(col_id);
@@ -2443,7 +2552,7 @@ subview<eT>::each_row(const std::function< void(Row<eT>&) >& F)
}
}
if(ii < n_rows)
if(ii < local_n_rows)
{
tmp1 = (*this).row(ii);
@@ -2462,20 +2571,23 @@ subview<eT>::each_row(const std::function< void(const Row<eT>&) >& F) const
{
arma_debug_sigprint();
podarray<eT> array1(n_cols);
podarray<eT> array2(n_cols);
const uword local_n_rows = n_rows;
const uword local_n_cols = n_cols;
Row<eT> tmp1( array1.memptr(), n_cols, false, true );
Row<eT> tmp2( array2.memptr(), n_cols, false, true );
podarray<eT> array1(local_n_cols);
podarray<eT> array2(local_n_cols);
Row<eT> tmp1( array1.memptr(), local_n_cols, false, true );
Row<eT> tmp2( array2.memptr(), local_n_cols, false, true );
eT* tmp1_mem = tmp1.memptr();
eT* tmp2_mem = tmp2.memptr();
uword ii, jj;
for(ii=0, jj=1; jj < n_rows; ii+=2, jj+=2)
for(ii=0, jj=1; jj < local_n_rows; ii+=2, jj+=2)
{
for(uword col_id = 0; col_id < n_cols; ++col_id)
for(uword col_id = 0; col_id < local_n_cols; ++col_id)
{
const eT* col_mem = colptr(col_id);
@@ -2487,7 +2599,7 @@ subview<eT>::each_row(const std::function< void(const Row<eT>&) >& F) const
F(tmp2);
}
if(ii < n_rows)
if(ii < local_n_rows)
{
tmp1 = (*this).row(ii);
@@ -3264,7 +3376,7 @@ template<typename eT>
inline
subview_col<eT>::subview_col(const Mat<eT>& in_m, const uword in_col)
: subview<eT>(in_m, 0, in_col, in_m.n_rows, 1)
, colmem(subview<eT>::colptr(0))
, colmem(subview<eT>::startptr())
{
arma_debug_sigprint();
}
@@ -3275,7 +3387,7 @@ template<typename eT>
inline
subview_col<eT>::subview_col(const Mat<eT>& in_m, const uword in_col, const uword in_row1, const uword in_n_rows)
: subview<eT>(in_m, in_row1, in_col, in_n_rows, 1)
, colmem(subview<eT>::colptr(0))
, colmem(subview<eT>::startptr())
{
arma_debug_sigprint();
}
@@ -4268,7 +4380,7 @@ template<typename eT>
inline
subview_row<eT>::subview_row(const Mat<eT>& in_m, const uword in_row)
: subview<eT>(in_m, in_row, 0, 1, in_m.n_cols)
, rowmem(subview<eT>::colptr(0))
, rowmem(subview<eT>::startptr())
{
arma_debug_sigprint();
}
@@ -4279,7 +4391,7 @@ template<typename eT>
inline
subview_row<eT>::subview_row(const Mat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols)
: subview<eT>(in_m, in_row, in_col1, 1, in_n_cols)
, rowmem(subview<eT>::colptr(0))
, rowmem(subview<eT>::startptr())
{
arma_debug_sigprint();
}