Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
80087a3a55 | ||
|
|
d0b07c02a3 | ||
|
|
1716a6b531 | ||
|
|
a86cfc932b | ||
|
|
8ce3f3aa7d | ||
|
|
89158f7777 | ||
|
|
cedbd0eb89 | ||
|
|
fd38c47657 | ||
|
|
bb5c4469b3 | ||
|
|
36b0cd37ec | ||
|
|
59fbefc095 | ||
|
|
b1f3a185bf | ||
|
|
adcbf1380a | ||
|
|
733533f089 | ||
|
|
ae6f216a82 | ||
|
|
417bb37042 | ||
|
|
95cad27904 | ||
|
|
3e66e7b1f0 | ||
|
|
4a6cc3e9a8 | ||
|
|
0260b7f1dc | ||
|
|
6b180e1943 | ||
|
|
afec1a5f5a | ||
|
|
7ab5657470 | ||
|
|
fa63e6d717 | ||
|
|
bf69c85cb8 | ||
|
|
5e888a2fc7 | ||
|
|
f0db911a5c | ||
|
|
efff7a8f3f | ||
|
|
7f5569ffba | ||
|
|
7c9ef72802 | ||
|
|
c75af66d72 | ||
|
|
ce769c625f | ||
|
|
f1e65e55de | ||
|
|
7e4a956dbd | ||
|
|
43b071020a | ||
|
|
f548057ee7 | ||
|
|
e260407a3e | ||
|
|
f049b04688 | ||
|
|
8af4d74bd4 | ||
|
|
a039d60a47 | ||
|
|
a4634e8888 | ||
|
|
df1eec4fb9 | ||
|
|
4524c7580f | ||
|
|
536a642b64 | ||
|
|
80e1faa764 | ||
|
|
4e8e1564e0 | ||
|
|
cd0a21d242 | ||
|
|
e43f4f7ef9 | ||
|
|
f2691c6beb | ||
|
|
825dbf7e60 | ||
|
|
ed078509da | ||
|
|
759a36d0b3 | ||
|
|
e0d2196ae5 | ||
|
|
998c7814bc | ||
|
|
ebd9209b31 | ||
|
|
745b02d4d7 | ||
|
|
b28fd1456c | ||
|
|
44a7a9cfed | ||
|
|
ee9e26902f | ||
|
|
c14a60deec | ||
|
|
33e382b623 | ||
|
|
7334664999 | ||
|
|
f021766215 | ||
|
|
5491a20833 | ||
|
|
1cab3be4df | ||
|
|
08e1cb5211 | ||
|
|
70c45a2f17 | ||
|
|
2dfed59b94 | ||
|
|
8bf7834041 | ||
|
|
1461d33045 | ||
|
|
e05bc82e7b | ||
|
|
9201e8ddd0 | ||
|
|
30dd62780b | ||
|
|
5dd6c665a5 | ||
|
|
2e6b4ed0a3 | ||
|
|
08c0647e54 | ||
|
|
ff7f5d63e6 | ||
|
|
2288ec1497 | ||
|
|
1df5fc83b7 | ||
|
|
81df0a1f93 | ||
|
|
bceaf09865 | ||
|
|
3992546579 | ||
|
|
602f6217e0 | ||
|
|
449e6f682f | ||
|
|
03df540096 | ||
|
|
b21700fc85 | ||
|
|
02438fff53 | ||
|
|
451d5d2cec | ||
|
|
534f135ef5 | ||
|
|
8bd0d6692a | ||
|
|
ad1bed2686 | ||
|
|
36e3d67a28 | ||
|
|
e3db651df7 | ||
|
|
fa52e3f5ef | ||
|
|
e6b06b21da | ||
|
|
252708e389 | ||
|
|
4b468f5009 | ||
|
|
1244651dda | ||
|
|
e4b96542b3 | ||
|
|
5701dd07a8 | ||
|
|
bdc89797cd | ||
|
|
2110b7d82c | ||
|
|
3bcfde3238 | ||
|
|
3495f87581 | ||
|
|
8a24c0d724 | ||
|
|
ec75a6107c | ||
|
|
450e1ba8a5 | ||
|
|
a0dcf97054 | ||
|
|
cd96c0d9e2 | ||
|
|
5e4ce67bf4 | ||
|
|
7dbe9fa6c3 | ||
|
|
7da30298dd | ||
|
|
f347a5640e | ||
|
|
c7433b6e60 | ||
|
|
e712b832e8 | ||
|
|
8a736f85a3 | ||
|
|
9f8bf056c2 | ||
|
|
b79a7e005c | ||
|
|
cae3a6a4bf | ||
|
|
fb6278f692 | ||
|
|
8622e81b8a | ||
|
|
f788d4032f | ||
|
|
c2b1eea864 | ||
|
|
6eb9394e13 | ||
|
|
391a1df2e8 | ||
|
|
7b718b1ae9 | ||
|
|
bc18db7a51 | ||
|
|
505339b6e5 | ||
|
|
f015fac562 | ||
|
|
502cbca4ba | ||
|
|
5e5331acd4 | ||
|
|
2dddc1367e | ||
|
|
5ca720b31f | ||
|
|
f72922fa68 | ||
|
|
c18e7f0aff |
+4
-2
@@ -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 "")
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
Armadillo C++ Linear Algebra Library
|
||||
Copyright 2008-2025 Conrad Sanderson (https://conradsanderson.id.au)
|
||||
Copyright 2008-2026 Conrad Sanderson (https://conradsanderson.id.au)
|
||||
Copyright 2008-2016 National ICT Australia (NICTA)
|
||||
Copyright 2017-2025 Data61 / CSIRO
|
||||
Copyright 2017-2026 Data61 / CSIRO
|
||||
|
||||
This product includes software developed by Conrad Sanderson (https://conradsanderson.id.au)
|
||||
This product includes software developed at National ICT Australia (NICTA)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
### Armadillo: C++ Library for Linear Algebra & Scientific Computing
|
||||
https://arma.sourceforge.net
|
||||
|
||||
Copyright 2008-2025 Conrad Sanderson (https://conradsanderson.id.au)
|
||||
Copyright 2008-2026 Conrad Sanderson (https://conradsanderson.id.au)
|
||||
Copyright 2008-2016 National ICT Australia (NICTA)
|
||||
Copyright 2017-2025 Data61 / CSIRO
|
||||
Copyright 2017-2026 Data61 / CSIRO
|
||||
|
||||
---
|
||||
|
||||
@@ -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.
@@ -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<<i>type</i>>, colvec, vec</a></td><td> </td><td>dense column vector class</td></tr>
|
||||
<tr><td><a href="#Row">Row<<i>type</i>>, rowvec</a></td><td> </td><td>dense row vector class</td></tr>
|
||||
<tr><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td><a href="#Cube">Cube<<i>type</i>>, cube, cx_cube</a></td><td> </td><td>dense cube class ("3D matrix")</td></tr>
|
||||
<tr><td><a href="#Cube">Cube<<i>type</i>>, cube, cx_cube</a></td><td> </td><td>dense cube class (quasi third-order tensor, aka "3D matrix")</td></tr>
|
||||
<tr><td><a href="#field">field<<i>object type</i>></a></td><td> </td><td>class for storing arbitrary objects in matrix-like or cube-like layouts</td></tr>
|
||||
<tr><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td><a href="#SpMat">SpMat<<i>type</i>>, sp_mat, sp_cx_mat</a></td><td> </td><td>sparse matrix class</td></tr>
|
||||
<tr><td> </td><td> </td><td> </td></tr>
|
||||
<tr><td><a href="#operators">operators</a></td><td> </td><td><code><big>+</big> <big>−</big> <big>*</big> % / == != <= >= < > && ||</code></td></tr>
|
||||
@@ -569,8 +579,6 @@ Conrad Sanderson and Ryan Curtin.
|
||||
<tr style="background-color: #F5F5F5;"><td><a href="#example_prog">example program</a></td><td> </td><td>short example program</td></tr>
|
||||
<tr><td><a href="#config_hpp">config.hpp</a></td><td> </td><td>configuration options</td></tr>
|
||||
<tr><td><a href="#changelog">API additions</a></td><td> </td><td>API stability and list of API additions</td></tr>
|
||||
<!--<tr><td><a href="#log_add">log_add</a></td><td> </td><td>TODO</td></tr>-->
|
||||
<!--<tr><td><a href="#catching_exceptions">catching exceptions</a></td><td> </td><td>TODO</td></tr>-->
|
||||
</tbody>
|
||||
</table>
|
||||
</ul>
|
||||
@@ -751,6 +759,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,28 +785,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> ↦ </td><td>set all elements to 0 (default in Armadillo >= 10.5)</td></tr>
|
||||
<tr><td><code>fill::ones</code></td><td> ↦ </td><td>set all elements to 1</td></tr>
|
||||
<tr><td><code>fill::eye</code></td><td> ↦ </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> ↦ </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> ↦ </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> ↦ </td><td>set all elements to specified scalar</td></tr>
|
||||
<tr><td><code>fill::none</code></td><td> ↦ </td><td>do not initialise the elements (matrix may have garbage values)</td></tr>
|
||||
<tr><td><code>fill::zeros</code></td><td> ↦ </td><td>set all elements to 0 (default operation)</td></tr>
|
||||
<tr><td><code>fill::ones</code></td><td> ↦ </td><td>set all elements to 1</td></tr>
|
||||
<!-- <tr><td><code>fill::nan</code></td><td> ↦ </td><td>set all elements to NaN</td></tr> -->
|
||||
<!-- <tr><td><code>fill::pos_inf</code></td><td> ↦ </td><td>set all elements to +infinity</td></tr> -->
|
||||
<!-- <tr><td><code>fill::neg_inf</code></td><td> ↦ </td><td>set all elements to -infinity</td></tr> -->
|
||||
<tr><td><code>fill::value(scalar)</code></td><td> ↦ </td><td>set all elements to the specified scalar</td></tr>
|
||||
<tr><td><code>fill::eye</code></td><td> ↦ </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> ↦ </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> ↦ </td><td>set elements to random values from a normal/Gaussian distribution with mean = 0 and variance = 1</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
<b>Caveat:</b>
|
||||
<ul>
|
||||
<li>in Armadillo >= 10.5, the default initialisation is <code>fill::zeros</code></li>
|
||||
<li>in Armadillo <= 10.4, the default initialisation is <code>fill::none</code></li>
|
||||
</ul>
|
||||
</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;
|
||||
@@ -884,6 +893,16 @@ data is copied from auxiliary memory, where <i>ptr_aux_mem</i> is a pointer to t
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
Support for the <i>std::uint8_t</i> and <i>std::int8_t</i> element types can be enabled by defining both <code>ARMA_U8_TYPE</code> and <code>ARMA_S8_TYPE</code> before including the armadillo header:
|
||||
<ul>
|
||||
<pre>
|
||||
#define ARMA_U8_TYPE std::uint8_t
|
||||
#define ARMA_S8_TYPE std::int8_t
|
||||
#include <armadillo>
|
||||
</pre>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
Examples:
|
||||
@@ -1151,6 +1170,8 @@ main exceptions are functions which require square matrices
|
||||
<br>
|
||||
<li>
|
||||
Constructors:
|
||||
<br>
|
||||
<br>
|
||||
<ul>
|
||||
<table>
|
||||
<tbody>
|
||||
@@ -1423,6 +1444,8 @@ main exceptions are functions which require square matrices
|
||||
<br>
|
||||
<li>
|
||||
Constructors:
|
||||
<br>
|
||||
<br>
|
||||
<ul>
|
||||
<table>
|
||||
<tbody>
|
||||
@@ -1549,11 +1572,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>
|
||||
@@ -1701,6 +1724,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>
|
||||
@@ -1719,27 +1744,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> ↦ </td><td>set all elements to 0 (default in Armadillo >= 10.5)</td></tr>
|
||||
<tr><td><code>fill::ones</code></td><td> ↦ </td><td>set all elements to 1</td></tr>
|
||||
<tr><td><code>fill::randu</code></td><td> ↦ </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> ↦ </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> ↦ </td><td>set all elements to specified scalar</td></tr>
|
||||
<tr><td><code>fill::none</code></td><td> ↦ </td><td>do not initialise the elements (cube may have garbage values)</td></tr>
|
||||
<tr><td><code>fill::zeros</code></td><td> ↦ </td><td>set all elements to 0 (default operation)</td></tr>
|
||||
<tr><td><code>fill::ones</code></td><td> ↦ </td><td>set all elements to 1</td></tr>
|
||||
<!-- <tr><td><code>fill::nan</code></td><td> ↦ </td><td>set all elements to NaN</td></tr> -->
|
||||
<!-- <tr><td><code>fill::pos_inf</code></td><td> ↦ </td><td>set all elements to +infinity</td></tr> -->
|
||||
<!-- <tr><td><code>fill::neg_inf</code></td><td> ↦ </td><td>set all elements to -infinity</td></tr> -->
|
||||
<tr><td><code>fill::value(scalar)</code></td><td> ↦ </td><td>set all elements to the specified scalar</td></tr>
|
||||
<tr><td><code>fill::randu</code></td><td> ↦ </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> ↦ </td><td>set elements to random values from a normal/Gaussian distribution with mean = 0 and variance = 1</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
<b>Caveat:</b>
|
||||
<ul>
|
||||
<li>in Armadillo >= 10.5, the default initialisation is <code>fill::zeros</code></li>
|
||||
<li>in Armadillo <= 10.4, the default initialisation is <code>fill::none</code></li>
|
||||
</ul>
|
||||
</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.
|
||||
@@ -1875,6 +1899,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>
|
||||
@@ -1901,6 +1927,7 @@ mat A = randn(2,3);
|
||||
mat B = randn(4,5);
|
||||
|
||||
field<mat> F(2,1);
|
||||
|
||||
F(0,0) = A;
|
||||
F(1,0) = B;
|
||||
|
||||
@@ -2075,6 +2102,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>
|
||||
@@ -2112,6 +2141,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 1: <code>sp_mat(<i>locations</i>, <i>values</i>, <i>sort_locations = true</i>)</code></li>
|
||||
<li>form 2: <code>sp_mat(<i>locations</i>, <i>values</i>, <i>n_rows</i>, <i>n_cols</i>, <i>sort_locations = true</i>, <i>check_for_zeros = true</i>)</code></li>
|
||||
@@ -2165,6 +2196,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 & 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>
|
||||
@@ -2214,10 +2247,6 @@ See also:
|
||||
<li><a href="#element_access">element access</a></li>
|
||||
<li><a href="#iterators_spmat">element iterators (sparse matrices)</a></li>
|
||||
<li><a href="#print">printing matrices</a></li>
|
||||
<!--
|
||||
<li><a href="#SpCol">SpCol class</a> (TODO: add to documentation)</li>
|
||||
<li><a href="#SpRow">SpRow class</a> (TODO: add to documentation)</li>
|
||||
-->
|
||||
<li><a href="https://en.wikipedia.org/wiki/Sparse_matrix">Sparse Matrix in Wikipedia</a></li>
|
||||
<li><a href="#Mat">Mat class</a> (dense matrix)</li>
|
||||
</ul>
|
||||
@@ -2944,6 +2973,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>
|
||||
@@ -3102,7 +3132,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>
|
||||
@@ -3113,29 +3143,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() & .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>
|
||||
@@ -3920,6 +3959,10 @@ Instances of <i>span(start,end)</i> can be replaced by <i>span::all</i> to indic
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
To distinguish <i>span(start,end)</i> from <i>std::span</i>, use the <i>arma::</i> prefix, ie. <i>arma::span(start,end)</i>
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
For functions requiring one or more vector of indices,
|
||||
eg. <i>X.submat(vector_of_row_indices, vector_of_column_indices)</i>,
|
||||
each vector of indices must be of type <i><a href="#Col">uvec</a></i>
|
||||
@@ -4083,8 +4126,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>
|
||||
@@ -4299,7 +4342,7 @@ Similar to "broadcasting" in Matlab / Octave
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
Supported operations for forms 1 and 2:
|
||||
Supported operations for forms 1 and 2:
|
||||
<br>
|
||||
<br>
|
||||
<ul>
|
||||
@@ -4314,7 +4357,7 @@ Supported operations for forms 1 and 2:
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
For form 2:
|
||||
For form 2:
|
||||
<ul>
|
||||
<li>the argument <i>vector_of_indices</i> contains a list of indices of the columns/rows to be used; it must evaluate to a vector of type <i><a href="#Col">uvec</a></i></li>
|
||||
<li>arithmetic operations as per form 1 are supported</li>
|
||||
@@ -4322,7 +4365,7 @@ For form 2:
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
For form 3:
|
||||
For form 3:
|
||||
<ul>
|
||||
<li>apply the given <i>lambda_function</i> to each column vector or row vector</li>
|
||||
<li>the function must accept a reference to a <a href="#Col">Col</a> or <a href="#Row">Row</a> object with the same element type as the underlying matrix</li>
|
||||
@@ -4395,7 +4438,7 @@ Similar to "broadcasting" in Matlab / Octave
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
Supported operations for form 1:
|
||||
Supported operations for form 1:
|
||||
<br>
|
||||
<br>
|
||||
<ul>
|
||||
@@ -4411,7 +4454,7 @@ Supported operations for form 1:
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
For form 2:
|
||||
For form 2:
|
||||
<ul>
|
||||
<li>the argument <i>vector_of_indices</i> contains a list of indices of the slices to be used; it must evaluate to a vector of type <i><a href="#Col">uvec</a></i></li>
|
||||
<li>arithmetic operations as per form 1 are supported, except for <code><b>*</b></code> and <code><b>*=</b></code> (ie. matrix multiplication)</li>
|
||||
@@ -4419,7 +4462,7 @@ For form 2:
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
For form 3:
|
||||
For form 3:
|
||||
<ul>
|
||||
<li>apply the given <i>lambda_function</i> to each slice</li>
|
||||
<li>the function must accept a reference to a <a href="#Mat">Mat</a> object with the same element type as the underlying cube</li>
|
||||
@@ -4427,7 +4470,7 @@ For form 3:
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
For form 4:
|
||||
For form 4:
|
||||
<ul>
|
||||
<li>apply the given <i>lambda_function</i> to each slice, as per form 3</li>
|
||||
<li>the argument <i>use_mp</i> is a bool to enable the use of OpenMP for multi-threaded execution of <i>lambda_function</i> on multiple slices at the same time</li>
|
||||
@@ -5817,6 +5860,7 @@ Examples:
|
||||
<ul>
|
||||
<pre>
|
||||
mat X(4, 5, fill::randu);
|
||||
|
||||
vec v = X.as_col();
|
||||
</pre>
|
||||
</ul>
|
||||
@@ -5870,9 +5914,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>
|
||||
@@ -6822,6 +6868,7 @@ See also:
|
||||
<li><a href="#has_nan">.has_nan()</a></li>
|
||||
<li><a href="#find_finite_nonfinite">find_finite() / find_nonfinite()</a></li>
|
||||
<li><a href="#find_nan_nonnan">find_nan() / find_nonnan()</a></li>
|
||||
<li><a href="#omit_nan_nonfinite">omit_nan() / omit_nonfinite()</a></li>
|
||||
<li><a href="#constants">constants (pi, nan, inf, ...)</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -6864,6 +6911,7 @@ See also:
|
||||
<li><a href="#replace">.replace()</a></li>
|
||||
<li><a href="#is_finite">.is_finite()</a>
|
||||
<li><a href="#find_finite_nonfinite">find_finite() / find_nonfinite()</a></li>
|
||||
<li><a href="#omit_nan_nonfinite">omit_nonfinite()</a></li>
|
||||
<li><a href="#constants">constants (pi, nan, inf, ...)</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -6911,6 +6959,7 @@ See also:
|
||||
<li><a href="#replace">.replace()</a></li>
|
||||
<li><a href="#is_finite">.is_finite()</a>
|
||||
<li><a href="#find_nan_nonnan">find_nan() / find_nonnan()</a></li>
|
||||
<li><a href="#omit_nan_nonfinite">omit_nan()</a></li>
|
||||
<li><a href="#constants">constants (pi, nan, inf, ...)</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -7129,58 +7178,58 @@ A.brief_print("A:");
|
||||
<br>
|
||||
<br>
|
||||
<ul>
|
||||
<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>auto_detect</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>auto_detect</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Used only by <i>.load()</i> only: attempt to automatically detect the file type as one of the formats described below;
|
||||
<br>[ default operation for <i>.load()</i> ]<br><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>arma_binary</b><br></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>arma_binary</b><br></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Numerical data stored in machine dependent binary format, with a simple header to speed up loading.
|
||||
The header indicates the type and size of matrix/cube.
|
||||
<br>[ default operation for <i>.save()</i> ]
|
||||
<br>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>arma_ascii</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>arma_ascii</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Numerical data stored in human readable text format, with a simple header to speed up loading.
|
||||
The header indicates the type and size of matrix/cube.
|
||||
<br>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>raw_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>raw_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Numerical data stored in machine dependent raw binary format, without a header.
|
||||
Matrices are loaded to have one column,
|
||||
while cubes are loaded to have one slice with one column.
|
||||
The <a href="#reshape_member">.reshape()</a> function can be used to alter the size of the loaded matrix/cube without losing data.
|
||||
<br>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>raw_ascii</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>raw_ascii</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Numerical data stored in raw ASCII format, without a header.
|
||||
The numbers are separated by whitespace.
|
||||
The number of columns must be the same in each row.
|
||||
@@ -7189,26 +7238,26 @@ Data which was saved in Matlab/Octave using the <i>-ascii</i> option can be read
|
||||
Complex numbers are stored in standard C++ notation, which is a tuple surrounded by brackets: eg. (1.23,4.56) indicates 1.24 + 4.56i.
|
||||
<br>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>csv_ascii</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>csv_ascii</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Numerical data stored in comma separated value (CSV) text format, <b>without</b> a header.
|
||||
To save/load <b>with</b> a header, use the <b>csv_name(</b>filename,header<b>)</b> specification instead (more details below).
|
||||
Handles complex numbers stored in the compound form of 1.24+4.56i.
|
||||
Applicable to <i>Mat</i> and <i>SpMat</i>.
|
||||
<br>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>coord_ascii</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>coord_ascii</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Numerical data stored as a text file in coordinate list format, without a header.
|
||||
Only non-zero values are stored.
|
||||
<br>
|
||||
@@ -7219,39 +7268,39 @@ For real matrices, each line contains information in the following format:
|
||||
<br><b>Caveat:</b> not supported by <i>auto_detect</i>.
|
||||
<br>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>pgm_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>pgm_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Image data stored in Portable Gray Map (PGM) format.
|
||||
Applicable to <i>Mat</i> only.
|
||||
Saving <i>int</i>, <i>float</i> or <i>double</i> matrices is a lossy operation, as each element is copied and converted to an 8 bit representation.
|
||||
As such the matrix should have values in the [0,255] interval, otherwise the resulting image may not display correctly.
|
||||
<br>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>ppm_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>ppm_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Image data stored in Portable Pixel Map (PPM) format.
|
||||
Applicable to <i>Cube</i> only.
|
||||
Saving <i>int</i>, <i>float</i> or <i>double</i> matrices is a lossy operation, as each element is copied and converted to an 8 bit representation.
|
||||
As such the cube/field should have values in the [0,255] interval, otherwise the resulting image may not display correctly.
|
||||
<br>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>hdf5_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>hdf5_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Numerical data stored in portable <a href="https://en.wikipedia.org/wiki/Hierarchical_Data_Format">HDF5</a> binary format.
|
||||
<ul>
|
||||
<li>
|
||||
@@ -7267,10 +7316,10 @@ for loading, the order of operations is:
|
||||
to explicitly control the dataset name, specify it via the <b>hdf5_name()</b> argument (more details below)
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
@@ -7387,6 +7436,7 @@ if(ok == false)
|
||||
<li><a href="https://en.wikipedia.org/wiki/Hierarchical_Data_Format">HDF</a> in Wikipedia</li>
|
||||
<li><a href="https://en.wikipedia.org/wiki/Comma-separated_values">CSV</a> in Wikipedia
|
||||
<li><a href="#save_load_field">saving / loading fields</a></li>
|
||||
<li><a href="#element_initialisation">element initialisation</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
@@ -7439,26 +7489,26 @@ Other than storing string fields as text files, the following file formats are s
|
||||
<br>
|
||||
<br>
|
||||
<ul>
|
||||
<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>auto_detect</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>auto_detect</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
<br>
|
||||
<li>
|
||||
<i>.load()</i>: attempt to automatically detect the field format type as one of the formats described below;
|
||||
this is the default operation
|
||||
</li>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>arma_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>arma_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
<br>
|
||||
<li>
|
||||
objects are stored in machine dependent binary format
|
||||
@@ -7469,13 +7519,13 @@ default type for fields of type <i>Mat</i>, <i>Col</i>, <i>Row</i> or <i>Cube</i
|
||||
only applicable to fields of type <i>Mat</i>, <i>Col</i>, <i>Row</i> or <i>Cube</i>
|
||||
</li>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>ppm_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>ppm_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
<br>
|
||||
<li>
|
||||
image data stored in Portable Pixmap Map (PPM) format
|
||||
@@ -7494,11 +7544,10 @@ it is assumed that the red, green and blue components are stored in the first, s
|
||||
saving <i>int</i>, <i>float</i> or <i>double</i> matrices is a lossy operation,
|
||||
as each matrix element is copied and converted to an 8 bit representation
|
||||
</li>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
@@ -9606,7 +9655,7 @@ vec b = diff(a);
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
<b>Caveat:</b> <a href="#norm">norm()</a> is preferred for calculating the 2-norm, as it reduces the incidence of numerical underflows and overflows
|
||||
<b>Caveat:</b> to obtain the Euclidean norm, use the more robust <a href="#norm">norm(x)</a> instead of <i>sqrt(dot(x,x))</i>
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
@@ -9732,10 +9781,6 @@ See also:
|
||||
<li><i>expmat_sym(B,A)</i> resets <i>B</i> and returns a bool set to <i>false</i> (exception is not thrown)</li>
|
||||
</ul>
|
||||
</li>
|
||||
<!--
|
||||
<br>
|
||||
<li><b>Caveat:</b> there is no explicit check whether <i>A</i> is symmetric/hermitian</li>
|
||||
-->
|
||||
<br>
|
||||
<li><b>Caveat:</b> the matrix exponential operation is generally <b>not</b> the same as applying the <a href="#misc_fns">exp()</a> function to each element</li>
|
||||
<br>
|
||||
@@ -10706,10 +10751,6 @@ See also:
|
||||
<li><i>logmat_sympd(B,A)</i> resets <i>B</i> and returns a bool set to <i>false</i> (exception is not thrown)</li>
|
||||
</ul>
|
||||
</li>
|
||||
<!--
|
||||
<br>
|
||||
<li><b>Caveat:</b> there is no explicit check whether <i>A</i> is symmetric/hermitian positive definite</li>
|
||||
-->
|
||||
<br>
|
||||
<li><b>Caveat:</b> the matrix logarithm operation is generally <b>not</b> the same as applying the <a href="#misc_fns">log()</a> function to each element</li>
|
||||
<br>
|
||||
@@ -11092,6 +11133,9 @@ See also:
|
||||
<li><a href="#nonzeros">nonzeros()</a>
|
||||
<li><a href="#vectorise">vectorise()</a>
|
||||
<li><a href="#for_each">.for_each()</a>
|
||||
<li><a href="#is_finite">.is_finite()</a>
|
||||
<li><a href="#has_inf">.has_inf()</a>
|
||||
<li><a href="#has_nan">.has_nan()</a>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
@@ -11103,11 +11147,6 @@ See also:
|
||||
<tbody>
|
||||
<tr><td><b>pow( A, scalar )</b></td><td> </td><td>(form 1)</td></tr>
|
||||
<tr><td><b>pow( A, B )</b></td><td> </td><td>(form 2)</td></tr>
|
||||
<!--
|
||||
<tr><td><b>pow( M.each_col(), C )</b></td><td> </td><td>(form 3)</td></tr>
|
||||
<tr><td><b>pow( M.each_row(), R )</b></td><td> </td><td>(form 4)</td></tr>
|
||||
<tr><td><b>pow( Q.each_slice(), M )</b></td><td> </td><td>(form 5)</td></tr>
|
||||
-->
|
||||
</tbody>
|
||||
</table>
|
||||
<ul>
|
||||
@@ -11117,17 +11156,6 @@ See also:
|
||||
<br>
|
||||
<li>form 2: raise each element in <i>A</i> to the power denoted by the corresponding element in <i>B</i>; sizes of <i>A</i> and <i>B</i> must be the same</li>
|
||||
<br>
|
||||
<!--
|
||||
<li>form 3: for each column vector of matrix <i>M</i>, raise each element to the power denoted by the corresponding element in column vector <i>C</i>;
|
||||
<br>the number of rows in <i>M</i> and <i>C</i> must be the same</li>
|
||||
<br>
|
||||
<li>form 4: for each row vector of matrix <i>M</i>, raise each element to the power denoted by the corresponding element in row vector <i>R</i>;
|
||||
<br>the number of columns in <i>M</i> and <i>R</i> must be the same</li>
|
||||
<br>
|
||||
<li>form 5: for each slice of cube <i>Q</i>, raise each element to the power denoted by the corresponding element in matrix <i>M</i>;
|
||||
<br>the number of rows and columns in <i>Q</i> and <i>M</i> must be the same</li>
|
||||
<br>
|
||||
-->
|
||||
<li><b>Caveats</b>:
|
||||
<ul>
|
||||
<li>to raise all elements to the power 2, use <a href="#misc_fns">square()</a> instead</li>
|
||||
@@ -11144,13 +11172,6 @@ mat B(5, 6, fill::randu);
|
||||
mat X = pow(A, 3.45);
|
||||
mat Y = pow(A, B);
|
||||
</pre>
|
||||
<!--
|
||||
vec C(5, fill::randu);
|
||||
rowvec R(6, fill::randu);
|
||||
|
||||
mat Z1 = pow(A.each_col(), C);
|
||||
mat Z2 = pow(A.each_row(), R);
|
||||
-->
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
@@ -11159,10 +11180,6 @@ See also:
|
||||
<ul>
|
||||
<li><a href="#powmat">powmat()</a></li>
|
||||
<li><a href="#misc_fns">miscellaneous element-wise functions</a></li>
|
||||
<!--
|
||||
<li><a href="#each_colrow">.each_col() & .each_row()</a></li>
|
||||
<li><a href="#each_slice">.each_slice()</a></li>
|
||||
-->
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
@@ -12047,10 +12064,6 @@ See also:
|
||||
<li><i>sqrtmat_sympd(B,A)</i> resets <i>B</i> and returns a bool set to <i>false</i> (exception is not thrown)</li>
|
||||
</ul>
|
||||
</li>
|
||||
<!--
|
||||
<br>
|
||||
<li><b>Caveat:</b> there is no explicit check whether <i>A</i> is symmetric/hermitian positive definite</li>
|
||||
-->
|
||||
<br>
|
||||
<li><b>Caveat:</b> the matrix square root operation is generally <b>not</b> the same as applying the <a href="#misc_fns">sqrt()</a> function to each element</li>
|
||||
<br>
|
||||
@@ -13191,10 +13204,6 @@ the divide-and-conquer method provides slightly different results than the stand
|
||||
<li><i>eig_sym(eigval,eigvec,X)</i> resets <i>eigval</i> & <i>eigvec</i> and returns a bool set to <i>false</i> (exception is not thrown)</li>
|
||||
</ul>
|
||||
</li>
|
||||
<!--
|
||||
<br>
|
||||
<li><b>Caveat:</b> there is no explicit check whether <i>X</i> is symmetric/hermitian</li>
|
||||
-->
|
||||
<br>
|
||||
<li>
|
||||
Examples:
|
||||
@@ -13572,10 +13581,6 @@ If <i>A</i> is not square sized, a <i>std::logic_error</i> exception is thrown
|
||||
<li><i>inv_sympd(B,rcond,A)</i> resets <i>B</i>, sets rcond to zero, and returns a bool set to <i>false</i> (exception is not thrown)</li>
|
||||
</ul>
|
||||
</li>
|
||||
<!--
|
||||
<br>
|
||||
<li><b>Caveat:</b> there is no explicit check whether <i>A</i> is symmetric/hermitian positive definite</li>
|
||||
-->
|
||||
<br>
|
||||
<li>
|
||||
<b>Caveat:</b>
|
||||
@@ -14967,7 +14972,6 @@ See also:
|
||||
<ul>
|
||||
<li><a href="#spsolve_factoriser">spsolve_factoriser</a></li>
|
||||
<li><a href="#solve">solve()</a> - solve dense system of linear equations</li>
|
||||
<!-- <li><a href="http://crd-legacy.lbl.gov/~xiaoye/SuperLU/">SuperLU home page</a> -->
|
||||
<li><a href="https://portal.nersc.gov/project/sparse/superlu/">SuperLU home page</a>
|
||||
<li><a href="https://mathworld.wolfram.com/LinearSystemofEquations.html">linear system of equations in MathWorld</a></li>
|
||||
<li><a href="https://en.wikipedia.org/wiki/Linear_system_of_equations">system of linear equations in Wikipedia</a></li>
|
||||
@@ -17888,7 +17892,6 @@ model.save("my_model.gmm");
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
machine epsilon; approximately 2.2204e-16; difference between 1 and the next representable value
|
||||
<!-- machine epsilon: the difference between 1 and the value least greater than 1 that is representable (type and machine dependent) -->
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -18433,7 +18436,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>
|
||||
@@ -18490,7 +18493,7 @@ See also:
|
||||
<b>RNG seed setting</b>
|
||||
<ul>
|
||||
<li>
|
||||
There are two functions to change the seed used by the random number generator (RNG):
|
||||
Functions to change the seed used by the random number generator (RNG):
|
||||
<br>
|
||||
<br>
|
||||
<table style="text-align: left;" border="0" cellpadding="2" cellspacing="2">
|
||||
@@ -18614,33 +18617,6 @@ See also:
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
<!--
|
||||
<div class="pagebreak"></div><div class="noprint"><hr class="greyline"><br></div>
|
||||
<a name="log_add"></a>
|
||||
<b>log_add(log_a, log_b)</b>
|
||||
<ul>
|
||||
<li>
|
||||
Safe replacement for log(exp(log_a) + exp(log_b))
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
Usage:
|
||||
<ul>
|
||||
<li>
|
||||
<i>scalar_type</i> log_c = log_add(log_a, log_b)
|
||||
</li>
|
||||
<li>
|
||||
<i>scalar_type</i> is either <i>float</i> or <i>double</i>
|
||||
</li>
|
||||
<li>
|
||||
log_a, log_b and log_c must have the same type
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<br>
|
||||
-->
|
||||
|
||||
<div class="pagebreak"></div><div class="noprint"><hr class="greyline"><br></div>
|
||||
<a name="uword"></a>
|
||||
<b>uword</b>, <b>sword</b>
|
||||
@@ -18781,7 +18757,7 @@ rudimentary <i>fp16</i> hardware support is present on x86-64 CPUs with the F16C
|
||||
<br>
|
||||
</ul>
|
||||
<li>
|
||||
If no compiler or hardware support is detected, support for <i>fp16</i> element types is <b>not</b> automatically enableds
|
||||
If no compiler or hardware support is detected, support for <i>fp16</i> element types is <b>not</b> automatically enabled
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
@@ -18816,7 +18792,6 @@ fp16 val = X(2,3);
|
||||
<li><a href="#Mat">hmat</a> matrix type
|
||||
<li><a href="#Col">hvec</a> vector type
|
||||
<li><a href="https://en.cppreference.com/w/cpp/types/floating-point.html">std::float16_t</a> in cppreference.com</li>
|
||||
<!-- <li><a href="https://en.cppreference.com/w/cpp/header/stdfloat.html">std::float16_t</a> in cppreference.com</li> -->
|
||||
<li><a href="https://en.wikipedia.org/wiki/Half-precision_floating-point_format">half-precision floating point format in Wikipedia</a></li>
|
||||
<li><a href="https://en.wikipedia.org/wiki/AVX-512">AVX-512 extensions in Wikipedia</a></li>
|
||||
<!-- <li><a href="https://gcc.gnu.org/onlinedocs/gcc/Half-Precision.html">gcc half-precision documentation</a></li> -->
|
||||
@@ -20688,60 +20663,6 @@ See also:
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
<!--
|
||||
<div class="pagebreak"></div><div class="noprint"><hr class="greyline"><br></div>
|
||||
<a name="catching_exceptions"></a>
|
||||
<br>
|
||||
<b>how to catch std::runtime_error exceptions</b>
|
||||
<br>
|
||||
<br>
|
||||
<ul>
|
||||
<li>
|
||||
If a function such as <a href="#inv">inv()</a> fails to find a solution,
|
||||
an error message is printed and a <i>std::runtime_error</i> exception is thrown.
|
||||
If the exception is not caught, the program typically terminates.
|
||||
Below is an example of how to catch exceptions:
|
||||
<ul>
|
||||
<pre>
|
||||
#include <iostream>
|
||||
#include <armadillo>
|
||||
|
||||
using namespace std;
|
||||
using namespace arma;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
// create a non-invertible matrix
|
||||
mat A(5, 5, fill::zeros);
|
||||
|
||||
mat B;
|
||||
|
||||
try
|
||||
{
|
||||
B = inv(A);
|
||||
}
|
||||
catch (std::runtime_error& x)
|
||||
{
|
||||
cout << "caught an exception" << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
</ul>
|
||||
<li>
|
||||
See also:
|
||||
<ul>
|
||||
<li><a href="#logging">logging of warnings and errors</a></li>
|
||||
<li><a href="https://cplusplus.com/doc/tutorial/exceptions/">tutorial on exceptions</a></li>
|
||||
<li><a href="https://cplusplus.com/reference/stdexcept/runtime_error/">std::runtime_error</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
</ul>
|
||||
<br>
|
||||
-->
|
||||
|
||||
<div class="pagebreak"></div><div class="noprint"><hr class="greyline"><br></div>
|
||||
<a name="api_additions"></a>
|
||||
<a name="changelog"></a>
|
||||
@@ -20789,19 +20710,6 @@ and may be changed or removed without notice.
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<!--
|
||||
<br>
|
||||
<li>
|
||||
<a name="deprecated"></a>
|
||||
List of deprecated functionality; this functionality will be <b>removed</b> in version A.B:
|
||||
<ul>
|
||||
<li>
|
||||
...
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
-->
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<li>
|
||||
@@ -20818,6 +20726,7 @@ List of additions and changes for each version:
|
||||
<li>added <a href="#rande">rande()</a> for generating matrices with elements from exponential distributions</li>
|
||||
<li>shift() has been deprecated in favour of <a href="#circshift">circshift()</a>, for consistency with Matlab/Octave</li>
|
||||
<li>reworked detection of aliasing, leading to more efficient compiled code</li>
|
||||
<li>faster handling of submatrices with one row</li>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
@@ -21926,6 +21835,7 @@ use <i>my_function( mat(A+B) )</i>.
|
||||
<br>
|
||||
</ul>
|
||||
|
||||
|
||||
<!-- END CONTENT -->
|
||||
|
||||
|
||||
|
||||
@@ -244,9 +244,9 @@ BaseCube<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::res
|
||||
|
||||
typedef typename get_pod_type<elem_type>::result T;
|
||||
|
||||
arma_conform_check( (tol < T(0)), "is_zero(): parameter 'tol' must be >= 0" );
|
||||
arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" );
|
||||
|
||||
if(ProxyCube<derived>::use_at || is_Cube<typename ProxyCube<derived>::stored_type>::value)
|
||||
if(is_Cube<typename ProxyCube<derived>::stored_type>::value || ProxyCube<derived>::use_at)
|
||||
{
|
||||
const unwrap_cube<derived> U( (*this).get_ref() );
|
||||
|
||||
@@ -263,22 +263,52 @@ BaseCube<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::res
|
||||
|
||||
if(is_cx<elem_type>::yes)
|
||||
{
|
||||
for(uword i=0; i<n_elem; ++i)
|
||||
if(tol == T(0))
|
||||
{
|
||||
const elem_type val = Pea[i];
|
||||
|
||||
const T val_real = access::tmp_real(val);
|
||||
const T val_imag = access::tmp_imag(val);
|
||||
|
||||
if(eop_aux::arma_abs(val_real) > tol) { return false; }
|
||||
if(eop_aux::arma_abs(val_imag) > tol) { return false; }
|
||||
for(uword i=0; i < n_elem; ++i)
|
||||
{
|
||||
const elem_type val = Pea[i];
|
||||
|
||||
const T val_real = access::tmp_real(val);
|
||||
const T val_imag = access::tmp_imag(val);
|
||||
|
||||
if(eop_aux::arma_abs(val_real) != T(0)) { return false; }
|
||||
if(eop_aux::arma_abs(val_imag) != T(0)) { return false; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(uword i=0; i < n_elem; ++i)
|
||||
{
|
||||
const elem_type val = Pea[i];
|
||||
|
||||
const T val_real = access::tmp_real(val);
|
||||
const T val_imag = access::tmp_imag(val);
|
||||
|
||||
if( (eop_aux::arma_abs(val_real) <= tol) == false ) { return false; }
|
||||
if( (eop_aux::arma_abs(val_imag) <= tol) == false ) { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
else // not complex
|
||||
{
|
||||
for(uword i=0; i < n_elem; ++i)
|
||||
if(tol == T(0))
|
||||
{
|
||||
if(eop_aux::arma_abs(Pea[i]) > tol) { return false; }
|
||||
for(uword i=0; i < n_elem; ++i)
|
||||
{
|
||||
const elem_type val = Pea[i];
|
||||
|
||||
if(val != elem_type(0)) { return false; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(uword i=0; i < n_elem; ++i)
|
||||
{
|
||||
const elem_type val = Pea[i];
|
||||
|
||||
if( (eop_aux::arma_abs(val) <= tol) == false ) { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -352,7 +352,7 @@ Base<elem_type,derived>::is_symmetric(const typename get_pod_type<elem_type>::re
|
||||
|
||||
if(tol == T(0)) { return (*this).is_symmetric(); }
|
||||
|
||||
arma_conform_check( (tol < T(0)), "is_symmetric(): parameter 'tol' must be >= 0" );
|
||||
arma_conform_check( ((tol >= T(0)) == false), "is_symmetric(): parameter 'tol' must be > 0" );
|
||||
|
||||
const quasi_unwrap<derived> U( (*this).get_ref() );
|
||||
|
||||
@@ -365,8 +365,12 @@ Base<elem_type,derived>::is_symmetric(const typename get_pod_type<elem_type>::re
|
||||
|
||||
if(norm_A == T(0)) { return true; }
|
||||
|
||||
if(arma_isnan(norm_A)) { return false; }
|
||||
|
||||
const T norm_A_Ast = as_scalar( arma::max(sum(abs(A - A.st()), 1), 0) );
|
||||
|
||||
if(arma_isnan(norm_A_Ast)) { return false; }
|
||||
|
||||
return ( (norm_A_Ast / norm_A) <= tol );
|
||||
}
|
||||
|
||||
@@ -435,7 +439,7 @@ Base<elem_type,derived>::is_hermitian(const typename get_pod_type<elem_type>::re
|
||||
|
||||
if(tol == T(0)) { return (*this).is_hermitian(); }
|
||||
|
||||
arma_conform_check( (tol < T(0)), "is_hermitian(): parameter 'tol' must be >= 0" );
|
||||
arma_conform_check( ((tol >= T(0)) == false), "is_hermitian(): parameter 'tol' must be > 0" );
|
||||
|
||||
const quasi_unwrap<derived> U( (*this).get_ref() );
|
||||
|
||||
@@ -448,8 +452,12 @@ Base<elem_type,derived>::is_hermitian(const typename get_pod_type<elem_type>::re
|
||||
|
||||
if(norm_A == T(0)) { return true; }
|
||||
|
||||
if(arma_isnan(norm_A)) { return false; }
|
||||
|
||||
const T norm_A_At = as_scalar( arma::max(sum(abs(A - A.t()), 1), 0) );
|
||||
|
||||
if(arma_isnan(norm_A_At)) { return false; }
|
||||
|
||||
return ( (norm_A_At / norm_A) <= tol );
|
||||
}
|
||||
|
||||
@@ -464,9 +472,9 @@ Base<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::result
|
||||
|
||||
typedef typename get_pod_type<elem_type>::result T;
|
||||
|
||||
arma_conform_check( (tol < T(0)), "is_zero(): parameter 'tol' must be >= 0" );
|
||||
arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" );
|
||||
|
||||
if(Proxy<derived>::use_at || is_Mat<typename Proxy<derived>::stored_type>::value)
|
||||
if( (quasi_unwrap<derived>::has_orig_mem) || (is_Mat<typename Proxy<derived>::stored_type>::value) || (Proxy<derived>::use_at) )
|
||||
{
|
||||
const quasi_unwrap<derived> U( (*this).get_ref() );
|
||||
|
||||
@@ -483,22 +491,52 @@ Base<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::result
|
||||
|
||||
if(is_cx<elem_type>::yes)
|
||||
{
|
||||
for(uword i=0; i<n_elem; ++i)
|
||||
if(tol == T(0))
|
||||
{
|
||||
const elem_type val = Pea[i];
|
||||
|
||||
const T val_real = access::tmp_real(val);
|
||||
const T val_imag = access::tmp_imag(val);
|
||||
|
||||
if(eop_aux::arma_abs(val_real) > tol) { return false; }
|
||||
if(eop_aux::arma_abs(val_imag) > tol) { return false; }
|
||||
for(uword i=0; i < n_elem; ++i)
|
||||
{
|
||||
const elem_type val = Pea[i];
|
||||
|
||||
const T val_real = access::tmp_real(val);
|
||||
const T val_imag = access::tmp_imag(val);
|
||||
|
||||
if(eop_aux::arma_abs(val_real) != T(0)) { return false; }
|
||||
if(eop_aux::arma_abs(val_imag) != T(0)) { return false; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(uword i=0; i < n_elem; ++i)
|
||||
{
|
||||
const elem_type val = Pea[i];
|
||||
|
||||
const T val_real = access::tmp_real(val);
|
||||
const T val_imag = access::tmp_imag(val);
|
||||
|
||||
if( (eop_aux::arma_abs(val_real) <= tol) == false ) { return false; }
|
||||
if( (eop_aux::arma_abs(val_imag) <= tol) == false ) { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
else // not complex
|
||||
{
|
||||
for(uword i=0; i<n_elem; ++i)
|
||||
if(tol == T(0))
|
||||
{
|
||||
if(eop_aux::arma_abs(Pea[i]) > tol) { return false; }
|
||||
for(uword i=0; i < n_elem; ++i)
|
||||
{
|
||||
const elem_type val = Pea[i];
|
||||
|
||||
if(val != elem_type(0)) { return false; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(uword i=0; i < n_elem; ++i)
|
||||
{
|
||||
const elem_type val = Pea[i];
|
||||
|
||||
if( (eop_aux::arma_abs(val) <= tol) == false ) { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -897,6 +935,8 @@ Base_extra_yes<elem_type,derived>::is_sympd() const
|
||||
// default value for tol
|
||||
const T tol = T(100) * std::numeric_limits<T>::epsilon() * norm(X, "fro");
|
||||
|
||||
if(arma_isnan(tol)) { return false; }
|
||||
|
||||
if(X.is_hermitian(tol) == false) { return false; }
|
||||
|
||||
if(X.is_empty()) { return false; }
|
||||
@@ -917,7 +957,7 @@ Base_extra_yes<elem_type,derived>::is_sympd(typename get_pod_type<elem_type>::re
|
||||
|
||||
typedef typename get_pod_type<elem_type>::result T;
|
||||
|
||||
arma_conform_check( (tol < T(0)), "is_sympd(): parameter 'tol' must be >= 0" );
|
||||
arma_conform_check( ((tol >= T(0)) == false), "is_sympd(): parameter 'tol' must be >= 0" );
|
||||
|
||||
Mat<elem_type> X = static_cast<const derived&>(*this);
|
||||
|
||||
|
||||
@@ -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>() ); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -4197,12 +4187,12 @@ Cube<eT>::clamp(const eT min_val, const eT max_val)
|
||||
|
||||
if(is_cx<eT>::no)
|
||||
{
|
||||
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Cube::clamp(): min_val must be less than max_val" );
|
||||
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "Cube::clamp(): min_val must be less than max_val" );
|
||||
}
|
||||
else
|
||||
{
|
||||
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Cube::clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "Cube::clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "Cube::clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "Cube::clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
}
|
||||
|
||||
arrayops::clamp(memptr(), n_elem, min_val, max_val);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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,11 +2540,11 @@ 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);
|
||||
|
||||
(*this).operator=(X);
|
||||
subview_elem1<eT,T1>::extract_noalias(*this, X);
|
||||
}
|
||||
|
||||
|
||||
@@ -2571,11 +2559,11 @@ 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);
|
||||
|
||||
(*this).operator=(X);
|
||||
subview_elem1<eT,T1>::extract_noalias(*this, X);
|
||||
}
|
||||
|
||||
|
||||
@@ -2680,11 +2668,11 @@ 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);
|
||||
|
||||
(*this).operator=(X);
|
||||
subview_elem2<eT,T1,T2>::extract_noalias(*this, X);
|
||||
}
|
||||
|
||||
|
||||
@@ -2699,11 +2687,11 @@ 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);
|
||||
|
||||
(*this).operator=(X);
|
||||
subview_elem2<eT,T1,T2>::extract_noalias(*this, X);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -7863,12 +7885,12 @@ Mat<eT>::clamp(const eT min_val, const eT max_val)
|
||||
|
||||
if(is_cx<eT>::no)
|
||||
{
|
||||
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Mat::clamp(): min_val must be less than max_val" );
|
||||
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "Mat::clamp(): min_val must be less than max_val" );
|
||||
}
|
||||
else
|
||||
{
|
||||
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Mat::clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "Mat::clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "Mat::clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "Mat::clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
}
|
||||
|
||||
arrayops::clamp(memptr(), n_elem, min_val, max_val);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1537,7 +1537,7 @@ struct Proxy_xtrans_default< Op<T1, op_htrans> >
|
||||
arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return void_ptr(&(U.M)) == void_ptr(&X); }
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return U.is_alias(X); }
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool has_overlap(const subview<eT2>& X) const { return is_alias(X.m); }
|
||||
@@ -1578,7 +1578,7 @@ struct Proxy_xtrans_default< Op<T1, op_strans> >
|
||||
arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return void_ptr(&(U.M)) == void_ptr(&X); }
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return U.is_alias(X); }
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool has_overlap(const subview<eT2>& X) const { return is_alias(X.m); }
|
||||
@@ -2441,7 +2441,7 @@ struct Proxy_vectorise_col_mat< Op<T1, op_vectorise_col> >
|
||||
arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return ( void_ptr(&X) == void_ptr(&(U.M)) ); }
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return U.is_alias(X); }
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool has_overlap(const subview<eT2>& X) const { return is_alias(X.m); }
|
||||
|
||||
@@ -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>() ); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -527,7 +527,7 @@ SpBase<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::resul
|
||||
|
||||
typedef typename get_pod_type<elem_type>::result T;
|
||||
|
||||
arma_conform_check( (tol < T(0)), "is_zero(): parameter 'tol' must be >= 0" );
|
||||
arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" );
|
||||
|
||||
const SpProxy<derived> P( (*this).get_ref() );
|
||||
|
||||
@@ -554,8 +554,8 @@ SpBase<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::resul
|
||||
const T val_real = access::tmp_real(val);
|
||||
const T val_imag = access::tmp_imag(val);
|
||||
|
||||
if(eop_aux::arma_abs(val_real) > tol) { return false; }
|
||||
if(eop_aux::arma_abs(val_imag) > tol) { return false; }
|
||||
if( (eop_aux::arma_abs(val_real) <= tol) == false ) { return false; }
|
||||
if( (eop_aux::arma_abs(val_imag) <= tol) == false ) { return false; }
|
||||
|
||||
++it;
|
||||
}
|
||||
@@ -564,7 +564,7 @@ SpBase<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::resul
|
||||
{
|
||||
while(it != it_end)
|
||||
{
|
||||
if(eop_aux::arma_abs(*it) > tol) { return false; }
|
||||
if( (eop_aux::arma_abs(*it) <= tol) == false ) { return false; }
|
||||
|
||||
++it;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -3517,7 +3565,7 @@ SpMat<eT>::is_symmetric(const typename get_pod_type<elem_type>::result tol) cons
|
||||
|
||||
if(tol == T(0)) { return (*this).is_symmetric(); }
|
||||
|
||||
arma_conform_check( (tol < T(0)), "is_symmetric(): parameter 'tol' must be >= 0" );
|
||||
arma_conform_check( ((tol >= T(0)) == false), "is_symmetric(): parameter 'tol' must be > 0" );
|
||||
|
||||
const SpMat<eT>& A = (*this);
|
||||
|
||||
@@ -3527,8 +3575,12 @@ SpMat<eT>::is_symmetric(const typename get_pod_type<elem_type>::result tol) cons
|
||||
|
||||
if(norm_A == T(0)) { return true; }
|
||||
|
||||
if(arma_isnan(norm_A)) { return false; }
|
||||
|
||||
const T norm_A_Ast = as_scalar( arma::max(sum(abs(A - A.st()), 1), 0) );
|
||||
|
||||
if(arma_isnan(norm_A_Ast)) { return false; }
|
||||
|
||||
return ( (norm_A_Ast / norm_A) <= tol );
|
||||
}
|
||||
|
||||
@@ -3563,7 +3615,7 @@ SpMat<eT>::is_hermitian(const typename get_pod_type<elem_type>::result tol) cons
|
||||
|
||||
if(tol == T(0)) { return (*this).is_hermitian(); }
|
||||
|
||||
arma_conform_check( (tol < T(0)), "is_hermitian(): parameter 'tol' must be >= 0" );
|
||||
arma_conform_check( ((tol >= T(0)) == false), "is_hermitian(): parameter 'tol' must be > 0" );
|
||||
|
||||
const SpMat<eT>& A = (*this);
|
||||
|
||||
@@ -3573,8 +3625,12 @@ SpMat<eT>::is_hermitian(const typename get_pod_type<elem_type>::result tol) cons
|
||||
|
||||
if(norm_A == T(0)) { return true; }
|
||||
|
||||
if(arma_isnan(norm_A)) { return false; }
|
||||
|
||||
const T norm_A_At = as_scalar( arma::max(sum(abs(A - A.t()), 1), 0) );
|
||||
|
||||
if(arma_isnan(norm_A_At)) { return false; }
|
||||
|
||||
return ( (norm_A_At / norm_A) <= tol );
|
||||
}
|
||||
|
||||
@@ -4156,12 +4212,12 @@ SpMat<eT>::clamp(const eT min_val, const eT max_val)
|
||||
|
||||
if(is_cx<eT>::no)
|
||||
{
|
||||
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpMat::clamp(): min_val must be less than max_val" );
|
||||
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "SpMat::clamp(): min_val must be less than max_val" );
|
||||
}
|
||||
else
|
||||
{
|
||||
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpMat::clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "SpMat::clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "SpMat::clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "SpMat::clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
}
|
||||
|
||||
if(n_nonzero == 0) { return *this; }
|
||||
@@ -4341,7 +4397,7 @@ SpMat<eT>::sprandu(const uword in_rows, const uword in_cols, const double densit
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
arma_conform_check( ( (density < double(0)) || (density > double(1)) ), "sprandu(): density must be in the [0,1] interval" );
|
||||
arma_conform_check( ( ((density >= double(0)) == false) || ((density <= double(1)) == false) ), "sprandu(): density must be in the [0,1] interval" );
|
||||
|
||||
const uword new_n_nonzero = uword(density * double(in_rows) * double(in_cols) + 0.5);
|
||||
|
||||
@@ -4418,7 +4474,7 @@ SpMat<eT>::sprandn(const uword in_rows, const uword in_cols, const double densit
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
arma_conform_check( ( (density < double(0)) || (density > double(1)) ), "sprandn(): density must be in the [0,1] interval" );
|
||||
arma_conform_check( ( ((density >= double(0)) == false) || ((density <= double(1)) == false) ), "sprandn(): density must be in the [0,1] interval" );
|
||||
|
||||
const uword new_n_nonzero = uword(density * double(in_rows) * double(in_cols) + 0.5);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -905,12 +946,12 @@ SpSubview<eT>::clamp(const eT min_val, const eT max_val)
|
||||
|
||||
if(is_cx<eT>::no)
|
||||
{
|
||||
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpSubview::clamp(): min_val must be less than max_val" );
|
||||
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "SpSubview::clamp(): min_val must be less than max_val" );
|
||||
}
|
||||
else
|
||||
{
|
||||
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpSubview::clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "SpSubview::clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "SpSubview::clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "SpSubview::clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
}
|
||||
|
||||
if((n_elem == 0) || (n_nonzero == 0)) { return; }
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
#undef ARMA_USE_THREAD_LOCAL
|
||||
#define ARMA_USE_THREAD_LOCAL
|
||||
|
||||
#undef ARMA_USE_THREAD_UNIQUE_RNG_SEED
|
||||
#define ARMA_USE_THREAD_UNIQUE_RNG_SEED
|
||||
|
||||
#if (defined(ARMA_RNG_ALT) || defined(ARMA_DONT_USE_CXX11_RNG))
|
||||
#undef ARMA_USE_CXX11_RNG
|
||||
#endif
|
||||
@@ -34,6 +37,10 @@
|
||||
#undef ARMA_USE_THREAD_LOCAL
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_USE_THREAD_UNIQUE_RNG_SEED)
|
||||
#undef ARMA_USE_THREAD_UNIQUE_RNG_SEED
|
||||
#endif
|
||||
|
||||
|
||||
// NOTE: ARMA_WARMUP_PRODUCER enables a workaround
|
||||
// NOTE: for thread_local issue on macOS 11 and/or AppleClang 12.0
|
||||
@@ -129,24 +136,42 @@ arma_rng::get_producer()
|
||||
{
|
||||
#if defined(ARMA_USE_THREAD_LOCAL)
|
||||
|
||||
// use a thread-safe RNG, with each thread having its own unique starting seed
|
||||
// thread-safe RNG
|
||||
|
||||
static std::atomic<std::size_t> mt19937_64_producer_counter(0);
|
||||
|
||||
static thread_local std::mt19937_64 mt19937_64_producer( std::mt19937_64::default_seed + mt19937_64_producer_counter++ );
|
||||
|
||||
arma_rng::warmup_producer(mt19937_64_producer);
|
||||
#if defined(ARMA_USE_THREAD_UNIQUE_RNG_SEED)
|
||||
|
||||
// each thread has unique starting seed
|
||||
|
||||
#if defined(ARMA_USE_OPENMP)
|
||||
|
||||
static thread_local std::mt19937_64 mt19937_64_producer( std::mt19937_64::default_seed + arma_rng::seed_type(omp_get_thread_num()) );
|
||||
|
||||
#else
|
||||
|
||||
static std::atomic<std::size_t> mt19937_64_producer_counter(0);
|
||||
|
||||
static thread_local std::mt19937_64 mt19937_64_producer( std::mt19937_64::default_seed + mt19937_64_producer_counter++ );
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// each thread has the same starting seed
|
||||
|
||||
static thread_local std::mt19937_64 mt19937_64_producer( std::mt19937_64::default_seed );
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// use a plain RNG in case we don't have thread_local
|
||||
// plain RNG in case we don't have thread_local
|
||||
|
||||
static std::mt19937_64 mt19937_64_producer( std::mt19937_64::default_seed );
|
||||
|
||||
arma_rng::warmup_producer(mt19937_64_producer);
|
||||
|
||||
#endif
|
||||
|
||||
arma_rng::warmup_producer(mt19937_64_producer);
|
||||
|
||||
return mt19937_64_producer;
|
||||
}
|
||||
|
||||
@@ -226,9 +251,45 @@ arma_rng::set_seed(const arma_rng::seed_type val)
|
||||
}
|
||||
#elif defined(ARMA_USE_CXX11_RNG)
|
||||
{
|
||||
arma_rng::lock_producer();
|
||||
arma_rng::get_producer().seed(val);
|
||||
arma_rng::unlock_producer();
|
||||
#if defined(ARMA_USE_OPENMP) && defined(ARMA_USE_THREAD_LOCAL)
|
||||
{
|
||||
arma_rng::lock_producer();
|
||||
|
||||
#if defined(ARMA_USE_THREAD_UNIQUE_RNG_SEED)
|
||||
constexpr bool thread_unique_rng_seed = true;
|
||||
#else
|
||||
constexpr bool thread_unique_rng_seed = false;
|
||||
#endif
|
||||
|
||||
// if we're already in a parallel region, assume the user is setting the seed for each thread
|
||||
|
||||
if( (thread_unique_rng_seed == false) || bool(omp_in_parallel()) )
|
||||
{
|
||||
arma_rng::get_producer().seed(val);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int n_threads = int( (std::max)( int(1), int(omp_get_max_threads()) ) );
|
||||
|
||||
#pragma omp parallel for ordered schedule(static) num_threads(n_threads)
|
||||
for(int t=0; t < n_threads; ++t)
|
||||
{
|
||||
#pragma omp ordered
|
||||
{
|
||||
arma_rng::get_producer().seed(val + arma_rng::seed_type(omp_get_thread_num()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
arma_rng::unlock_producer();
|
||||
}
|
||||
#else
|
||||
{
|
||||
arma_rng::lock_producer();
|
||||
arma_rng::get_producer().seed(val);
|
||||
arma_rng::unlock_producer();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#define ARMA_VERSION_MAJOR 15
|
||||
#define ARMA_VERSION_MINOR 2
|
||||
#define ARMA_VERSION_PATCH 1
|
||||
#define ARMA_VERSION_PATCH 7
|
||||
#define ARMA_VERSION_NAME "Medium Roast Deluxe"
|
||||
|
||||
|
||||
|
||||
@@ -994,7 +994,7 @@ arrayops::is_zero(const eT* mem, const uword n_elem, const eT abs_limit, const t
|
||||
{
|
||||
for(uword i=0; i<n_elem; ++i)
|
||||
{
|
||||
if(eop_aux::arma_abs(mem[i]) > abs_limit) { return false; }
|
||||
if( (eop_aux::arma_abs(mem[i]) <= abs_limit) == false ) { return false; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1028,8 +1028,8 @@ arrayops::is_zero(const std::complex<T>* mem, const uword n_elem, const T abs_li
|
||||
{
|
||||
const eT& val = mem[i];
|
||||
|
||||
if(std::abs(std::real(val)) > abs_limit) { return false; }
|
||||
if(std::abs(std::imag(val)) > abs_limit) { return false; }
|
||||
if( (std::abs(std::real(val)) <= abs_limit) == false ) { return false; }
|
||||
if( (std::abs(std::imag(val)) <= abs_limit) == false ) { return false; }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -134,15 +134,25 @@ diagview<eT>::operator+=(const eT val)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
Mat<eT>& t_m = const_cast< Mat<eT>& >(m);
|
||||
diagview<eT>& d = *this;
|
||||
|
||||
const uword t_n_elem = n_elem;
|
||||
const uword t_row_offset = row_offset;
|
||||
const uword t_col_offset = col_offset;
|
||||
Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m);
|
||||
|
||||
for(uword ii=0; ii < t_n_elem; ++ii)
|
||||
const uword d_n_elem = d.n_elem;
|
||||
const uword d_row_offset = d.row_offset;
|
||||
const uword d_col_offset = d.col_offset;
|
||||
|
||||
uword ii,jj;
|
||||
|
||||
for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
|
||||
{
|
||||
t_m.at( ii + t_row_offset, ii + t_col_offset) += val;
|
||||
d_m.at( ii + d_row_offset, ii + d_col_offset) += val;
|
||||
d_m.at( jj + d_row_offset, jj + d_col_offset) += val;
|
||||
}
|
||||
|
||||
if(ii < d_n_elem)
|
||||
{
|
||||
d_m.at( ii + d_row_offset, ii + d_col_offset) += val;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,15 +165,25 @@ diagview<eT>::operator-=(const eT val)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
Mat<eT>& t_m = const_cast< Mat<eT>& >(m);
|
||||
diagview<eT>& d = *this;
|
||||
|
||||
const uword t_n_elem = n_elem;
|
||||
const uword t_row_offset = row_offset;
|
||||
const uword t_col_offset = col_offset;
|
||||
Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m);
|
||||
|
||||
for(uword ii=0; ii < t_n_elem; ++ii)
|
||||
const uword d_n_elem = d.n_elem;
|
||||
const uword d_row_offset = d.row_offset;
|
||||
const uword d_col_offset = d.col_offset;
|
||||
|
||||
uword ii,jj;
|
||||
|
||||
for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
|
||||
{
|
||||
t_m.at( ii + t_row_offset, ii + t_col_offset) -= val;
|
||||
d_m.at( ii + d_row_offset, ii + d_col_offset) -= val;
|
||||
d_m.at( jj + d_row_offset, jj + d_col_offset) -= val;
|
||||
}
|
||||
|
||||
if(ii < d_n_elem)
|
||||
{
|
||||
d_m.at( ii + d_row_offset, ii + d_col_offset) -= val;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,15 +196,25 @@ diagview<eT>::operator*=(const eT val)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
Mat<eT>& t_m = const_cast< Mat<eT>& >(m);
|
||||
diagview<eT>& d = *this;
|
||||
|
||||
const uword t_n_elem = n_elem;
|
||||
const uword t_row_offset = row_offset;
|
||||
const uword t_col_offset = col_offset;
|
||||
Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m);
|
||||
|
||||
for(uword ii=0; ii < t_n_elem; ++ii)
|
||||
const uword d_n_elem = d.n_elem;
|
||||
const uword d_row_offset = d.row_offset;
|
||||
const uword d_col_offset = d.col_offset;
|
||||
|
||||
uword ii,jj;
|
||||
|
||||
for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
|
||||
{
|
||||
t_m.at( ii + t_row_offset, ii + t_col_offset) *= val;
|
||||
d_m.at( ii + d_row_offset, ii + d_col_offset) *= val;
|
||||
d_m.at( jj + d_row_offset, jj + d_col_offset) *= val;
|
||||
}
|
||||
|
||||
if(ii < d_n_elem)
|
||||
{
|
||||
d_m.at( ii + d_row_offset, ii + d_col_offset) *= val;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,15 +227,25 @@ diagview<eT>::operator/=(const eT val)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
Mat<eT>& t_m = const_cast< Mat<eT>& >(m);
|
||||
diagview<eT>& d = *this;
|
||||
|
||||
const uword t_n_elem = n_elem;
|
||||
const uword t_row_offset = row_offset;
|
||||
const uword t_col_offset = col_offset;
|
||||
Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m);
|
||||
|
||||
for(uword ii=0; ii < t_n_elem; ++ii)
|
||||
const uword d_n_elem = d.n_elem;
|
||||
const uword d_row_offset = d.row_offset;
|
||||
const uword d_col_offset = d.col_offset;
|
||||
|
||||
uword ii,jj;
|
||||
|
||||
for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
|
||||
{
|
||||
t_m.at( ii + t_row_offset, ii + t_col_offset) /= val;
|
||||
d_m.at( ii + d_row_offset, ii + d_col_offset) /= val;
|
||||
d_m.at( jj + d_row_offset, jj + d_col_offset) /= val;
|
||||
}
|
||||
|
||||
if(ii < d_n_elem)
|
||||
{
|
||||
d_m.at( ii + d_row_offset, ii + d_col_offset) /= val;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,6 +276,12 @@ diagview<eT>::operator= (const Base<eT,T1>& o)
|
||||
"diagview: given object has incompatible size"
|
||||
);
|
||||
|
||||
constexpr bool is_gen_zeros = (is_same_type< T1, Gen<Mat<eT>, gen_zeros> >::yes) || (is_same_type< T1, Gen<Col<eT>, gen_zeros> >::yes);
|
||||
constexpr bool is_gen_ones = (is_same_type< T1, Gen<Mat<eT>, gen_ones > >::yes) || (is_same_type< T1, Gen<Col<eT>, gen_ones > >::yes);
|
||||
|
||||
if(is_gen_zeros) { d.zeros(); return; }
|
||||
if(is_gen_ones ) { d.ones(); return; }
|
||||
|
||||
const bool have_alias = P.is_alias(d_m);
|
||||
|
||||
if(have_alias) { arma_debug_print("aliasing detected"); }
|
||||
@@ -948,13 +994,25 @@ diagview<eT>::fill(const eT val)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
Mat<eT>& x = const_cast< Mat<eT>& >(m);
|
||||
diagview<eT>& d = *this;
|
||||
|
||||
const uword local_n_elem = n_elem;
|
||||
Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m);
|
||||
|
||||
for(uword ii=0; ii < local_n_elem; ++ii)
|
||||
const uword d_n_elem = d.n_elem;
|
||||
const uword d_row_offset = d.row_offset;
|
||||
const uword d_col_offset = d.col_offset;
|
||||
|
||||
uword ii,jj;
|
||||
|
||||
for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
|
||||
{
|
||||
x.at(ii+row_offset, ii+col_offset) = val;
|
||||
d_m.at( ii + d_row_offset, ii + d_col_offset) = val;
|
||||
d_m.at( jj + d_row_offset, jj + d_col_offset) = val;
|
||||
}
|
||||
|
||||
if(ii < d_n_elem)
|
||||
{
|
||||
d_m.at( ii + d_row_offset, ii + d_col_offset) = val;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -373,29 +373,37 @@ inline
|
||||
std::string
|
||||
diskio::gen_tmp_name(const std::string& x)
|
||||
{
|
||||
union { uword val; void* ptr; } u;
|
||||
arma_debug_sigprint();
|
||||
|
||||
u.val = uword(0);
|
||||
u.ptr = const_cast<std::string*>(&x);
|
||||
const char* charlist = "0123456789abcdefghijklmnopqrstuvwxyz";
|
||||
const char* suffix1 = ".!";
|
||||
|
||||
const u16 a = u16( (u.val >> 8) & 0xFFFF );
|
||||
const u16 b = u16( (std::clock()) & 0xFFFF );
|
||||
constexpr std::size_t charlist_length = 36;
|
||||
constexpr std::size_t suffix1_length = 2;
|
||||
constexpr std::size_t suffix2_length = 6;
|
||||
|
||||
std::ostringstream ss;
|
||||
typedef typename std::minstd_rand::result_type local_seed_type;
|
||||
|
||||
ss << x << ".tmp_";
|
||||
std::minstd_rand local_engine;
|
||||
std::uniform_int_distribution<std::size_t> local_distr(0, charlist_length - 1);
|
||||
|
||||
ss.setf(std::ios_base::hex, std::ios_base::basefield);
|
||||
local_engine.seed( static_cast<local_seed_type>( (std::clock()) & 0xFFFF ) );
|
||||
|
||||
ss.width(4);
|
||||
ss.fill('0');
|
||||
ss << a;
|
||||
const std::size_t x_length = x.length();
|
||||
|
||||
ss.width(4);
|
||||
ss.fill('0');
|
||||
ss << b;
|
||||
std::string out(x_length + suffix1_length + suffix2_length, '0'); // create string filled with char '0' (not 0)
|
||||
|
||||
return ss.str();
|
||||
std::size_t count = 0;
|
||||
|
||||
for(; count < x_length; ++count) { out[count] = x[count]; }
|
||||
|
||||
for(std::size_t i=0; i < suffix1_length; ++i, ++count) { out[count] = suffix1[i]; }
|
||||
|
||||
local_distr(local_engine); // ignore first random number
|
||||
|
||||
for(std::size_t i=0; i < suffix2_length; ++i, ++count) { out[count] = charlist[ local_distr(local_engine)]; }
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -94,7 +94,9 @@ field<oT>::field(const subview_field<oT>& X)
|
||||
{
|
||||
arma_debug_sigprint_this(this);
|
||||
|
||||
(*this).operator=(X);
|
||||
init(X.n_rows, X.n_cols, X.n_slices);
|
||||
|
||||
subview_field<oT>::extract(*this, X);
|
||||
}
|
||||
|
||||
|
||||
@@ -107,7 +109,20 @@ field<oT>::operator=(const subview_field<oT>& X)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
subview_field<oT>::extract(*this, X);
|
||||
const bool alias = (this == &(X.f));
|
||||
|
||||
if(alias == false)
|
||||
{
|
||||
(*this).init(X.n_rows, X.n_cols, X.n_slices);
|
||||
|
||||
subview_field<oT>::extract(*this, X);
|
||||
}
|
||||
else
|
||||
{
|
||||
field<oT> tmp(X);
|
||||
|
||||
(*this).operator=(std::move(tmp));
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
//
|
||||
|
||||
|
||||
@@ -110,8 +110,8 @@ internal_approx_equal_worker
|
||||
|
||||
arma_conform_check( ((use_abs_diff == false) && (use_rel_diff == false)), "internal_approx_equal_worker(): both 'use_abs_diff' and 'use_rel_diff' are false" );
|
||||
|
||||
if(use_abs_diff) { arma_conform_check( cond_rel< is_signed<T>::value >::lt(abs_tol, T(0)), "approx_equal(): argument 'abs_tol' must be >= 0" ); }
|
||||
if(use_rel_diff) { arma_conform_check( cond_rel< is_signed<T>::value >::lt(rel_tol, T(0)), "approx_equal(): argument 'rel_tol' must be >= 0" ); }
|
||||
if(use_abs_diff) { arma_conform_check( (cond_rel< is_signed<T>::value >::lt(abs_tol, T(0)) || arma_isnan(abs_tol)), "approx_equal(): argument 'abs_tol' must be >= 0" ); }
|
||||
if(use_rel_diff) { arma_conform_check( (cond_rel< is_signed<T>::value >::lt(rel_tol, T(0)) || arma_isnan(rel_tol)), "approx_equal(): argument 'rel_tol' must be >= 0" ); }
|
||||
|
||||
const Proxy<T1> PA(A.get_ref());
|
||||
const Proxy<T2> PB(B.get_ref());
|
||||
@@ -203,8 +203,8 @@ internal_approx_equal_worker
|
||||
|
||||
arma_conform_check( ((use_abs_diff == false) && (use_rel_diff == false)), "internal_approx_equal_worker(): both 'use_abs_diff' and 'use_rel_diff' are false" );
|
||||
|
||||
if(use_abs_diff) { arma_conform_check( cond_rel< is_signed<T>::value >::lt(abs_tol, T(0)), "approx_equal(): argument 'abs_tol' must be >= 0" ); }
|
||||
if(use_rel_diff) { arma_conform_check( cond_rel< is_signed<T>::value >::lt(rel_tol, T(0)), "approx_equal(): argument 'rel_tol' must be >= 0" ); }
|
||||
if(use_abs_diff) { arma_conform_check( (cond_rel< is_signed<T>::value >::lt(abs_tol, T(0)) || arma_isnan(abs_tol)), "approx_equal(): argument 'abs_tol' must be >= 0" ); }
|
||||
if(use_rel_diff) { arma_conform_check( (cond_rel< is_signed<T>::value >::lt(rel_tol, T(0)) || arma_isnan(rel_tol)), "approx_equal(): argument 'rel_tol' must be >= 0" ); }
|
||||
|
||||
const ProxyCube<T1> PA(A.get_ref());
|
||||
const ProxyCube<T2> PB(B.get_ref());
|
||||
@@ -418,7 +418,7 @@ approx_equal(const SpBase<typename T1::elem_type,T1>& A, const SpBase<typename T
|
||||
|
||||
arma_conform_check( (sig == 'r'), "approx_equal(): only the \"absdiff\" method is currently implemented for sparse matrices" );
|
||||
|
||||
arma_conform_check( cond_rel< is_signed<T>::value >::lt(tol, T(0)), "approx_equal(): argument 'tol' must be >= 0" );
|
||||
arma_conform_check( (cond_rel< is_signed<T>::value >::lt(tol, T(0)) || arma_isnan(tol)), "approx_equal(): argument 'tol' must be >= 0" );
|
||||
|
||||
const unwrap_spmat<T1> UA(A.get_ref());
|
||||
const unwrap_spmat<T2> UB(B.get_ref());
|
||||
@@ -460,8 +460,8 @@ approx_equal(const SpBase<typename T1::elem_type,T1>& A, const SpBase<typename T
|
||||
|
||||
arma_conform_check( ((sig == 'r') || (sig == 'b')), "approx_equal(): only the \"absdiff\" method is currently implemented for sparse matrices" );
|
||||
|
||||
arma_conform_check( cond_rel< is_signed<T>::value >::lt(abs_tol, T(0)), "approx_equal(): argument 'abs_tol' must be >= 0" );
|
||||
arma_conform_check( cond_rel< is_signed<T>::value >::lt(rel_tol, T(0)), "approx_equal(): argument 'rel_tol' must be >= 0" );
|
||||
arma_conform_check( (cond_rel< is_signed<T>::value >::lt(abs_tol, T(0)) || arma_isnan(abs_tol)), "approx_equal(): argument 'abs_tol' must be >= 0" );
|
||||
arma_conform_check( (cond_rel< is_signed<T>::value >::lt(rel_tol, T(0)) || arma_isnan(rel_tol)), "approx_equal(): argument 'rel_tol' must be >= 0" );
|
||||
|
||||
return approx_equal(A.get_ref(), B.get_ref(), "abs", abs_tol);
|
||||
}
|
||||
|
||||
@@ -97,12 +97,12 @@ clamp(const SpBase<typename T1::elem_type,T1>& X, const typename T1::elem_type m
|
||||
|
||||
if(is_cx<eT>::no)
|
||||
{
|
||||
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "clamp(): min_val must be less than max_val" );
|
||||
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "clamp(): min_val must be less than max_val" );
|
||||
}
|
||||
else
|
||||
{
|
||||
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
}
|
||||
|
||||
SpMat<eT> out = X.get_ref();
|
||||
|
||||
@@ -47,7 +47,7 @@ rande(const uword n_rows, const uword n_cols, const distr_param& param = distr_p
|
||||
|
||||
param.get_double_vals(lambda, unused);
|
||||
|
||||
arma_conform_check( (lambda <= double(0)), "rande(): incorrect distribution parameters; lambda must be greater than zero" );
|
||||
arma_conform_check( ((lambda > double(0)) == false), "rande(): incorrect distribution parameters; lambda must be greater than zero" );
|
||||
|
||||
obj_type out(n_rows, n_cols, arma_nozeros_indicator());
|
||||
|
||||
@@ -138,7 +138,7 @@ rande(const distr_param& param = distr_param())
|
||||
|
||||
param.get_double_vals(lambda, unused);
|
||||
|
||||
arma_conform_check( (lambda <= double(0)), "rande(): incorrect distribution parameters; lambda must be greater than zero" );
|
||||
arma_conform_check( ((lambda > double(0)) == false), "rande(): incorrect distribution parameters; lambda must be greater than zero" );
|
||||
|
||||
double out_val = double(0);
|
||||
|
||||
@@ -162,7 +162,7 @@ rande(const distr_param& param = distr_param())
|
||||
|
||||
param.get_double_vals(lambda, unused);
|
||||
|
||||
arma_conform_check( (lambda <= double(0)), "rande(): incorrect distribution parameters; lambda must be greater than zero" );
|
||||
arma_conform_check( ((lambda > double(0)) == false), "rande(): incorrect distribution parameters; lambda must be greater than zero" );
|
||||
|
||||
eT out_val = eT(0);
|
||||
|
||||
@@ -189,7 +189,7 @@ rande(const uword n_rows, const uword n_cols, const uword n_slices, const distr_
|
||||
|
||||
param.get_double_vals(lambda, unused);
|
||||
|
||||
arma_conform_check( (lambda <= double(0)), "rande(): incorrect distribution parameters; lambda must be greater than zero" );
|
||||
arma_conform_check( ((lambda > double(0)) == false), "rande(): incorrect distribution parameters; lambda must be greater than zero" );
|
||||
|
||||
cube_type out(n_rows, n_cols, n_slices, arma_nozeros_indicator());
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ randg(const uword n_rows, const uword n_cols, const distr_param& param = distr_p
|
||||
|
||||
param.get_double_vals(a,b);
|
||||
|
||||
arma_conform_check( ((a <= double(0)) || (b <= double(0))), "randg(): incorrect distribution parameters; a and b must be greater than zero" );
|
||||
arma_conform_check( ( ((a > double(0)) == false) || ((b > double(0)) == false) ), "randg(): incorrect distribution parameters; a and b must be greater than zero" );
|
||||
|
||||
obj_type out(n_rows, n_cols, arma_nozeros_indicator());
|
||||
|
||||
@@ -138,7 +138,7 @@ randg(const distr_param& param = distr_param())
|
||||
|
||||
param.get_double_vals(a,b);
|
||||
|
||||
arma_conform_check( ((a <= double(0)) || (b <= double(0))), "randg(): incorrect distribution parameters; a and b must be greater than zero" );
|
||||
arma_conform_check( ( ((a > double(0)) == false) || ((b > double(0)) == false) ), "randg(): incorrect distribution parameters; a and b must be greater than zero" );
|
||||
|
||||
double out_val = double(0);
|
||||
|
||||
@@ -162,7 +162,7 @@ randg(const distr_param& param = distr_param())
|
||||
|
||||
param.get_double_vals(a,b);
|
||||
|
||||
arma_conform_check( ((a <= double(0)) || (b <= double(0))), "randg(): incorrect distribution parameters; a and b must be greater than zero" );
|
||||
arma_conform_check( ( ((a > double(0)) == false) || ((b > double(0)) == false) ), "randg(): incorrect distribution parameters; a and b must be greater than zero" );
|
||||
|
||||
eT out_val = eT(0);
|
||||
|
||||
@@ -189,7 +189,7 @@ randg(const uword n_rows, const uword n_cols, const uword n_slices, const distr_
|
||||
|
||||
param.get_double_vals(a,b);
|
||||
|
||||
arma_conform_check( ((a <= double(0)) || (b <= double(0))), "randg(): incorrect distribution parameters; a and b must be greater than zero" );
|
||||
arma_conform_check( ( ((a > double(0)) == false) || ((b > double(0)) == false) ), "randg(): incorrect distribution parameters; a and b must be greater than zero" );
|
||||
|
||||
cube_type out(n_rows, n_cols, n_slices, arma_nozeros_indicator());
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ randi(const uword n_rows, const uword n_cols, const distr_param& param = distr_p
|
||||
|
||||
param.get_int_vals(a,b);
|
||||
|
||||
arma_conform_check( (a > b), "randi(): incorrect distribution parameters; a must be less than b" );
|
||||
arma_conform_check( ((a <= b) == false), "randi(): incorrect distribution parameters; a must be less than b" );
|
||||
|
||||
obj_type out(n_rows, n_cols, arma_nozeros_indicator());
|
||||
|
||||
@@ -142,7 +142,7 @@ randi(const distr_param& param)
|
||||
|
||||
param.get_int_vals(a,b);
|
||||
|
||||
arma_conform_check( (a > b), "randi(): incorrect distribution parameters; a must be less than b" );
|
||||
arma_conform_check( ((a <= b) == false), "randi(): incorrect distribution parameters; a must be less than b" );
|
||||
|
||||
sword out_val = sword(0);
|
||||
|
||||
@@ -166,7 +166,7 @@ randi(const distr_param& param)
|
||||
|
||||
param.get_int_vals(a,b);
|
||||
|
||||
arma_conform_check( (a > b), "randi(): incorrect distribution parameters; a must be less than b" );
|
||||
arma_conform_check( ((a <= b) == false), "randi(): incorrect distribution parameters; a must be less than b" );
|
||||
|
||||
eT out_val = eT(0);
|
||||
|
||||
@@ -218,7 +218,7 @@ randi(const uword n_rows, const uword n_cols, const uword n_slices, const distr_
|
||||
|
||||
param.get_int_vals(a,b);
|
||||
|
||||
arma_conform_check( (a > b), "randi(): incorrect distribution parameters; a must be less than b" );
|
||||
arma_conform_check( ((a <= b) == false), "randi(): incorrect distribution parameters; a must be less than b" );
|
||||
|
||||
cube_type out(n_rows, n_cols, n_slices, arma_nozeros_indicator());
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ randn(const distr_param& param)
|
||||
|
||||
param.get_double_vals(mu,sd);
|
||||
|
||||
arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
|
||||
arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
|
||||
|
||||
const double val = double(arma_rng::randn<double>());
|
||||
|
||||
@@ -86,7 +86,7 @@ randn(const distr_param& param)
|
||||
|
||||
param.get_double_vals(mu,sd);
|
||||
|
||||
arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
|
||||
arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
|
||||
|
||||
eT val = eT(0);
|
||||
|
||||
@@ -119,7 +119,7 @@ randn(const uword n_elem, const distr_param& param = distr_param())
|
||||
|
||||
param.get_double_vals(mu,sd);
|
||||
|
||||
arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
|
||||
arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
|
||||
|
||||
arma_rng::randn<double>::fill(out.memptr(), n_elem, mu, sd);
|
||||
}
|
||||
@@ -156,7 +156,7 @@ randn(const uword n_elem, const distr_param& param = distr_param(), const typena
|
||||
|
||||
param.get_double_vals(mu,sd);
|
||||
|
||||
arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
|
||||
arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
|
||||
|
||||
arma_rng::randn<eT>::fill(out.memptr(), out.n_elem, mu, sd);
|
||||
}
|
||||
@@ -188,7 +188,7 @@ randn(const uword n_rows, const uword n_cols, const distr_param& param = distr_p
|
||||
|
||||
param.get_double_vals(mu,sd);
|
||||
|
||||
arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
|
||||
arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
|
||||
|
||||
arma_rng::randn<double>::fill(out.memptr(), out.n_elem, mu, sd);
|
||||
}
|
||||
@@ -237,7 +237,7 @@ randn(const uword n_rows, const uword n_cols, const distr_param& param = distr_p
|
||||
|
||||
param.get_double_vals(mu,sd);
|
||||
|
||||
arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
|
||||
arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
|
||||
|
||||
arma_rng::randn<eT>::fill(out.memptr(), out.n_elem, mu, sd);
|
||||
}
|
||||
@@ -284,7 +284,7 @@ randn(const uword n_rows, const uword n_cols, const uword n_slices, const distr_
|
||||
|
||||
param.get_double_vals(mu,sd);
|
||||
|
||||
arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
|
||||
arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
|
||||
|
||||
arma_rng::randn<double>::fill(out.memptr(), out.n_elem, mu, sd);
|
||||
}
|
||||
@@ -330,7 +330,7 @@ randn(const uword n_rows, const uword n_cols, const uword n_slices, const distr_
|
||||
|
||||
param.get_double_vals(mu,sd);
|
||||
|
||||
arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
|
||||
arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
|
||||
|
||||
arma_rng::randn<eT>::fill(out.memptr(), out.n_elem, mu, sd);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ randu(const distr_param& param)
|
||||
|
||||
param.get_double_vals(a,b);
|
||||
|
||||
arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" );
|
||||
arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" );
|
||||
|
||||
const double val = double(arma_rng::randu<double>());
|
||||
|
||||
@@ -86,7 +86,7 @@ randu(const distr_param& param)
|
||||
|
||||
param.get_double_vals(a,b);
|
||||
|
||||
arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" );
|
||||
arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" );
|
||||
|
||||
eT val = eT(0);
|
||||
|
||||
@@ -119,7 +119,7 @@ randu(const uword n_elem, const distr_param& param = distr_param())
|
||||
|
||||
param.get_double_vals(a,b);
|
||||
|
||||
arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" );
|
||||
arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" );
|
||||
|
||||
arma_rng::randu<double>::fill(out.memptr(), n_elem, a, b);
|
||||
}
|
||||
@@ -156,7 +156,7 @@ randu(const uword n_elem, const distr_param& param = distr_param(), const typena
|
||||
|
||||
param.get_double_vals(a,b);
|
||||
|
||||
arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" );
|
||||
arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" );
|
||||
|
||||
arma_rng::randu<eT>::fill(out.memptr(), out.n_elem, a, b);
|
||||
}
|
||||
@@ -188,7 +188,7 @@ randu(const uword n_rows, const uword n_cols, const distr_param& param = distr_p
|
||||
|
||||
param.get_double_vals(a,b);
|
||||
|
||||
arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" );
|
||||
arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" );
|
||||
|
||||
arma_rng::randu<double>::fill(out.memptr(), out.n_elem, a, b);
|
||||
}
|
||||
@@ -237,7 +237,7 @@ randu(const uword n_rows, const uword n_cols, const distr_param& param = distr_p
|
||||
|
||||
param.get_double_vals(a,b);
|
||||
|
||||
arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" );
|
||||
arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" );
|
||||
|
||||
arma_rng::randu<eT>::fill(out.memptr(), out.n_elem, a, b);
|
||||
}
|
||||
@@ -284,7 +284,7 @@ randu(const uword n_rows, const uword n_cols, const uword n_slices, const distr_
|
||||
|
||||
param.get_double_vals(a,b);
|
||||
|
||||
arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" );
|
||||
arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" );
|
||||
|
||||
arma_rng::randu<double>::fill(out.memptr(), out.n_elem, a, b);
|
||||
}
|
||||
@@ -330,7 +330,7 @@ randu(const uword n_rows, const uword n_cols, const uword n_slices, const distr_
|
||||
|
||||
param.get_double_vals(a,b);
|
||||
|
||||
arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" );
|
||||
arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" );
|
||||
|
||||
arma_rng::randu<eT>::fill(out.memptr(), out.n_elem, a, b);
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ spsolve_helper
|
||||
|
||||
const superlu_opts& opts = (settings.id == 1) ? static_cast<const superlu_opts&>(settings) : superlu_opts_default;
|
||||
|
||||
arma_conform_check( ( (opts.pivot_thresh < double(0)) || (opts.pivot_thresh > double(1)) ), "spsolve(): pivot_thresh must be in the [0,1] interval" );
|
||||
arma_conform_check( ( ((opts.pivot_thresh >= double(0)) == false) || ((opts.pivot_thresh <= double(1)) == false) ), "spsolve(): pivot_thresh must be in the [0,1] interval" );
|
||||
|
||||
if(sig == 's') // SuperLU solver
|
||||
{
|
||||
@@ -110,12 +110,12 @@ spsolve_helper
|
||||
|
||||
if( (status == false) && (rcond > T(0)) )
|
||||
{
|
||||
arma_warn(2, "spsolve(): system is singular (rcond: ", rcond, ")");
|
||||
arma_warn(2, "spsolve(): system is singular; rcond: ", rcond);
|
||||
}
|
||||
|
||||
if( (status == true) && (rcond > T(0)) && (rcond < std::numeric_limits<T>::epsilon()) )
|
||||
{
|
||||
arma_warn(2, "solve(): solution computed, but system is singular to working precision (rcond: ", rcond, ")");
|
||||
arma_warn(2, "spsolve(): solution computed, but system is singular to working precision; rcond: ", rcond);
|
||||
}
|
||||
|
||||
return status;
|
||||
|
||||
@@ -47,7 +47,7 @@ svds_helper
|
||||
"svds(): two or more output objects are the same object"
|
||||
);
|
||||
|
||||
arma_conform_check( (tol < T(0)), "svds(): tol must be >= 0" );
|
||||
arma_conform_check( ((tol >= T(0)) == false), "svds(): tol must be >= 0" );
|
||||
|
||||
const unwrap_spmat<T1> tmp(X.get_ref());
|
||||
const SpMat<eT>& A = tmp.M;
|
||||
@@ -171,7 +171,7 @@ svds_helper
|
||||
"svds(): two or more output objects are the same object"
|
||||
);
|
||||
|
||||
arma_conform_check( (tol < T(0)), "svds(): tol must be >= 0" );
|
||||
arma_conform_check( ((tol >= T(0)) == false), "svds(): tol must be >= 0" );
|
||||
|
||||
const unwrap_spmat<T1> tmp(X.get_ref());
|
||||
const SpMat<eT>& A = tmp.M;
|
||||
|
||||
@@ -380,7 +380,7 @@ glue_solve_gen_full::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, const
|
||||
}
|
||||
else
|
||||
{
|
||||
arma_warn(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution");
|
||||
arma_warn(2, "solve(): system is singular; rcond: ", rcond, "; attempting approx solution");
|
||||
}
|
||||
|
||||
// TODO: conditionally recreate A: have a separate state flag which indicates whether A was previously overwritten
|
||||
@@ -472,7 +472,7 @@ glue_solve_tri_default::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, co
|
||||
}
|
||||
else
|
||||
{
|
||||
arma_warn(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution");
|
||||
arma_warn(2, "solve(): system is singular; rcond: ", rcond, "; attempting approx solution");
|
||||
}
|
||||
|
||||
Mat<eT> triA = (triu) ? trimatu(A) : trimatl(A); // trimatu() and trimatl() return the same type
|
||||
@@ -598,7 +598,7 @@ glue_solve_tri_full::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, const
|
||||
}
|
||||
else
|
||||
{
|
||||
arma_warn(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution");
|
||||
arma_warn(2, "solve(): system is singular; rcond: ", rcond, "; attempting approx solution");
|
||||
}
|
||||
|
||||
Mat<eT> triA = (triu) ? trimatu(A) : trimatl(A); // trimatu() and trimatl() return the same type
|
||||
|
||||
@@ -683,9 +683,9 @@ gmm_diag<eT>::learn
|
||||
|| (seed_mode == random_subset)
|
||||
|| (seed_mode == random_spread);
|
||||
|
||||
arma_conform_check( (dist_mode_ok == false), "gmm_diag::learn(): dist_mode must be eucl_dist or maha_dist" );
|
||||
arma_conform_check( (seed_mode_ok == false), "gmm_diag::learn(): unknown seed_mode" );
|
||||
arma_conform_check( (var_floor < eT(0) ), "gmm_diag::learn(): variance floor is negative" );
|
||||
arma_conform_check( (dist_mode_ok == false), "gmm_diag::learn(): dist_mode must be eucl_dist or maha_dist" );
|
||||
arma_conform_check( (seed_mode_ok == false), "gmm_diag::learn(): unknown seed_mode" );
|
||||
arma_conform_check( ((var_floor >= eT(0)) == false), "gmm_diag::learn(): variance floor must be > 0" );
|
||||
|
||||
const unwrap<T1> tmp_X(data.get_ref());
|
||||
const Mat<eT>& X = tmp_X.M;
|
||||
|
||||
@@ -722,9 +722,9 @@ gmm_full<eT>::learn
|
||||
|| (seed_mode == random_subset)
|
||||
|| (seed_mode == random_spread);
|
||||
|
||||
arma_conform_check( (dist_mode_ok == false), "gmm_full::learn(): dist_mode must be eucl_dist or maha_dist" );
|
||||
arma_conform_check( (seed_mode_ok == false), "gmm_full::learn(): unknown seed_mode" );
|
||||
arma_conform_check( (var_floor < eT(0) ), "gmm_full::learn(): variance floor is negative" );
|
||||
arma_conform_check( (dist_mode_ok == false), "gmm_full::learn(): dist_mode must be eucl_dist or maha_dist" );
|
||||
arma_conform_check( (seed_mode_ok == false), "gmm_full::learn(): unknown seed_mode" );
|
||||
arma_conform_check( ((var_floor >= eT(0)) == false), "gmm_full::learn(): variance floor must be > 0" );
|
||||
|
||||
const unwrap<T1> tmp_X(data.get_ref());
|
||||
const Mat<eT>& X = tmp_X.M;
|
||||
|
||||
@@ -77,8 +77,8 @@ SparseGenRealShiftSolve<eT>::SparseGenRealShiftSolve(const SpMat<eT>& mat_obj, c
|
||||
|
||||
if( (x_rcond < std::numeric_limits<eT>::epsilon()) || arma_isnan(x_rcond) )
|
||||
{
|
||||
if(x_rcond == eT(0)) { arma_warn(2, "matrix is singular to working precision"); }
|
||||
else { arma_warn(2, "matrix is singular to working precision (rcond: ", x_rcond, ")"); }
|
||||
if(x_rcond == eT(0)) { arma_warn(2, "matrix is singular to working precision"); }
|
||||
else { arma_warn(2, "matrix is singular to working precision; rcond: ", x_rcond); }
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ op_clamp::apply(Mat<typename T1::elem_type>& out, const mtOp<typename T1::elem_t
|
||||
const eT min_val = in.aux;
|
||||
const eT max_val = in.aux_out_eT;
|
||||
|
||||
arma_conform_check( (min_val > max_val), "clamp(): min_val must be less than max_val" );
|
||||
arma_conform_check( ((min_val <= max_val) == false), "clamp(): min_val must be less than max_val" );
|
||||
|
||||
if(is_Mat<T1>::value)
|
||||
{
|
||||
@@ -83,7 +83,7 @@ op_clamp::apply(Mat_noalias<typename T1::elem_type>& out, const mtOp<typename T1
|
||||
const eT min_val = in.aux;
|
||||
const eT max_val = in.aux_out_eT;
|
||||
|
||||
arma_conform_check( (min_val > max_val), "clamp(): min_val must be less than max_val" );
|
||||
arma_conform_check( ((min_val <= max_val) == false), "clamp(): min_val must be less than max_val" );
|
||||
|
||||
if((quasi_unwrap<T1>::has_orig_mem) || (is_Mat<typename Proxy<T1>::stored_type>::value) || (arma_config::openmp && Proxy<T1>::use_mp))
|
||||
{
|
||||
@@ -186,7 +186,7 @@ op_clamp::apply(Cube<typename T1::elem_type>& out, const mtOpCube<typename T1::e
|
||||
const eT min_val = in.aux;
|
||||
const eT max_val = in.aux_out_eT;
|
||||
|
||||
arma_conform_check( (min_val > max_val), "clamp(): min_val must be less than max_val" );
|
||||
arma_conform_check( ((min_val <= max_val) == false), "clamp(): min_val must be less than max_val" );
|
||||
|
||||
if(is_Cube<T1>::value)
|
||||
{
|
||||
@@ -350,8 +350,8 @@ op_clamp_cx::apply_direct(Mat<eT>& out, const Mat<eT>& X, const eT min_val, cons
|
||||
const T max_val_real = std::real(max_val);
|
||||
const T max_val_imag = std::imag(max_val);
|
||||
|
||||
arma_conform_check( (min_val_real > max_val_real), "clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( (min_val_imag > max_val_imag), "clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
arma_conform_check( ((min_val_real <= max_val_real) == false), "clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( ((min_val_imag <= max_val_imag) == false), "clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
|
||||
if(&out != &X)
|
||||
{
|
||||
@@ -401,8 +401,8 @@ op_clamp_cx::apply_proxy_noalias(Mat<typename T1::elem_type>& out, const Proxy<T
|
||||
const T max_val_real = std::real(max_val);
|
||||
const T max_val_imag = std::imag(max_val);
|
||||
|
||||
arma_conform_check( (min_val_real > max_val_real), "clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( (min_val_imag > max_val_imag), "clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
arma_conform_check( ((min_val_real <= max_val_real) == false), "clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( ((min_val_imag <= max_val_imag) == false), "clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
|
||||
const uword n_rows = P.get_n_rows();
|
||||
const uword n_cols = P.get_n_cols();
|
||||
@@ -503,8 +503,8 @@ op_clamp_cx::apply_direct(Cube<eT>& out, const Cube<eT>& X, const eT min_val, co
|
||||
const T max_val_real = std::real(max_val);
|
||||
const T max_val_imag = std::imag(max_val);
|
||||
|
||||
arma_conform_check( (min_val_real > max_val_real), "clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( (min_val_imag > max_val_imag), "clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
arma_conform_check( ((min_val_real <= max_val_real) == false), "clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( ((min_val_imag <= max_val_imag) == false), "clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
|
||||
if(&out != &X)
|
||||
{
|
||||
@@ -554,8 +554,8 @@ op_clamp_cx::apply_proxy_noalias(Cube<typename T1::elem_type>& out, const ProxyC
|
||||
const T max_val_real = std::real(max_val);
|
||||
const T max_val_imag = std::imag(max_val);
|
||||
|
||||
arma_conform_check( (min_val_real > max_val_real), "clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( (min_val_imag > max_val_imag), "clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
arma_conform_check( ((min_val_real <= max_val_real) == false), "clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( ((min_val_imag <= max_val_imag) == false), "clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
|
||||
const uword n_rows = P.get_n_rows();
|
||||
const uword n_cols = P.get_n_cols();
|
||||
|
||||
@@ -207,7 +207,7 @@ op_expmat_sym::apply_direct(Mat<typename T1::elem_type>& out, const Base<typenam
|
||||
|
||||
if((arma_config::check_conform) && (arma_config::warn_level > 0) && (is_cx<eT>::yes) && (sym_helper::check_diag_imag(X) == false))
|
||||
{
|
||||
arma_warn(1, "inv_sympd(): imaginary components on diagonal are non-zero");
|
||||
arma_warn(1, "expmat_sym(): imaginary components on diagonal are non-zero");
|
||||
}
|
||||
|
||||
if(is_op_diagmat<T1>::value || X.is_diagmat())
|
||||
|
||||
@@ -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_cols != 0)
|
||||
{
|
||||
eT* outptr = out.memptr();
|
||||
|
||||
|
||||
@@ -65,12 +65,18 @@ struct op_mean
|
||||
template<typename T1>
|
||||
inline static typename T1::elem_type mean_all(const T1& X);
|
||||
|
||||
template<typename T1>
|
||||
inline static typename T1::elem_type mean_all_proxy(const Proxy<T1>& P);
|
||||
|
||||
template<typename T1>
|
||||
inline static typename T1::elem_type mean_all(const Op<T1, op_omit>& X);
|
||||
|
||||
template<typename eT, typename functor>
|
||||
inline static eT mean_all_omit(const eT* X_mem, const uword N, functor is_omitted);
|
||||
|
||||
template<typename T1, typename functor>
|
||||
inline static typename T1::elem_type mean_all_omit(const Proxy<T1>& P, functor is_omitted);
|
||||
|
||||
//
|
||||
|
||||
template<typename eT>
|
||||
|
||||
@@ -435,17 +435,94 @@ op_mean::mean_all(const T1& X)
|
||||
arma_debug_sigprint();
|
||||
|
||||
typedef typename T1::elem_type eT;
|
||||
typedef typename T1::pod_type T;
|
||||
|
||||
const quasi_unwrap<T1> U(X);
|
||||
eT result = eT(0);
|
||||
|
||||
if(U.M.n_elem == 0)
|
||||
if( (is_Mat<typename Proxy<T1>::stored_type>::value == false) && (Proxy<T1>::use_at == false) && (Proxy<T1>::use_mp == false) && (is_fp16<T>::no) )
|
||||
{
|
||||
arma_conform_check(true, "mean(): object has no elements");
|
||||
arma_debug_print("op_mean::mean_all(): using proxy");
|
||||
|
||||
return Datum<eT>::nan;
|
||||
const Proxy<T1> P(X);
|
||||
|
||||
if(P.get_n_elem() == 0)
|
||||
{
|
||||
arma_conform_check(true, "mean(): object has no elements");
|
||||
|
||||
return Datum<eT>::nan;
|
||||
}
|
||||
|
||||
result = op_mean::mean_all_proxy(P);
|
||||
}
|
||||
else
|
||||
{
|
||||
arma_debug_print("op_mean::mean_all(): using quasi_unwrap");
|
||||
|
||||
const quasi_unwrap<T1> U(X);
|
||||
|
||||
if(U.M.n_elem == 0)
|
||||
{
|
||||
arma_conform_check(true, "mean(): object has no elements");
|
||||
|
||||
return Datum<eT>::nan;
|
||||
}
|
||||
|
||||
result = op_mean::direct_mean(U.M.memptr(), U.M.n_elem);
|
||||
}
|
||||
|
||||
return op_mean::direct_mean(U.M.memptr(), U.M.n_elem);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T1>
|
||||
inline
|
||||
typename T1::elem_type
|
||||
op_mean::mean_all_proxy(const Proxy<T1>& P)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
typedef typename T1::elem_type eT;
|
||||
typedef typename T1::pod_type T;
|
||||
|
||||
const uword N = P.get_n_elem();
|
||||
|
||||
const typename Proxy<T1>::ea_type Pea = P.get_ea();
|
||||
|
||||
eT acc1 = eT(0);
|
||||
eT acc2 = eT(0);
|
||||
|
||||
uword i,j;
|
||||
|
||||
for(i=0, j=1; j < N; i+=2, j+=2)
|
||||
{
|
||||
acc1 += Pea[i];
|
||||
acc2 += Pea[j];
|
||||
}
|
||||
|
||||
if(i < N)
|
||||
{
|
||||
acc1 += Pea[i];
|
||||
}
|
||||
|
||||
const eT mean = (acc1 + acc2) / T(N);
|
||||
|
||||
if(arma_isfinite(mean)) { return mean; }
|
||||
|
||||
// handle possible overflow
|
||||
|
||||
eT r_mean = eT(0);
|
||||
|
||||
for(uword ii=0; ii < N; ++ii)
|
||||
{
|
||||
const eT val = Pea[ii];
|
||||
|
||||
if(arma_isnonfinite(val)) { return mean; }
|
||||
|
||||
r_mean = r_mean + (val - r_mean) / T(ii+1);
|
||||
}
|
||||
|
||||
return r_mean;
|
||||
}
|
||||
|
||||
|
||||
@@ -467,22 +544,39 @@ op_mean::mean_all(const Op<T1, op_omit>& in)
|
||||
if(omit_mode == 2) { arma_warn(1, "omit_nonfinite(): detection of non-finite values is not reliable in fast math mode"); }
|
||||
}
|
||||
|
||||
const quasi_unwrap<T1> U(in.m);
|
||||
|
||||
if(U.M.n_elem == 0)
|
||||
{
|
||||
arma_conform_check(true, "mean(): object has no elements");
|
||||
|
||||
return Datum<eT>::nan;
|
||||
}
|
||||
|
||||
auto is_omitted_1 = [](const eT& x) -> bool { return arma_isnan(x); };
|
||||
auto is_omitted_2 = [](const eT& x) -> bool { return arma_isnonfinite(x); };
|
||||
|
||||
eT result = eT(0);
|
||||
|
||||
if(omit_mode == 1) { result = op_mean::mean_all_omit(U.M.memptr(), U.M.n_elem, is_omitted_1); }
|
||||
if(omit_mode == 2) { result = op_mean::mean_all_omit(U.M.memptr(), U.M.n_elem, is_omitted_2); }
|
||||
if( (is_Mat<typename Proxy<T1>::stored_type>::value == false) && (Proxy<T1>::use_at == false) && (Proxy<T1>::use_mp == false) )
|
||||
{
|
||||
const Proxy<T1> P(in.m);
|
||||
|
||||
if(P.get_n_elem() == 0)
|
||||
{
|
||||
arma_conform_check(true, "mean(): object has no elements");
|
||||
|
||||
return Datum<eT>::nan;
|
||||
}
|
||||
|
||||
if(omit_mode == 1) { result = op_mean::mean_all_omit(P, is_omitted_1); }
|
||||
if(omit_mode == 2) { result = op_mean::mean_all_omit(P, is_omitted_2); }
|
||||
}
|
||||
else
|
||||
{
|
||||
const quasi_unwrap<T1> U(in.m);
|
||||
|
||||
if(U.M.n_elem == 0)
|
||||
{
|
||||
arma_conform_check(true, "mean(): object has no elements");
|
||||
|
||||
return Datum<eT>::nan;
|
||||
}
|
||||
|
||||
if(omit_mode == 1) { result = op_mean::mean_all_omit(U.M.memptr(), U.M.n_elem, is_omitted_1); }
|
||||
if(omit_mode == 2) { result = op_mean::mean_all_omit(U.M.memptr(), U.M.n_elem, is_omitted_2); }
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -535,6 +629,55 @@ op_mean::mean_all_omit(const eT* X_mem, const uword N, functor is_omitted)
|
||||
|
||||
|
||||
|
||||
template<typename T1, typename functor>
|
||||
inline
|
||||
typename T1::elem_type
|
||||
op_mean::mean_all_omit(const Proxy<T1>& P, functor is_omitted)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
typedef typename T1::elem_type eT;
|
||||
typedef typename T1::pod_type T;
|
||||
|
||||
const uword N = P.get_n_elem();
|
||||
|
||||
uword count = 0;
|
||||
eT acc = eT(0);
|
||||
|
||||
for(uword i=0; i < N; ++i)
|
||||
{
|
||||
const eT val = P[i];
|
||||
|
||||
if(is_omitted(val) == false) { acc += val; ++count; }
|
||||
}
|
||||
|
||||
acc /= T(count);
|
||||
|
||||
if(arma_isfinite(acc)) { return acc; }
|
||||
|
||||
// handle possible overflow
|
||||
|
||||
eT r_mean = eT(0);
|
||||
|
||||
count = 0;
|
||||
|
||||
for(uword i=0; i < N; ++i)
|
||||
{
|
||||
const eT val = P[i];
|
||||
|
||||
if(is_omitted(val) == false)
|
||||
{
|
||||
r_mean = r_mean + (val - r_mean) / T(count+1); // kept as count+1 to use same algorithm as op_mean::direct_mean_robust()
|
||||
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
return r_mean;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
|
||||
|
||||
|
||||
@@ -110,8 +110,8 @@ op_norm2est::norm2est
|
||||
typedef typename T1::pod_type T;
|
||||
typedef typename T1::elem_type eT;
|
||||
|
||||
arma_conform_check( (tolerance < T(0)), "norm2est(): parameter 'tolerance' must be > 0" );
|
||||
arma_conform_check( (max_iter == uword(0)), "norm2est(): parameter 'max_iter' must be > 0" );
|
||||
arma_conform_check( ((tolerance >= T(0)) == false), "norm2est(): parameter 'tolerance' must be > 0" );
|
||||
arma_conform_check( (max_iter == uword(0)), "norm2est(): parameter 'max_iter' must be > 0" );
|
||||
|
||||
const T tol = (tolerance == T(0)) ? T(1e-6) : T(tolerance);
|
||||
|
||||
@@ -190,8 +190,8 @@ op_norm2est::norm2est
|
||||
typedef typename T1::pod_type T;
|
||||
typedef typename T1::elem_type eT;
|
||||
|
||||
arma_conform_check( (tolerance < T(0)), "norm2est(): parameter 'tolerance' must be > 0" );
|
||||
arma_conform_check( (max_iter == uword(0)), "norm2est(): parameter 'max_iter' must be > 0" );
|
||||
arma_conform_check( ((tolerance >= T(0)) == false), "norm2est(): parameter 'tolerance' must be > 0" );
|
||||
arma_conform_check( (max_iter == uword(0)), "norm2est(): parameter 'max_iter' must be > 0" );
|
||||
|
||||
const T tol = (tolerance == T(0)) ? T(1e-6) : T(tolerance);
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ op_orth::apply_direct(Mat<typename T1::elem_type>& out, const Base<typename T1::
|
||||
typedef typename T1::elem_type eT;
|
||||
typedef typename T1::pod_type T;
|
||||
|
||||
arma_conform_check((tol < T(0)), "orth(): tolerance must be >= 0");
|
||||
arma_conform_check( ((tol >= T(0)) == false), "orth(): tolerance must be > 0" );
|
||||
|
||||
Mat<eT> U;
|
||||
Col< T> s;
|
||||
@@ -87,6 +87,8 @@ op_orth::apply_direct(Mat<typename T1::elem_type>& out, const Base<typename T1::
|
||||
// set tolerance to default if it hasn't been specified
|
||||
if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * s_mem[0] * std::numeric_limits<T>::epsilon(); }
|
||||
|
||||
if(arma_isnan(tol)) { return false; }
|
||||
|
||||
uword count = 0;
|
||||
|
||||
for(uword i=0; i < s_n_elem; ++i) { count += (s_mem[i] > tol) ? uword(1) : uword(0); }
|
||||
@@ -141,7 +143,7 @@ op_null::apply_direct(Mat<typename T1::elem_type>& out, const Base<typename T1::
|
||||
typedef typename T1::elem_type eT;
|
||||
typedef typename T1::pod_type T;
|
||||
|
||||
arma_conform_check((tol < T(0)), "null(): tolerance must be >= 0");
|
||||
arma_conform_check( ((tol >= T(0)) == false), "null(): tolerance must be > 0" );
|
||||
|
||||
Mat<eT> U;
|
||||
Col< T> s;
|
||||
@@ -174,6 +176,8 @@ op_null::apply_direct(Mat<typename T1::elem_type>& out, const Base<typename T1::
|
||||
// set tolerance to default if it hasn't been specified
|
||||
if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * s_mem[0] * std::numeric_limits<T>::epsilon(); }
|
||||
|
||||
if(arma_isnan(tol)) { return false; }
|
||||
|
||||
uword count = 0;
|
||||
|
||||
for(uword i=0; i < s_n_elem; ++i) { count += (s_mem[i] > tol) ? uword(1) : uword(0); }
|
||||
|
||||
@@ -94,7 +94,7 @@ op_pinv::apply_direct(Mat<typename T1::elem_type>& out, const Base<typename T1::
|
||||
typedef typename T1::elem_type eT;
|
||||
typedef typename T1::pod_type T;
|
||||
|
||||
arma_conform_check((tol < T(0)), "pinv(): tolerance must be >= 0");
|
||||
arma_conform_check( ((tol >= T(0)) == false), "pinv(): tolerance must be > 0" );
|
||||
|
||||
// method_id = 0 -> default setting
|
||||
// method_id = 1 -> use standard algorithm
|
||||
@@ -176,6 +176,8 @@ op_pinv::apply_diag(Mat<eT>& out, const Mat<eT>& A, typename get_pod_type<eT>::r
|
||||
|
||||
if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * max_abs_Aii * std::numeric_limits<T>::epsilon(); }
|
||||
|
||||
if(arma_isnan(tol)) { return false; }
|
||||
|
||||
for(uword i=0; i<N; ++i)
|
||||
{
|
||||
if(diag_abs_vals[i] >= tol)
|
||||
@@ -236,6 +238,8 @@ op_pinv::apply_sym(Mat<eT>& out, const Mat<eT>& A, typename get_pod_type<eT>::re
|
||||
// set tolerance to default if it hasn't been specified
|
||||
if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * abs_eigval[0] * std::numeric_limits<T>::epsilon(); }
|
||||
|
||||
if(arma_isnan(tol)) { return false; }
|
||||
|
||||
uword count = 0;
|
||||
|
||||
for(uword i=0; i < abs_eigval.n_elem; ++i) { count += (abs_eigval[i] >= tol) ? uword(1) : uword(0); }
|
||||
@@ -310,6 +314,8 @@ op_pinv::apply_gen(Mat<eT>& out, Mat<eT>& A, typename get_pod_type<eT>::result t
|
||||
// set tolerance to default if it hasn't been specified
|
||||
if( (tol == T(0)) && (s.n_elem > 0) ) { tol = (std::max)(n_rows, n_cols) * s[0] * std::numeric_limits<T>::epsilon(); }
|
||||
|
||||
if(arma_isnan(tol)) { return false; }
|
||||
|
||||
uword count = 0;
|
||||
|
||||
for(uword i=0; i < s.n_elem; ++i) { count += (s[i] >= tol) ? uword(1) : uword(0); }
|
||||
|
||||
@@ -87,6 +87,8 @@ op_rank::apply_diag(uword& out, Mat<eT>& A, typename get_pod_type<eT>::result to
|
||||
|
||||
typedef typename get_pod_type<eT>::result T;
|
||||
|
||||
out = uword(0);
|
||||
|
||||
const uword N = (std::min)(A.n_rows, A.n_cols);
|
||||
|
||||
podarray<T> diag_abs_vals(N);
|
||||
@@ -98,7 +100,7 @@ op_rank::apply_diag(uword& out, Mat<eT>& A, typename get_pod_type<eT>::result to
|
||||
const eT Aii = A.at(i,i);
|
||||
const T abs_Aii = std::abs(Aii);
|
||||
|
||||
if(arma_isnan(Aii)) { out = uword(0); return false; }
|
||||
if(arma_isnan(Aii)) { return false; }
|
||||
|
||||
diag_abs_vals[i] = abs_Aii;
|
||||
|
||||
@@ -108,6 +110,8 @@ op_rank::apply_diag(uword& out, Mat<eT>& A, typename get_pod_type<eT>::result to
|
||||
// set tolerance to default if it hasn't been specified
|
||||
if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * max_abs_Aii * std::numeric_limits<T>::epsilon(); }
|
||||
|
||||
if(arma_isnan(tol)) { return false; }
|
||||
|
||||
uword count = 0;
|
||||
|
||||
for(uword i=0; i<N; ++i) { count += (diag_abs_vals[i] > tol) ? uword(1) : uword(0); }
|
||||
@@ -128,18 +132,20 @@ op_rank::apply_sym(uword& out, Mat<eT>& A, typename get_pod_type<eT>::result tol
|
||||
|
||||
typedef typename get_pod_type<eT>::result T;
|
||||
|
||||
if(A.is_square() == false) { out = uword(0); return false; }
|
||||
out = uword(0);
|
||||
|
||||
if(A.is_square() == false) { return false; }
|
||||
|
||||
Col<T> v;
|
||||
|
||||
const bool status = auxlib::eig_sym(v, A);
|
||||
|
||||
if(status == false) { out = uword(0); return false; }
|
||||
if(status == false) { return false; }
|
||||
|
||||
const uword v_n_elem = v.n_elem;
|
||||
T* v_mem = v.memptr();
|
||||
|
||||
if(v_n_elem == 0) { out = uword(0); return true; }
|
||||
if(v_n_elem == 0) { return true; }
|
||||
|
||||
T max_abs_v = T(0);
|
||||
|
||||
@@ -148,6 +154,8 @@ op_rank::apply_sym(uword& out, Mat<eT>& A, typename get_pod_type<eT>::result tol
|
||||
// set tolerance to default if it hasn't been specified
|
||||
if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * max_abs_v * std::numeric_limits<T>::epsilon(); }
|
||||
|
||||
if(arma_isnan(tol)) { return false; }
|
||||
|
||||
uword count = 0;
|
||||
|
||||
for(uword i=0; i < v_n_elem; ++i) { count += (v_mem[i] > tol) ? uword(1) : uword(0); }
|
||||
@@ -168,20 +176,24 @@ op_rank::apply_gen(uword& out, Mat<eT>& A, typename get_pod_type<eT>::result tol
|
||||
|
||||
typedef typename get_pod_type<eT>::result T;
|
||||
|
||||
out = uword(0);
|
||||
|
||||
Col<T> s;
|
||||
|
||||
const bool status = auxlib::svd_dc(s, A);
|
||||
|
||||
if(status == false) { out = uword(0); return false; }
|
||||
if(status == false) { return false; }
|
||||
|
||||
const uword s_n_elem = s.n_elem;
|
||||
const T* s_mem = s.memptr();
|
||||
|
||||
if(s_n_elem == 0) { out = uword(0); return true; }
|
||||
if(s_n_elem == 0) { return true; }
|
||||
|
||||
// set tolerance to default if it hasn't been specified
|
||||
if(tol == T(0)) { tol = (std::max)(A.n_rows, A.n_cols) * s_mem[0] * std::numeric_limits<T>::epsilon(); }
|
||||
|
||||
if(arma_isnan(tol)) { return false; }
|
||||
|
||||
uword count = 0;
|
||||
|
||||
for(uword i=0; i < s_n_elem; ++i) { count += (s_mem[i] > tol) ? uword(1) : uword(0); }
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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_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)
|
||||
|
||||
@@ -113,7 +113,7 @@ op_wishrnd::apply_noalias_mode2(Mat<eT>& out, const Mat<eT>& D, const eT df)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
arma_conform_check( (df <= eT(0)), "df must be greater than zero" );
|
||||
arma_conform_check( ((df > eT(0)) == false), "df must be greater than zero" );
|
||||
arma_conform_check( (D.is_square() == false), "wishrnd(): given matrix must be square sized" );
|
||||
|
||||
if(D.is_empty()) { out.reset(); return true; }
|
||||
@@ -256,7 +256,7 @@ op_iwishrnd::apply_noalias_mode2(Mat<eT>& out, const Mat<eT>& Dinv, const eT df)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
arma_conform_check( (df <= eT(0)), "df must be greater than zero" );
|
||||
arma_conform_check( ((df > eT(0)) == false), "df must be greater than zero" );
|
||||
arma_conform_check( (Dinv.is_square() == false), "iwishrnd(): given matrix must be square sized" );
|
||||
|
||||
if(Dinv.is_empty()) { out.reset(); return true; }
|
||||
|
||||
@@ -214,6 +214,8 @@ sp_auxlib::eigs_sym_newarp(Col<eT>& eigval, Mat<eT>& eigvec, const SpMat<eT>& X,
|
||||
if(ncv < (n_eigvals + 1)) { ncv = (n_eigvals + 1); }
|
||||
if(ncv > n ) { ncv = n; }
|
||||
|
||||
if(arma_isnan(opts.tol)) { return false; }
|
||||
|
||||
eT tol = (std::max)(eT(opts.tol), std::numeric_limits<eT>::epsilon());
|
||||
|
||||
uword maxiter = uword(opts.maxiter);
|
||||
@@ -347,6 +349,8 @@ sp_auxlib::eigs_sym_newarp(Col<eT>& eigval, Mat<eT>& eigvec, const SpMat<eT>& X,
|
||||
if(ncv < (n_eigvals + 1)) { ncv = (n_eigvals + 1); }
|
||||
if(ncv > n ) { ncv = n; }
|
||||
|
||||
if(arma_isnan(opts.tol)) { return false; }
|
||||
|
||||
eT tol = (std::max)(eT(opts.tol), std::numeric_limits<eT>::epsilon());
|
||||
|
||||
uword maxiter = uword(opts.maxiter);
|
||||
@@ -503,7 +507,7 @@ sp_auxlib::eigs_sym_arpack(Col<eT>& eigval, Mat<eT>& eigvec, const SpMat<eT>& X,
|
||||
arpack::seupd(&rvec, &howmny, select.memptr(), eigval.memptr(), eigvec.memptr(), &ldz, (eT*) &sigma, &bmat, &n, which, &nev, &tol, resid.memptr(), &ncv, v.memptr(), &ldv, iparam.memptr(), ipntr.memptr(), workd.memptr(), workl.memptr(), &lworkl, &info);
|
||||
|
||||
// Check for errors.
|
||||
if(info != 0) { arma_warn(1, "eigs_sym(): ARPACK error ", info, " in seupd()"); return false; }
|
||||
if(info != 0) { arma_warn(1, "eigs_sym(): arpack::seupd() error: ", info); return false; }
|
||||
|
||||
return (info == 0);
|
||||
}
|
||||
@@ -667,6 +671,8 @@ sp_auxlib::eigs_gen_newarp(Col< std::complex<T> >& eigval, Mat< std::complex<T>
|
||||
if(ncv < (n_eigvals + 3)) { ncv = (n_eigvals + 3); }
|
||||
if(ncv > n ) { ncv = n; }
|
||||
|
||||
if(arma_isnan(opts.tol)) { return false; }
|
||||
|
||||
T tol = (std::max)(T(opts.tol), std::numeric_limits<T>::epsilon());
|
||||
|
||||
uword maxiter = uword(opts.maxiter);
|
||||
@@ -890,7 +896,7 @@ sp_auxlib::eigs_gen_arpack(Col< std::complex<T> >& eigval, Mat< std::complex<T>
|
||||
arpack::neupd(&rvec, &howmny, select.memptr(), dr.memptr(), di.memptr(), z.memptr(), &ldz, (T*) &sigmar, (T*) &sigmai, workev.memptr(), &bmat, &n, which, &nev, &tol, resid.memptr(), &ncv, v.memptr(), &ldv, iparam.memptr(), ipntr.memptr(), workd.memptr(), workl.memptr(), &lworkl, rwork.memptr(), &info);
|
||||
|
||||
// Check for errors.
|
||||
if(info != 0) { arma_warn(1, "eigs_gen(): ARPACK error ", info, " in neupd()"); return false; }
|
||||
if(info != 0) { arma_warn(1, "eigs_gen(): arpack::neupd() error: ", info); return false; }
|
||||
|
||||
// Put it into the outputs.
|
||||
eigval.set_size(n_eigvals);
|
||||
@@ -1138,7 +1144,7 @@ sp_auxlib::eigs_gen(Col< std::complex<T> >& eigval, Mat< std::complex<T> >& eigv
|
||||
(std::complex<T>*) NULL, eigvec.memptr(), &ldz, (std::complex<T>*) &sigma, (std::complex<T>*) NULL, workev.memptr(), &bmat, &n, which, &nev, &tol, resid.memptr(), &ncv, v.memptr(), &ldv, iparam.memptr(), ipntr.memptr(), workd.memptr(), workl.memptr(), &lworkl, rwork.memptr(), &info);
|
||||
|
||||
// Check for errors.
|
||||
if(info != 0) { arma_warn(1, "eigs_gen(): ARPACK error ", info, " in neupd()"); return false; }
|
||||
if(info != 0) { arma_warn(1, "eigs_gen(): arpack::neupd() error: ", info); return false; }
|
||||
|
||||
return (info == 0);
|
||||
}
|
||||
@@ -1258,7 +1264,7 @@ sp_auxlib::spsolve_simple(Mat<typename T1::elem_type>& X, const SpBase<typename
|
||||
else
|
||||
if(info < 0)
|
||||
{
|
||||
arma_warn(1, "spsolve(): unknown SuperLU error code from gssv(): ", info);
|
||||
arma_warn(1, "spsolve(): superlu::gssv() error: ", info);
|
||||
}
|
||||
|
||||
// No need to extract the data from x, since it's using the same memory as X
|
||||
@@ -1406,7 +1412,7 @@ sp_auxlib::spsolve_refine(Mat<typename T1::elem_type>& X, typename T1::pod_type&
|
||||
else
|
||||
if( (info == superlu::int_t(A.n_cols+1)) && (user_opts.allow_ugly) )
|
||||
{
|
||||
arma_warn(2, "spsolve(): system is singular to working precision (rcond: ", rcond, ")");
|
||||
arma_warn(2, "spsolve(): system is singular to working precision; rcond: ", rcond);
|
||||
status = true;
|
||||
}
|
||||
else
|
||||
@@ -1417,7 +1423,7 @@ sp_auxlib::spsolve_refine(Mat<typename T1::elem_type>& X, typename T1::pod_type&
|
||||
else
|
||||
if(info < 0)
|
||||
{
|
||||
arma_warn(1, "spsolve(): unknown SuperLU error code from gssvx(): ", info);
|
||||
arma_warn(1, "spsolve(): superlu::gssvx() error: ", info);
|
||||
}
|
||||
|
||||
// No need to extract the data from x, since it's using the same memory as X
|
||||
@@ -2013,11 +2019,11 @@ sp_auxlib::run_aupd_plain
|
||||
|
||||
if(sym)
|
||||
{
|
||||
arma_warn(1, "eigs_sym(): ARPACK error ", info, " in saupd()");
|
||||
arma_warn(1, "eigs_sym(): arpack::saupd() error: ", info);
|
||||
}
|
||||
else
|
||||
{
|
||||
arma_warn(1, "eigs_gen(): ARPACK error ", info, " in naupd()");
|
||||
arma_warn(1, "eigs_gen(): arpack::naupd() error: ", info);
|
||||
}
|
||||
|
||||
return; // Parent frame can look at the value of info.
|
||||
@@ -2200,7 +2206,7 @@ sp_auxlib::run_aupd_shiftinvert
|
||||
|
||||
if( (x_rcond < std::numeric_limits<eT>::epsilon()) || arma_isnan(x_rcond) )
|
||||
{
|
||||
arma_warn(2, "matrix is singular to working precision (rcond: ", x_rcond, ")");
|
||||
arma_warn(2, "matrix is singular to working precision; rcond: ", x_rcond);
|
||||
info = blas_int(-1);
|
||||
return;
|
||||
}
|
||||
@@ -2270,11 +2276,11 @@ sp_auxlib::run_aupd_shiftinvert
|
||||
|
||||
if(sym)
|
||||
{
|
||||
arma_warn(2, "eigs_sym(): ARPACK error ", info, " in saupd()");
|
||||
arma_warn(2, "eigs_sym(): arpack::saupd() error: ", info);
|
||||
}
|
||||
else
|
||||
{
|
||||
arma_warn(2, "eigs_gen(): ARPACK error ", info, " in naupd()");
|
||||
arma_warn(2, "eigs_gen(): arpack::naupd() error: ", info);
|
||||
}
|
||||
|
||||
return; // Parent frame can look at the value of info.
|
||||
|
||||
@@ -923,7 +923,7 @@ spdiagview<eT>::clamp(const eT min_val, const eT max_val)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
SpMat<eT> tmp(*this);
|
||||
Mat<eT> tmp(*this);
|
||||
|
||||
tmp.clamp(min_val, max_val);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -392,11 +395,16 @@ class subview_col : public subview<eT>
|
||||
|
||||
arma_warn_unused arma_inline const Op<subview_col<eT>,op_strans> as_row() const;
|
||||
|
||||
inline void replace(const eT old_val, const eT new_val);
|
||||
|
||||
inline void fill(const eT val);
|
||||
inline void zeros();
|
||||
inline void ones();
|
||||
inline void randu();
|
||||
inline void randn();
|
||||
|
||||
arma_warn_unused inline bool is_finite() const;
|
||||
arma_warn_unused inline bool is_zero(const pod_type tol = 0) const;
|
||||
|
||||
arma_warn_unused inline bool has_inf() const;
|
||||
arma_warn_unused inline bool has_nan() const;
|
||||
@@ -552,11 +560,16 @@ class subview_row : public subview<eT>
|
||||
|
||||
arma_warn_unused arma_inline const Op<subview_row<eT>,op_strans> as_col() const;
|
||||
|
||||
inline void replace(const eT old_val, const eT new_val);
|
||||
|
||||
inline void fill(const eT val);
|
||||
inline void zeros();
|
||||
inline void ones();
|
||||
inline void randu();
|
||||
inline void randn();
|
||||
|
||||
arma_warn_unused inline bool is_finite() const;
|
||||
arma_warn_unused inline bool is_zero(const pod_type tol = 0) const;
|
||||
|
||||
arma_warn_unused inline bool has_inf() const;
|
||||
arma_warn_unused inline bool has_nan() const;
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
@@ -1216,18 +1226,20 @@ subview_cube<eT>::clamp(const eT min_val, const eT max_val)
|
||||
|
||||
if(is_cx<eT>::no)
|
||||
{
|
||||
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "subview_cube::clamp(): min_val must be less than max_val" );
|
||||
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "subview_cube::clamp(): min_val must be less than max_val" );
|
||||
}
|
||||
else
|
||||
{
|
||||
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "subview_cube::clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "subview_cube::clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "subview_cube::clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "subview_cube::clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
}
|
||||
|
||||
const uword local_n_rows = n_rows;
|
||||
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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1372,10 +1395,16 @@ subview_cube<eT>::is_zero(const typename get_pod_type<eT>::result tol) const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
typedef typename get_pod_type<elem_type>::result T;
|
||||
|
||||
arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" );
|
||||
|
||||
const uword local_n_rows = n_rows;
|
||||
const uword local_n_cols = n_cols;
|
||||
const uword local_n_slices = n_slices;
|
||||
|
||||
if( (local_n_rows == 0) || (local_n_cols == 0) || (local_n_slices == 0) ) { return false; }
|
||||
|
||||
for(uword slice = 0; slice < local_n_slices; ++slice)
|
||||
{
|
||||
for(uword col = 0; col < local_n_cols; ++col)
|
||||
@@ -1402,11 +1431,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 +1460,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 +1489,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 +1652,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 +1662,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 +1742,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 +1752,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 +1787,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 +1814,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 +1841,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 +1868,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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -90,6 +90,8 @@ class subview_elem1 : public Base< eT, subview_elem1<eT,T1> >
|
||||
template<typename T2> inline void operator%= (const Base<eT,T2>& x);
|
||||
template<typename T2> inline void operator/= (const Base<eT,T2>& x);
|
||||
|
||||
inline static void extract_noalias(Mat<eT>& out, const subview_elem1& in);
|
||||
|
||||
inline static void extract(Mat<eT>& out, const subview_elem1& in);
|
||||
|
||||
template<typename op_type> inline static void mat_inplace_op(Mat<eT>& out, const subview_elem1& in);
|
||||
|
||||
@@ -759,6 +759,55 @@ subview_elem1<eT,T1>::operator/= (const Base<eT,T2>& x)
|
||||
|
||||
|
||||
|
||||
template<typename eT, typename T1>
|
||||
inline
|
||||
void
|
||||
subview_elem1<eT,T1>::extract_noalias(Mat<eT>& out, const subview_elem1<eT,T1>& in)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
const quasi_unwrap<T1> tmp1(in.a.get_ref());
|
||||
const umat& aa = tmp1.M;
|
||||
|
||||
if(resolves_to_vector<T1>::no)
|
||||
{
|
||||
arma_conform_check( ( (aa.is_vec() == false) && (aa.is_empty() == false) ), "Mat::elem(): given object must be a vector" );
|
||||
}
|
||||
|
||||
const uword* aa_mem = aa.memptr();
|
||||
const uword aa_n_elem = aa.n_elem;
|
||||
|
||||
const eT* m_mem = in.m.memptr();
|
||||
const uword m_n_elem = in.m.n_elem;
|
||||
|
||||
out.set_size(aa_n_elem, 1);
|
||||
|
||||
eT* out_mem = out.memptr();
|
||||
|
||||
uword i,j;
|
||||
for(i=0, j=1; j<aa_n_elem; i+=2, j+=2)
|
||||
{
|
||||
const uword ii = aa_mem[i];
|
||||
const uword jj = aa_mem[j];
|
||||
|
||||
arma_conform_check_bounds( ( (ii >= m_n_elem) || (jj >= m_n_elem) ), "Mat::elem(): index out of bounds" );
|
||||
|
||||
out_mem[i] = m_mem[ii];
|
||||
out_mem[j] = m_mem[jj];
|
||||
}
|
||||
|
||||
if(i < aa_n_elem)
|
||||
{
|
||||
const uword ii = aa_mem[i];
|
||||
|
||||
arma_conform_check_bounds( (ii >= m_n_elem) , "Mat::elem(): index out of bounds" );
|
||||
|
||||
out_mem[i] = m_mem[ii];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT, typename T1>
|
||||
inline
|
||||
void
|
||||
@@ -777,12 +826,12 @@ subview_elem1<eT,T1>::extract(Mat<eT>& actual_out, const subview_elem1<eT,T1>& i
|
||||
const uword* aa_mem = aa.memptr();
|
||||
const uword aa_n_elem = aa.n_elem;
|
||||
|
||||
const Mat<eT>& m_local = in.m;
|
||||
const Mat<eT>& m = in.m;
|
||||
|
||||
const eT* m_mem = m_local.memptr();
|
||||
const uword m_n_elem = m_local.n_elem;
|
||||
const eT* m_mem = m.memptr();
|
||||
const uword m_n_elem = m.n_elem;
|
||||
|
||||
const bool alias = (&actual_out == &m_local);
|
||||
const bool alias = (&actual_out == &m);
|
||||
|
||||
if(alias) { arma_debug_print("subview_elem1::extract(): aliasing detected"); }
|
||||
|
||||
|
||||
@@ -98,6 +98,8 @@ class subview_elem2 : public Base< eT, subview_elem2<eT,T1,T2> >
|
||||
template<typename expr> inline void operator%= (const SpBase<eT,expr>& x);
|
||||
template<typename expr> inline void operator/= (const SpBase<eT,expr>& x);
|
||||
|
||||
inline static void extract_noalias(Mat<eT>& out, const subview_elem2& in);
|
||||
|
||||
inline static void extract(Mat<eT>& out, const subview_elem2& in);
|
||||
|
||||
inline static void plus_inplace(Mat<eT>& out, const subview_elem2& in);
|
||||
|
||||
@@ -917,6 +917,121 @@ subview_elem2<eT,T1,T2>::operator/= (const SpBase<eT,expr>& x)
|
||||
|
||||
|
||||
|
||||
template<typename eT, typename T1, typename T2>
|
||||
inline
|
||||
void
|
||||
subview_elem2<eT,T1,T2>::extract_noalias(Mat<eT>& out, const subview_elem2<eT,T1,T2>& in)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
const Mat<eT>& m = in.m;
|
||||
|
||||
const uword m_n_rows = m.n_rows;
|
||||
const uword m_n_cols = m.n_cols;
|
||||
|
||||
if( (in.all_rows == false) && (in.all_cols == false) )
|
||||
{
|
||||
const quasi_unwrap<T1> tmp1(in.base_ri.get_ref());
|
||||
const quasi_unwrap<T2> tmp2(in.base_ci.get_ref());
|
||||
|
||||
const umat& ri = tmp1.M;
|
||||
const umat& ci = tmp2.M;
|
||||
|
||||
arma_conform_check
|
||||
(
|
||||
( ((ri.is_vec() == false) && (ri.is_empty() == false)) || ((ci.is_vec() == false) && (ci.is_empty() == false)) ),
|
||||
"Mat::elem(): given object must be a vector"
|
||||
);
|
||||
|
||||
const uword* ri_mem = ri.memptr();
|
||||
const uword ri_n_elem = ri.n_elem;
|
||||
|
||||
const uword* ci_mem = ci.memptr();
|
||||
const uword ci_n_elem = ci.n_elem;
|
||||
|
||||
out.set_size(ri_n_elem, ci_n_elem);
|
||||
|
||||
eT* out_mem = out.memptr();
|
||||
uword out_count = 0;
|
||||
|
||||
for(uword ci_count=0; ci_count < ci_n_elem; ++ci_count)
|
||||
{
|
||||
const uword col = ci_mem[ci_count];
|
||||
|
||||
arma_conform_check_bounds( (col >= m_n_cols), "Mat::elem(): index out of bounds" );
|
||||
|
||||
for(uword ri_count=0; ri_count < ri_n_elem; ++ri_count)
|
||||
{
|
||||
const uword row = ri_mem[ri_count];
|
||||
|
||||
arma_conform_check_bounds( (row >= m_n_rows), "Mat::elem(): index out of bounds" );
|
||||
|
||||
out_mem[out_count] = m.at(row,col);
|
||||
++out_count;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
if( (in.all_rows == true) && (in.all_cols == false) )
|
||||
{
|
||||
const quasi_unwrap<T2> tmp2(in.base_ci.get_ref());
|
||||
|
||||
const umat& ci = tmp2.M;
|
||||
|
||||
arma_conform_check
|
||||
(
|
||||
( (ci.is_vec() == false) && (ci.is_empty() == false) ),
|
||||
"Mat::elem(): given object must be a vector"
|
||||
);
|
||||
|
||||
const uword* ci_mem = ci.memptr();
|
||||
const uword ci_n_elem = ci.n_elem;
|
||||
|
||||
out.set_size(m_n_rows, ci_n_elem);
|
||||
|
||||
for(uword ci_count=0; ci_count < ci_n_elem; ++ci_count)
|
||||
{
|
||||
const uword col = ci_mem[ci_count];
|
||||
|
||||
arma_conform_check_bounds( (col >= m_n_cols), "Mat::elem(): index out of bounds" );
|
||||
|
||||
arrayops::copy( out.colptr(ci_count), m.colptr(col), m_n_rows );
|
||||
}
|
||||
}
|
||||
else
|
||||
if( (in.all_rows == false) && (in.all_cols == true) )
|
||||
{
|
||||
const quasi_unwrap<T1> tmp1(in.base_ri.get_ref());
|
||||
|
||||
const umat& ri = tmp1.M;
|
||||
|
||||
arma_conform_check
|
||||
(
|
||||
( (ri.is_vec() == false) && (ri.is_empty() == false) ),
|
||||
"Mat::elem(): given object must be a vector"
|
||||
);
|
||||
|
||||
const uword* ri_mem = ri.memptr();
|
||||
const uword ri_n_elem = ri.n_elem;
|
||||
|
||||
out.set_size(ri_n_elem, m_n_cols);
|
||||
|
||||
for(uword col=0; col < m_n_cols; ++col)
|
||||
{
|
||||
for(uword ri_count=0; ri_count < ri_n_elem; ++ri_count)
|
||||
{
|
||||
const uword row = ri_mem[ri_count];
|
||||
|
||||
arma_conform_check_bounds( (row >= m_n_rows), "Mat::elem(): index out of bounds" );
|
||||
|
||||
out.at(ri_count,col) = m.at(row,col);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT, typename T1, typename T2>
|
||||
inline
|
||||
void
|
||||
@@ -924,12 +1039,12 @@ subview_elem2<eT,T1,T2>::extract(Mat<eT>& actual_out, const subview_elem2<eT,T1,
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
Mat<eT>& m_local = const_cast< Mat<eT>& >(in.m);
|
||||
const Mat<eT>& m = in.m;
|
||||
|
||||
const uword m_n_rows = m_local.n_rows;
|
||||
const uword m_n_cols = m_local.n_cols;
|
||||
const uword m_n_rows = m.n_rows;
|
||||
const uword m_n_cols = m.n_cols;
|
||||
|
||||
const bool alias = (&actual_out == &m_local);
|
||||
const bool alias = (&actual_out == &m);
|
||||
|
||||
if(alias) { arma_debug_print("subview_elem2::extract(): aliasing detected"); }
|
||||
|
||||
@@ -973,7 +1088,7 @@ subview_elem2<eT,T1,T2>::extract(Mat<eT>& actual_out, const subview_elem2<eT,T1,
|
||||
|
||||
arma_conform_check_bounds( (row >= m_n_rows), "Mat::elem(): index out of bounds" );
|
||||
|
||||
out_mem[out_count] = m_local.at(row,col);
|
||||
out_mem[out_count] = m.at(row,col);
|
||||
++out_count;
|
||||
}
|
||||
}
|
||||
@@ -981,7 +1096,7 @@ subview_elem2<eT,T1,T2>::extract(Mat<eT>& actual_out, const subview_elem2<eT,T1,
|
||||
else
|
||||
if( (in.all_rows == true) && (in.all_cols == false) )
|
||||
{
|
||||
const unwrap_check_mixed<T2> tmp2(in.base_ci.get_ref(), m_local);
|
||||
const unwrap_check_mixed<T2> tmp2(in.base_ci.get_ref(), m);
|
||||
|
||||
const umat& ci = tmp2.M;
|
||||
|
||||
@@ -1002,13 +1117,13 @@ subview_elem2<eT,T1,T2>::extract(Mat<eT>& actual_out, const subview_elem2<eT,T1,
|
||||
|
||||
arma_conform_check_bounds( (col >= m_n_cols), "Mat::elem(): index out of bounds" );
|
||||
|
||||
arrayops::copy( out.colptr(ci_count), m_local.colptr(col), m_n_rows );
|
||||
arrayops::copy( out.colptr(ci_count), m.colptr(col), m_n_rows );
|
||||
}
|
||||
}
|
||||
else
|
||||
if( (in.all_rows == false) && (in.all_cols == true) )
|
||||
{
|
||||
const unwrap_check_mixed<T1> tmp1(in.base_ri.get_ref(), m_local);
|
||||
const unwrap_check_mixed<T1> tmp1(in.base_ri.get_ref(), m);
|
||||
|
||||
const umat& ri = tmp1.M;
|
||||
|
||||
@@ -1031,7 +1146,7 @@ subview_elem2<eT,T1,T2>::extract(Mat<eT>& actual_out, const subview_elem2<eT,T1,
|
||||
|
||||
arma_conform_check_bounds( (row >= m_n_rows), "Mat::elem(): index out of bounds" );
|
||||
|
||||
out.at(ri_count,col) = m_local.at(row,col);
|
||||
out.at(ri_count,col) = m.at(row,col);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -507,24 +507,17 @@ subview_field<oT>::fill(const oT& x)
|
||||
template<typename oT>
|
||||
inline
|
||||
void
|
||||
subview_field<oT>::extract(field<oT>& actual_out, const subview_field<oT>& in)
|
||||
subview_field<oT>::extract(field<oT>& out, const subview_field<oT>& in)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
//
|
||||
const bool alias = (&actual_out == &in.f);
|
||||
|
||||
field<oT>* tmp = (alias) ? new field<oT> : nullptr;
|
||||
field<oT>& out = (alias) ? (*tmp) : actual_out;
|
||||
|
||||
//
|
||||
// NOTE: we're assuming that the field has already been set to the correct size and there is no aliasing;
|
||||
// size setting and alias checking is done by either the field constructor or operator=()
|
||||
|
||||
const uword n_rows = in.n_rows;
|
||||
const uword n_cols = in.n_cols;
|
||||
const uword n_slices = in.n_slices;
|
||||
|
||||
out.set_size(n_rows, n_cols, n_slices);
|
||||
|
||||
arma_debug_print(arma_str::format("out.n_rows: %u; out.n_cols: %u; out.n_slices: %u; in.f.n_rows: %u; in.f.n_cols: %u; in.f.n_slices: %u") % out.n_rows % out.n_cols % out.n_slices % in.f.n_rows % in.f.n_cols % in.f.n_slices);
|
||||
|
||||
if(n_slices == 1)
|
||||
@@ -544,12 +537,6 @@ subview_field<oT>::extract(field<oT>& actual_out, const subview_field<oT>& in)
|
||||
out.at(row,col,slice) = in.at(row,col,slice);
|
||||
}
|
||||
}
|
||||
|
||||
if(alias)
|
||||
{
|
||||
actual_out = out;
|
||||
delete tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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,35 +976,14 @@ 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 == 1)
|
||||
if(s_n_rows == 0) { return; }
|
||||
|
||||
if( (s.aux_row1 == 0) && (s_n_rows == s.m.n_rows) )
|
||||
{
|
||||
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));
|
||||
|
||||
if(arma_isnan(old_val))
|
||||
{
|
||||
for(uword ucol=0; ucol < s_n_cols; ++ucol)
|
||||
{
|
||||
(*Aptr) = (arma_isnan(*Aptr)) ? new_val : (*Aptr);
|
||||
|
||||
Aptr += A_n_rows;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(uword ucol=0; ucol < s_n_cols; ++ucol)
|
||||
{
|
||||
(*Aptr) = ((*Aptr) == old_val) ? new_val : (*Aptr);
|
||||
|
||||
Aptr += A_n_rows;
|
||||
}
|
||||
}
|
||||
arrayops::replace(s.colptr(0), s.n_elem, old_val, new_val);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1018,8 +1005,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)
|
||||
{
|
||||
@@ -1038,18 +1027,20 @@ subview<eT>::clamp(const eT min_val, const eT max_val)
|
||||
|
||||
if(is_cx<eT>::no)
|
||||
{
|
||||
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "subview::clamp(): min_val must be less than max_val" );
|
||||
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "subview::clamp(): min_val must be less than max_val" );
|
||||
}
|
||||
else
|
||||
{
|
||||
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "subview::clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "subview::clamp(): imag(min_val) must be less than imag(max_val)" );
|
||||
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "subview::clamp(): real(min_val) must be less than real(max_val)" );
|
||||
arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "subview::clamp(): imag(min_val) must be less than imag(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,34 +1059,20 @@ 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 == 1)
|
||||
if(s_n_rows == 0) { return; }
|
||||
|
||||
if( (s.aux_row1 == 0) && (s_n_rows == s.m.n_rows) )
|
||||
{
|
||||
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));
|
||||
|
||||
for(uword ii=0; ii < s_n_cols; ++ii)
|
||||
{
|
||||
(*Aptr) = val; Aptr += A_n_rows;
|
||||
}
|
||||
arrayops::inplace_set( s.colptr(0), val, s.n_elem );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (s.aux_row1 == 0) && (s_n_rows == s.m.n_rows) )
|
||||
for(uword ucol=0; ucol < s_n_cols; ++ucol)
|
||||
{
|
||||
arrayops::inplace_set( s.colptr(0), val, s.n_elem );
|
||||
}
|
||||
else
|
||||
{
|
||||
for(uword ucol=0; ucol < s_n_cols; ++ucol)
|
||||
{
|
||||
arrayops::inplace_set( s.colptr(ucol), val, s_n_rows );
|
||||
}
|
||||
arrayops::inplace_set( s.colptr(ucol), val, s_n_rows );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1109,7 +1086,24 @@ 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) { return; }
|
||||
|
||||
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,15 +1151,26 @@ 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)
|
||||
{
|
||||
// NOTE: special handling to ensure that the same sequence is generated as per subview_row::randu()
|
||||
|
||||
podarray<eT> tmp(s_n_cols);
|
||||
|
||||
eT* tmp_mem = tmp.memptr();
|
||||
|
||||
arma_rng::randu<eT>::fill( tmp_mem, s_n_cols );
|
||||
|
||||
for(uword ii=0; ii < s_n_cols; ++ii) { at(0,ii) = tmp_mem[ii]; }
|
||||
eT* mem_ptr = startptr();
|
||||
|
||||
const uword m_n_rows = s.m.n_rows;
|
||||
|
||||
for(uword ii=0; ii < s_n_cols; ++ii)
|
||||
{
|
||||
(*mem_ptr) = tmp_mem[ii]; mem_ptr += m_n_rows;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1197,15 +1202,26 @@ 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)
|
||||
{
|
||||
// NOTE: special handling to ensure that the same sequence is generated as per subview_row::randu()
|
||||
|
||||
podarray<eT> tmp(s_n_cols);
|
||||
|
||||
eT* tmp_mem = tmp.memptr();
|
||||
|
||||
arma_rng::randn<eT>::fill( tmp_mem, s_n_cols );
|
||||
|
||||
for(uword ii=0; ii < s_n_cols; ++ii) { at(0,ii) = tmp_mem[ii]; }
|
||||
eT* mem_ptr = startptr();
|
||||
|
||||
const uword m_n_rows = s.m.n_rows;
|
||||
|
||||
for(uword ii=0; ii < s_n_cols; ++ii)
|
||||
{
|
||||
(*mem_ptr) = tmp_mem[ii]; mem_ptr += m_n_rows;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1410,7 +1426,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 +1436,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 +1519,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;
|
||||
@@ -1500,10 +1539,16 @@ subview<eT>::is_zero(const typename get_pod_type<eT>::result tol) const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
typedef typename get_pod_type<eT>::result T;
|
||||
|
||||
arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" );
|
||||
|
||||
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) || (local_n_cols == 0) ) { return false; }
|
||||
|
||||
for(uword ii=0; ii < local_n_cols; ++ii)
|
||||
{
|
||||
if(arrayops::is_zero(colptr(ii), local_n_rows, tol) == false) { return false; }
|
||||
}
|
||||
@@ -1525,9 +1570,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 +1595,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 +1620,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 +1644,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 +1722,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 +1772,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 +1822,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 +1872,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 +2441,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 +2460,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 +2480,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 +2507,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 +2516,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 +2535,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 +2563,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 +3340,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 +3351,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();
|
||||
}
|
||||
@@ -3455,6 +3531,18 @@ subview_col<eT>::as_row() const
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
subview_col<eT>::replace(const eT old_val, const eT new_val)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
arrayops::replace( access::rwp(colmem), subview<eT>::n_rows, old_val, new_val );
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
@@ -3491,6 +3579,30 @@ subview_col<eT>::ones()
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
subview_col<eT>::randu()
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
arma_rng::randu<eT>::fill( access::rwp(colmem), subview<eT>::n_rows );
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
subview_col<eT>::randn()
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
arma_rng::randn<eT>::fill( access::rwp(colmem), subview<eT>::n_rows );
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
@@ -3505,6 +3617,22 @@ subview_col<eT>::is_finite() const
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
subview_col<eT>::is_zero(const typename get_pod_type<eT>::result tol) const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
typedef typename get_pod_type<eT>::result T;
|
||||
|
||||
arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" );
|
||||
|
||||
return arrayops::is_zero(colmem, subview<eT>::n_rows, tol);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
@@ -4268,7 +4396,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 +4407,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();
|
||||
}
|
||||
@@ -4486,6 +4614,40 @@ subview_row<eT>::as_col() const
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
subview_row<eT>::replace(const eT old_val, const eT new_val)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
eT* mem_ptr = access::rwp(rowmem);
|
||||
|
||||
const uword local_s_n_cols = subview<eT>::n_cols;
|
||||
const uword local_m_n_rows = subview<eT>::m.n_rows;
|
||||
|
||||
if(arma_isnan(old_val))
|
||||
{
|
||||
for(uword ii=0; ii < local_s_n_cols; ++ii)
|
||||
{
|
||||
eT& val = (*mem_ptr); mem_ptr += local_m_n_rows;
|
||||
|
||||
val = (arma_isnan(val)) ? new_val : val;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(uword ii=0; ii < local_s_n_cols; ++ii)
|
||||
{
|
||||
eT& val = (*mem_ptr); mem_ptr += local_m_n_rows;
|
||||
|
||||
val = (val == old_val) ? new_val : val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
@@ -4530,6 +4692,58 @@ subview_row<eT>::ones()
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
subview_row<eT>::randu()
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
const uword local_s_n_cols = subview<eT>::n_cols;
|
||||
const uword local_m_n_rows = subview<eT>::m.n_rows;
|
||||
|
||||
podarray<eT> tmp(local_s_n_cols);
|
||||
|
||||
eT* tmp_mem = tmp.memptr();
|
||||
|
||||
arma_rng::randu<eT>::fill( tmp_mem, local_s_n_cols );
|
||||
|
||||
eT* mem_ptr = access::rwp(rowmem);
|
||||
|
||||
for(uword ii=0; ii < local_s_n_cols; ++ii)
|
||||
{
|
||||
(*mem_ptr) = tmp_mem[ii]; mem_ptr += local_m_n_rows;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
subview_row<eT>::randn()
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
const uword local_s_n_cols = subview<eT>::n_cols;
|
||||
const uword local_m_n_rows = subview<eT>::m.n_rows;
|
||||
|
||||
podarray<eT> tmp(local_s_n_cols);
|
||||
|
||||
eT* tmp_mem = tmp.memptr();
|
||||
|
||||
arma_rng::randn<eT>::fill( tmp_mem, local_s_n_cols );
|
||||
|
||||
eT* mem_ptr = access::rwp(rowmem);
|
||||
|
||||
for(uword ii=0; ii < local_s_n_cols; ++ii)
|
||||
{
|
||||
(*mem_ptr) = tmp_mem[ii]; mem_ptr += local_m_n_rows;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
@@ -4556,6 +4770,80 @@ subview_row<eT>::is_finite() const
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
subview_row<eT>::is_zero(const typename get_pod_type<eT>::result tol) const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
typedef typename get_pod_type<eT>::result T;
|
||||
|
||||
arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" );
|
||||
|
||||
const uword local_s_n_cols = subview<eT>::n_cols;
|
||||
const uword local_m_n_rows = subview<eT>::m.n_rows;
|
||||
|
||||
if(local_s_n_cols == 0) { return false; }
|
||||
|
||||
const eT* mem_ptr = rowmem;
|
||||
|
||||
if(is_cx<eT>::yes)
|
||||
{
|
||||
if(tol == T(0))
|
||||
{
|
||||
for(uword ii=0; ii < local_s_n_cols; ++ii)
|
||||
{
|
||||
const eT& val = (*mem_ptr); mem_ptr += local_m_n_rows;
|
||||
|
||||
const T val_real = access::tmp_real(val);
|
||||
const T val_imag = access::tmp_imag(val);
|
||||
|
||||
if(eop_aux::arma_abs(val_real) != T(0)) { return false; }
|
||||
if(eop_aux::arma_abs(val_imag) != T(0)) { return false; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(uword ii=0; ii < local_s_n_cols; ++ii)
|
||||
{
|
||||
const eT& val = (*mem_ptr); mem_ptr += local_m_n_rows;
|
||||
|
||||
const T val_real = access::tmp_real(val);
|
||||
const T val_imag = access::tmp_imag(val);
|
||||
|
||||
if( (eop_aux::arma_abs(val_real) <= tol) == false ) { return false; }
|
||||
if( (eop_aux::arma_abs(val_imag) <= tol) == false ) { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
else // not complex
|
||||
{
|
||||
if(tol == T(0))
|
||||
{
|
||||
for(uword ii=0; ii < local_s_n_cols; ++ii)
|
||||
{
|
||||
const eT val = (*mem_ptr); mem_ptr += local_m_n_rows;
|
||||
|
||||
if(val != eT(0)) { return false; }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(uword ii=0; ii < local_s_n_cols; ++ii)
|
||||
{
|
||||
const eT val = (*mem_ptr); mem_ptr += local_m_n_rows;
|
||||
|
||||
if( (eop_aux::arma_abs(val) <= tol) == false ) { return false; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
#else
|
||||
#if UCHAR_MAX >= 0xff
|
||||
typedef unsigned char u8;
|
||||
typedef char s8;
|
||||
typedef char s8; // kept for compatibility with earlier versions of Armadillo
|
||||
#elif defined(UINT8_MAX)
|
||||
typedef uint8_t u8;
|
||||
typedef int8_t s8;
|
||||
|
||||
@@ -38,6 +38,9 @@ struct unwrap_default
|
||||
}
|
||||
|
||||
const Mat<eT> M;
|
||||
|
||||
template<typename eT2>
|
||||
constexpr bool is_alias(const Mat<eT2>&) const { return false; }
|
||||
};
|
||||
|
||||
|
||||
@@ -55,6 +58,9 @@ struct unwrap_fixed
|
||||
}
|
||||
|
||||
const T1& M;
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return (void_ptr(&M) == void_ptr(&X)); }
|
||||
};
|
||||
|
||||
|
||||
@@ -94,6 +100,9 @@ struct unwrap< Mat<eT> >
|
||||
}
|
||||
|
||||
const Mat<eT>& M;
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return (is_same_type<eT,eT2>::yes) && (void_ptr(&M) == void_ptr(&X)); }
|
||||
};
|
||||
|
||||
|
||||
@@ -111,6 +120,9 @@ struct unwrap< Row<eT> >
|
||||
}
|
||||
|
||||
const Row<eT>& M;
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return (is_same_type<eT,eT2>::yes) && (void_ptr(&M) == void_ptr(&X)); }
|
||||
};
|
||||
|
||||
|
||||
@@ -128,6 +140,9 @@ struct unwrap< Col<eT> >
|
||||
}
|
||||
|
||||
const Col<eT>& M;
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return (is_same_type<eT,eT2>::yes) && (void_ptr(&M) == void_ptr(&X)); }
|
||||
};
|
||||
|
||||
|
||||
@@ -145,6 +160,9 @@ struct unwrap< subview_col<eT> >
|
||||
}
|
||||
|
||||
const Col<eT> M;
|
||||
|
||||
template<typename eT2>
|
||||
constexpr bool is_alias(const Mat<eT2>&) const { return false; }
|
||||
};
|
||||
|
||||
|
||||
@@ -162,6 +180,9 @@ struct unwrap< subview_cols<eT> >
|
||||
}
|
||||
|
||||
const Mat<eT> M;
|
||||
|
||||
template<typename eT2>
|
||||
constexpr bool is_alias(const Mat<eT2>&) const { return false; }
|
||||
};
|
||||
|
||||
|
||||
@@ -179,6 +200,9 @@ struct unwrap< mtGlue<out_eT, T1, T2, glue_type> >
|
||||
}
|
||||
|
||||
const Mat<out_eT> M;
|
||||
|
||||
template<typename eT2>
|
||||
constexpr bool is_alias(const Mat<eT2>&) const { return false; }
|
||||
};
|
||||
|
||||
|
||||
@@ -196,6 +220,9 @@ struct unwrap< mtOp<out_eT, T1, op_type> >
|
||||
}
|
||||
|
||||
const Mat<out_eT> M;
|
||||
|
||||
template<typename eT2>
|
||||
constexpr bool is_alias(const Mat<eT2>&) const { return false; }
|
||||
};
|
||||
|
||||
|
||||
@@ -311,7 +338,6 @@ struct quasi_unwrap< Mat<eT> >
|
||||
template<typename eT>
|
||||
struct quasi_unwrap< Row<eT> >
|
||||
{
|
||||
|
||||
inline
|
||||
quasi_unwrap(const Row<eT>& A)
|
||||
: M(A)
|
||||
|
||||
Reference in New Issue
Block a user