Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ab1eaba0d3 | ||
|
|
58832a44ea | ||
|
|
45f0ea0f6f | ||
|
|
0a37f157a4 | ||
|
|
3dcae8d83e | ||
|
|
78f090f132 | ||
|
|
6c060b9d89 | ||
|
|
053f0d3133 | ||
|
|
c60cf9ec1a | ||
|
|
eb338e8ed7 | ||
|
|
3a23ca275b | ||
|
|
d20277d147 | ||
|
|
269ebbad54 | ||
|
|
942a1941bd | ||
|
|
e6925c658a | ||
|
|
e9b732faa5 | ||
|
|
adb1dc90c8 | ||
|
|
b339eaa4e7 | ||
|
|
024ac3b8f2 | ||
|
|
6438a10480 | ||
|
|
39c28be90a | ||
|
|
fdd93b5f40 | ||
|
|
794812af6d | ||
|
|
2656ea3dcf | ||
|
|
9264eef882 | ||
|
|
5c5ccac350 | ||
|
|
053907dc1f | ||
|
|
287f80244b | ||
|
|
c8ea9a0fd3 | ||
|
|
871c689ed9 | ||
|
|
a676522ba5 | ||
|
|
a313b4fd0c | ||
|
|
85233ddbe7 | ||
|
|
b6e9484b31 | ||
|
|
a18a68289b | ||
|
|
b3f4e55604 | ||
|
|
702eb6c68b | ||
|
|
0bdd169d38 | ||
|
|
79f57ff784 | ||
|
|
a3bc2bc599 | ||
|
|
2cdd3feebb | ||
|
|
ca70fdfba3 | ||
|
|
9608d14058 | ||
|
|
112861df8b | ||
|
|
15232980d3 | ||
|
|
6058b46519 | ||
|
|
0b07572a24 | ||
|
|
bb819ee649 | ||
|
|
ee965fc4b7 | ||
|
|
a7c16f40df | ||
|
|
e83cea1b48 | ||
|
|
dbca4d6631 | ||
|
|
8cdca5cbe9 | ||
|
|
121b0a744a | ||
|
|
4ec712dcc6 | ||
|
|
e6bfb6941d | ||
|
|
d2bdd90982 | ||
|
|
59a24f45f2 | ||
|
|
ef011e704b | ||
|
|
943fe56b61 | ||
|
|
670ca673f8 | ||
|
|
265e66f43e | ||
|
|
baf9ab7970 | ||
|
|
dd5e73ae20 | ||
|
|
5d1ceb6aa9 | ||
|
|
acc8680aa8 | ||
|
|
8cb75d0ac5 | ||
|
|
77fccf7db1 | ||
|
|
18a2a42061 | ||
|
|
b2f8023392 | ||
|
|
bcc950cb9e | ||
|
|
5c313e8a6d | ||
|
|
d13194f8e8 | ||
|
|
437c7299b9 | ||
|
|
b744b74533 | ||
|
|
f22d60c74f | ||
|
|
44e1beabce | ||
|
|
f003381651 | ||
|
|
538ae305bf | ||
|
|
d00fc06c06 | ||
|
|
8650784ac7 | ||
|
|
f0acfbbf63 | ||
|
|
da8ea7ea20 | ||
|
|
d484a3d7ad | ||
|
|
978d7d6e76 | ||
|
|
65eefbfce6 | ||
|
|
6e469f1d38 | ||
|
|
3280fd41ae | ||
|
|
97f85611c1 | ||
|
|
7b38cfca6e | ||
|
|
30122e7adf | ||
|
|
0481314430 | ||
|
|
ef7fec1385 | ||
|
|
42623aff06 | ||
|
|
3165f618ed | ||
|
|
93a652c50c | ||
|
|
f506e86466 | ||
|
|
c7053e8c23 | ||
|
|
95a8229587 | ||
|
|
4b3fdadd7f | ||
|
|
7ce8e17e99 | ||
|
|
25d5285cbd | ||
|
|
53806daa3f | ||
|
|
bcca9da94d | ||
|
|
6da76d1019 | ||
|
|
cb73277ec7 | ||
|
|
6d15ecca58 | ||
|
|
e701de5738 | ||
|
|
b4e2b8de7c | ||
|
|
b0ff7506b0 | ||
|
|
1bf38c114d | ||
|
|
96e98edec9 | ||
|
|
6e838ef11c | ||
|
|
55059a4e30 | ||
|
|
98c7800566 | ||
|
|
0e5978f981 | ||
|
|
b52dae4657 | ||
|
|
1b037556da | ||
|
|
6a1c5d7ff3 | ||
|
|
ce4d54c82b | ||
|
|
bca1545ae3 | ||
|
|
b908470f3b | ||
|
|
7c75e9e594 | ||
|
|
55c30cbc73 | ||
|
|
d56115ef45 | ||
|
|
c7f1711d6c | ||
|
|
e280d25c9a | ||
|
|
27f4297396 | ||
|
|
5eabafe2b3 | ||
|
|
ed1ec45817 | ||
|
|
901c5c3d0c | ||
|
|
19292dff3a | ||
|
|
53f8e0664f | ||
|
|
d66e799b5c | ||
|
|
053d5a5787 | ||
|
|
cb3203f130 | ||
|
|
44411aadee | ||
|
|
c953e836e7 |
@@ -303,7 +303,7 @@ the active solution platform must be set to x64, instead of win32.
|
||||
|
||||
The MSVC project was tested on Windows 10 (64 bit) with Visual Studio C++ 2019.
|
||||
Adaptations may be required for 32 bit systems, later versions of Windows and/or the compiler.
|
||||
For example, options such as `ARMA_BLAS_LONG` and `ARMA_BLAS_UNDERSCORE`,
|
||||
For example, options such as `ARMA_BLAS_LONG_LONG` and `ARMA_BLAS_UNDERSCORE`,
|
||||
defined in `include/armadillo_bits/config.hpp`, may need to be either enabled or disabled.
|
||||
|
||||
The folder `examples/lib_win64` contains a copy of lib and dll files
|
||||
@@ -333,29 +333,28 @@ as used by the replacement libraries. Specifically, the following defines
|
||||
may need to be enabled or disabled:
|
||||
|
||||
ARMA_USE_WRAPPER
|
||||
ARMA_BLAS_CAPITALS
|
||||
ARMA_BLAS_UNDERSCORE
|
||||
ARMA_BLAS_LONG
|
||||
ARMA_BLAS_LONG_LONG
|
||||
ARMA_DONT_USE_FORTRAN_HIDDEN_ARGS
|
||||
ARMA_BLAS_UNDERSCORE
|
||||
ARMA_BLAS_CAPITALS
|
||||
|
||||
See the documentation for more information on the above defines.
|
||||
|
||||
On Linux-based systems, MKL might be installed in a non-standard location such as `/opt`
|
||||
which can cause problems during linking.
|
||||
Before installing Armadillo, the system should know where the MKL libraries are located.
|
||||
For example, `/opt/intel/mkl/lib/intel64/`.
|
||||
This can be achieved by setting the `LD_LIBRARY_PATH` environment variable,
|
||||
or for a more permanent solution, adding the directory locations to `/etc/ld.so.conf`.
|
||||
It may also be possible to store a text file with the locations
|
||||
in the `/etc/ld.so.conf.d` directory. For example, `/etc/ld.so.conf.d/mkl.conf`.
|
||||
If `/etc/ld.so.conf` is modified or `/etc/ld.so.conf.d/mkl.conf` is created,
|
||||
`/sbin/ldconfig` must be run afterwards.
|
||||
Examples: `/opt/intel/oneapi/mkl/latest/lib`, `/opt/intel/mkl/lib/intel64/`.
|
||||
|
||||
Below is an example of `/etc/ld.so.conf.d/mkl.conf`
|
||||
where Intel MKL is installed in `/opt/intel`
|
||||
Before installing Armadillo, the system must know where the MKL libraries are located.
|
||||
This can be achieved via several ways:
|
||||
|
||||
/opt/intel/lib/intel64
|
||||
/opt/intel/mkl/lib/intel64
|
||||
1. By setting the `LD_LIBRARY_PATH` environment variable.
|
||||
|
||||
2. By adding the MKL library directory locations to the `/etc/ld.so.conf` text file,
|
||||
followed by running `/sbin/ldconfig`.
|
||||
|
||||
3. By creating a text file named `/etc/ld.so.conf.d/mkl.conf`
|
||||
which contains the MKL library directory locations,
|
||||
followed by running `/sbin/ldconfig`.
|
||||
|
||||
If MKL is installed and it is persistently giving problems during linking,
|
||||
Support for MKL can be disabled by editing the CMakeLists.txt file,
|
||||
@@ -461,12 +460,12 @@ Octave/Matlab with C++ code that uses Armadillo matrices.
|
||||
|
||||
### 16: Related Software Using Armadillo
|
||||
|
||||
* ensmallen: C++ library for non-linear numerical optimisation (L-BFGS, SGD, CMA-ES, etc)
|
||||
https://ensmallen.org/
|
||||
|
||||
* MLPACK: extensive library of machine learning algorithms
|
||||
https://mlpack.org
|
||||
|
||||
* ensmallen: C++ library for numerical optimisation (L-BFGS, SGD, CMA-ES, etc)
|
||||
https://ensmallen.org/
|
||||
|
||||
* RcppArmadillo: integration of Armadillo with R
|
||||
https://dirk.eddelbuettel.com/code/rcpp.armadillo.html
|
||||
|
||||
|
||||
@@ -115,6 +115,9 @@ foreach (MKL_NAME ${MKL_NAMES})
|
||||
/usr/local/mkl/*/lib/em64t
|
||||
/usr/local/mkl/*/lib/lib64
|
||||
/usr/local/mkl/*/lib/32
|
||||
/usr/local/intel/oneapi/mkl/latest/lib
|
||||
/opt/intel/oneapi/mkl/latest/lib
|
||||
/opt/intel/oneapi/mkl/*/lib
|
||||
)
|
||||
|
||||
set(TMP_LIBRARY ${${MKL_NAME}_LIBRARY})
|
||||
|
||||
@@ -150,7 +150,7 @@ hr.greyline
|
||||
<a class="noprint" style="display:scroll; position:fixed; bottom:5px; right:5px;" href="#top"><font size=-1>[top]</font></a>
|
||||
|
||||
<a name="top"></a>
|
||||
<big><b>API Documentation for Armadillo 14.0</b></big>
|
||||
<big><b>API Documentation for Armadillo 14.2</b></big>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
@@ -543,7 +543,7 @@ Conrad Sanderson and Ryan Curtin.
|
||||
<tr style="background-color: #F5F5F5;"><td><a href="#running_stat">running_stat</a></td><td> </td><td>running statistics of scalars (one dimensional process/signal)</td></tr>
|
||||
<tr style="background-color: #F5F5F5;"><td><a href="#running_stat_vec">running_stat_vec</a></td><td> </td><td>running statistics of vectors (multi-dimensional process/signal)</td></tr>
|
||||
<tr><td><a href="#kmeans">kmeans</a></td><td> </td><td>cluster data into disjoint sets</td></tr>
|
||||
<tr><td><a href="#gmm_diag">gmm_diag/gmm_full</a></td><td> </td><td>probabilistic clustering and likelihood calculation via Gaussian mixture models</td></tr>
|
||||
<tr><td><a href="#gmm_diag">gmm_diag/gmm_full</a></td><td> </td><td>probabilistic clustering and likelihood calculation via mixture of Gaussians</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</ul>
|
||||
@@ -4218,7 +4218,6 @@ See also:
|
||||
<li><a href="#submat">submatrix views</a></li>
|
||||
<li><a href="#diag">diagonal views</a></li>
|
||||
<li><a href="#repmat">repmat()</a></li>
|
||||
<li><a href="#pow">pow()</a></li>
|
||||
<li><a href="#for_each">.for_each()</a></li>
|
||||
<li><a href="#each_slice">.each_slice()</a></li>
|
||||
</ul>
|
||||
@@ -4323,7 +4322,6 @@ See also:
|
||||
<ul>
|
||||
<li><a href="#operators">math & relational operators</a></li>
|
||||
<li><a href="#subcube">subcube views</a></li>
|
||||
<li><a href="#pow">pow()</a></li>
|
||||
<li><a href="#for_each">.for_each()</a></li>
|
||||
<li><a href="#each_colrow">.each_col() & .each_row()</a> </li>
|
||||
<li><a href="https://www.cprogramming.com/c++11/c++11-lambda-closures.html">lambda function</a> at cprogramming.com</li>
|
||||
@@ -8212,18 +8210,13 @@ sp_mat A = sprandu<sp_mat>(100, 200, 0.1);
|
||||
<a name="toeplitz"></a>
|
||||
<b>toeplitz( A )</b>
|
||||
<br><b>toeplitz( A, B )</b>
|
||||
<br><b>circ_toeplitz( A )</b>
|
||||
<ul>
|
||||
<li>
|
||||
toeplitz(): generate a Toeplitz matrix, with the first column specified by <i>A</i>, and (optionally) the first row specified by <i>B</i>
|
||||
Generate a Toeplitz matrix, with the first column specified by vector <i>A</i>, and (optionally) the first row specified by vector <i>B</i>
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
circ_toeplitz(): generate a circulant Toeplitz matrix
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
A and B must be vectors
|
||||
If argument <i>B</i> is omitted, the first row is assumed to be the same as the first column
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
@@ -8231,8 +8224,8 @@ Examples:
|
||||
<ul>
|
||||
<pre>
|
||||
vec A(5, fill::randu);
|
||||
|
||||
mat X = toeplitz(A);
|
||||
mat Y = circ_toeplitz(A);
|
||||
</pre>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -8241,7 +8234,6 @@ mat Y = circ_toeplitz(A);
|
||||
<ul>
|
||||
<li><a href="https://mathworld.wolfram.com/ToeplitzMatrix.html">Toeplitz matrix in MathWorld</a></li>
|
||||
<li><a href="https://en.wikipedia.org/wiki/Toeplitz_matrix">Toeplitz matrix in Wikipedia</a></li>
|
||||
<li><a href="https://en.wikipedia.org/wiki/Circulant_matrix">Circulant matrix in Wikipedia</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
@@ -10757,9 +10749,11 @@ 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>
|
||||
@@ -10767,9 +10761,9 @@ See also:
|
||||
<br>
|
||||
<li>form 1: raise all elements in <i>A</i> to the power denoted by the given scalar</li>
|
||||
<br>
|
||||
<li>form 2: raise each element in <i>A</i> to the power denoted by the corresponding element in <i>B</i>;
|
||||
<br>the sizes of <i>A</i> and <i>B</i> must be the same</li>
|
||||
<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>
|
||||
@@ -10779,6 +10773,7 @@ See also:
|
||||
<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>
|
||||
@@ -10794,13 +10789,14 @@ 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);
|
||||
</pre>
|
||||
-->
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
@@ -10808,10 +10804,11 @@ mat Z2 = pow(A.each_row(), R);
|
||||
See also:
|
||||
<ul>
|
||||
<li><a href="#powmat">powmat()</a></li>
|
||||
<li><a href="#abs">abs()</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>
|
||||
@@ -12608,7 +12605,7 @@ For single argument functions, <i>B = trig_fn(A)</i>, where <i>trig_fn</i> is ap
|
||||
<i>tan</i>, <i>atan</i>, <i>tanh</i>, <i>atanh</i>
|
||||
</li>
|
||||
<li>
|
||||
<i>sinc</i>, defined as sinc(x) = sin(πx) / (πx) for x ≠ 0, and sinc(x) = 1 for x = 0
|
||||
<i>sinc</i>, defined as sinc(x) = sin(π·x) / (π·x) for x ≠ 0, and sinc(x) = 1 for x = 0
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -13741,7 +13738,7 @@ The number of rows in <i>A</i> and <i>B</i> must be the same
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
By default, matrix <i>A</i> is analysed to automatically determine whether it is a general matrix, band matrix, diagonal matrix, or symmetric/hermitian positive definite (SPD) matrix;
|
||||
By default, matrix <i>A</i> is analysed to automatically determine whether it is a general matrix, band matrix, diagonal matrix, or symmetric/hermitian positive definite (sympd) matrix;
|
||||
based on the detected matrix structure, a specialised solver is used for faster execution;
|
||||
if no solution is found, an approximate solver is automatically used as a fallback;
|
||||
see the <a href="armadillo_solver_2020.pdf">associated paper</a> for more details
|
||||
@@ -13760,13 +13757,16 @@ the solution can be computed faster by explicitly indicating that <i>A</i> is tr
|
||||
<tr><td><code>solve_opts::fast</code></td><td> </td><td>fast mode: disable determining solution quality via rcond, disable iterative refinement, disable equilibration</td></tr>
|
||||
<tr><td><code>solve_opts::refine</code></td><td> </td><td>apply iterative refinement to improve solution quality (matrix <i>A</i> must be square)</td></tr>
|
||||
<tr><td><code>solve_opts::equilibrate</code></td><td> </td><td>equilibrate the system before solving (matrix <i>A</i> must be square)</td></tr>
|
||||
<tr><td><code>solve_opts::likely_sympd</code></td><td> </td><td>indicate that matrix <i>A</i> is likely symmetric/hermitian positive definite</td></tr>
|
||||
<tr><td><code>solve_opts::likely_sympd</code></td><td> </td><td>indicate that matrix <i>A</i> is likely symmetric/hermitian positive definite (sympd)</td></tr>
|
||||
<tr><td><code>solve_opts::allow_ugly</code></td><td> </td><td>keep solutions of systems that are singular to working precision</td></tr>
|
||||
<tr><td><code>solve_opts::no_approx</code></td><td> </td><td>do not find approximate solutions for rank deficient systems</td></tr>
|
||||
<!--
|
||||
<tr><td><code>solve_opts::no_band</code></td><td> </td><td>do not use specialised solver for band matrices or diagonal matrices</td></tr>
|
||||
<tr><td><code>solve_opts::no_trimat</code></td><td> </td><td>do not use specialised solver for triangular matrices</td></tr>
|
||||
<tr><td><code>solve_opts::no_sympd</code></td><td> </td><td>do not use specialised solver for symmetric/hermitian positive definite matrices</td></tr>
|
||||
<tr><td><code>solve_opts::force_approx</code></td><td> </td><td>skip the standard solver and directly use of the approximate solver</td></tr>
|
||||
-->
|
||||
<tr><td><code>solve_opts::force_sym</code></td><td> </td><td>force use of the symmetric/hermitian solver (not limited to sympd matrices)</td></tr>
|
||||
<tr><td><code>solve_opts::force_approx</code></td><td> </td><td>force use of the approximate solver</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
@@ -13774,7 +13774,7 @@ the above settings can be combined using the <code>+</code> operator; for exampl
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
If a rank deficient system is detected and the <i><code>solve_opts::no_approx</code></i> option is <b>not</b> enabled, a warning is emitted and an approximate solution is attempted;
|
||||
If a rank deficient system is detected and the <code>solve_opts::no_approx</code> option is <b>not</b> enabled, a warning is emitted and an approximate solution is attempted;
|
||||
<br>since Armadillo 10.4, this warning can be disabled by setting <a href="#config_hpp">ARMA_WARN_LEVEL</a> to 1 before including the armadillo header:
|
||||
<br><code>#define ARMA_WARN_LEVEL 1</code>
|
||||
<br><code>#include <armadillo></code>
|
||||
@@ -13783,9 +13783,9 @@ If a rank deficient system is detected and the <i><code>solve_opts::no_approx</c
|
||||
<li>
|
||||
<b>Caveats:</b>
|
||||
<ul>
|
||||
<li>using <i><code>solve_opts::fast</code></i> will speed up finding the solution, but for poorly conditioned systems the solution may have lower quality</li>
|
||||
<li>not all SPD matrices are automatically detected; to skip the analysis step and directly indicate that matrix <i>A</i> is likely SPD, use <code>solve_opts::likely_sympd</code></li>
|
||||
<li>using <i><code>solve_opts::force_approx</code></i> is only advised if the system is known to be rank deficient; the approximate solver is considerably slower</li>
|
||||
<li>using <code>solve_opts::fast</code> will speed up finding the solution, but for poorly conditioned systems the solution may have lower quality</li>
|
||||
<li>not all sympd matrices are automatically detected; to directly indicate that matrix <i>A</i> is likely sympd, use <code>solve_opts::likely_sympd</code></li>
|
||||
<li>using <code>solve_opts::force_approx</code> is only advised if the system is known to be rank deficient; the approximate solver is considerably slower</li>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
@@ -15359,8 +15359,8 @@ For the <i>var()</i> and <i>stddev()</i> functions:
|
||||
<br>
|
||||
<li>
|
||||
<b>Caveat:</b>
|
||||
to obtain statistics for integer matrices/vectors (eg. <a href="#Mat">umat</a>, <a href="#Mat">imat</a>, <a href="#Col">uvec</a>, <a href="#Col">ivec</a>),
|
||||
convert to a matrix/vector with floating point values (eg. <a href="#Mat">mat</a>, <a href="#Col">vec</a>) using the <a href="#conv_to">conv_to()</a> function
|
||||
to obtain statistics for an integer vector or matrix (eg. <a href="#Col">uvec</a>, <a href="#Col">ivec</a>),
|
||||
first use the <a href="#conv_to">conv_to()</a> function to obtain a floating point representation (eg. <a href="#Col">vec</a>)
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
@@ -15375,6 +15375,9 @@ double m = mean(mean(A));
|
||||
|
||||
vec v(5, fill::randu);
|
||||
double x = var(v);
|
||||
|
||||
ivec w = {1, 2, 3, 4}; // integer vector
|
||||
double y = mean( conv_to<vec>::from(w) );
|
||||
</pre>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -19116,7 +19119,7 @@ Armadillo extensively uses template meta-programming,
|
||||
so it's recommended to enable optimisation when compiling programs (eg. use the -O2 or -O3 options for GCC or clang)
|
||||
</li>
|
||||
<br>
|
||||
<li>See the <a href="http://arma.sourceforge.net/faq.html">Questions</a> page for more info on compiling and linking</li>
|
||||
<li>See the <a href="https://arma.sourceforge.net/faq.html">Questions</a> page for more info on compiling and linking</li>
|
||||
<br>
|
||||
<li>See also the example program that comes with the Armadillo archive</li>
|
||||
</ul>
|
||||
@@ -19149,7 +19152,7 @@ Some options can also be specified by explicitly defining them <b>before</b> inc
|
||||
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Disable going through the run-time Armadillo wrapper library (<i>libarmadillo.so</i>) when calling LAPACK, BLAS, ARPACK, SuperLU and HDF5 functions.
|
||||
Disable going through the run-time Armadillo wrapper library (<i>libarmadillo.so</i>) when calling LAPACK, BLAS, ARPACK, and SuperLU functions.
|
||||
You will need to directly link with BLAS, LAPACK, etc (eg. <code><i>-lblas -llapack</i></code>)
|
||||
</td>
|
||||
</tr>
|
||||
@@ -19694,35 +19697,14 @@ Append an underscore to BLAS and LAPACK function names (eg. dgemm_ vs dgemm). En
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;">
|
||||
<code>ARMA_BLAS_LONG</code>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Use "long" instead of "int" when calling BLAS and LAPACK functions
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;">
|
||||
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;">
|
||||
<!-- <code>ARMA_BLAS_64BIT_INT</code> -->
|
||||
<code>ARMA_BLAS_LONG_LONG</code>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Use "long long" instead of "int" when calling BLAS and LAPACK functions
|
||||
Use "long long" instead of "int" when calling BLAS and LAPACK functions; the "long long" type is a 64 bit integer type on all platforms
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -19837,7 +19819,7 @@ Use Intel MKL <i>mkl_malloc()</i> and <i>mkl_free()</i> instead of standard <i>m
|
||||
Use Intel MKL types for complex numbers.
|
||||
You will need to include appropriate MKL headers before the Armadillo header.
|
||||
You may also need to enable one or more of the following options:
|
||||
<code>ARMA_BLAS_LONG</code>, <code>ARMA_BLAS_LONG_LONG</code>, <code>ARMA_DONT_USE_FORTRAN_HIDDEN_ARGS</code>
|
||||
<code>ARMA_BLAS_LONG_LONG</code>, <code>ARMA_DONT_USE_FORTRAN_HIDDEN_ARGS</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -19860,10 +19842,12 @@ You may also need to enable one or more of the following options:
|
||||
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Use 64 bit integers. Automatically enabled when using a 64-bit platform, except when using Armadillo in the R environment (via RcppArmadillo).
|
||||
Use 64 bit integers for matrix and vector sizes.
|
||||
Automatically enabled when using a 64-bit platform, except when using Armadillo in the R environment (via RcppArmadillo).
|
||||
Useful if matrices/vectors capable of holding more than 4 billion elements are required.
|
||||
<!-- Your machine and compiler must have support for 64 bit integers (eg. via "long" or "long long"). -->
|
||||
This can also be enabled by adding <i>#define ARMA_64BIT_WORD</i> before each instance of <i>#include <armadillo></i>
|
||||
This can also be enabled by adding <code>#define ARMA_64BIT_WORD</code> before each instance of <code>#include <armadillo></code>.
|
||||
<br>See also the <code>ARMA_BLAS_LONG_LONG</code> option.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -20140,6 +20124,16 @@ List of additions and changes for each version:
|
||||
|
||||
|
||||
|
||||
<a name="version_142"></a>
|
||||
<li>Version 14.2:
|
||||
<ul>
|
||||
<li>faster handling of symmetric matrices by <a href="#inv">inv()</a>, <a href="#rcond">rcond()</a>, <a href="#powmat">powmat()</a></li>
|
||||
<li>faster handling of hermitian matrices by <a href="#inv">inv()</a>, <a href="#rcond">rcond()</a>, <a href="#powmat">powmat()</a>, <a href="#cond">cond()</a>, <a href="#pinv">pinv()</a>, <a href="#rank">rank()</a></li>
|
||||
<li>added <code>solve_opts::force_sym</code> option to <a href="#solve">solve()</a> to force use of the symmetric/hermitian solver (not limited to sympd matrices)</li>
|
||||
<li>more efficient handling of compound expressions by <a href="#solve">solve()</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
<a name="version_140"></a>
|
||||
<li>Version 14.0
|
||||
<ul>
|
||||
@@ -20210,7 +20204,7 @@ List of additions and changes for each version:
|
||||
<a name="version_114"></a>
|
||||
<li>Version 11.4:
|
||||
<ul>
|
||||
<li>extended <a href="#pow">pow()</a> with various forms of element-wise power operations</li>
|
||||
<li>extended <a href="#pow">pow()</a> with secondary element-wise form</li>
|
||||
<li>added <a href="#find_nan">find_nan()</a> to find indices of NaN elements</li>
|
||||
<li>faster handling of compound expressions by <a href="#sum">sum()</a></li>
|
||||
</ul>
|
||||
@@ -20587,7 +20581,7 @@ this requires a C++11/C++14 compiler with OpenMP 3.1+ support
|
||||
<ul>
|
||||
<li>
|
||||
changed license to the permissive <a href="https://opensource.org/licenses/Apache-2.0">Apache License 2.0</a>;
|
||||
see the <a href="http://arma.sourceforge.net/faq.html#license">Questions page</a> for more info
|
||||
see the <a href="https://arma.sourceforge.net/faq.html#license">Questions page</a> for more info
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -21088,7 +21082,7 @@ the <i>uword</i> type then has a minimum width of 64 bits
|
||||
<li>Version 2.2:
|
||||
<ul>
|
||||
<li>added <a href="#svd_econ">svd_econ()</a></li>
|
||||
<li>added <a href="#toeplitz">circ_toeplitz()</a></li>
|
||||
<!-- <li>added <a href="#toeplitz">circ_toeplitz()</a></li> -->
|
||||
<li>added <a href="#is_vec">.is_colvec()</a> and <a href="#is_vec">.is_rowvec()</a></li>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
#include <iostream>
|
||||
#include <armadillo>
|
||||
|
||||
using namespace std;
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
using namespace arma;
|
||||
|
||||
// Armadillo documentation is available at:
|
||||
|
||||
@@ -127,11 +127,11 @@ struct Base
|
||||
arma_warn_unused inline elem_type min() const;
|
||||
arma_warn_unused inline elem_type max() const;
|
||||
|
||||
inline elem_type min(uword& index_of_min_val) const;
|
||||
inline elem_type max(uword& index_of_max_val) const;
|
||||
arma_frown("use .index_min() instead") inline elem_type min(uword& index_of_min_val) const;
|
||||
arma_frown("use .index_max() instead") inline elem_type max(uword& index_of_max_val) const;
|
||||
|
||||
inline elem_type min(uword& row_of_min_val, uword& col_of_min_val) const;
|
||||
inline elem_type max(uword& row_of_max_val, uword& col_of_max_val) const;
|
||||
arma_frown("use .index_min() with ind2sub() instead") inline elem_type min(uword& row_of_min_val, uword& col_of_min_val) const;
|
||||
arma_frown("use .index_max() with ind2sub() instead") inline elem_type max(uword& row_of_max_val, uword& col_of_max_val) const;
|
||||
|
||||
arma_warn_unused inline uword index_min() const;
|
||||
arma_warn_unused inline uword index_max() const;
|
||||
|
||||
@@ -187,6 +187,8 @@ class Col<eT>::fixed : public Col<eT>
|
||||
{
|
||||
private:
|
||||
|
||||
using Mat<eT>::mem_local;
|
||||
|
||||
static constexpr bool use_extra = (fixed_n_elem > arma_config::mat_prealloc);
|
||||
|
||||
arma_align_mem eT mem_local_extra[ (use_extra) ? fixed_n_elem : 1 ];
|
||||
|
||||
@@ -1345,11 +1345,11 @@ Col<eT>::fixed<fixed_n_elem>::fixed(const fill::fill_class<fill_type>&)
|
||||
{
|
||||
arma_debug_sigprint_this(this);
|
||||
|
||||
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_eye >::yes) { (*this).eye(); }
|
||||
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_zeros>::yes) { (*this).zeros(); }
|
||||
if(is_same_type<fill_type, fill::fill_ones >::yes) { (*this).ones(); }
|
||||
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(); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -36,6 +36,9 @@ class CubeToMatOp : public Base< typename T1::elem_type, CubeToMatOp<T1, op_type
|
||||
arma_aligned const T1& m; //!< the operand; must be derived from BaseCube
|
||||
arma_aligned uword aux_uword; //!< auxiliary data, uword format
|
||||
|
||||
template<typename eT2>
|
||||
constexpr bool is_alias(const Mat<eT2>&) const { return false; }
|
||||
|
||||
static constexpr bool is_row = op_type::template traits<T1>::is_row;
|
||||
static constexpr bool is_col = op_type::template traits<T1>::is_col;
|
||||
static constexpr bool is_xvec = op_type::template traits<T1>::is_xvec;
|
||||
|
||||
@@ -387,12 +387,11 @@ class Cube : public BaseCube< eT, Cube<eT> >
|
||||
arma_warn_unused inline eT min() const;
|
||||
arma_warn_unused inline eT max() const;
|
||||
|
||||
inline eT min(uword& index_of_min_val) const;
|
||||
inline eT max(uword& index_of_max_val) const;
|
||||
|
||||
inline eT min(uword& row_of_min_val, uword& col_of_min_val, uword& slice_of_min_val) const;
|
||||
inline eT max(uword& row_of_max_val, uword& col_of_max_val, uword& slice_of_max_val) const;
|
||||
arma_frown("use .index_min() instead") inline eT min(uword& index_of_min_val) const;
|
||||
arma_frown("use .index_max() instead") inline eT max(uword& index_of_max_val) const;
|
||||
|
||||
arma_frown("use .index_min() with ind2sub() instead") inline eT min(uword& row_of_min_val, uword& col_of_min_val, uword& slice_of_min_val) const;
|
||||
arma_frown("use .index_max() with ind2sub() instead") inline eT max(uword& row_of_max_val, uword& col_of_max_val, uword& slice_of_max_val) const;
|
||||
|
||||
arma_cold inline bool save(const std::string name, const file_type type = arma_binary) const;
|
||||
arma_cold inline bool save(const hdf5_name& spec, const file_type type = hdf5_binary) const;
|
||||
@@ -486,6 +485,9 @@ class Cube<eT>::fixed : public Cube<eT>
|
||||
{
|
||||
private:
|
||||
|
||||
using Cube<eT>::mat_ptrs_local;
|
||||
using Cube<eT>::mem_local;
|
||||
|
||||
static constexpr uword fixed_n_elem = fixed_n_rows * fixed_n_cols * fixed_n_slices;
|
||||
static constexpr uword fixed_n_elem_slice = fixed_n_rows * fixed_n_cols;
|
||||
|
||||
|
||||
@@ -3448,7 +3448,7 @@ Cube<eT>::at_alt(const uword i) const
|
||||
|
||||
|
||||
|
||||
//! linear element accessor (treats the cube as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
|
||||
//! linear element accessor (treats the cube as a vector); bounds checking not done when ARMA_DONT_CHECK_CONFORMANCE is defined
|
||||
template<typename eT>
|
||||
arma_inline
|
||||
eT&
|
||||
@@ -3461,7 +3461,7 @@ Cube<eT>::operator() (const uword i)
|
||||
|
||||
|
||||
|
||||
//! linear element accessor (treats the cube as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
|
||||
//! linear element accessor (treats the cube as a vector); bounds checking not done when ARMA_DONT_CHECK_CONFORMANCE is defined
|
||||
template<typename eT>
|
||||
arma_inline
|
||||
const eT&
|
||||
@@ -3517,7 +3517,7 @@ Cube<eT>::at(const uword i) const
|
||||
|
||||
|
||||
|
||||
//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
|
||||
//! element accessor; bounds checking not done when ARMA_DONT_CHECK_CONFORMANCE is defined
|
||||
template<typename eT>
|
||||
arma_inline
|
||||
eT&
|
||||
@@ -3537,7 +3537,7 @@ Cube<eT>::operator() (const uword in_row, const uword in_col, const uword in_sli
|
||||
|
||||
|
||||
|
||||
//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
|
||||
//! element accessor; bounds checking not done when ARMA_DONT_CHECK_CONFORMANCE is defined
|
||||
template<typename eT>
|
||||
arma_inline
|
||||
const eT&
|
||||
@@ -5412,10 +5412,10 @@ Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::fixed(const fill::f
|
||||
|
||||
mem_setup();
|
||||
|
||||
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_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" );
|
||||
}
|
||||
|
||||
@@ -54,6 +54,9 @@ class Gen
|
||||
inline void apply_inplace_div (Mat<elem_type>& out) const;
|
||||
|
||||
inline void apply(subview<elem_type>& out) const;
|
||||
|
||||
template<typename eT2>
|
||||
constexpr bool is_alias(const Mat<eT2>&) const { return false; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -56,6 +56,9 @@ class Glue
|
||||
inline Glue(const T1& in_A, const T2& in_B, const uword in_aux_uword);
|
||||
inline ~Glue();
|
||||
|
||||
template<typename eT2>
|
||||
inline bool is_alias(const Mat<eT2>& X) const;
|
||||
|
||||
const T1& A; //!< first operand; must be derived from Base
|
||||
const T2& B; //!< second operand; must be derived from Base
|
||||
uword aux_uword; //!< storage of auxiliary data, uword format
|
||||
|
||||
@@ -53,4 +53,17 @@ Glue<T1,T2,glue_type>::~Glue()
|
||||
|
||||
|
||||
|
||||
template<typename T1, typename T2, typename glue_type>
|
||||
template<typename eT2>
|
||||
inline
|
||||
bool
|
||||
Glue<T1,T2,glue_type>::is_alias(const Mat<eT2>& X) const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
return (A.is_alias(X) || B.is_alias(X));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
@@ -541,11 +541,11 @@ class Mat : public Base< eT, Mat<eT> >
|
||||
arma_warn_unused inline eT min() const;
|
||||
arma_warn_unused inline eT max() const;
|
||||
|
||||
inline eT min(uword& index_of_min_val) const;
|
||||
inline eT max(uword& index_of_max_val) const;
|
||||
arma_frown("use .index_min() instead") inline eT min(uword& index_of_min_val) const;
|
||||
arma_frown("use .index_max() instead") inline eT max(uword& index_of_max_val) const;
|
||||
|
||||
inline eT min(uword& row_of_min_val, uword& col_of_min_val) const;
|
||||
inline eT max(uword& row_of_max_val, uword& col_of_max_val) const;
|
||||
arma_frown("use .index_min() with ind2sub() instead") inline eT min(uword& row_of_min_val, uword& col_of_min_val) const;
|
||||
arma_frown("use .index_max() with ind2sub() instead") inline eT max(uword& row_of_max_val, uword& col_of_max_val) const;
|
||||
|
||||
|
||||
arma_cold inline bool save(const std::string name, const file_type type = arma_binary) const;
|
||||
@@ -771,6 +771,9 @@ class Mat : public Base< eT, Mat<eT> >
|
||||
|
||||
inline void steal_mem_col(Mat& X, const uword max_n_rows);
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const; //!< don't use this unless you're writing code internal to Armadillo
|
||||
|
||||
|
||||
template<uword fixed_n_rows, uword fixed_n_cols> class fixed;
|
||||
|
||||
@@ -822,6 +825,8 @@ class Mat<eT>::fixed : public Mat<eT>
|
||||
{
|
||||
private:
|
||||
|
||||
using Mat<eT>::mem_local;
|
||||
|
||||
static constexpr uword fixed_n_elem = fixed_n_rows * fixed_n_cols;
|
||||
static constexpr bool use_extra = (fixed_n_elem > arma_config::mat_prealloc);
|
||||
|
||||
|
||||
@@ -1324,6 +1324,19 @@ Mat<eT>::steal_mem_col(Mat<eT>& x, const uword max_n_rows)
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
template<typename eT2>
|
||||
arma_inline
|
||||
bool
|
||||
Mat<eT>::is_alias(const Mat<eT2>& X) const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
return (is_same_type<eT,eT2>::yes) && (void_ptr(this) == void_ptr(&X));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! construct a matrix from a given auxiliary array of eTs.
|
||||
//! if copy_aux_mem is true, new memory is allocated and the array is copied.
|
||||
//! if copy_aux_mem is false, the auxiliary array is used directly (without allocating memory and copying).
|
||||
@@ -6378,7 +6391,7 @@ Mat<eT>::at_alt(const uword ii) const
|
||||
|
||||
|
||||
|
||||
//! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
|
||||
//! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_DONT_CHECK_CONFORMANCE is defined
|
||||
template<typename eT>
|
||||
arma_inline
|
||||
eT&
|
||||
@@ -6391,7 +6404,7 @@ Mat<eT>::operator() (const uword ii)
|
||||
|
||||
|
||||
|
||||
//! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
|
||||
//! linear element accessor (treats the matrix as a vector); bounds checking not done when ARMA_DONT_CHECK_CONFORMANCE is defined
|
||||
template<typename eT>
|
||||
arma_inline
|
||||
const eT&
|
||||
@@ -6447,7 +6460,7 @@ Mat<eT>::at(const uword ii) const
|
||||
|
||||
|
||||
|
||||
//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
|
||||
//! element accessor; bounds checking not done when ARMA_DONT_CHECK_CONFORMANCE is defined
|
||||
template<typename eT>
|
||||
arma_inline
|
||||
eT&
|
||||
@@ -6460,7 +6473,7 @@ Mat<eT>::operator() (const uword in_row, const uword in_col)
|
||||
|
||||
|
||||
|
||||
//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
|
||||
//! element accessor; bounds checking not done when ARMA_DONT_CHECK_CONFORMANCE is defined
|
||||
template<typename eT>
|
||||
arma_inline
|
||||
const eT&
|
||||
@@ -9552,11 +9565,11 @@ Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const fill::fill_class<fill_ty
|
||||
{
|
||||
arma_debug_sigprint_this(this);
|
||||
|
||||
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_eye >::yes) { (*this).eye(); }
|
||||
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_zeros>::yes) { (*this).zeros(); }
|
||||
if(is_same_type<fill_type, fill::fill_ones >::yes) { (*this).ones(); }
|
||||
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(); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -58,6 +58,9 @@ class Op
|
||||
inline Op(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
|
||||
inline ~Op();
|
||||
|
||||
template<typename eT2>
|
||||
inline bool is_alias(const Mat<eT2>& X) const;
|
||||
|
||||
arma_aligned const T1& m; //!< the operand; must be derived from Base
|
||||
arma_aligned elem_type aux; //!< auxiliary data, using the element type as used by T1
|
||||
arma_aligned uword aux_uword_a; //!< auxiliary data, uword format
|
||||
|
||||
@@ -76,4 +76,17 @@ Op<T1, op_type>::~Op()
|
||||
|
||||
|
||||
|
||||
template<typename T1, typename op_type>
|
||||
template<typename eT2>
|
||||
inline
|
||||
bool
|
||||
Op<T1, op_type>::is_alias(const Mat<eT2>& X) const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
return m.is_alias(X);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
@@ -188,7 +188,7 @@ struct Proxy< Mat<eT> >
|
||||
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 (is_same_type<eT,eT2>::value) ? (void_ptr(&Q) == void_ptr(&X)) : false; }
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return (is_same_type<eT,eT2>::yes) && (void_ptr(&Q) == void_ptr(&X)); }
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool has_overlap(const subview<eT2>& X) const { return is_alias(X.m); }
|
||||
@@ -235,7 +235,7 @@ struct Proxy< Col<eT> >
|
||||
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 (is_same_type<eT,eT2>::value) ? (void_ptr(&Q) == void_ptr(&X)) : false; }
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return (is_same_type<eT,eT2>::yes) && (void_ptr(&Q) == void_ptr(&X)); }
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool has_overlap(const subview<eT2>& X) const { return is_alias(X.m); }
|
||||
@@ -282,7 +282,7 @@ struct Proxy< Row<eT> >
|
||||
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 (is_same_type<eT,eT2>::value) ? (void_ptr(&Q) == void_ptr(&X)) : false; }
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return (is_same_type<eT,eT2>::yes) && (void_ptr(&Q) == void_ptr(&X)); }
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool has_overlap(const subview<eT2>& X) const { return is_alias(X.m); }
|
||||
@@ -1013,7 +1013,7 @@ struct Proxy< subview<eT> >
|
||||
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 (is_same_type<eT,eT2>::value) ? (void_ptr(&(Q.m)) == void_ptr(&X)) : false; }
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return (is_same_type<eT,eT2>::yes) && (void_ptr(&(Q.m)) == void_ptr(&X)); }
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool has_overlap(const subview<eT2>& X) const { return Q.check_overlap(X); }
|
||||
@@ -1060,7 +1060,7 @@ struct Proxy< subview_col<eT> >
|
||||
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 (is_same_type<eT,eT2>::value) ? (void_ptr(&(Q.m)) == void_ptr(&X)) : false; }
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return (is_same_type<eT,eT2>::yes) && (void_ptr(&(Q.m)) == void_ptr(&X)); }
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool has_overlap(const subview<eT2>& X) const { return Q.check_overlap(X); }
|
||||
@@ -1109,7 +1109,7 @@ struct Proxy< subview_cols<eT> >
|
||||
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 (is_same_type<eT,eT2>::value) ? (void_ptr(&(sv.m)) == void_ptr(&X)) : false; }
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return (is_same_type<eT,eT2>::yes) && (void_ptr(&(sv.m)) == void_ptr(&X)); }
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool has_overlap(const subview<eT2>& X) const { return sv.check_overlap(X); }
|
||||
@@ -1156,7 +1156,7 @@ struct Proxy< subview_row<eT> >
|
||||
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 (is_same_type<eT,eT2>::value) ? (void_ptr(&(Q.m)) == void_ptr(&X)) : false; }
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return (is_same_type<eT,eT2>::yes) && (void_ptr(&(Q.m)) == void_ptr(&X)); }
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool has_overlap(const subview<eT2>& X) const { return Q.check_overlap(X); }
|
||||
@@ -1304,7 +1304,7 @@ struct Proxy< diagview<eT> >
|
||||
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 (is_same_type<eT,eT2>::value) ? (void_ptr(&(Q.m)) == void_ptr(&X)) : false; }
|
||||
arma_inline bool is_alias(const Mat<eT2>& X) const { return (is_same_type<eT,eT2>::yes) && (void_ptr(&(Q.m)) == void_ptr(&X)); }
|
||||
|
||||
template<typename eT2>
|
||||
arma_inline bool has_overlap(const subview<eT2>& X) const { return is_alias(X.m); }
|
||||
|
||||
@@ -187,6 +187,8 @@ class Row<eT>::fixed : public Row<eT>
|
||||
{
|
||||
private:
|
||||
|
||||
using Mat<eT>::mem_local;
|
||||
|
||||
static constexpr bool use_extra = (fixed_n_elem > arma_config::mat_prealloc);
|
||||
|
||||
arma_align_mem eT mem_local_extra[ (use_extra) ? fixed_n_elem : 1 ];
|
||||
|
||||
@@ -1345,11 +1345,11 @@ Row<eT>::fixed<fixed_n_elem>::fixed(const fill::fill_class<fill_type>&)
|
||||
{
|
||||
arma_debug_sigprint_this(this);
|
||||
|
||||
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_eye >::yes) { (*this).eye(); }
|
||||
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_zeros>::yes) { (*this).zeros(); }
|
||||
if(is_same_type<fill_type, fill::fill_ones >::yes) { (*this).ones(); }
|
||||
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(); }
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -76,11 +76,11 @@ struct SpBase
|
||||
arma_warn_unused inline elem_type min() const;
|
||||
arma_warn_unused inline elem_type max() const;
|
||||
|
||||
inline elem_type min(uword& index_of_min_val) const;
|
||||
inline elem_type max(uword& index_of_max_val) const;
|
||||
arma_frown("use .index_min() instead") inline elem_type min(uword& index_of_min_val) const;
|
||||
arma_frown("use .index_max() instead") inline elem_type max(uword& index_of_max_val) const;
|
||||
|
||||
inline elem_type min(uword& row_of_min_val, uword& col_of_min_val) const;
|
||||
inline elem_type max(uword& row_of_max_val, uword& col_of_max_val) const;
|
||||
arma_frown("use .index_min() with ind2sub() instead") inline elem_type min(uword& row_of_min_val, uword& col_of_min_val) const;
|
||||
arma_frown("use .index_max() with ind2sub() instead") inline elem_type max(uword& row_of_max_val, uword& col_of_max_val) const;
|
||||
|
||||
arma_warn_unused inline uword index_min() const;
|
||||
arma_warn_unused inline uword index_max() const;
|
||||
|
||||
@@ -36,6 +36,9 @@ class SpToDGlue : public Base< typename T1::elem_type, SpToDGlue<T1, T2, glue_ty
|
||||
inline explicit SpToDGlue(const T1& in_A, const T2& in_B);
|
||||
inline ~SpToDGlue();
|
||||
|
||||
template<typename eT2>
|
||||
constexpr bool is_alias(const Mat<eT2>&) const { return false; }
|
||||
|
||||
const T1& A; //!< first operand; must be derived from Base or SpBase
|
||||
const T2& B; //!< second operand; must be derived from Base or SpBase
|
||||
};
|
||||
|
||||
@@ -39,6 +39,9 @@ class SpToDOp : public Base< typename T1::elem_type, SpToDOp<T1, op_type> >
|
||||
inline SpToDOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
|
||||
inline ~SpToDOp();
|
||||
|
||||
template<typename eT2>
|
||||
constexpr bool is_alias(const Mat<eT2>&) const { return false; }
|
||||
|
||||
arma_aligned const T1& m; //!< the operand; must be derived from SpBase
|
||||
arma_aligned elem_type aux; //!< auxiliary data, using the element type as used by T1
|
||||
arma_aligned uword aux_uword_a; //!< auxiliary data, uword format
|
||||
|
||||
@@ -91,6 +91,8 @@ class op_diagmat;
|
||||
class op_trimat;
|
||||
class op_vectorise_row;
|
||||
class op_vectorise_col;
|
||||
class op_symmatu;
|
||||
class op_symmatl;
|
||||
|
||||
class op_row_as_mat;
|
||||
class op_col_as_mat;
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
|
||||
|
||||
#define ARMA_VERSION_MAJOR 14
|
||||
#define ARMA_VERSION_MINOR 0
|
||||
#define ARMA_VERSION_PATCH 2
|
||||
#define ARMA_VERSION_NAME "Stochastic Parrot"
|
||||
#define ARMA_VERSION_MINOR 2
|
||||
#define ARMA_VERSION_PATCH 3
|
||||
#define ARMA_VERSION_NAME "Smooth Caffeine"
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -43,6 +43,18 @@ class auxlib
|
||||
template<typename eT>
|
||||
inline static bool inv_tr_rcond(Mat<eT>& A, typename get_pod_type<eT>::result& out_rcond, const uword layout);
|
||||
|
||||
template<typename eT>
|
||||
inline static bool inv_sym(Mat<eT>& A);
|
||||
|
||||
template<typename T>
|
||||
inline static bool inv_sym(Mat< std::complex<T> >& A);
|
||||
|
||||
template<typename eT>
|
||||
inline static bool inv_sym_rcond(Mat<eT>& A, eT& out_rcond);
|
||||
|
||||
template<typename T>
|
||||
inline static bool inv_sym_rcond(Mat< std::complex<T> >& A, T& out_rcond);
|
||||
|
||||
template<typename eT>
|
||||
inline static bool inv_sympd(Mat<eT>& A, bool& out_sympd_state);
|
||||
|
||||
@@ -50,10 +62,10 @@ class auxlib
|
||||
inline static bool inv_sympd(Mat<eT>& out, const Mat<eT>& X);
|
||||
|
||||
template<typename eT>
|
||||
inline static bool inv_sympd_rcond(Mat<eT>& A, bool& out_sympd_state, eT& out_rcond);
|
||||
inline static bool inv_sympd_rcond(Mat<eT>& A, eT& out_rcond);
|
||||
|
||||
template<typename T>
|
||||
inline static bool inv_sympd_rcond(Mat< std::complex<T> >& A, bool& out_sympd_state, T& out_rcond);
|
||||
inline static bool inv_sympd_rcond(Mat< std::complex<T> >& A, T& out_rcond);
|
||||
|
||||
|
||||
//
|
||||
@@ -269,6 +281,20 @@ class auxlib
|
||||
|
||||
//
|
||||
|
||||
template<typename T1>
|
||||
inline static bool solve_sym_fast(Mat<typename T1::pod_type>& out, Mat<typename T1::pod_type>& A, const Base<typename T1::pod_type,T1>& B_expr);
|
||||
|
||||
template<typename T1>
|
||||
inline static bool solve_sym_fast(Mat< std::complex<typename T1::pod_type> >& out, Mat< std::complex<typename T1::pod_type> >& A, const Base< std::complex<typename T1::pod_type>, T1 >& B_expr);
|
||||
|
||||
template<typename T1>
|
||||
inline static bool solve_sym_rcond(Mat<typename T1::pod_type>& out, typename T1::pod_type& out_rcond, Mat<typename T1::pod_type>& A, const Base<typename T1::pod_type,T1>& B_expr);
|
||||
|
||||
template<typename T1>
|
||||
inline static bool solve_sym_rcond(Mat< std::complex<typename T1::pod_type> >& out, typename T1::pod_type& out_rcond, Mat< std::complex<typename T1::pod_type> >& A, const Base< std::complex<typename T1::pod_type>,T1>& B_expr);
|
||||
|
||||
//
|
||||
|
||||
template<typename T1>
|
||||
inline static bool solve_sympd_fast(Mat<typename T1::elem_type>& out, Mat<typename T1::elem_type>& A, const Base<typename T1::elem_type,T1>& B_expr);
|
||||
|
||||
@@ -388,10 +414,10 @@ class auxlib
|
||||
inline static T rcond(Mat< std::complex<T> >& A);
|
||||
|
||||
template<typename eT>
|
||||
inline static eT rcond_sympd(Mat<eT>& A, bool& calc_ok);
|
||||
inline static eT rcond_sym(Mat<eT>& A);
|
||||
|
||||
template<typename T>
|
||||
inline static T rcond_sympd(Mat< std::complex<T> >& A, bool& calc_ok);
|
||||
template<typename T>
|
||||
inline static T rcond_sym(Mat< std::complex<T> >& A);
|
||||
|
||||
template<typename eT>
|
||||
inline static eT rcond_trimat(const Mat<eT>& A, const uword layout);
|
||||
|
||||
@@ -28,6 +28,10 @@ auxlib::inv(Mat<eT>& A)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
// NOTE: given a matrix with NaN values, lapack::getrf() and lapack::getri() do not necessarily fail,
|
||||
// NOTE: and can produce matrices with NaN values.
|
||||
// NOTE: we're not checking for non-finite values to avoid breaking existing user code.
|
||||
|
||||
if(A.is_empty()) { return true; }
|
||||
|
||||
#if defined(ARMA_USE_LAPACK)
|
||||
@@ -46,7 +50,7 @@ auxlib::inv(Mat<eT>& A)
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
if(n > 16)
|
||||
if(n > blas_int(podarray_prealloc_n_elem::val))
|
||||
{
|
||||
eT work_query[2] = {};
|
||||
blas_int lwork_query = -1;
|
||||
@@ -130,7 +134,7 @@ auxlib::inv_rcond(Mat<eT>& A, typename get_pod_type<eT>::result& out_rcond)
|
||||
|
||||
out_rcond = auxlib::lu_rcond<T>(A, norm_val);
|
||||
|
||||
if(n > 16)
|
||||
if(n > blas_int(podarray_prealloc_n_elem::val))
|
||||
{
|
||||
eT work_query[2] = {};
|
||||
blas_int lwork_query = -1;
|
||||
@@ -242,6 +246,316 @@ auxlib::inv_tr_rcond(Mat<eT>& A, typename get_pod_type<eT>::result& out_rcond, c
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
auxlib::inv_sym(Mat<eT>& A)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
if(A.is_empty()) { return true; }
|
||||
|
||||
#if defined(ARMA_USE_LAPACK)
|
||||
{
|
||||
arma_conform_assert_blas_size(A);
|
||||
|
||||
char uplo = 'L';
|
||||
blas_int n = blas_int(A.n_rows);
|
||||
blas_int lda = blas_int(A.n_rows);
|
||||
blas_int lwork = (std::max)(blas_int(podarray_prealloc_n_elem::val), n);
|
||||
blas_int info = 0;
|
||||
|
||||
podarray<blas_int> ipiv(A.n_rows);
|
||||
|
||||
if(n > blas_int(podarray_prealloc_n_elem::val))
|
||||
{
|
||||
eT work_query[2] = {};
|
||||
blas_int lwork_query = -1;
|
||||
|
||||
arma_debug_print("lapack::sytrf()");
|
||||
lapack::sytrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), &work_query[0], &lwork_query, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
blas_int lwork_proposed = static_cast<blas_int>( access::tmp_real(work_query[0]) );
|
||||
|
||||
lwork = (std::max)(lwork_proposed, lwork);
|
||||
}
|
||||
|
||||
podarray<eT> work( static_cast<uword>(lwork) );
|
||||
|
||||
arma_debug_print("lapack::sytrf()");
|
||||
lapack::sytrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), work.memptr(), &lwork, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
arma_debug_print("lapack::sytri()");
|
||||
lapack::sytri(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), work.memptr(), &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
A = symmatl(A);
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
{
|
||||
arma_ignore(A);
|
||||
arma_stop_logic_error("inv_sym(): use of LAPACK must be enabled");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
auxlib::inv_sym(Mat< std::complex<T> >& A)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
// NOTE: the function name is required for overloading, but is a misnomer: it processes complex hermitian matrices
|
||||
|
||||
if(A.is_empty()) { return true; }
|
||||
|
||||
#if defined(ARMA_CRIPPLED_LAPACK)
|
||||
{
|
||||
arma_debug_print("auxlib::inv_sym(): redirecting to auxlib::inv() due to crippled LAPACK");
|
||||
|
||||
return auxlib::inv(A);
|
||||
}
|
||||
#elif defined(ARMA_USE_LAPACK)
|
||||
{
|
||||
typedef typename std::complex<T> eT;
|
||||
|
||||
arma_conform_assert_blas_size(A);
|
||||
|
||||
char uplo = 'L';
|
||||
blas_int n = blas_int(A.n_rows);
|
||||
blas_int lda = blas_int(A.n_rows);
|
||||
blas_int lwork = (std::max)(blas_int(podarray_prealloc_n_elem::val), n);
|
||||
blas_int info = 0;
|
||||
|
||||
podarray<blas_int> ipiv(A.n_rows);
|
||||
|
||||
if(n > blas_int(podarray_prealloc_n_elem::val))
|
||||
{
|
||||
eT work_query[2] = {};
|
||||
blas_int lwork_query = -1;
|
||||
|
||||
arma_debug_print("lapack::hetrf()");
|
||||
lapack::hetrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), &work_query[0], &lwork_query, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
blas_int lwork_proposed = static_cast<blas_int>( access::tmp_real(work_query[0]) );
|
||||
|
||||
lwork = (std::max)(lwork_proposed, lwork);
|
||||
}
|
||||
|
||||
podarray<eT> work( static_cast<uword>(lwork) );
|
||||
|
||||
arma_debug_print("lapack::hetrf()");
|
||||
lapack::hetrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), work.memptr(), &lwork, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
arma_debug_print("lapack::hetri()");
|
||||
lapack::hetri(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), work.memptr(), &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
A = symmatl(A);
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
{
|
||||
arma_ignore(A);
|
||||
arma_stop_logic_error("inv_sym(): use of LAPACK must be enabled");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
auxlib::inv_sym_rcond(Mat<eT>& A, eT& out_rcond)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
out_rcond = eT(0);
|
||||
|
||||
if(A.is_empty()) { return true; }
|
||||
|
||||
#if defined(ARMA_USE_LAPACK)
|
||||
{
|
||||
arma_conform_assert_blas_size(A);
|
||||
|
||||
char norm_id = '1';
|
||||
char uplo = 'L';
|
||||
blas_int n = blas_int(A.n_rows);
|
||||
blas_int lda = blas_int(A.n_rows);
|
||||
blas_int lwork = (std::max)(blas_int(podarray_prealloc_n_elem::val), 2*n); // 2*n due to lapack::sycon() requirements
|
||||
blas_int info = 0;
|
||||
eT norm_val = eT(0);
|
||||
eT tmp_rcond = eT(0);
|
||||
|
||||
podarray<blas_int> ipiv(A.n_rows);
|
||||
podarray<blas_int> iwork(A.n_rows);
|
||||
|
||||
if( (2*n) > blas_int(podarray_prealloc_n_elem::val) )
|
||||
{
|
||||
eT work_query[2] = {};
|
||||
blas_int lwork_query = -1;
|
||||
|
||||
arma_debug_print("lapack::sytrf()");
|
||||
lapack::sytrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), &work_query[0], &lwork_query, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
blas_int lwork_proposed = static_cast<blas_int>( access::tmp_real(work_query[0]) );
|
||||
|
||||
lwork = (std::max)(lwork_proposed, lwork);
|
||||
}
|
||||
|
||||
podarray<eT> work( static_cast<uword>(lwork) );
|
||||
|
||||
arma_debug_print("lapack::lansy()");
|
||||
norm_val = (has_blas_float_bug<eT>::value) ? auxlib::norm1_sym(A) : lapack::lansy(&norm_id, &uplo, &n, A.memptr(), &lda, work.memptr());
|
||||
|
||||
arma_debug_print("lapack::sytrf()");
|
||||
lapack::sytrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), work.memptr(), &lwork, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
arma_debug_print("lapack::sycon()");
|
||||
lapack::sycon(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), &norm_val, &tmp_rcond, work.memptr(), iwork.memptr(), &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
out_rcond = tmp_rcond;
|
||||
|
||||
if(arma_isnan(out_rcond)) { return false; }
|
||||
|
||||
arma_debug_print("lapack::sytri()");
|
||||
lapack::sytri(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), work.memptr(), &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
A = symmatl(A);
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
{
|
||||
arma_ignore(A);
|
||||
arma_ignore(out_rcond);
|
||||
arma_stop_logic_error("inv_sym_rcond(): use of LAPACK must be enabled");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
auxlib::inv_sym_rcond(Mat< std::complex<T> >& A, T& out_rcond)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
// NOTE: the function name is required for overloading, but is a misnomer: it processes complex hermitian matrices
|
||||
|
||||
out_rcond = T(0);
|
||||
|
||||
if(A.is_empty()) { return true; }
|
||||
|
||||
#if defined(ARMA_CRIPPLED_LAPACK)
|
||||
{
|
||||
arma_debug_print("auxlib::inv_sym_rcond(): redirecting to auxlib::inv_rcond() due to crippled LAPACK");
|
||||
|
||||
return auxlib::inv_rcond(A, out_rcond);
|
||||
}
|
||||
#elif defined(ARMA_USE_LAPACK)
|
||||
{
|
||||
typedef typename std::complex<T> eT;
|
||||
|
||||
arma_conform_assert_blas_size(A);
|
||||
|
||||
char norm_id = '1';
|
||||
char uplo = 'L';
|
||||
blas_int n = blas_int(A.n_rows);
|
||||
blas_int lda = blas_int(A.n_rows);
|
||||
blas_int lwork = (std::max)(blas_int(podarray_prealloc_n_elem::val), 2*n); // 2*n due to lapack::hecon() requirements
|
||||
blas_int info = 0;
|
||||
T norm_val = T(0);
|
||||
T tmp_rcond = T(0);
|
||||
|
||||
podarray<blas_int> ipiv(A.n_rows);
|
||||
podarray<T> lanhe_work(A.n_rows);
|
||||
|
||||
if( (2*n) > blas_int(podarray_prealloc_n_elem::val) )
|
||||
{
|
||||
eT work_query[2] = {};
|
||||
blas_int lwork_query = -1;
|
||||
|
||||
arma_debug_print("lapack::hetrf()");
|
||||
lapack::hetrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), &work_query[0], &lwork_query, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
blas_int lwork_proposed = static_cast<blas_int>( access::tmp_real(work_query[0]) );
|
||||
|
||||
lwork = (std::max)(lwork_proposed, lwork);
|
||||
}
|
||||
|
||||
podarray<eT> work( static_cast<uword>(lwork) );
|
||||
|
||||
arma_debug_print("lapack::lanhe()");
|
||||
norm_val = (has_blas_float_bug<T>::value) ? auxlib::norm1_sym(A) : lapack::lanhe(&norm_id, &uplo, &n, A.memptr(), &lda, lanhe_work.memptr());
|
||||
|
||||
arma_debug_print("lapack::hetrf()");
|
||||
lapack::hetrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), work.memptr(), &lwork, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
arma_debug_print("lapack::hecon()");
|
||||
lapack::hecon(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), &norm_val, &tmp_rcond, work.memptr(), &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
out_rcond = tmp_rcond;
|
||||
|
||||
if(arma_isnan(out_rcond)) { return false; }
|
||||
|
||||
arma_debug_print("lapack::hetri()");
|
||||
lapack::hetri(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), work.memptr(), &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
A = symmatl(A);
|
||||
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
{
|
||||
arma_ignore(A);
|
||||
arma_ignore(out_rcond);
|
||||
arma_stop_logic_error("inv_sym_rcond(): use of LAPACK must be enabled");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
@@ -310,12 +624,10 @@ auxlib::inv_sympd(Mat<eT>& out, const Mat<eT>& X)
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
auxlib::inv_sympd_rcond(Mat<eT>& A, bool& out_sympd_state, eT& out_rcond)
|
||||
auxlib::inv_sympd_rcond(Mat<eT>& A, eT& out_rcond)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
out_sympd_state = false;
|
||||
|
||||
if(A.is_empty()) { return true; }
|
||||
|
||||
#if defined(ARMA_USE_LAPACK)
|
||||
@@ -340,8 +652,6 @@ auxlib::inv_sympd_rcond(Mat<eT>& A, bool& out_sympd_state, eT& out_rcond)
|
||||
|
||||
if(info != 0) { out_rcond = eT(0); return false; }
|
||||
|
||||
out_sympd_state = true;
|
||||
|
||||
out_rcond = auxlib::lu_rcond_sympd<T>(A, norm_val);
|
||||
|
||||
if(arma_isnan(out_rcond)) { return false; }
|
||||
@@ -358,7 +668,6 @@ auxlib::inv_sympd_rcond(Mat<eT>& A, bool& out_sympd_state, eT& out_rcond)
|
||||
#else
|
||||
{
|
||||
arma_ignore(A);
|
||||
arma_ignore(out_sympd_state);
|
||||
arma_ignore(out_rcond);
|
||||
arma_stop_logic_error("inv_sympd_rcond(): use LAPACK must be enabled");
|
||||
return false;
|
||||
@@ -371,18 +680,15 @@ auxlib::inv_sympd_rcond(Mat<eT>& A, bool& out_sympd_state, eT& out_rcond)
|
||||
template<typename T>
|
||||
inline
|
||||
bool
|
||||
auxlib::inv_sympd_rcond(Mat< std::complex<T> >& A, bool& out_sympd_state, T& out_rcond)
|
||||
auxlib::inv_sympd_rcond(Mat< std::complex<T> >& A, T& out_rcond)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
out_sympd_state = false;
|
||||
|
||||
if(A.is_empty()) { return true; }
|
||||
|
||||
#if defined(ARMA_CRIPPLED_LAPACK)
|
||||
{
|
||||
arma_ignore(A);
|
||||
arma_ignore(out_sympd_state);
|
||||
arma_ignore(out_rcond);
|
||||
return false;
|
||||
}
|
||||
@@ -406,8 +712,6 @@ auxlib::inv_sympd_rcond(Mat< std::complex<T> >& A, bool& out_sympd_state, T& out
|
||||
|
||||
if(info != 0) { out_rcond = T(0); return false; }
|
||||
|
||||
out_sympd_state = true;
|
||||
|
||||
out_rcond = auxlib::lu_rcond_sympd<T>(A, norm_val);
|
||||
|
||||
if(arma_isnan(out_rcond)) { return false; }
|
||||
@@ -424,7 +728,6 @@ auxlib::inv_sympd_rcond(Mat< std::complex<T> >& A, bool& out_sympd_state, T& out
|
||||
#else
|
||||
{
|
||||
arma_ignore(A);
|
||||
arma_ignore(out_sympd_state);
|
||||
arma_ignore(out_rcond);
|
||||
arma_stop_logic_error("inv_sympd_rcond(): use LAPACK must be enabled");
|
||||
return false;
|
||||
@@ -4262,6 +4565,328 @@ auxlib::solve_square_refine(Mat< std::complex<typename T1::pod_type> >& out, typ
|
||||
|
||||
|
||||
|
||||
template<typename T1>
|
||||
inline
|
||||
bool
|
||||
auxlib::solve_sym_fast(Mat<typename T1::pod_type>& out, Mat<typename T1::pod_type>& A, const Base<typename T1::pod_type,T1>& B_expr)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
out = B_expr.get_ref();
|
||||
|
||||
const uword B_n_rows = out.n_rows;
|
||||
const uword B_n_cols = out.n_cols;
|
||||
|
||||
arma_conform_check( (A.n_rows != B_n_rows), "solve(): number of rows in given matrices must be the same", [&](){ out.soft_reset(); } );
|
||||
|
||||
if(A.is_empty() || out.is_empty()) { out.zeros(A.n_cols, B_n_cols); return true; }
|
||||
|
||||
#if defined(ARMA_USE_LAPACK)
|
||||
{
|
||||
typedef typename T1::pod_type eT;
|
||||
|
||||
arma_conform_assert_blas_size(A,out);
|
||||
|
||||
char uplo = 'L';
|
||||
blas_int n = blas_int(A.n_rows);
|
||||
blas_int lda = blas_int(A.n_rows);
|
||||
blas_int ldb = blas_int(out.n_rows);
|
||||
blas_int nrhs = blas_int(out.n_cols);
|
||||
blas_int lwork = (std::max)(blas_int(podarray_prealloc_n_elem::val), n);
|
||||
blas_int info = 0;
|
||||
|
||||
podarray<blas_int> ipiv(A.n_rows);
|
||||
|
||||
if(n > blas_int(podarray_prealloc_n_elem::val))
|
||||
{
|
||||
eT work_query[2] = {};
|
||||
blas_int lwork_query = -1;
|
||||
|
||||
arma_debug_print("lapack::sytrf()");
|
||||
lapack::sytrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), &work_query[0], &lwork_query, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
blas_int lwork_proposed = static_cast<blas_int>( access::tmp_real(work_query[0]) );
|
||||
|
||||
lwork = (std::max)(lwork_proposed, lwork);
|
||||
}
|
||||
|
||||
podarray<eT> work( static_cast<uword>(lwork) );
|
||||
|
||||
arma_debug_print("lapack::sytrf()");
|
||||
lapack::sytrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), work.memptr(), &lwork, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
arma_debug_print("lapack::sytrs()");
|
||||
lapack::sytrs(&uplo, &n, &nrhs, A.memptr(), &lda, ipiv.memptr(), out.memptr(), &ldb, &info);
|
||||
|
||||
return (info == 0);
|
||||
}
|
||||
#else
|
||||
{
|
||||
arma_stop_logic_error("solve(): use of LAPACK must be enabled");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T1>
|
||||
inline
|
||||
bool
|
||||
auxlib::solve_sym_fast(Mat< std::complex<typename T1::pod_type> >& out, Mat< std::complex<typename T1::pod_type> >& A, const Base< std::complex<typename T1::pod_type>, T1 >& B_expr)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
out = B_expr.get_ref();
|
||||
|
||||
const uword B_n_rows = out.n_rows;
|
||||
const uword B_n_cols = out.n_cols;
|
||||
|
||||
arma_conform_check( (A.n_rows != B_n_rows), "solve(): number of rows in given matrices must be the same", [&](){ out.soft_reset(); } );
|
||||
|
||||
if(A.is_empty() || out.is_empty()) { out.zeros(A.n_cols, B_n_cols); return true; }
|
||||
|
||||
#if defined(ARMA_CRIPPLED_LAPACK)
|
||||
{
|
||||
arma_debug_print("auxlib::solve_sym_fast(): redirecting to auxlib::solve_square_fast() due to crippled LAPACK");
|
||||
|
||||
return auxlib::solve_square_fast(out, A, B_expr);
|
||||
}
|
||||
#elif defined(ARMA_USE_LAPACK)
|
||||
{
|
||||
typedef typename T1::pod_type T;
|
||||
typedef std::complex<T> eT;
|
||||
|
||||
arma_conform_assert_blas_size(A,out);
|
||||
|
||||
char uplo = 'L';
|
||||
blas_int n = blas_int(A.n_rows);
|
||||
blas_int lda = blas_int(A.n_rows);
|
||||
blas_int ldb = blas_int(out.n_rows);
|
||||
blas_int nrhs = blas_int(out.n_cols);
|
||||
blas_int lwork = (std::max)(blas_int(podarray_prealloc_n_elem::val), n);
|
||||
blas_int info = 0;
|
||||
|
||||
podarray<blas_int> ipiv(A.n_rows);
|
||||
|
||||
if(n > blas_int(podarray_prealloc_n_elem::val))
|
||||
{
|
||||
eT work_query[2] = {};
|
||||
blas_int lwork_query = -1;
|
||||
|
||||
arma_debug_print("lapack::hetrf()");
|
||||
lapack::hetrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), &work_query[0], &lwork_query, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
blas_int lwork_proposed = static_cast<blas_int>( access::tmp_real(work_query[0]) );
|
||||
|
||||
lwork = (std::max)(lwork_proposed, lwork);
|
||||
}
|
||||
|
||||
podarray<eT> work( static_cast<uword>(lwork) );
|
||||
|
||||
arma_debug_print("lapack::hetrf()");
|
||||
lapack::hetrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), work.memptr(), &lwork, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
arma_debug_print("lapack::hetrs()");
|
||||
lapack::hetrs(&uplo, &n, &nrhs, A.memptr(), &lda, ipiv.memptr(), out.memptr(), &ldb, &info);
|
||||
|
||||
return (info == 0);
|
||||
}
|
||||
#else
|
||||
{
|
||||
arma_stop_logic_error("solve(): use of LAPACK must be enabled");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T1>
|
||||
inline
|
||||
bool
|
||||
auxlib::solve_sym_rcond(Mat<typename T1::pod_type>& out, typename T1::pod_type& out_rcond, Mat<typename T1::pod_type>& A, const Base<typename T1::pod_type,T1>& B_expr)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
out = B_expr.get_ref();
|
||||
|
||||
const uword B_n_rows = out.n_rows;
|
||||
const uword B_n_cols = out.n_cols;
|
||||
|
||||
arma_conform_check( (A.n_rows != B_n_rows), "solve(): number of rows in given matrices must be the same", [&](){ out.soft_reset(); } );
|
||||
|
||||
if(A.is_empty() || out.is_empty()) { out.zeros(A.n_cols, B_n_cols); return true; }
|
||||
|
||||
#if defined(ARMA_CRIPPLED_LAPACK)
|
||||
{
|
||||
arma_debug_print("auxlib::solve_sym_rcond(): redirecting to auxlib::solve_square_rcond() due to crippled LAPACK");
|
||||
|
||||
return auxlib::solve_square_rcond(out, out_rcond, A, B_expr);
|
||||
}
|
||||
#elif defined(ARMA_USE_LAPACK)
|
||||
{
|
||||
typedef typename T1::pod_type eT;
|
||||
|
||||
out_rcond = eT(0);
|
||||
|
||||
arma_conform_assert_blas_size(A,out);
|
||||
|
||||
char norm_id = '1';
|
||||
char uplo = 'L';
|
||||
blas_int n = blas_int(A.n_rows);
|
||||
blas_int lda = blas_int(A.n_rows);
|
||||
blas_int ldb = blas_int(out.n_rows);
|
||||
blas_int nrhs = blas_int(out.n_cols);
|
||||
blas_int lwork = (std::max)(blas_int(podarray_prealloc_n_elem::val), 2*n); // 2*n due to lapack::sycon() requirements
|
||||
blas_int info = 0;
|
||||
eT norm_val = eT(0);
|
||||
eT tmp_rcond = eT(0);
|
||||
|
||||
podarray<blas_int> ipiv(A.n_rows);
|
||||
podarray<blas_int> iwork(A.n_rows);
|
||||
|
||||
if( (2*n) > blas_int(podarray_prealloc_n_elem::val) )
|
||||
{
|
||||
eT work_query[2] = {};
|
||||
blas_int lwork_query = -1;
|
||||
|
||||
arma_debug_print("lapack::sytrf()");
|
||||
lapack::sytrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), &work_query[0], &lwork_query, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
blas_int lwork_proposed = static_cast<blas_int>( access::tmp_real(work_query[0]) );
|
||||
|
||||
lwork = (std::max)(lwork_proposed, lwork);
|
||||
}
|
||||
|
||||
podarray<eT> work( static_cast<uword>(lwork) );
|
||||
|
||||
arma_debug_print("lapack::lansy()");
|
||||
norm_val = (has_blas_float_bug<eT>::value) ? auxlib::norm1_sym(A) : lapack::lansy(&norm_id, &uplo, &n, A.memptr(), &n, work.memptr());
|
||||
|
||||
arma_debug_print("lapack::sytrf()");
|
||||
lapack::sytrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), work.memptr(), &lwork, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
arma_debug_print("lapack::sytrs()");
|
||||
lapack::sytrs(&uplo, &n, &nrhs, A.memptr(), &lda, ipiv.memptr(), out.memptr(), &ldb, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
arma_debug_print("lapack::sycon()");
|
||||
lapack::sycon(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), &norm_val, &tmp_rcond, work.memptr(), iwork.memptr(), &info);
|
||||
|
||||
out_rcond = tmp_rcond;
|
||||
|
||||
return (info == 0);
|
||||
}
|
||||
#else
|
||||
{
|
||||
arma_stop_logic_error("solve(): use of LAPACK must be enabled");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T1>
|
||||
inline
|
||||
bool
|
||||
auxlib::solve_sym_rcond(Mat< std::complex<typename T1::pod_type> >& out, typename T1::pod_type& out_rcond, Mat< std::complex<typename T1::pod_type> >& A, const Base< std::complex<typename T1::pod_type>,T1>& B_expr)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
out = B_expr.get_ref();
|
||||
|
||||
const uword B_n_rows = out.n_rows;
|
||||
const uword B_n_cols = out.n_cols;
|
||||
|
||||
arma_conform_check( (A.n_rows != B_n_rows), "solve(): number of rows in given matrices must be the same", [&](){ out.soft_reset(); } );
|
||||
|
||||
if(A.is_empty() || out.is_empty()) { out.zeros(A.n_cols, B_n_cols); return true; }
|
||||
|
||||
#if defined(ARMA_USE_LAPACK)
|
||||
{
|
||||
typedef typename T1::pod_type T;
|
||||
typedef typename std::complex<T> eT;
|
||||
|
||||
out_rcond = T(0);
|
||||
|
||||
arma_conform_assert_blas_size(A,out);
|
||||
|
||||
char norm_id = '1';
|
||||
char uplo = 'L';
|
||||
blas_int n = blas_int(A.n_rows);
|
||||
blas_int lda = blas_int(A.n_rows);
|
||||
blas_int ldb = blas_int(out.n_rows);
|
||||
blas_int nrhs = blas_int(out.n_cols);
|
||||
blas_int lwork = (std::max)(blas_int(podarray_prealloc_n_elem::val), 2*n); // 2*n due to lapack::hecon() requirements
|
||||
blas_int info = 0;
|
||||
T norm_val = T(0);
|
||||
T tmp_rcond = T(0);
|
||||
|
||||
podarray<blas_int> ipiv(A.n_rows);
|
||||
podarray<T> lanhe_work(A.n_rows);
|
||||
|
||||
if( (2*n) > blas_int(podarray_prealloc_n_elem::val) )
|
||||
{
|
||||
eT work_query[2] = {};
|
||||
blas_int lwork_query = -1;
|
||||
|
||||
arma_debug_print("lapack::hetrf()");
|
||||
lapack::hetrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), &work_query[0], &lwork_query, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
blas_int lwork_proposed = static_cast<blas_int>( access::tmp_real(work_query[0]) );
|
||||
|
||||
lwork = (std::max)(lwork_proposed, lwork);
|
||||
}
|
||||
|
||||
podarray<eT> work( static_cast<uword>(lwork) );
|
||||
|
||||
arma_debug_print("lapack::lanhe()");
|
||||
norm_val = (has_blas_float_bug<T>::value) ? auxlib::norm1_sym(A) : lapack::lanhe(&norm_id, &uplo, &n, A.memptr(), &lda, lanhe_work.memptr());
|
||||
|
||||
arma_debug_print("lapack::hetrf()");
|
||||
lapack::hetrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), work.memptr(), &lwork, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
arma_debug_print("lapack::hetrs()");
|
||||
lapack::hetrs(&uplo, &n, &nrhs, A.memptr(), &lda, ipiv.memptr(), out.memptr(), &ldb, &info);
|
||||
|
||||
if(info != 0) { return false; }
|
||||
|
||||
arma_debug_print("lapack::hecon()");
|
||||
lapack::hecon(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), &norm_val, &tmp_rcond, work.memptr(), &info);
|
||||
|
||||
out_rcond = tmp_rcond;
|
||||
|
||||
return (info == 0);
|
||||
}
|
||||
#else
|
||||
{
|
||||
arma_stop_logic_error("solve(): use of LAPACK must be enabled");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T1>
|
||||
inline
|
||||
bool
|
||||
@@ -6189,47 +6814,60 @@ auxlib::rcond(Mat< std::complex<T> >& A)
|
||||
template<typename eT>
|
||||
inline
|
||||
eT
|
||||
auxlib::rcond_sympd(Mat<eT>& A, bool& calc_ok)
|
||||
auxlib::rcond_sym(Mat<eT>& A)
|
||||
{
|
||||
#if defined(ARMA_USE_LAPACK)
|
||||
{
|
||||
arma_conform_assert_blas_size(A);
|
||||
|
||||
calc_ok = false;
|
||||
char norm_id = '1';
|
||||
char uplo = 'L';
|
||||
blas_int n = blas_int(A.n_rows);
|
||||
blas_int lda = blas_int(A.n_rows);
|
||||
blas_int lwork = (std::max)(blas_int(podarray_prealloc_n_elem::val), 2*n); // 2*n due to lapack::sycon() requirements
|
||||
blas_int info = 0;
|
||||
eT norm_val = eT(0);
|
||||
eT out_rcond = eT(0);
|
||||
|
||||
char norm_id = '1';
|
||||
char uplo = 'L';
|
||||
blas_int n = blas_int(A.n_rows); // assuming square matrix
|
||||
blas_int lda = blas_int(A.n_rows);
|
||||
eT norm_val = eT(0);
|
||||
eT rcond = eT(0);
|
||||
blas_int info = blas_int(0);
|
||||
podarray<blas_int> ipiv(A.n_rows);
|
||||
podarray<blas_int> iwork(A.n_rows);
|
||||
|
||||
podarray<eT> work(3*A.n_rows);
|
||||
podarray<blas_int> iwork( A.n_rows);
|
||||
if( (2*n) > blas_int(podarray_prealloc_n_elem::val) )
|
||||
{
|
||||
eT work_query[2] = {};
|
||||
blas_int lwork_query = -1;
|
||||
|
||||
arma_debug_print("lapack::sytrf()");
|
||||
lapack::sytrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), &work_query[0], &lwork_query, &info);
|
||||
|
||||
if(info != 0) { return eT(0); }
|
||||
|
||||
blas_int lwork_proposed = static_cast<blas_int>( access::tmp_real(work_query[0]) );
|
||||
|
||||
lwork = (std::max)(lwork_proposed, lwork);
|
||||
}
|
||||
|
||||
podarray<eT> work( static_cast<uword>(lwork) );
|
||||
|
||||
arma_debug_print("lapack::lansy()");
|
||||
norm_val = (has_blas_float_bug<eT>::value) ? auxlib::norm1_sym(A) : lapack::lansy(&norm_id, &uplo, &n, A.memptr(), &lda, work.memptr());
|
||||
|
||||
arma_debug_print("lapack::potrf()");
|
||||
lapack::potrf(&uplo, &n, A.memptr(), &lda, &info);
|
||||
arma_debug_print("lapack::sytrf()");
|
||||
lapack::sytrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), work.memptr(), &lwork, &info);
|
||||
|
||||
if(info != blas_int(0)) { return eT(0); }
|
||||
if(info != 0) { return eT(0); }
|
||||
|
||||
arma_debug_print("lapack::pocon()");
|
||||
lapack::pocon(&uplo, &n, A.memptr(), &lda, &norm_val, &rcond, work.memptr(), iwork.memptr(), &info);
|
||||
arma_debug_print("lapack::sycon()");
|
||||
lapack::sycon(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), &norm_val, &out_rcond, work.memptr(), iwork.memptr(), &info);
|
||||
|
||||
if(info != blas_int(0)) { return eT(0); }
|
||||
if(info != 0) { return eT(0); }
|
||||
|
||||
calc_ok = true;
|
||||
|
||||
return rcond;
|
||||
return out_rcond;
|
||||
}
|
||||
#else
|
||||
{
|
||||
arma_ignore(A);
|
||||
calc_ok = false;
|
||||
arma_stop_logic_error("rcond(): use of LAPACK must be enabled");
|
||||
arma_stop_logic_error("rcond_sym(): use of LAPACK must be enabled");
|
||||
return eT(0);
|
||||
}
|
||||
#endif
|
||||
@@ -6240,13 +6878,13 @@ auxlib::rcond_sympd(Mat<eT>& A, bool& calc_ok)
|
||||
template<typename T>
|
||||
inline
|
||||
T
|
||||
auxlib::rcond_sympd(Mat< std::complex<T> >& A, bool& calc_ok)
|
||||
auxlib::rcond_sym(Mat< std::complex<T> >& A)
|
||||
{
|
||||
// NOTE: the function name is required for overloading, but is a misnomer: it processes complex hermitian matrices
|
||||
|
||||
#if defined(ARMA_CRIPPLED_LAPACK)
|
||||
{
|
||||
arma_debug_print("auxlib::rcond_sympd(): redirecting to auxlib::rcond() due to crippled LAPACK");
|
||||
|
||||
calc_ok = true;
|
||||
arma_debug_print("auxlib::rcond_sym(): redirecting to auxlib::rcond() due to crippled LAPACK");
|
||||
|
||||
return auxlib::rcond(A);
|
||||
}
|
||||
@@ -6256,41 +6894,54 @@ auxlib::rcond_sympd(Mat< std::complex<T> >& A, bool& calc_ok)
|
||||
|
||||
arma_conform_assert_blas_size(A);
|
||||
|
||||
calc_ok = false;
|
||||
char norm_id = '1';
|
||||
char uplo = 'L';
|
||||
blas_int n = blas_int(A.n_rows);
|
||||
blas_int lda = blas_int(A.n_rows);
|
||||
blas_int lwork = (std::max)(blas_int(podarray_prealloc_n_elem::val), 2*n); // 2*n due to lapack::hecon() requirements
|
||||
blas_int info = 0;
|
||||
T norm_val = T(0);
|
||||
T out_rcond = T(0);
|
||||
|
||||
char norm_id = '1';
|
||||
char uplo = 'L';
|
||||
blas_int n = blas_int(A.n_rows); // assuming square matrix
|
||||
blas_int lda = blas_int(A.n_rows);
|
||||
T norm_val = T(0);
|
||||
T rcond = T(0);
|
||||
blas_int info = blas_int(0);
|
||||
podarray<blas_int> ipiv(A.n_rows);
|
||||
podarray<T> lanhe_work(A.n_rows);
|
||||
|
||||
podarray<eT> work(2*A.n_rows);
|
||||
podarray< T> rwork( A.n_rows);
|
||||
if( (2*n) > blas_int(podarray_prealloc_n_elem::val) )
|
||||
{
|
||||
eT work_query[2] = {};
|
||||
blas_int lwork_query = -1;
|
||||
|
||||
arma_debug_print("lapack::hetrf()");
|
||||
lapack::hetrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), &work_query[0], &lwork_query, &info);
|
||||
|
||||
if(info != 0) { return T(0); }
|
||||
|
||||
blas_int lwork_proposed = static_cast<blas_int>( access::tmp_real(work_query[0]) );
|
||||
|
||||
lwork = (std::max)(lwork_proposed, lwork);
|
||||
}
|
||||
|
||||
podarray<eT> work( static_cast<uword>(lwork) );
|
||||
|
||||
arma_debug_print("lapack::lanhe()");
|
||||
norm_val = (has_blas_float_bug<eT>::value) ? auxlib::norm1_sym(A) : lapack::lanhe(&norm_id, &uplo, &n, A.memptr(), &lda, rwork.memptr());
|
||||
norm_val = (has_blas_float_bug<T>::value) ? auxlib::norm1_sym(A) : lapack::lanhe(&norm_id, &uplo, &n, A.memptr(), &lda, lanhe_work.memptr());
|
||||
|
||||
arma_debug_print("lapack::potrf()");
|
||||
lapack::potrf(&uplo, &n, A.memptr(), &lda, &info);
|
||||
arma_debug_print("lapack::hetrf()");
|
||||
lapack::hetrf(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), work.memptr(), &lwork, &info);
|
||||
|
||||
if(info != blas_int(0)) { return T(0); }
|
||||
if(info != 0) { return T(0); }
|
||||
|
||||
arma_debug_print("lapack::cx_pocon()");
|
||||
lapack::cx_pocon(&uplo, &n, A.memptr(), &lda, &norm_val, &rcond, work.memptr(), rwork.memptr(), &info);
|
||||
arma_debug_print("lapack::hecon()");
|
||||
lapack::hecon(&uplo, &n, A.memptr(), &lda, ipiv.memptr(), &norm_val, &out_rcond, work.memptr(), &info);
|
||||
|
||||
if(info != blas_int(0)) { return T(0); }
|
||||
if(info != 0) { return T(0); }
|
||||
|
||||
calc_ok = true;
|
||||
|
||||
return rcond;
|
||||
return out_rcond;
|
||||
}
|
||||
#else
|
||||
{
|
||||
arma_ignore(A);
|
||||
calc_ok = false;
|
||||
arma_stop_logic_error("rcond(): use of LAPACK must be enabled");
|
||||
arma_stop_logic_error("rcond_sym(): use of LAPACK must be enabled");
|
||||
return T(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -83,10 +83,8 @@
|
||||
#endif
|
||||
|
||||
|
||||
#if (!defined(ARMA_HAVE_CXX14))
|
||||
#if (!defined(ARMA_IGNORE_DEPRECATED_MARKER)) || defined(ARMA_DONT_IGNORE_DEPRECATED_MARKER) || defined(ARMA_DEBUG)
|
||||
#pragma message ("INFO: support for C++11 is deprecated")
|
||||
#endif
|
||||
#if (!defined(ARMA_HAVE_CXX14)) && (!defined(ARMA_IGNORE_DEPRECATED_MARKER))
|
||||
#pragma message ("INFO: support for C++11 is deprecated; minimum recommended standard is C++14")
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -168,6 +168,10 @@
|
||||
// gcc 6.1 has proper C++14 support and fixes an OpenMP related bug:
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=57580
|
||||
|
||||
#if (ARMA_GCC_VERSION < 80100)
|
||||
#pragma message("INFO: support for GCC versions older than 8.1 is deprecated")
|
||||
#endif
|
||||
|
||||
#define ARMA_GOOD_COMPILER
|
||||
|
||||
#undef arma_hot
|
||||
@@ -310,7 +314,7 @@
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
#if (_MSC_VER < 1900)
|
||||
#if (_MSC_VER < 1910)
|
||||
#error "*** newer compiler required ***"
|
||||
#endif
|
||||
|
||||
@@ -473,11 +477,10 @@
|
||||
#undef major
|
||||
|
||||
|
||||
// optionally allow disabling of compile-time deprecation messages (not recommended)
|
||||
// NOTE: option 'ARMA_IGNORE_DEPRECATED_MARKER' will be removed
|
||||
// NOTE: disabling deprecation messages is counter-productive
|
||||
// WARNING: option 'ARMA_IGNORE_DEPRECATED_MARKER' will be removed;
|
||||
// WARNING: disabling deprecation messages is counter-productive
|
||||
|
||||
#if defined(ARMA_IGNORE_DEPRECATED_MARKER) && (!defined(ARMA_DONT_IGNORE_DEPRECATED_MARKER)) && (!defined(ARMA_DEBUG))
|
||||
#if defined(ARMA_IGNORE_DEPRECATED_MARKER)
|
||||
#undef arma_deprecated
|
||||
#define arma_deprecated
|
||||
|
||||
|
||||
@@ -102,11 +102,8 @@
|
||||
//// Uncomment the above line if your BLAS and LAPACK libraries have function names with a trailing underscore.
|
||||
//// Conversely, comment it out if the function names don't have a trailing underscore.
|
||||
|
||||
// #define ARMA_BLAS_LONG
|
||||
//// Uncomment the above line if your BLAS and LAPACK libraries use "long" instead of "int"
|
||||
|
||||
// #define ARMA_BLAS_LONG_LONG
|
||||
//// Uncomment the above line if your BLAS and LAPACK libraries use "long long" instead of "int"
|
||||
//// Uncomment the above line if your BLAS and LAPACK libraries use 64 bit integers, ie. "long long" instead of "int"
|
||||
|
||||
// #define ARMA_BLAS_NOEXCEPT
|
||||
//// Uncomment the above line if you require BLAS functions to have the 'noexcept' specification
|
||||
@@ -131,7 +128,7 @@
|
||||
//// Uncomment the above line to use Intel MKL types for complex numbers.
|
||||
//// You will need to include appropriate MKL headers before the Armadillo header.
|
||||
//// You may also need to enable or disable the following options:
|
||||
//// ARMA_BLAS_LONG, ARMA_BLAS_LONG_LONG, ARMA_USE_FORTRAN_HIDDEN_ARGS
|
||||
//// ARMA_BLAS_LONG_LONG, ARMA_USE_FORTRAN_HIDDEN_ARGS
|
||||
|
||||
#if !defined(ARMA_USE_OPENMP)
|
||||
// #define ARMA_USE_OPENMP
|
||||
@@ -306,6 +303,12 @@
|
||||
#undef ARMA_64BIT_WORD
|
||||
#endif
|
||||
|
||||
// for compatibility with earlier versions of Armadillo
|
||||
#if defined(ARMA_BLAS_LONG) || defined(ARMA_BLAS_LONG_LONG)
|
||||
#undef ARMA_BLAS_64BIT_INT
|
||||
#define ARMA_BLAS_64BIT_INT
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_OPTIMISE_BAND) || defined(ARMA_DONT_OPTIMISE_SOLVE_BAND)
|
||||
#undef ARMA_OPTIMISE_BAND
|
||||
#endif
|
||||
@@ -330,6 +333,10 @@
|
||||
#undef ARMA_CHECK_NONFINITE
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_IGNORE_DEPRECATED_MARKER)
|
||||
#undef ARMA_IGNORE_DEPRECATED_MARKER
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_NO_DEBUG)
|
||||
#undef ARMA_DEBUG
|
||||
#undef ARMA_EXTRA_DEBUG
|
||||
@@ -347,6 +354,8 @@
|
||||
|
||||
#undef ARMA_WARN_LEVEL
|
||||
#define ARMA_WARN_LEVEL 3
|
||||
|
||||
#undef ARMA_IGNORE_DEPRECATED_MARKER
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_PRINT_EXCEPTIONS)
|
||||
@@ -357,6 +366,15 @@
|
||||
#undef ARMA_CRIPPLED_LAPACK
|
||||
#endif
|
||||
|
||||
// WARNING: option ARMA_IGNORE_DEPRECATED_MARKER will be removed
|
||||
// WARNING: option ARMA_CRIPPLED_LAPACK will be removed
|
||||
|
||||
#if defined(ARMA_CRIPPLED_LAPACK)
|
||||
#if (!defined(ARMA_IGNORE_DEPRECATED_MARKER))
|
||||
#pragma message ("option ARMA_CRIPPLED_LAPACK is deprecated and will be removed")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// if Armadillo was installed on this system via CMake and ARMA_USE_WRAPPER is not defined,
|
||||
// ARMA_AUX_LIBS lists the libraries required by Armadillo on this system, and
|
||||
|
||||
@@ -102,11 +102,8 @@
|
||||
//// Uncomment the above line if your BLAS and LAPACK libraries have function names with a trailing underscore.
|
||||
//// Conversely, comment it out if the function names don't have a trailing underscore.
|
||||
|
||||
// #define ARMA_BLAS_LONG
|
||||
//// Uncomment the above line if your BLAS and LAPACK libraries use "long" instead of "int"
|
||||
|
||||
// #define ARMA_BLAS_LONG_LONG
|
||||
//// Uncomment the above line if your BLAS and LAPACK libraries use "long long" instead of "int"
|
||||
//// Uncomment the above line if your BLAS and LAPACK libraries use 64 bit integers, ie. "long long" instead of "int"
|
||||
|
||||
// #define ARMA_BLAS_NOEXCEPT
|
||||
//// Uncomment the above line if you require BLAS functions to have the 'noexcept' specification
|
||||
@@ -131,7 +128,7 @@
|
||||
//// Uncomment the above line to use Intel MKL types for complex numbers.
|
||||
//// You will need to include appropriate MKL headers before the Armadillo header.
|
||||
//// You may also need to enable or disable the following options:
|
||||
//// ARMA_BLAS_LONG, ARMA_BLAS_LONG_LONG, ARMA_USE_FORTRAN_HIDDEN_ARGS
|
||||
//// ARMA_BLAS_LONG_LONG, ARMA_USE_FORTRAN_HIDDEN_ARGS
|
||||
|
||||
#if !defined(ARMA_USE_OPENMP)
|
||||
// #define ARMA_USE_OPENMP
|
||||
@@ -306,6 +303,12 @@
|
||||
#undef ARMA_64BIT_WORD
|
||||
#endif
|
||||
|
||||
// for compatibility with earlier versions of Armadillo
|
||||
#if defined(ARMA_BLAS_LONG) || defined(ARMA_BLAS_LONG_LONG)
|
||||
#undef ARMA_BLAS_64BIT_INT
|
||||
#define ARMA_BLAS_64BIT_INT
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_OPTIMISE_BAND) || defined(ARMA_DONT_OPTIMISE_SOLVE_BAND)
|
||||
#undef ARMA_OPTIMISE_BAND
|
||||
#endif
|
||||
@@ -330,6 +333,10 @@
|
||||
#undef ARMA_CHECK_NONFINITE
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_IGNORE_DEPRECATED_MARKER)
|
||||
#undef ARMA_IGNORE_DEPRECATED_MARKER
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_NO_DEBUG)
|
||||
#undef ARMA_DEBUG
|
||||
#undef ARMA_EXTRA_DEBUG
|
||||
@@ -347,6 +354,8 @@
|
||||
|
||||
#undef ARMA_WARN_LEVEL
|
||||
#define ARMA_WARN_LEVEL 3
|
||||
|
||||
#undef ARMA_IGNORE_DEPRECATED_MARKER
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_PRINT_EXCEPTIONS)
|
||||
@@ -357,6 +366,15 @@
|
||||
#undef ARMA_CRIPPLED_LAPACK
|
||||
#endif
|
||||
|
||||
// WARNING: option ARMA_IGNORE_DEPRECATED_MARKER will be removed
|
||||
// WARNING: option ARMA_CRIPPLED_LAPACK will be removed
|
||||
|
||||
#if defined(ARMA_CRIPPLED_LAPACK)
|
||||
#if (!defined(ARMA_IGNORE_DEPRECATED_MARKER))
|
||||
#pragma message ("option ARMA_CRIPPLED_LAPACK is deprecated and will be removed")
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// if Armadillo was installed on this system via CMake and ARMA_USE_WRAPPER is not defined,
|
||||
// ARMA_AUX_LIBS lists the libraries required by Armadillo on this system, and
|
||||
|
||||
@@ -269,6 +269,30 @@
|
||||
#define arma_cpstrf cpstrf
|
||||
#define arma_zpstrf zpstrf
|
||||
|
||||
#define arma_ssytrf ssytrf
|
||||
#define arma_dsytrf dsytrf
|
||||
|
||||
#define arma_chetrf chetrf
|
||||
#define arma_zhetrf zhetrf
|
||||
|
||||
#define arma_ssytrs ssytrs
|
||||
#define arma_dsytrs dsytrs
|
||||
|
||||
#define arma_chetrs chetrs
|
||||
#define arma_zhetrs zhetrs
|
||||
|
||||
#define arma_ssytri ssytri
|
||||
#define arma_dsytri dsytri
|
||||
|
||||
#define arma_chetri chetri
|
||||
#define arma_zhetri zhetri
|
||||
|
||||
#define arma_ssycon ssycon
|
||||
#define arma_dsycon dsycon
|
||||
|
||||
#define arma_checon checon
|
||||
#define arma_zhecon zhecon
|
||||
|
||||
#else
|
||||
|
||||
#define arma_sgetrf SGETRF
|
||||
@@ -505,6 +529,30 @@
|
||||
#define arma_cpstrf CPSTRF
|
||||
#define arma_zpstrf ZPSTRF
|
||||
|
||||
#define arma_ssytrf SSYTRF
|
||||
#define arma_dsytrf DSYTRF
|
||||
|
||||
#define arma_chetrf CHETRF
|
||||
#define arma_zhetrf ZHETRF
|
||||
|
||||
#define arma_ssytrs SSYTRS
|
||||
#define arma_dsytrs DSYTRS
|
||||
|
||||
#define arma_chetrs CHETRS
|
||||
#define arma_zhetrs ZHETRS
|
||||
|
||||
#define arma_ssytri SSYTRI
|
||||
#define arma_dsytri DSYTRI
|
||||
|
||||
#define arma_chetri CHETRI
|
||||
#define arma_zhetri ZHETRI
|
||||
|
||||
#define arma_ssycon SSYCON
|
||||
#define arma_dsycon DSYCON
|
||||
|
||||
#define arma_checon CHECON
|
||||
#define arma_zhecon ZHECON
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -846,6 +894,38 @@ extern "C"
|
||||
void arma_fortran(arma_cpstrf)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* piv, blas_int* rank, const float* tol, float* work, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_zpstrf)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* piv, blas_int* rank, const double* tol, double* work, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
|
||||
// factorisation of symmetric matrix (real)
|
||||
void arma_fortran(arma_ssytrf)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, blas_int* ipiv, float* work, const blas_int* lwork, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_dsytrf)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, blas_int* ipiv, double* work, const blas_int* lwork, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
|
||||
// factorisation of hermitian matrix (complex)
|
||||
void arma_fortran(arma_chetrf)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* ipiv, blas_cxf* work, const blas_int* lwork, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_zhetrf)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* ipiv, blas_cxd* work, const blas_int* lwork, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
|
||||
// solve system using pre-computed factorisation (real)
|
||||
void arma_fortran(arma_ssytrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const float* a, const blas_int* lda, const blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_dsytrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const double* a, const blas_int* lda, const blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
|
||||
// solve system using pre-computed factorisation (complex)
|
||||
void arma_fortran(arma_chetrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const blas_cxf* a, const blas_int* lda, const blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_zhetrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const blas_cxd* a, const blas_int* lda, const blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
|
||||
// inverse of symmetric matrix using pre-computed factorisation (real)
|
||||
void arma_fortran(arma_ssytri)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, const blas_int* ipiv, float* work, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_dsytri)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, const blas_int* ipiv, double* work, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
|
||||
// inverse of hermitian matrix using pre-computed factorisation (complex)
|
||||
void arma_fortran(arma_chetri)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, const blas_int* ipiv, blas_cxf* work, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_zhetri)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, const blas_int* ipiv, blas_cxd* work, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
|
||||
// rcond of symmetric matrix using pre-computed factorisation (real)
|
||||
void arma_fortran(arma_ssycon)(const char* uplo, const blas_int* n, const float* a, const blas_int* lda, const blas_int* ipiv, const float* anorm, float* rcond, float* work, blas_int* iwork, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_dsycon)(const char* uplo, const blas_int* n, const double* a, const blas_int* lda, const blas_int* ipiv, const double* anorm, double* rcond, double* work, blas_int* iwork, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
|
||||
// rcond of hermitian matrix using pre-computed factorisation (complex)
|
||||
void arma_fortran(arma_checon)(const char* uplo, const blas_int* n, const blas_cxf* a, const blas_int* lda, const blas_int* ipiv, const float* anorm, float* rcond, blas_cxf* work, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_zhecon)(const char* uplo, const blas_int* n, const blas_cxd* a, const blas_int* lda, const blas_int* ipiv, const double* anorm, double* rcond, blas_cxd* work, blas_int* info, blas_len uplo_len) ARMA_NOEXCEPT;
|
||||
|
||||
#else
|
||||
|
||||
// prototypes without hidden arguments
|
||||
@@ -1170,6 +1250,38 @@ extern "C"
|
||||
void arma_fortran(arma_cpstrf)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* piv, blas_int* rank, const float* tol, float* work, blas_int* info) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_zpstrf)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* piv, blas_int* rank, const double* tol, double* work, blas_int* info) ARMA_NOEXCEPT;
|
||||
|
||||
// factorisation of symmetric matrix (real)
|
||||
void arma_fortran(arma_ssytrf)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, blas_int* ipiv, float* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_dsytrf)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, blas_int* ipiv, double* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT;
|
||||
|
||||
// factorisation of hermitian matrix (complex)
|
||||
void arma_fortran(arma_chetrf)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* ipiv, blas_cxf* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_zhetrf)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* ipiv, blas_cxd* work, const blas_int* lwork, blas_int* info) ARMA_NOEXCEPT;
|
||||
|
||||
// solve system using pre-computed factorisation (real)
|
||||
void arma_fortran(arma_ssytrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const float* a, const blas_int* lda, const blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_dsytrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const double* a, const blas_int* lda, const blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT;
|
||||
|
||||
// solve system using pre-computed factorisation (complex)
|
||||
void arma_fortran(arma_zhetrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const blas_cxd* a, const blas_int* lda, const blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_chetrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const blas_cxf* a, const blas_int* lda, const blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info) ARMA_NOEXCEPT;
|
||||
|
||||
// inverse of symmetric matrix using pre-computed factorisation (real)
|
||||
void arma_fortran(arma_ssytri)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, const blas_int* ipiv, float* work, blas_int* info) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_dsytri)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, const blas_int* ipiv, double* work, blas_int* info) ARMA_NOEXCEPT;
|
||||
|
||||
// inverse of hermitian matrix using pre-computed factorisation (complex)
|
||||
void arma_fortran(arma_chetri)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, const blas_int* ipiv, blas_cxf* work, blas_int* info) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_zhetri)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, const blas_int* ipiv, blas_cxd* work, blas_int* info) ARMA_NOEXCEPT;
|
||||
|
||||
// rcond of symmetric matrix using pre-computed factorisation (real)
|
||||
void arma_fortran(arma_ssycon)(const char* uplo, const blas_int* n, const float* a, const blas_int* lda, const blas_int* ipiv, const float* anorm, float* rcond, float* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_dsycon)(const char* uplo, const blas_int* n, const double* a, const blas_int* lda, const blas_int* ipiv, const double* anorm, double* rcond, double* work, blas_int* iwork, blas_int* info) ARMA_NOEXCEPT;
|
||||
|
||||
// rcond of hermitian matrix using pre-computed factorisation (complex)
|
||||
void arma_fortran(arma_checon)(const char* uplo, const blas_int* n, const blas_cxf* a, const blas_int* lda, const blas_int* ipiv, const float* anorm, float* rcond, blas_cxf* work, blas_int* info) ARMA_NOEXCEPT;
|
||||
void arma_fortran(arma_zhecon)(const char* uplo, const blas_int* n, const blas_cxd* a, const blas_int* lda, const blas_int* ipiv, const double* anorm, double* rcond, blas_cxd* work, blas_int* info) ARMA_NOEXCEPT;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -108,6 +108,9 @@ class diagview : public Base< eT, diagview<eT> >
|
||||
inline static void schur_inplace(Mat<eT>& out, const diagview& in);
|
||||
inline static void div_inplace(Mat<eT>& out, const diagview& in);
|
||||
|
||||
template<typename eT2>
|
||||
inline bool is_alias(const Mat<eT2>& X) const;
|
||||
|
||||
|
||||
friend class Mat<eT>;
|
||||
friend class subview<eT>;
|
||||
|
||||
@@ -236,13 +236,13 @@ diagview<eT>::operator= (const Base<eT,T1>& o)
|
||||
"diagview: given object has incompatible size"
|
||||
);
|
||||
|
||||
const bool is_alias = P.is_alias(d_m);
|
||||
const bool have_alias = P.is_alias(d_m);
|
||||
|
||||
if(is_alias) { arma_debug_print("aliasing detected"); }
|
||||
if(have_alias) { arma_debug_print("aliasing detected"); }
|
||||
|
||||
if( (is_Mat<typename Proxy<T1>::stored_type>::value) || (Proxy<T1>::use_at) || (is_alias) )
|
||||
if( (is_Mat<typename Proxy<T1>::stored_type>::value) || (Proxy<T1>::use_at) || (have_alias) )
|
||||
{
|
||||
const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, is_alias);
|
||||
const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, have_alias);
|
||||
const Mat<eT>& x = tmp.M;
|
||||
|
||||
const eT* x_mem = x.memptr();
|
||||
@@ -309,13 +309,13 @@ diagview<eT>::operator+=(const Base<eT,T1>& o)
|
||||
"diagview: given object has incompatible size"
|
||||
);
|
||||
|
||||
const bool is_alias = P.is_alias(d_m);
|
||||
const bool have_alias = P.is_alias(d_m);
|
||||
|
||||
if(is_alias) { arma_debug_print("aliasing detected"); }
|
||||
if(have_alias) { arma_debug_print("aliasing detected"); }
|
||||
|
||||
if( (is_Mat<typename Proxy<T1>::stored_type>::value) || (Proxy<T1>::use_at) || (is_alias) )
|
||||
if( (is_Mat<typename Proxy<T1>::stored_type>::value) || (Proxy<T1>::use_at) || (have_alias) )
|
||||
{
|
||||
const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, is_alias);
|
||||
const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, have_alias);
|
||||
const Mat<eT>& x = tmp.M;
|
||||
|
||||
const eT* x_mem = x.memptr();
|
||||
@@ -382,13 +382,13 @@ diagview<eT>::operator-=(const Base<eT,T1>& o)
|
||||
"diagview: given object has incompatible size"
|
||||
);
|
||||
|
||||
const bool is_alias = P.is_alias(d_m);
|
||||
const bool have_alias = P.is_alias(d_m);
|
||||
|
||||
if(is_alias) { arma_debug_print("aliasing detected"); }
|
||||
if(have_alias) { arma_debug_print("aliasing detected"); }
|
||||
|
||||
if( (is_Mat<typename Proxy<T1>::stored_type>::value) || (Proxy<T1>::use_at) || (is_alias) )
|
||||
if( (is_Mat<typename Proxy<T1>::stored_type>::value) || (Proxy<T1>::use_at) || (have_alias) )
|
||||
{
|
||||
const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, is_alias);
|
||||
const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, have_alias);
|
||||
const Mat<eT>& x = tmp.M;
|
||||
|
||||
const eT* x_mem = x.memptr();
|
||||
@@ -455,13 +455,13 @@ diagview<eT>::operator%=(const Base<eT,T1>& o)
|
||||
"diagview: given object has incompatible size"
|
||||
);
|
||||
|
||||
const bool is_alias = P.is_alias(d_m);
|
||||
const bool have_alias = P.is_alias(d_m);
|
||||
|
||||
if(is_alias) { arma_debug_print("aliasing detected"); }
|
||||
if(have_alias) { arma_debug_print("aliasing detected"); }
|
||||
|
||||
if( (is_Mat<typename Proxy<T1>::stored_type>::value) || (Proxy<T1>::use_at) || (is_alias) )
|
||||
if( (is_Mat<typename Proxy<T1>::stored_type>::value) || (Proxy<T1>::use_at) || (have_alias) )
|
||||
{
|
||||
const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, is_alias);
|
||||
const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, have_alias);
|
||||
const Mat<eT>& x = tmp.M;
|
||||
|
||||
const eT* x_mem = x.memptr();
|
||||
@@ -528,13 +528,13 @@ diagview<eT>::operator/=(const Base<eT,T1>& o)
|
||||
"diagview: given object has incompatible size"
|
||||
);
|
||||
|
||||
const bool is_alias = P.is_alias(d_m);
|
||||
const bool have_alias = P.is_alias(d_m);
|
||||
|
||||
if(is_alias) { arma_debug_print("aliasing detected"); }
|
||||
if(have_alias) { arma_debug_print("aliasing detected"); }
|
||||
|
||||
if( (is_Mat<typename Proxy<T1>::stored_type>::value) || (Proxy<T1>::use_at) || (is_alias) )
|
||||
if( (is_Mat<typename Proxy<T1>::stored_type>::value) || (Proxy<T1>::use_at) || (have_alias) )
|
||||
{
|
||||
const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, is_alias);
|
||||
const unwrap_check<typename Proxy<T1>::stored_type> tmp(P.Q, have_alias);
|
||||
const Mat<eT>& x = tmp.M;
|
||||
|
||||
const eT* x_mem = x.memptr();
|
||||
@@ -1022,4 +1022,17 @@ diagview<eT>::randn()
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
template<typename eT2>
|
||||
inline
|
||||
bool
|
||||
diagview<eT>::is_alias(const Mat<eT2>& X) const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
return m.is_alias(X);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
@@ -44,6 +44,9 @@ class eGlue : public Base< typename T1::elem_type, eGlue<T1, T2, eglue_type> >
|
||||
arma_inline ~eGlue();
|
||||
arma_inline eGlue(const T1& in_A, const T2& in_B);
|
||||
|
||||
template<typename eT2>
|
||||
inline bool is_alias(const Mat<eT2>& X) const;
|
||||
|
||||
arma_inline uword get_n_rows() const;
|
||||
arma_inline uword get_n_cols() const;
|
||||
arma_inline uword get_n_elem() const;
|
||||
|
||||
@@ -49,6 +49,17 @@ eGlue<T1,T2,eglue_type>::eGlue(const T1& in_A, const T2& in_B)
|
||||
|
||||
|
||||
|
||||
template<typename T1, typename T2, typename eglue_type>
|
||||
template<typename eT2>
|
||||
inline
|
||||
bool
|
||||
eGlue<T1,T2,eglue_type>::is_alias(const Mat<eT2>& X) const
|
||||
{
|
||||
return (P1.is_alias(X) || P2.is_alias(X));
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T1, typename T2, typename eglue_type>
|
||||
arma_inline
|
||||
uword
|
||||
|
||||
@@ -50,6 +50,9 @@ class eOp : public Base< typename T1::elem_type, eOp<T1, eop_type> >
|
||||
inline eOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
|
||||
inline eOp(const T1& in_m, const elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b);
|
||||
|
||||
template<typename eT2>
|
||||
inline bool is_alias(const Mat<eT2>& X) const;
|
||||
|
||||
arma_inline uword get_n_rows() const;
|
||||
arma_inline uword get_n_cols() const;
|
||||
arma_inline uword get_n_elem() const;
|
||||
|
||||
@@ -74,7 +74,20 @@ eOp<T1, eop_type>::~eOp()
|
||||
arma_debug_sigprint();
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T1, typename eop_type>
|
||||
template<typename eT2>
|
||||
inline
|
||||
bool
|
||||
eOp<T1, eop_type>::is_alias(const Mat<eT2>& X) const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
return P.is_alias(X);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T1, typename eop_type>
|
||||
arma_inline
|
||||
|
||||
@@ -50,7 +50,8 @@ class fft_engine_fftw3
|
||||
podarray<cx_type> Y_work; // for storing output
|
||||
|
||||
inline
|
||||
~fft_engine_fftw3()
|
||||
void
|
||||
finish()
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
@@ -59,6 +60,33 @@ class fft_engine_fftw3
|
||||
// fftw3::cleanup<cx_type>(); // NOTE: this also removes any wisdom acquired by FFTW3
|
||||
}
|
||||
|
||||
inline
|
||||
~fft_engine_fftw3()
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
#if defined(ARMA_USE_OPENMP)
|
||||
{
|
||||
#pragma omp critical (arma_fft_engine_fftw3)
|
||||
{
|
||||
(*this).finish();
|
||||
}
|
||||
}
|
||||
#elif defined(ARMA_USE_STD_MUTEX)
|
||||
{
|
||||
std::mutex& plan_mutex = fft_engine_fftw3_aux::get_plan_mutex();
|
||||
|
||||
const std::lock_guard<std::mutex> lock(plan_mutex);
|
||||
|
||||
(*this).finish();
|
||||
}
|
||||
#else
|
||||
{
|
||||
(*this).finish();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
inline
|
||||
fft_engine_fftw3(const uword in_N)
|
||||
: N (in_N )
|
||||
|
||||
@@ -531,7 +531,7 @@ field<oT>::at(const uword i) const
|
||||
|
||||
|
||||
|
||||
//! linear element accessor (treats the field as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
|
||||
//! linear element accessor (treats the field as a vector); bounds checking not done when ARMA_DONT_CHECK_CONFORMANCE is defined
|
||||
template<typename oT>
|
||||
arma_inline
|
||||
oT&
|
||||
@@ -544,7 +544,7 @@ field<oT>::operator() (const uword i)
|
||||
|
||||
|
||||
|
||||
//! linear element accessor (treats the field as a vector); bounds checking not done when ARMA_NO_DEBUG is defined
|
||||
//! linear element accessor (treats the field as a vector); bounds checking not done when ARMA_DONT_CHECK_CONFORMANCE is defined
|
||||
template<typename oT>
|
||||
arma_inline
|
||||
const oT&
|
||||
@@ -557,7 +557,7 @@ field<oT>::operator() (const uword i) const
|
||||
|
||||
|
||||
|
||||
//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
|
||||
//! element accessor; bounds checking not done when ARMA_DONT_CHECK_CONFORMANCE is defined
|
||||
template<typename oT>
|
||||
arma_inline
|
||||
oT&
|
||||
@@ -570,7 +570,7 @@ field<oT>::operator() (const uword in_row, const uword in_col)
|
||||
|
||||
|
||||
|
||||
//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
|
||||
//! element accessor; bounds checking not done when ARMA_DONT_CHECK_CONFORMANCE is defined
|
||||
template<typename oT>
|
||||
arma_inline
|
||||
const oT&
|
||||
@@ -583,7 +583,7 @@ field<oT>::operator() (const uword in_row, const uword in_col) const
|
||||
|
||||
|
||||
|
||||
//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
|
||||
//! element accessor; bounds checking not done when ARMA_DONT_CHECK_CONFORMANCE is defined
|
||||
template<typename oT>
|
||||
arma_inline
|
||||
oT&
|
||||
@@ -596,7 +596,7 @@ field<oT>::operator() (const uword in_row, const uword in_col, const uword in_sl
|
||||
|
||||
|
||||
|
||||
//! element accessor; bounds checking not done when ARMA_NO_DEBUG is defined
|
||||
//! element accessor; bounds checking not done when ARMA_DONT_CHECK_CONFORMANCE is defined
|
||||
template<typename oT>
|
||||
arma_inline
|
||||
const oT&
|
||||
|
||||
@@ -840,7 +840,7 @@ accu(const BaseCube<typename T1::elem_type,T1>& X)
|
||||
|
||||
if(is_Cube<typename ProxyCube<T1>::stored_type>::value)
|
||||
{
|
||||
unwrap_cube<typename ProxyCube<T1>::stored_type> tmp(P.Q);
|
||||
const unwrap_cube<typename ProxyCube<T1>::stored_type> tmp(P.Q);
|
||||
|
||||
return arrayops::accumulate(tmp.M.memptr(), tmp.M.n_elem);
|
||||
}
|
||||
@@ -993,6 +993,8 @@ accu(const SpGlue<T1,T2,spglue_schur>& expr)
|
||||
const SpProxy<T1> px(expr.A);
|
||||
const SpProxy<T2> py(expr.B);
|
||||
|
||||
arma_conform_assert_same_size(px.get_n_rows(), px.get_n_cols(), py.get_n_rows(), py.get_n_cols(), "element-wise multiplication");
|
||||
|
||||
typename SpProxy<T1>::const_iterator_type x_it = px.begin();
|
||||
typename SpProxy<T1>::const_iterator_type x_it_end = px.end();
|
||||
|
||||
|
||||
@@ -147,46 +147,6 @@ logspace(const double A, const double B, const uword N = 50u)
|
||||
|
||||
|
||||
|
||||
//
|
||||
// log_exp_add
|
||||
|
||||
template<typename eT>
|
||||
arma_warn_unused
|
||||
inline
|
||||
typename arma_real_only<eT>::result
|
||||
log_add_exp(eT log_a, eT log_b)
|
||||
{
|
||||
if(log_a < log_b)
|
||||
{
|
||||
std::swap(log_a, log_b);
|
||||
}
|
||||
|
||||
const eT negdelta = log_b - log_a;
|
||||
|
||||
if( (negdelta < Datum<eT>::log_min) || (arma_isfinite(negdelta) == false) )
|
||||
{
|
||||
return log_a;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (log_a + std::log1p(std::exp(negdelta)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// for compatibility with earlier versions
|
||||
template<typename eT>
|
||||
arma_warn_unused
|
||||
inline
|
||||
typename arma_real_only<eT>::result
|
||||
log_add(eT log_a, eT log_b)
|
||||
{
|
||||
return log_add_exp(log_a, log_b);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! kept for compatibility with old user code
|
||||
template<typename eT>
|
||||
arma_warn_unused
|
||||
@@ -584,4 +544,54 @@ affmul(const T1& A, const T2& B)
|
||||
|
||||
|
||||
|
||||
namespace priv
|
||||
{
|
||||
// internal use only
|
||||
template<typename eT>
|
||||
arma_warn_unused
|
||||
inline
|
||||
typename arma_real_only<eT>::result
|
||||
internal_log_add_exp(eT log_a, eT log_b)
|
||||
{
|
||||
if(log_a < log_b) { std::swap(log_a, log_b); }
|
||||
|
||||
const eT negdelta = log_b - log_a;
|
||||
|
||||
if( (negdelta < Datum<eT>::log_min) || (arma_isfinite(negdelta) == false) )
|
||||
{
|
||||
return log_a;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (log_a + std::log1p(std::exp(negdelta)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// DO NOT USE; kept only for compatibility with old user code
|
||||
template<typename eT>
|
||||
arma_deprecated
|
||||
inline
|
||||
typename arma_real_only<eT>::result
|
||||
log_add_exp(eT log_a, eT log_b)
|
||||
{
|
||||
return priv::internal_log_add_exp(log_a, log_b);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// DO NOT USE; kept only for compatibility with old user code
|
||||
template<typename eT>
|
||||
arma_deprecated
|
||||
inline
|
||||
typename arma_real_only<eT>::result
|
||||
log_add(eT log_a, eT log_b)
|
||||
{
|
||||
return priv::internal_log_add_exp(log_a, log_b);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
template<typename T1, typename T2>
|
||||
arma_warn_unused
|
||||
arma_inline
|
||||
inline
|
||||
typename
|
||||
enable_if2
|
||||
<
|
||||
@@ -44,7 +44,7 @@ pow
|
||||
|
||||
|
||||
template<typename parent, unsigned int mode, typename T2>
|
||||
arma_warn_unused
|
||||
arma_deprecated
|
||||
inline
|
||||
Mat<typename parent::elem_type>
|
||||
pow
|
||||
@@ -62,7 +62,7 @@ pow
|
||||
|
||||
template<typename T1, typename T2>
|
||||
arma_warn_unused
|
||||
arma_inline
|
||||
inline
|
||||
const GlueCube<T1, T2, glue_powext>
|
||||
pow
|
||||
(
|
||||
@@ -78,7 +78,7 @@ pow
|
||||
|
||||
|
||||
template<typename eT, typename T2>
|
||||
arma_warn_unused
|
||||
arma_deprecated
|
||||
inline
|
||||
Cube<eT>
|
||||
pow
|
||||
@@ -100,7 +100,7 @@ pow
|
||||
|
||||
template<typename T1, typename T2>
|
||||
arma_warn_unused
|
||||
arma_inline
|
||||
inline
|
||||
typename
|
||||
enable_if2
|
||||
<
|
||||
@@ -121,7 +121,7 @@ pow
|
||||
|
||||
|
||||
template<typename parent, unsigned int mode, typename T2>
|
||||
arma_warn_unused
|
||||
arma_deprecated
|
||||
inline
|
||||
typename
|
||||
enable_if2
|
||||
@@ -144,7 +144,7 @@ pow
|
||||
|
||||
template<typename T1, typename T2>
|
||||
arma_warn_unused
|
||||
arma_inline
|
||||
inline
|
||||
const mtGlueCube<typename T1::elem_type, T1, T2, glue_powext_cx>
|
||||
pow
|
||||
(
|
||||
@@ -160,7 +160,7 @@ pow
|
||||
|
||||
|
||||
template<typename T, typename T2>
|
||||
arma_warn_unused
|
||||
arma_deprecated
|
||||
inline
|
||||
Cube< std::complex<T> >
|
||||
pow
|
||||
|
||||
@@ -140,6 +140,7 @@ namespace solve_opts
|
||||
static constexpr uword flag_refine = uword(1u << 9);
|
||||
static constexpr uword flag_no_trimat = uword(1u << 10);
|
||||
static constexpr uword flag_force_approx = uword(1u << 11);
|
||||
static constexpr uword flag_force_sym = uword(1u << 12);
|
||||
|
||||
struct opts_none : public opts { inline constexpr opts_none() : opts(flag_none ) {} };
|
||||
struct opts_fast : public opts { inline constexpr opts_fast() : opts(flag_fast ) {} };
|
||||
@@ -154,6 +155,7 @@ namespace solve_opts
|
||||
struct opts_refine : public opts { inline constexpr opts_refine() : opts(flag_refine ) {} };
|
||||
struct opts_no_trimat : public opts { inline constexpr opts_no_trimat() : opts(flag_no_trimat ) {} };
|
||||
struct opts_force_approx : public opts { inline constexpr opts_force_approx() : opts(flag_force_approx) {} };
|
||||
struct opts_force_sym : public opts { inline constexpr opts_force_sym() : opts(flag_force_sym ) {} };
|
||||
|
||||
static constexpr opts_none none;
|
||||
static constexpr opts_fast fast;
|
||||
@@ -168,6 +170,7 @@ namespace solve_opts
|
||||
static constexpr opts_refine refine;
|
||||
static constexpr opts_no_trimat no_trimat;
|
||||
static constexpr opts_force_approx force_approx;
|
||||
static constexpr opts_force_sym force_sym;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@ glue_solve_gen_full::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, const
|
||||
const bool refine = has_user_flags && bool(flags & solve_opts::flag_refine );
|
||||
const bool no_trimat = has_user_flags && bool(flags & solve_opts::flag_no_trimat );
|
||||
const bool force_approx = has_user_flags && bool(flags & solve_opts::flag_force_approx);
|
||||
const bool force_sym = has_user_flags && bool(flags & solve_opts::flag_force_sym );
|
||||
|
||||
if(has_user_flags)
|
||||
{
|
||||
@@ -114,10 +115,11 @@ glue_solve_gen_full::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, const
|
||||
if(refine ) { arma_debug_print("refine"); }
|
||||
if(no_trimat ) { arma_debug_print("no_trimat"); }
|
||||
if(force_approx) { arma_debug_print("force_approx"); }
|
||||
if(force_sym ) { arma_debug_print("force_sym"); }
|
||||
|
||||
arma_conform_check( (fast && equilibrate ), "solve(): options 'fast' and 'equilibrate' are mutually exclusive" );
|
||||
arma_conform_check( (fast && refine ), "solve(): options 'fast' and 'refine' are mutually exclusive" );
|
||||
arma_conform_check( (no_sympd && likely_sympd), "solve(): options 'no_sympd' and 'likely_sympd' are mutually exclusive" );
|
||||
arma_conform_check( (fast && equilibrate ), "solve(): options 'fast' and 'equilibrate' are mutually exclusive" );
|
||||
arma_conform_check( (fast && refine ), "solve(): options 'fast' and 'refine' are mutually exclusive" );
|
||||
arma_conform_check( (no_sympd && likely_sympd), "solve(): options 'no_sympd' and 'likely_sympd' are mutually exclusive" );
|
||||
}
|
||||
|
||||
Mat<eT> A = A_expr.get_ref();
|
||||
@@ -128,26 +130,34 @@ glue_solve_gen_full::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, const
|
||||
|
||||
arma_conform_check( no_approx, "solve(): options 'no_approx' and 'force_approx' are mutually exclusive" );
|
||||
|
||||
if(fast) { arma_warn(2, "solve(): option 'fast' ignored for forced approximate solution" ); }
|
||||
if(equilibrate) { arma_warn(2, "solve(): option 'equilibrate' ignored for forced approximate solution" ); }
|
||||
if(refine) { arma_warn(2, "solve(): option 'refine' ignored for forced approximate solution" ); }
|
||||
if(likely_sympd) { arma_warn(2, "solve(): option 'likely_sympd' ignored for forced approximate solution" ); }
|
||||
if(fast) { arma_warn(2, "solve(): option 'fast' ignored for forced approximate solution" ); }
|
||||
if(equilibrate) { arma_warn(2, "solve(): option 'equilibrate' ignored for forced approximate solution" ); }
|
||||
if(refine) { arma_warn(2, "solve(): option 'refine' ignored for forced approximate solution" ); }
|
||||
if(likely_sympd) { arma_warn(2, "solve(): option 'likely_sympd' ignored for forced approximate solution" ); }
|
||||
if(force_sym) { arma_warn(2, "solve(): option 'force_sym' ignored for forced approximate solution" ); }
|
||||
|
||||
return auxlib::solve_approx_svd(actual_out, A, B_expr.get_ref()); // A is overwritten
|
||||
}
|
||||
|
||||
if(force_sym)
|
||||
{
|
||||
if((arma_config::check_conform) && (auxlib::rudimentary_sym_check(A) == false))
|
||||
{
|
||||
if(is_cx<eT>::no ) { arma_warn(1, "solve(): option 'force_sym' enabled, but given matrix is not symmetric"); }
|
||||
if(is_cx<eT>::yes) { arma_warn(1, "solve(): option 'force_sym' enabled, but given matrix is not hermitian"); }
|
||||
}
|
||||
|
||||
if(likely_sympd) { arma_warn(2, "solve(): option 'likely_sympd' ignored for forced symmetric solver" ); }
|
||||
if(equilibrate) { arma_warn(2, "solve(): option 'force_sym' ignored as option 'equilibrate' is enabled (combination not implemented yet)" ); }
|
||||
if(refine) { arma_warn(2, "solve(): option 'force_sym' ignored as option 'refine' is enabled (combination not implemented yet)" ); }
|
||||
}
|
||||
|
||||
// A_expr and B_expr can be used more than once (sympd optimisation fails or approximate solution required),
|
||||
// so ensure they are not overwritten in case we have aliasing
|
||||
|
||||
bool is_alias = true; // assume we have aliasing until we can prove otherwise
|
||||
const bool is_alias = A_expr.get_ref().is_alias(actual_out) || B_expr.get_ref().is_alias(actual_out);
|
||||
|
||||
if(is_Mat<T1>::value && is_Mat<T2>::value)
|
||||
{
|
||||
const quasi_unwrap<T1> UA( A_expr.get_ref() );
|
||||
const quasi_unwrap<T2> UB( B_expr.get_ref() );
|
||||
|
||||
is_alias = UA.is_alias(actual_out) || UB.is_alias(actual_out);
|
||||
}
|
||||
if(is_alias) { arma_debug_print("glue_solve_gen_full::apply(): aliasing detected"); }
|
||||
|
||||
Mat<eT> tmp;
|
||||
Mat<eT>& out = (is_alias) ? tmp : actual_out;
|
||||
@@ -162,12 +172,13 @@ glue_solve_gen_full::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, const
|
||||
uword KL = 0;
|
||||
uword KU = 0;
|
||||
|
||||
const bool is_band = arma_config::optimise_band && ((no_band || auxlib::crippled_lapack(A)) ? false : band_helper::is_band(KL, KU, A, uword(32)));
|
||||
const bool is_band = arma_config::optimise_band && ( (no_band || force_sym || auxlib::crippled_lapack(A)) ? false : band_helper::is_band(KL, KU, A, uword(32)) );
|
||||
|
||||
const bool is_triu = (no_trimat || refine || equilibrate || likely_sympd || is_band ) ? false : trimat_helper::is_triu(A);
|
||||
const bool is_tril = (no_trimat || refine || equilibrate || likely_sympd || is_band || is_triu) ? false : trimat_helper::is_tril(A);
|
||||
const bool is_triu = (no_trimat || refine || equilibrate || likely_sympd || force_sym || is_band ) ? false : trimat_helper::is_triu(A);
|
||||
const bool is_tril = (no_trimat || refine || equilibrate || likely_sympd || force_sym || is_band || is_triu) ? false : trimat_helper::is_tril(A);
|
||||
|
||||
const bool try_sympd = arma_config::optimise_sym && ((no_sympd || auxlib::crippled_lapack(A) || is_band || is_triu || is_tril) ? false : (likely_sympd ? true : sym_helper::guess_sympd(A, uword(16))));
|
||||
const bool is_sym = arma_config::optimise_sym && ( (refine || equilibrate || likely_sympd || force_sym || is_band || is_triu || is_tril || auxlib::crippled_lapack(A)) ? false : is_sym_expr<T1>::eval(A_expr.get_ref()) );
|
||||
const bool try_sympd = arma_config::optimise_sym && ( ( no_sympd || is_sym || force_sym || is_band || is_triu || is_tril || auxlib::crippled_lapack(A)) ? false : (likely_sympd ? true : sym_helper::guess_sympd(A, uword(16))) );
|
||||
|
||||
if(fast)
|
||||
{
|
||||
@@ -201,6 +212,13 @@ glue_solve_gen_full::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, const
|
||||
status = auxlib::solve_trimat_fast(out, A, B_expr.get_ref(), layout);
|
||||
}
|
||||
else
|
||||
if(force_sym || is_sym)
|
||||
{
|
||||
arma_debug_print("glue_solve_gen_full::apply(): fast + sym");
|
||||
|
||||
status = auxlib::solve_sym_fast(out, A, B_expr.get_ref()); // A is overwritten
|
||||
}
|
||||
else
|
||||
if(try_sympd)
|
||||
{
|
||||
arma_debug_print("glue_solve_gen_full::apply(): fast + try_sympd");
|
||||
@@ -238,6 +256,10 @@ glue_solve_gen_full::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, const
|
||||
|
||||
status = auxlib::solve_band_refine(out, rcond, A, KL, KU, B_expr, equilibrate);
|
||||
}
|
||||
// else
|
||||
// if(force_sym || is_sym) // TODO: implement auxlib::solve_sym_refine()
|
||||
// {
|
||||
// }
|
||||
else
|
||||
if(try_sympd)
|
||||
{
|
||||
@@ -287,6 +309,13 @@ glue_solve_gen_full::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, const
|
||||
status = auxlib::solve_trimat_rcond(out, rcond, A, B_expr.get_ref(), layout);
|
||||
}
|
||||
else
|
||||
if(force_sym || is_sym)
|
||||
{
|
||||
arma_debug_print("glue_solve_gen_full::apply(): rcond + sym");
|
||||
|
||||
status = auxlib::solve_sym_rcond(out, rcond, A, B_expr.get_ref()); // A is overwritten
|
||||
}
|
||||
else
|
||||
if(try_sympd)
|
||||
{
|
||||
bool sympd_state = false;
|
||||
@@ -315,6 +344,7 @@ glue_solve_gen_full::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, const
|
||||
if(equilibrate) { arma_warn(2, "solve(): option 'equilibrate' ignored for non-square matrix" ); }
|
||||
if(refine) { arma_warn(2, "solve(): option 'refine' ignored for non-square matrix" ); }
|
||||
if(likely_sympd) { arma_warn(2, "solve(): option 'likely_sympd' ignored for non-square matrix" ); }
|
||||
if(force_sym) { arma_warn(2, "solve(): option 'force_sym' ignored for non-square matrix" ); }
|
||||
|
||||
if(fast)
|
||||
{
|
||||
@@ -406,14 +436,9 @@ glue_solve_tri_default::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, co
|
||||
|
||||
const uword layout = (triu) ? uword(0) : uword(1);
|
||||
|
||||
bool is_alias = true;
|
||||
const bool is_alias = A_expr.get_ref().is_alias(actual_out) || B_expr.get_ref().is_alias(actual_out);
|
||||
|
||||
if(is_Mat<T2>::value)
|
||||
{
|
||||
const quasi_unwrap<T2> UB(B_expr.get_ref());
|
||||
|
||||
is_alias = UA.is_alias(actual_out) || UB.is_alias(actual_out);
|
||||
}
|
||||
if(is_alias) { arma_debug_print("glue_solve_tri_default::apply(): aliasing detected"); }
|
||||
|
||||
T rcond = T(0);
|
||||
bool status = false;
|
||||
@@ -497,6 +522,7 @@ glue_solve_tri_full::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, const
|
||||
const bool refine = bool(flags & solve_opts::flag_refine );
|
||||
const bool no_trimat = bool(flags & solve_opts::flag_no_trimat );
|
||||
const bool force_approx = bool(flags & solve_opts::flag_force_approx);
|
||||
const bool force_sym = bool(flags & solve_opts::flag_force_sym );
|
||||
|
||||
arma_debug_print("glue_solve_tri_full::apply(): enabled flags:");
|
||||
|
||||
@@ -510,6 +536,10 @@ glue_solve_tri_full::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, const
|
||||
if(refine ) { arma_debug_print("refine"); }
|
||||
if(no_trimat ) { arma_debug_print("no_trimat"); }
|
||||
if(force_approx) { arma_debug_print("force_approx"); }
|
||||
if(force_sym ) { arma_debug_print("force_sym"); }
|
||||
|
||||
arma_conform_check( (likely_sympd), "solve(): option 'likely_sympd' not applicable to triangular matrix" );
|
||||
arma_conform_check( (force_sym ), "solve(): option 'force_sym' not applicable to triangular matrix" );
|
||||
|
||||
if(no_trimat || equilibrate || refine || force_approx)
|
||||
{
|
||||
@@ -518,8 +548,6 @@ glue_solve_tri_full::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, const
|
||||
return glue_solve_gen_full::apply(actual_out, ((triu) ? trimatu(A_expr.get_ref()) : trimatl(A_expr.get_ref())), B_expr, (flags & mask));
|
||||
}
|
||||
|
||||
if(likely_sympd) { arma_warn(2, "solve(): option 'likely_sympd' ignored for triangular matrix"); }
|
||||
|
||||
const quasi_unwrap<T1> UA(A_expr.get_ref());
|
||||
const Mat<eT>& A = UA.M;
|
||||
|
||||
@@ -527,14 +555,9 @@ glue_solve_tri_full::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, const
|
||||
|
||||
const uword layout = (triu) ? uword(0) : uword(1);
|
||||
|
||||
bool is_alias = true;
|
||||
const bool is_alias = A_expr.get_ref().is_alias(actual_out) || B_expr.get_ref().is_alias(actual_out);
|
||||
|
||||
if(is_Mat<T2>::value)
|
||||
{
|
||||
const quasi_unwrap<T2> UB(B_expr.get_ref());
|
||||
|
||||
is_alias = UA.is_alias(actual_out) || UB.is_alias(actual_out);
|
||||
}
|
||||
if(is_alias) { arma_debug_print("glue_solve_tri_full::apply(): aliasing detected"); }
|
||||
|
||||
T rcond = T(0);
|
||||
bool status = false;
|
||||
|
||||
@@ -119,7 +119,9 @@ glue_times_redirect2_helper<true>::apply(Mat<typename T1::elem_type>& out, const
|
||||
|
||||
arma_conform_assert_mul_size(A, B, "matrix multiplication");
|
||||
|
||||
const bool status = (strip_inv<T1>::do_inv_spd) ? auxlib::solve_sympd_fast(out, A, B) : auxlib::solve_square_fast(out, A, B);
|
||||
const bool is_sym = (strip_inv<T1>::do_inv_spd) ? false : ( arma_config::optimise_sym && (auxlib::crippled_lapack(A) == false) && (is_sym_expr<T1>::eval(X.A) || sym_helper::is_approx_sym(A, uword(100))) );
|
||||
|
||||
const bool status = (strip_inv<T1>::do_inv_spd) ? auxlib::solve_sympd_fast(out, A, B) : ( (is_sym) ? auxlib::solve_sym_fast(out, A, B) : auxlib::solve_square_fast(out, A, B) );
|
||||
|
||||
if(status == false)
|
||||
{
|
||||
@@ -278,7 +280,9 @@ glue_times_redirect3_helper<true>::apply(Mat<typename T1::elem_type>& out, const
|
||||
if(is_cx<eT>::yes) { arma_warn(1, "inv_sympd(): given matrix is not hermitian"); }
|
||||
}
|
||||
|
||||
const bool status = (strip_inv<T1>::do_inv_spd) ? auxlib::solve_sympd_fast(out, A, BC) : auxlib::solve_square_fast(out, A, BC);
|
||||
const bool is_sym = (strip_inv<T1>::do_inv_spd) ? false : ( arma_config::optimise_sym && (auxlib::crippled_lapack(A) == false) && (is_sym_expr<T1>::eval(X.A.A) || sym_helper::is_approx_sym(A, uword(100))) );
|
||||
|
||||
const bool status = (strip_inv<T1>::do_inv_spd) ? auxlib::solve_sympd_fast(out, A, BC) : ( (is_sym) ? auxlib::solve_sym_fast(out, A, BC) : auxlib::solve_square_fast(out, A, BC) );
|
||||
|
||||
if(status == false)
|
||||
{
|
||||
@@ -315,7 +319,9 @@ glue_times_redirect3_helper<true>::apply(Mat<typename T1::elem_type>& out, const
|
||||
|
||||
Mat<eT> solve_result;
|
||||
|
||||
const bool status = (strip_inv<T2>::do_inv_spd) ? auxlib::solve_sympd_fast(solve_result, B, C) : auxlib::solve_square_fast(solve_result, B, C);
|
||||
const bool is_sym = (strip_inv<T1>::do_inv_spd) ? false : ( arma_config::optimise_sym && (auxlib::crippled_lapack(B) == false) && (is_sym_expr<T2>::eval(X.A.B) || sym_helper::is_approx_sym(B, uword(100))) );
|
||||
|
||||
const bool status = (strip_inv<T2>::do_inv_spd) ? auxlib::solve_sympd_fast(solve_result, B, C) : ( (is_sym) ? auxlib::solve_sym_fast(solve_result, B, C) : auxlib::solve_square_fast(solve_result, B, C) );
|
||||
|
||||
if(status == false)
|
||||
{
|
||||
@@ -552,7 +558,7 @@ glue_times::apply_inplace_plus(Mat<typename T1::elem_type>& out, const Glue<T1,
|
||||
|
||||
const bool use_alpha = partial_unwrap_check<T1>::do_times || partial_unwrap_check<T2>::do_times || (sign < sword(0));
|
||||
|
||||
const eT alpha = use_alpha ? ( tmp1.get_val() * tmp2.get_val() * ( (sign > sword(0)) ? eT(1) : eT(-1) ) ) : eT(0);
|
||||
const eT alpha = use_alpha ? ( tmp1.get_val() * tmp2.get_val() * ( (sign > sword(0)) ? eT(1) : eT(-1) ) ) : eT(0);
|
||||
|
||||
arma_conform_assert_mul_size(A, B, do_trans_A, do_trans_B, "matrix multiplication");
|
||||
|
||||
|
||||
@@ -1070,7 +1070,7 @@ gmm_diag<eT>::internal_scalar_log_p(const eT* x) const
|
||||
{
|
||||
const eT tmp = internal_scalar_log_p(x, g) + log_hefts_mem[g];
|
||||
|
||||
log_sum = log_add_exp(log_sum, tmp);
|
||||
log_sum = priv::internal_log_add_exp(log_sum, tmp);
|
||||
}
|
||||
|
||||
return log_sum;
|
||||
@@ -2556,7 +2556,7 @@ gmm_diag<eT>::em_generate_acc
|
||||
|
||||
for(uword g=1; g < N_gaus; ++g)
|
||||
{
|
||||
log_lhood_sum = log_add_exp(log_lhood_sum, gaus_log_lhoods_mem[g]);
|
||||
log_lhood_sum = priv::internal_log_add_exp(log_lhood_sum, gaus_log_lhoods_mem[g]);
|
||||
}
|
||||
|
||||
progress_log_lhood += log_lhood_sum;
|
||||
|
||||
@@ -937,7 +937,7 @@ gmm_full<eT>::init_constants(const bool calc_chol)
|
||||
Mat<eT>& inv_fcov = inv_fcovs.slice(g);
|
||||
|
||||
//const bool inv_ok = auxlib::inv(tmp_inv, fcov);
|
||||
const bool inv_ok = auxlib::inv_sympd(tmp_inv, fcov);
|
||||
const bool inv_ok = auxlib::inv_sympd(tmp_inv, fcov); // using inv_sympd() instead of inv() to ensure we can do cholesky decomp via op_chol
|
||||
|
||||
eT log_det_val = eT(0);
|
||||
eT log_det_sign = eT(0);
|
||||
@@ -1087,7 +1087,7 @@ gmm_full<eT>::internal_scalar_log_p(const eT* x) const
|
||||
{
|
||||
const eT log_val = internal_scalar_log_p(x, g) + log_hefts_mem[g];
|
||||
|
||||
log_sum = log_add_exp(log_sum, log_val);
|
||||
log_sum = priv::internal_log_add_exp(log_sum, log_val);
|
||||
}
|
||||
|
||||
return log_sum;
|
||||
@@ -2618,7 +2618,7 @@ gmm_full<eT>::em_generate_acc
|
||||
|
||||
for(uword g=1; g < N_gaus; ++g)
|
||||
{
|
||||
log_lhood_sum = log_add_exp(log_lhood_sum, gaus_log_lhoods_mem[g]);
|
||||
log_lhood_sum = priv::internal_log_add_exp(log_lhood_sum, gaus_log_lhoods_mem[g]);
|
||||
}
|
||||
|
||||
progress_log_lhood += log_lhood_sum;
|
||||
|
||||
@@ -37,6 +37,9 @@ class mtGlue : public Base< out_eT, mtGlue<out_eT, T1, T2, glue_type> >
|
||||
arma_inline mtGlue(const T1& in_A, const T2& in_B, const uword in_aux_uword);
|
||||
arma_inline ~mtGlue();
|
||||
|
||||
template<typename eT2>
|
||||
inline bool is_alias(const Mat<eT2>& X) const;
|
||||
|
||||
arma_aligned const T1& A; //!< first operand; must be derived from Base
|
||||
arma_aligned const T2& B; //!< second operand; must be derived from Base
|
||||
arma_aligned uword aux_uword; //!< storage of auxiliary data, uword format
|
||||
|
||||
@@ -53,4 +53,17 @@ mtGlue<out_eT,T1,T2,glue_type>::~mtGlue()
|
||||
|
||||
|
||||
|
||||
template<typename out_eT, typename T1, typename T2, typename glue_type>
|
||||
template<typename eT2>
|
||||
inline
|
||||
bool
|
||||
mtGlue<out_eT,T1,T2,glue_type>::is_alias(const Mat<eT2>& X) const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
return (A.is_alias(X) || B.is_alias(X));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
@@ -47,7 +47,10 @@ class mtOp : public Base< out_eT, mtOp<out_eT, T1, op_type> >
|
||||
inline mtOp(const mtOp_dual_aux_indicator&, const T1& in_m, const in_eT in_aux_a, const out_eT in_aux_b);
|
||||
|
||||
inline ~mtOp();
|
||||
|
||||
|
||||
template<typename eT2>
|
||||
inline bool is_alias(const Mat<eT2>& X) const;
|
||||
|
||||
|
||||
arma_aligned const T1& m; //!< the operand; must be derived from Base
|
||||
arma_aligned in_eT aux; //!< auxiliary data, using the element type as used by T1
|
||||
|
||||
@@ -101,4 +101,17 @@ mtOp<out_eT, T1, op_type>::~mtOp()
|
||||
|
||||
|
||||
|
||||
template<typename out_eT, typename T1, typename op_type>
|
||||
template<typename eT2>
|
||||
inline
|
||||
bool
|
||||
mtOp<out_eT, T1, op_type>::is_alias(const Mat<eT2>& X) const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
return m.is_alias(X);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
@@ -37,19 +37,12 @@ op_cond::apply(const Base<typename T1::elem_type, T1>& X)
|
||||
|
||||
if(is_op_diagmat<T1>::value || A.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_cond::apply(): detected diagonal matrix");
|
||||
arma_debug_print("op_cond::apply(): diag optimisation");
|
||||
|
||||
return op_cond::apply_diag(A);
|
||||
}
|
||||
|
||||
bool is_approx_sym = false;
|
||||
bool is_approx_sympd = false;
|
||||
|
||||
sym_helper::analyse_matrix(is_approx_sym, is_approx_sympd, A);
|
||||
|
||||
const bool do_sym = (is_cx<eT>::no) ? (is_approx_sym) : (is_approx_sym && is_approx_sympd);
|
||||
|
||||
if(do_sym)
|
||||
if(sym_helper::is_approx_sym(A))
|
||||
{
|
||||
arma_debug_print("op_cond: symmetric/hermitian optimisation");
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ op_expmat::apply_direct(Mat<typename T1::elem_type>& out, const Base<typename T1
|
||||
|
||||
if(A.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_expmat: detected diagonal matrix");
|
||||
arma_debug_print("op_expmat: diag optimisation");
|
||||
|
||||
const uword N = (std::min)(A.n_rows, A.n_cols);
|
||||
|
||||
@@ -86,19 +86,7 @@ op_expmat::apply_direct(Mat<typename T1::elem_type>& out, const Base<typename T1
|
||||
return true;
|
||||
}
|
||||
|
||||
bool do_sym = false;
|
||||
|
||||
if( (arma_config::optimise_sym) && (auxlib::crippled_lapack(A) == false) )
|
||||
{
|
||||
bool is_approx_sym = false;
|
||||
bool is_approx_sympd = false;
|
||||
|
||||
sym_helper::analyse_matrix(is_approx_sym, is_approx_sympd, A);
|
||||
|
||||
do_sym = ((is_cx<eT>::no) ? (is_approx_sym) : (is_approx_sym && is_approx_sympd));
|
||||
}
|
||||
|
||||
if(do_sym)
|
||||
if( (arma_config::optimise_sym) && (auxlib::crippled_lapack(A) == false) && sym_helper::is_approx_sym(A) )
|
||||
{
|
||||
arma_debug_print("op_expmat: symmetric/hermitian optimisation");
|
||||
|
||||
@@ -207,7 +195,7 @@ op_expmat_sym::apply_direct(Mat<typename T1::elem_type>& out, const Base<typenam
|
||||
|
||||
if(is_op_diagmat<T1>::value || X.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_expmat_sym: detected diagonal matrix");
|
||||
arma_debug_print("op_expmat_sym: diag optimisation");
|
||||
|
||||
out = X;
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ op_inv_gen_full::apply_direct(Mat<typename T1::elem_type>& out, const Base<typen
|
||||
|
||||
if(is_op_diagmat<T1>::value || out.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_inv_gen_full: detected diagonal matrix");
|
||||
arma_debug_print("op_inv_gen_full: diag optimisation");
|
||||
|
||||
eT* colmem = out.memptr();
|
||||
|
||||
@@ -216,28 +216,16 @@ op_inv_gen_full::apply_direct(Mat<typename T1::elem_type>& out, const Base<typen
|
||||
|
||||
if(is_triu_expr || is_tril_expr || is_triu_mat || is_tril_mat)
|
||||
{
|
||||
arma_debug_print("op_inv_gen_full: tri optimisation");
|
||||
|
||||
return auxlib::inv_tr(out, ((is_triu_expr || is_triu_mat) ? uword(0) : uword(1)));
|
||||
}
|
||||
|
||||
const bool try_sympd = arma_config::optimise_sym && sym_helper::guess_sympd(out);
|
||||
|
||||
if(try_sympd)
|
||||
if( (arma_config::optimise_sym) && (auxlib::crippled_lapack(out) == false) && ( is_sym_expr<T1>::eval(expr.get_ref()) || sym_helper::is_approx_sym(out, uword(100)) ) )
|
||||
{
|
||||
arma_debug_print("op_inv_gen_full: attempting sympd optimisation");
|
||||
arma_debug_print("op_inv_gen_full: symmetric/hermitian optimisation");
|
||||
|
||||
Mat<eT> tmp = out;
|
||||
|
||||
bool sympd_state = false;
|
||||
|
||||
const bool status = auxlib::inv_sympd(tmp, sympd_state);
|
||||
|
||||
if(status) { out.steal_mem(tmp); return true; }
|
||||
|
||||
if((status == false) && (sympd_state == true)) { return false; }
|
||||
|
||||
arma_debug_print("op_inv_gen_full: sympd optimisation failed");
|
||||
|
||||
// fallthrough if optimisation failed
|
||||
return auxlib::inv_sym(out);
|
||||
}
|
||||
|
||||
return auxlib::inv(out);
|
||||
@@ -348,7 +336,7 @@ op_inv_gen_rcond::apply_direct(Mat<typename T1::elem_type>& out, op_inv_gen_stat
|
||||
|
||||
if(is_op_diagmat<T1>::value || out.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_inv_gen_rcond: detected diagonal matrix");
|
||||
arma_debug_print("op_inv_gen_rcond: diag optimisation");
|
||||
|
||||
out_state.is_diag = true;
|
||||
|
||||
@@ -394,30 +382,18 @@ op_inv_gen_rcond::apply_direct(Mat<typename T1::elem_type>& out, op_inv_gen_stat
|
||||
|
||||
if(is_triu_expr || is_tril_expr || is_triu_mat || is_tril_mat)
|
||||
{
|
||||
arma_debug_print("op_inv_gen_rcond: tri optimisation");
|
||||
|
||||
return auxlib::inv_tr_rcond(out, out_state.rcond, ((is_triu_expr || is_triu_mat) ? uword(0) : uword(1)));
|
||||
}
|
||||
|
||||
const bool try_sympd = arma_config::optimise_sym && ((auxlib::crippled_lapack(out)) ? false : sym_helper::guess_sympd(out));
|
||||
|
||||
if(try_sympd)
|
||||
if( (arma_config::optimise_sym) && (auxlib::crippled_lapack(out) == false) && ( is_sym_expr<T1>::eval(expr.get_ref()) || sym_helper::is_approx_sym(out, uword(100)) ) )
|
||||
{
|
||||
arma_debug_print("op_inv_gen_rcond: attempting sympd optimisation");
|
||||
arma_debug_print("op_inv_gen_rcond: symmetric/hermitian optimisation");
|
||||
|
||||
out_state.is_sym = true;
|
||||
|
||||
Mat<eT> tmp = out;
|
||||
|
||||
bool sympd_state = false;
|
||||
|
||||
const bool status = auxlib::inv_sympd_rcond(tmp, sympd_state, out_state.rcond);
|
||||
|
||||
if(status) { out.steal_mem(tmp); return true; }
|
||||
|
||||
if((status == false) && (sympd_state == true)) { return false; }
|
||||
|
||||
arma_debug_print("op_inv_gen_rcond: sympd optimisation failed");
|
||||
|
||||
// fallthrough if optimisation failed
|
||||
return auxlib::inv_sym_rcond(out, out_state.rcond);
|
||||
}
|
||||
|
||||
return auxlib::inv_rcond(out, out_state.rcond);
|
||||
|
||||
@@ -191,7 +191,7 @@ op_inv_spd_full::apply_direct(Mat<typename T1::elem_type>& out, const Base<typen
|
||||
|
||||
if(is_op_diagmat<T1>::value || out.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_inv_spd_full: detected diagonal matrix");
|
||||
arma_debug_print("op_inv_spd_full: diag optimisation");
|
||||
|
||||
eT* colmem = out.memptr();
|
||||
|
||||
@@ -300,7 +300,7 @@ op_inv_spd_rcond::apply_direct(Mat<typename T1::elem_type>& out, op_inv_spd_stat
|
||||
|
||||
if(is_op_diagmat<T1>::value || out.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_inv_spd_rcond: detected diagonal matrix");
|
||||
arma_debug_print("op_inv_spd_rcond: diag optimisation");
|
||||
|
||||
out_state.is_diag = true;
|
||||
|
||||
@@ -355,9 +355,7 @@ op_inv_spd_rcond::apply_direct(Mat<typename T1::elem_type>& out, op_inv_spd_stat
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_sympd_junk = false;
|
||||
|
||||
return auxlib::inv_sympd_rcond(out, is_sympd_junk, out_state.rcond);
|
||||
return auxlib::inv_sympd_rcond(out, out_state.rcond);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -202,7 +202,7 @@ op_log_det_sympd::apply_direct(typename T1::pod_type& out_val, const Base<typena
|
||||
|
||||
if(is_op_diagmat<T1>::value || A.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_log_det_sympd: detected diagonal matrix");
|
||||
arma_debug_print("op_log_det_sympd: diag optimisation");
|
||||
|
||||
eT* colmem = A.memptr();
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ op_logmat::apply_direct(Mat< std::complex<typename T1::elem_type> >& out, const
|
||||
|
||||
if(A.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_logmat: detected diagonal matrix");
|
||||
arma_debug_print("op_logmat: diag optimisation");
|
||||
|
||||
const uword N = A.n_rows;
|
||||
|
||||
@@ -292,7 +292,7 @@ op_logmat_cx::apply_direct(Mat<typename T1::elem_type>& out, const Base<typename
|
||||
|
||||
if(S.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_logmat_cx: detected diagonal matrix");
|
||||
arma_debug_print("op_logmat_cx: diag optimisation");
|
||||
|
||||
const uword N = S.n_rows;
|
||||
|
||||
@@ -512,7 +512,7 @@ op_logmat_sympd::apply_direct(Mat<typename T1::elem_type>& out, const Base<typen
|
||||
|
||||
if(is_op_diagmat<T1>::value || X.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_logmat_sympd: detected diagonal matrix");
|
||||
arma_debug_print("op_logmat_sympd: diag optimisation");
|
||||
|
||||
out = X;
|
||||
|
||||
|
||||
@@ -393,32 +393,19 @@ op_max::direct_max(const eT* const X, const uword n_elem, uword& index_of_max_va
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
eT max_val_i = priv::most_neg<eT>();
|
||||
eT max_val_j = priv::most_neg<eT>();
|
||||
eT best_val = priv::most_neg<eT>();
|
||||
uword best_index = 0;
|
||||
|
||||
uword best_index_i = 0;
|
||||
uword best_index_j = 0;
|
||||
|
||||
uword i,j;
|
||||
for(i=0, j=1; j<n_elem; i+=2, j+=2)
|
||||
for(uword i=0; i < n_elem; ++i)
|
||||
{
|
||||
const eT X_i = X[i];
|
||||
const eT X_j = X[j];
|
||||
const eT val = X[i];
|
||||
|
||||
if(X_i > max_val_i) { max_val_i = X_i; best_index_i = i; }
|
||||
if(X_j > max_val_j) { max_val_j = X_j; best_index_j = j; }
|
||||
if(val > best_val) { best_val = val; best_index = i; }
|
||||
}
|
||||
|
||||
if(i < n_elem)
|
||||
{
|
||||
const eT X_i = X[i];
|
||||
|
||||
if(X_i > max_val_i) { max_val_i = X_i; best_index_i = i; }
|
||||
}
|
||||
index_of_max_val = best_index;
|
||||
|
||||
index_of_max_val = (max_val_i > max_val_j) ? best_index_i : best_index_j;
|
||||
|
||||
return (max_val_i > max_val_j) ? max_val_i : max_val_j;
|
||||
return best_val;
|
||||
}
|
||||
|
||||
|
||||
@@ -705,6 +692,8 @@ op_max::max_with_index(const Proxy<T1>& P, uword& index_of_max_val)
|
||||
{
|
||||
arma_conform_check(true, "max(): object has no elements");
|
||||
|
||||
index_of_max_val = 0;
|
||||
|
||||
return Datum<eT>::nan;
|
||||
}
|
||||
|
||||
@@ -786,6 +775,8 @@ op_max::max_with_index(const ProxyCube<T1>& P, uword& index_of_max_val)
|
||||
{
|
||||
arma_conform_check(true, "max(): object has no elements");
|
||||
|
||||
index_of_max_val = 0;
|
||||
|
||||
return Datum<eT>::nan;
|
||||
}
|
||||
|
||||
@@ -1160,6 +1151,8 @@ op_max::max_with_index(const Proxy<T1>& P, uword& index_of_max_val)
|
||||
{
|
||||
arma_conform_check(true, "max(): object has no elements");
|
||||
|
||||
index_of_max_val = 0;
|
||||
|
||||
return Datum<eT>::nan;
|
||||
}
|
||||
|
||||
@@ -1263,6 +1256,8 @@ op_max::max_with_index(const ProxyCube<T1>& P, uword& index_of_max_val)
|
||||
{
|
||||
arma_conform_check(true, "max(): object has no elements");
|
||||
|
||||
index_of_max_val = 0;
|
||||
|
||||
return Datum<eT>::nan;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ op_median::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_median>& expr)
|
||||
{
|
||||
Mat<eT> tmp;
|
||||
|
||||
op_median::apply_noalias(out, U.M, dim);
|
||||
op_median::apply_noalias(tmp, U.M, dim);
|
||||
|
||||
out.steal_mem(tmp);
|
||||
}
|
||||
|
||||
@@ -393,32 +393,19 @@ op_min::direct_min(const eT* const X, const uword n_elem, uword& index_of_min_va
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
eT min_val_i = priv::most_pos<eT>();
|
||||
eT min_val_j = priv::most_pos<eT>();
|
||||
eT best_val = priv::most_pos<eT>();
|
||||
uword best_index = 0;
|
||||
|
||||
uword best_index_i = 0;
|
||||
uword best_index_j = 0;
|
||||
|
||||
uword i,j;
|
||||
for(i=0, j=1; j<n_elem; i+=2, j+=2)
|
||||
for(uword i=0; i < n_elem; ++i)
|
||||
{
|
||||
const eT X_i = X[i];
|
||||
const eT X_j = X[j];
|
||||
const eT val = X[i];
|
||||
|
||||
if(X_i < min_val_i) { min_val_i = X_i; best_index_i = i; }
|
||||
if(X_j < min_val_j) { min_val_j = X_j; best_index_j = j; }
|
||||
if(val < best_val) { best_val = val; best_index = i; }
|
||||
}
|
||||
|
||||
if(i < n_elem)
|
||||
{
|
||||
const eT X_i = X[i];
|
||||
|
||||
if(X_i < min_val_i) { min_val_i = X_i; best_index_i = i; }
|
||||
}
|
||||
index_of_min_val = best_index;
|
||||
|
||||
index_of_min_val = (min_val_i < min_val_j) ? best_index_i : best_index_j;
|
||||
|
||||
return (min_val_i < min_val_j) ? min_val_i : min_val_j;
|
||||
return best_val;
|
||||
}
|
||||
|
||||
|
||||
@@ -705,6 +692,8 @@ op_min::min_with_index(const Proxy<T1>& P, uword& index_of_min_val)
|
||||
{
|
||||
arma_conform_check(true, "min(): object has no elements");
|
||||
|
||||
index_of_min_val = 0;
|
||||
|
||||
return Datum<eT>::nan;
|
||||
}
|
||||
|
||||
@@ -786,6 +775,8 @@ op_min::min_with_index(const ProxyCube<T1>& P, uword& index_of_min_val)
|
||||
{
|
||||
arma_conform_check(true, "min(): object has no elements");
|
||||
|
||||
index_of_min_val = 0;
|
||||
|
||||
return Datum<eT>::nan;
|
||||
}
|
||||
|
||||
@@ -1160,6 +1151,8 @@ op_min::min_with_index(const Proxy<T1>& P, uword& index_of_min_val)
|
||||
{
|
||||
arma_conform_check(true, "min(): object has no elements");
|
||||
|
||||
index_of_min_val = 0;
|
||||
|
||||
return Datum<eT>::nan;
|
||||
}
|
||||
|
||||
@@ -1263,6 +1256,8 @@ op_min::min_with_index(const ProxyCube<T1>& P, uword& index_of_min_val)
|
||||
{
|
||||
arma_conform_check(true, "min(): object has no elements");
|
||||
|
||||
index_of_min_val = 0;
|
||||
|
||||
return Datum<eT>::nan;
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ op_pinv::apply_direct(Mat<typename T1::elem_type>& out, const Base<typename T1::
|
||||
|
||||
if(is_op_diagmat<T1>::value || A.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_pinv: detected diagonal matrix");
|
||||
arma_debug_print("op_pinv: diag optimisation");
|
||||
|
||||
return op_pinv::apply_diag(out, A, tol);
|
||||
}
|
||||
@@ -119,15 +119,7 @@ op_pinv::apply_direct(Mat<typename T1::elem_type>& out, const Base<typename T1::
|
||||
{
|
||||
do_sym = is_sym_expr<T1>::eval(expr.get_ref());
|
||||
|
||||
if(do_sym == false)
|
||||
{
|
||||
bool is_approx_sym = false;
|
||||
bool is_approx_sympd = false;
|
||||
|
||||
sym_helper::analyse_matrix(is_approx_sym, is_approx_sympd, A);
|
||||
|
||||
do_sym = ((is_cx<eT>::no) ? (is_approx_sym) : (is_approx_sym && is_approx_sympd));
|
||||
}
|
||||
if(do_sym == false) { do_sym = sym_helper::is_approx_sym(A); }
|
||||
}
|
||||
|
||||
if(do_sym)
|
||||
|
||||
@@ -96,7 +96,7 @@ op_powmat::apply_direct_positive(Mat<eT>& out, const Mat<eT>& X, const uword y)
|
||||
|
||||
if(X.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_powmat: detected diagonal matrix");
|
||||
arma_debug_print("op_powmat: diag optimisation");
|
||||
|
||||
podarray<eT> tmp(N); // use temporary array in case we have aliasing
|
||||
|
||||
@@ -194,11 +194,11 @@ op_powmat_cx::apply_direct(Mat< std::complex<typename T1::pod_type> >& out, cons
|
||||
|
||||
if(A.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_powmat_cx: detected diagonal matrix");
|
||||
arma_debug_print("op_powmat_cx: diag optimisation");
|
||||
|
||||
podarray<out_eT> tmp(N); // use temporary array in case we have aliasing
|
||||
|
||||
for(uword i=0; i<N; ++i) { tmp[i] = eop_aux::pow( std::complex<in_T>(A.at(i,i)), y) ; }
|
||||
for(uword i=0; i<N; ++i) { tmp[i] = eop_aux::pow( std::complex<in_T>(A.at(i,i)), y ); }
|
||||
|
||||
out.zeros(N,N);
|
||||
|
||||
@@ -207,11 +207,11 @@ op_powmat_cx::apply_direct(Mat< std::complex<typename T1::pod_type> >& out, cons
|
||||
return true;
|
||||
}
|
||||
|
||||
const bool try_sympd = arma_config::optimise_sym && sym_helper::guess_sympd(A);
|
||||
const bool try_sym = arma_config::optimise_sym && sym_helper::is_approx_sym(A);
|
||||
|
||||
if(try_sympd)
|
||||
if(try_sym)
|
||||
{
|
||||
arma_debug_print("op_powmat_cx: attempting sympd optimisation");
|
||||
arma_debug_print("op_powmat_cx: symmetric/hermitian optimisation");
|
||||
|
||||
Col<in_T> eigval;
|
||||
Mat<in_eT> eigvec;
|
||||
@@ -220,16 +220,39 @@ op_powmat_cx::apply_direct(Mat< std::complex<typename T1::pod_type> >& out, cons
|
||||
|
||||
if(eig_status)
|
||||
{
|
||||
eigval = pow(eigval, y);
|
||||
bool all_pos = true;
|
||||
|
||||
const Mat<in_eT> tmp = diagmat(eigval) * eigvec.t();
|
||||
for(uword i=0; i<N; ++i) { all_pos = (eigval[i] <= in_T(0)) ? false : all_pos; }
|
||||
|
||||
out = conv_to< Mat<out_eT> >::from(eigvec * tmp);
|
||||
if(all_pos)
|
||||
{
|
||||
arma_debug_print("op_powmat_cx: all_pos = true");
|
||||
|
||||
eigval = pow(eigval, y);
|
||||
|
||||
const Mat<in_eT> tmp = eigvec * diagmat(eigval);
|
||||
|
||||
out = conv_to< Mat<out_eT> >::from(tmp * eigvec.t());
|
||||
}
|
||||
else
|
||||
{
|
||||
arma_debug_print("op_powmat_cx: all_pos = false");
|
||||
|
||||
Col<out_eT> cx_eigval_pow(N, arma_nozeros_indicator());
|
||||
|
||||
for(uword i=0; i<N; ++i) { cx_eigval_pow[i] = eop_aux::pow( std::complex<in_T>(eigval[i]), y ); }
|
||||
|
||||
const Mat<out_eT> cx_eigvec = conv_to< Mat<out_eT> >::from(eigvec);
|
||||
|
||||
const Mat<out_eT> tmp = cx_eigvec * diagmat(cx_eigval_pow);
|
||||
|
||||
out = tmp * cx_eigvec.t();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
arma_debug_print("op_powmat_cx: sympd optimisation failed");
|
||||
arma_debug_print("op_powmat_cx: symmetric/hermitian optimisation failed");
|
||||
|
||||
// fallthrough if optimisation failed
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ op_rank::apply(uword& out, const Base<typename T1::elem_type,T1>& expr, const ty
|
||||
|
||||
if(is_op_diagmat<T1>::value || A.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_rank::apply(): detected diagonal matrix");
|
||||
arma_debug_print("op_rank::apply(): diag optimisation");
|
||||
|
||||
return op_rank::apply_diag(out, A, tol);
|
||||
}
|
||||
@@ -50,15 +50,7 @@ op_rank::apply(uword& out, const Base<typename T1::elem_type,T1>& expr, const ty
|
||||
{
|
||||
do_sym = is_sym_expr<T1>::eval(expr.get_ref());
|
||||
|
||||
if(do_sym == false)
|
||||
{
|
||||
bool is_approx_sym = false;
|
||||
bool is_approx_sympd = false;
|
||||
|
||||
sym_helper::analyse_matrix(is_approx_sym, is_approx_sympd, A);
|
||||
|
||||
do_sym = (is_cx<eT>::no) ? (is_approx_sym) : (is_approx_sym && is_approx_sympd);
|
||||
}
|
||||
if(do_sym == false) { do_sym = sym_helper::is_approx_sym(A); }
|
||||
}
|
||||
|
||||
if(do_sym)
|
||||
|
||||
@@ -33,6 +33,8 @@ op_rcond::apply(const Base<typename T1::elem_type, T1>& X)
|
||||
|
||||
if(strip_trimat<T1>::do_trimat)
|
||||
{
|
||||
arma_debug_print("op_rcond::apply(): tri optimisation");
|
||||
|
||||
const strip_trimat<T1> S(X.get_ref());
|
||||
|
||||
const quasi_unwrap<typename strip_trimat<T1>::stored_type> U(S.M);
|
||||
@@ -52,7 +54,7 @@ op_rcond::apply(const Base<typename T1::elem_type, T1>& X)
|
||||
|
||||
if(is_op_diagmat<T1>::value || A.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_rcond::apply(): detected diagonal matrix");
|
||||
arma_debug_print("op_rcond::apply(): diag optimisation");
|
||||
|
||||
const eT* colmem = A.memptr();
|
||||
const uword N = A.n_rows;
|
||||
@@ -80,29 +82,18 @@ op_rcond::apply(const Base<typename T1::elem_type, T1>& X)
|
||||
|
||||
if(is_triu || is_tril)
|
||||
{
|
||||
arma_debug_print("op_rcond::apply(): tri optimisation");
|
||||
|
||||
const uword layout = (is_triu) ? uword(0) : uword(1);
|
||||
|
||||
return auxlib::rcond_trimat(A, layout);
|
||||
}
|
||||
|
||||
const bool try_sympd = arma_config::optimise_sym && (auxlib::crippled_lapack(A) ? false : sym_helper::guess_sympd(A));
|
||||
|
||||
if(try_sympd)
|
||||
if( (arma_config::optimise_sym) && (auxlib::crippled_lapack(A) == false) && ( is_sym_expr<T1>::eval(X.get_ref()) || sym_helper::is_approx_sym(A, uword(100)) ) )
|
||||
{
|
||||
arma_debug_print("op_rcond::apply(): attempting sympd optimisation");
|
||||
arma_debug_print("op_rcond::apply(): symmetric/hermitian optimisation");
|
||||
|
||||
bool calc_ok = false;
|
||||
|
||||
const T out_val = auxlib::rcond_sympd(A, calc_ok);
|
||||
|
||||
if(calc_ok) { return out_val; }
|
||||
|
||||
arma_debug_print("op_rcond::apply(): sympd optimisation failed");
|
||||
|
||||
// auxlib::rcond_sympd() may have failed because A isn't really sympd
|
||||
// restore A, as auxlib::rcond_sympd() may have destroyed it
|
||||
A = X.get_ref();
|
||||
// fallthrough to the next return statement
|
||||
return auxlib::rcond_sym(A);
|
||||
}
|
||||
|
||||
return auxlib::rcond(A);
|
||||
|
||||
@@ -81,12 +81,19 @@ op_reshape::apply_mat_inplace(Mat<eT>& A, const uword new_n_rows, const uword ne
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
if( (A.n_rows == new_n_rows) && (A.n_cols == new_n_cols) ) { return; }
|
||||
|
||||
arma_conform_check( (A.vec_state == 1) && (new_n_cols != 1), "reshape(): requested size is not compatible with column vector layout" );
|
||||
arma_conform_check( (A.vec_state == 2) && (new_n_rows != 1), "reshape(): requested size is not compatible with row vector layout" );
|
||||
|
||||
const uword new_n_elem = new_n_rows * new_n_cols;
|
||||
if(A.is_empty()) { A.zeros(new_n_rows, new_n_cols); return; }
|
||||
|
||||
if(A.n_elem == new_n_elem) { A.set_size(new_n_rows, new_n_cols); return; }
|
||||
const bool is_into_empty = ( (new_n_cols == uword(0)) || (new_n_rows == uword(0)) );
|
||||
const bool is_into_colvec = ( (new_n_cols == uword(1)) && (new_n_rows == A.n_elem) );
|
||||
const bool is_into_rowvec = ( (new_n_rows == uword(1)) && (new_n_cols == A.n_elem) );
|
||||
const bool is_rowcol_swap = ( (new_n_cols == A.n_rows) && (new_n_rows == A.n_cols) );
|
||||
|
||||
if(is_into_empty || is_into_colvec || is_into_rowvec || is_rowcol_swap) { A.set_size(new_n_rows, new_n_cols); return; }
|
||||
|
||||
Mat<eT> B;
|
||||
|
||||
@@ -208,9 +215,16 @@ op_reshape::apply_cube_inplace(Cube<eT>& A, const uword new_n_rows, const uword
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
const uword new_n_elem = new_n_rows * new_n_cols * new_n_slices;
|
||||
if( (A.n_rows == new_n_rows) && (A.n_cols == new_n_cols) && (A.n_slices == new_n_slices) ) { return; }
|
||||
|
||||
if(A.n_elem == new_n_elem) { A.set_size(new_n_rows, new_n_cols, new_n_slices); return; }
|
||||
if(A.is_empty()) { A.zeros(new_n_rows, new_n_cols, new_n_slices); return; }
|
||||
|
||||
const bool is_into_empty = ( (new_n_cols == uword(0)) || (new_n_rows == uword(0)) || (new_n_slices == uword(0) ) );
|
||||
const bool is_into_colvec = ( (new_n_cols == uword(1)) && (new_n_rows == A.n_elem) && (new_n_slices == uword(1) ) );
|
||||
const bool is_into_rowvec = ( (new_n_rows == uword(1)) && (new_n_cols == A.n_elem) && (new_n_slices == uword(1) ) );
|
||||
const bool is_rowcol_swap = ( (new_n_cols == A.n_rows) && (new_n_rows == A.n_cols) && (new_n_slices == A.n_slices) );
|
||||
|
||||
if(is_into_empty || is_into_colvec || is_into_rowvec || is_rowcol_swap) { A.set_size(new_n_rows, new_n_cols, new_n_slices); return; }
|
||||
|
||||
Cube<eT> B;
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ op_sqrtmat::apply_direct(Mat< std::complex<typename T1::elem_type> >& out, const
|
||||
|
||||
if(A.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_sqrtmat: detected diagonal matrix");
|
||||
arma_debug_print("op_sqrtmat: diag optimisation");
|
||||
|
||||
const uword N = A.n_rows;
|
||||
|
||||
@@ -325,7 +325,7 @@ op_sqrtmat_cx::apply_direct(Mat<typename T1::elem_type>& out, const Base<typenam
|
||||
|
||||
if(S.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_sqrtmat_cx: detected diagonal matrix");
|
||||
arma_debug_print("op_sqrtmat_cx: diag optimisation");
|
||||
|
||||
const uword N = S.n_rows;
|
||||
|
||||
@@ -489,7 +489,7 @@ op_sqrtmat_sympd::apply_direct(Mat<typename T1::elem_type>& out, const Base<type
|
||||
|
||||
if(is_op_diagmat<T1>::value || X.is_diagmat())
|
||||
{
|
||||
arma_debug_print("op_sqrtmat_sympd: detected diagonal matrix");
|
||||
arma_debug_print("op_sqrtmat_sympd: diag optimisation");
|
||||
|
||||
out = X;
|
||||
|
||||
|
||||
@@ -438,108 +438,6 @@ operator-
|
||||
|
||||
|
||||
|
||||
// TODO: this is an uncommon use case; remove?
|
||||
//! multiple applications of add/subtract scalars can be condensed
|
||||
template<typename T1, typename op_type>
|
||||
inline
|
||||
typename
|
||||
enable_if2
|
||||
<
|
||||
(is_arma_sparse_type<T1>::value &&
|
||||
(is_same_type<op_type, op_sp_plus>::value ||
|
||||
is_same_type<op_type, op_sp_minus_post>::value)),
|
||||
const SpToDOp<T1, op_sp_minus_post>
|
||||
>::result
|
||||
operator-
|
||||
(
|
||||
const SpToDOp<T1, op_type>& x,
|
||||
const typename T1::elem_type k
|
||||
)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
const typename T1::elem_type aux = (is_same_type<op_type, op_sp_plus>::value) ? -x.aux : x.aux;
|
||||
|
||||
return SpToDOp<T1, op_sp_minus_post>(x.m, aux + k);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: this is an uncommon use case; remove?
|
||||
//! multiple applications of add/subtract scalars can be condensed
|
||||
template<typename T1, typename op_type>
|
||||
inline
|
||||
typename
|
||||
enable_if2
|
||||
<
|
||||
(is_arma_sparse_type<T1>::value &&
|
||||
(is_same_type<op_type, op_sp_plus>::value ||
|
||||
is_same_type<op_type, op_sp_minus_post>::value)),
|
||||
const SpToDOp<T1, op_sp_minus_pre>
|
||||
>::result
|
||||
operator-
|
||||
(
|
||||
const typename T1::elem_type k,
|
||||
const SpToDOp<T1, op_type>& x
|
||||
)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
const typename T1::elem_type aux = (is_same_type<op_type, op_sp_plus>::value) ? -x.aux : x.aux;
|
||||
|
||||
return SpToDOp<T1, op_sp_minus_pre>(x.m, k + aux);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: this is an uncommon use case; remove?
|
||||
//! multiple applications of add/subtract scalars can be condensed
|
||||
template<typename T1, typename op_type>
|
||||
inline
|
||||
typename
|
||||
enable_if2
|
||||
<
|
||||
(is_arma_sparse_type<T1>::value &&
|
||||
is_same_type<op_type, op_sp_minus_pre>::value),
|
||||
const SpToDOp<T1, op_sp_minus_pre>
|
||||
>::result
|
||||
operator-
|
||||
(
|
||||
const SpToDOp<T1, op_type>& x,
|
||||
const typename T1::elem_type k
|
||||
)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
return SpToDOp<T1, op_sp_minus_pre>(x.m, x.aux - k);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: this is an uncommon use case; remove?
|
||||
//! multiple applications of add/subtract scalars can be condensed
|
||||
template<typename T1, typename op_type>
|
||||
inline
|
||||
typename
|
||||
enable_if2
|
||||
<
|
||||
(is_arma_sparse_type<T1>::value &&
|
||||
is_same_type<op_type, op_sp_minus_pre>::value),
|
||||
const SpToDOp<T1, op_sp_plus>
|
||||
>::result
|
||||
operator-
|
||||
(
|
||||
const typename T1::elem_type k,
|
||||
const SpToDOp<T1, op_type>& x
|
||||
)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
return SpToDOp<T1, op_sp_plus>(x.m, k - x.aux);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename parent, unsigned int mode, typename T2>
|
||||
arma_inline
|
||||
Mat<typename parent::elem_type>
|
||||
|
||||
@@ -370,109 +370,6 @@ operator+
|
||||
|
||||
|
||||
|
||||
// TODO: this is an uncommon use case; remove?
|
||||
//! multiple applications of add/subtract scalars can be condensed
|
||||
template<typename T1, typename op_type>
|
||||
inline
|
||||
typename
|
||||
enable_if2
|
||||
<
|
||||
(is_arma_sparse_type<T1>::value &&
|
||||
(is_same_type<op_type, op_sp_plus>::value ||
|
||||
is_same_type<op_type, op_sp_minus_post>::value)),
|
||||
const SpToDOp<T1, op_sp_plus>
|
||||
>::result
|
||||
operator+
|
||||
(
|
||||
const SpToDOp<T1, op_type>& x,
|
||||
const typename T1::elem_type k
|
||||
)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
const typename T1::elem_type aux = (is_same_type<op_type, op_sp_plus>::value) ? x.aux : -x.aux;
|
||||
|
||||
return SpToDOp<T1, op_sp_plus>(x.m, aux + k);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: this is an uncommon use case; remove?
|
||||
//! multiple applications of add/subtract scalars can be condensed
|
||||
template<typename T1, typename op_type>
|
||||
inline
|
||||
typename
|
||||
enable_if2
|
||||
<
|
||||
(is_arma_sparse_type<T1>::value &&
|
||||
is_same_type<op_type, op_sp_minus_pre>::value),
|
||||
const SpToDOp<T1, op_sp_minus_pre>
|
||||
>::result
|
||||
operator+
|
||||
(
|
||||
const SpToDOp<T1, op_type>& x,
|
||||
const typename T1::elem_type k
|
||||
)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
return SpToDOp<T1, op_sp_minus_pre>(x.m, x.aux + k);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: this is an uncommon use case; remove?
|
||||
//! multiple applications of add/subtract scalars can be condensed
|
||||
template<typename T1, typename op_type>
|
||||
inline
|
||||
typename
|
||||
enable_if2
|
||||
<
|
||||
(is_arma_sparse_type<T1>::value &&
|
||||
(is_same_type<op_type, op_sp_plus>::value ||
|
||||
is_same_type<op_type, op_sp_minus_post>::value)),
|
||||
const SpToDOp<T1, op_sp_plus>
|
||||
>::result
|
||||
operator+
|
||||
(
|
||||
const typename T1::elem_type k,
|
||||
const SpToDOp<T1, op_type>& x
|
||||
)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
const typename T1::elem_type aux = (is_same_type<op_type, op_sp_plus>::value) ? x.aux : -x.aux;
|
||||
|
||||
return SpToDOp<T1, op_sp_plus>(x.m, aux + k);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TODO: this is an uncommon use case; remove?
|
||||
//! multiple applications of add/subtract scalars can be condensed
|
||||
template<typename T1, typename op_type>
|
||||
inline
|
||||
typename
|
||||
enable_if2
|
||||
<
|
||||
(is_arma_sparse_type<T1>::value &&
|
||||
is_same_type<op_type, op_sp_minus_pre>::value),
|
||||
const SpToDOp<T1, op_sp_minus_pre>
|
||||
>::result
|
||||
operator+
|
||||
(
|
||||
const typename T1::elem_type k,
|
||||
const SpToDOp<T1, op_type>& x
|
||||
)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
return SpToDOp<T1, op_sp_minus_pre>(x.m, x.aux + k);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename parent, unsigned int mode, typename T2>
|
||||
arma_inline
|
||||
Mat<typename parent::elem_type>
|
||||
|
||||
@@ -2027,6 +2027,7 @@ sp_auxlib::run_aupd_plain
|
||||
arma_ignore(n_eigvals);
|
||||
arma_ignore(which);
|
||||
arma_ignore(X);
|
||||
arma_ignore(Xst);
|
||||
arma_ignore(sym);
|
||||
arma_ignore(n);
|
||||
arma_ignore(tol);
|
||||
|
||||
@@ -201,6 +201,9 @@ class subview : public Base< eT, subview<eT> >
|
||||
inline void swap_rows(const uword in_row1, const uword in_row2);
|
||||
inline void swap_cols(const uword in_col1, const uword in_col2);
|
||||
|
||||
template<typename eT2>
|
||||
inline bool is_alias(const Mat<eT2>& X) const;
|
||||
|
||||
|
||||
class const_iterator;
|
||||
|
||||
@@ -428,8 +431,8 @@ class subview_col : public subview<eT>
|
||||
arma_warn_unused inline eT min() const;
|
||||
arma_warn_unused inline eT max() const;
|
||||
|
||||
inline eT min(uword& index_of_min_val) const;
|
||||
inline eT max(uword& index_of_max_val) const;
|
||||
arma_frown("use .index_min() instead") inline eT min(uword& index_of_min_val) const;
|
||||
arma_frown("use .index_max() instead") inline eT max(uword& index_of_max_val) const;
|
||||
|
||||
arma_warn_unused inline uword index_min() const;
|
||||
arma_warn_unused inline uword index_max() const;
|
||||
|
||||
@@ -43,7 +43,7 @@ class subview_cube_each_common
|
||||
|
||||
|
||||
|
||||
|
||||
// NOTE: deliberately not derived from BaseCube
|
||||
template<typename eT>
|
||||
class subview_cube_each1 : public subview_cube_each_common<eT>
|
||||
{
|
||||
@@ -71,6 +71,7 @@ class subview_cube_each1 : public subview_cube_each_common<eT>
|
||||
|
||||
|
||||
|
||||
// NOTE: deliberately not derived from BaseCube
|
||||
template<typename eT, typename TB>
|
||||
class subview_cube_each2 : public subview_cube_each_common<eT>
|
||||
{
|
||||
|
||||
@@ -50,7 +50,7 @@ class subview_each_common
|
||||
|
||||
|
||||
|
||||
|
||||
// NOTE: deliberately not derived from Base
|
||||
template<typename parent, unsigned int mode>
|
||||
class subview_each1 : public subview_each_common<parent, mode>
|
||||
{
|
||||
@@ -80,6 +80,7 @@ class subview_each1 : public subview_each_common<parent, mode>
|
||||
|
||||
|
||||
|
||||
// NOTE: deliberately not derived from Base
|
||||
template<typename parent, unsigned int mode, typename TB>
|
||||
class subview_each2 : public subview_each_common<parent, mode>
|
||||
{
|
||||
|
||||
@@ -99,6 +99,9 @@ class subview_elem1 : public Base< eT, subview_elem1<eT,T1> >
|
||||
inline static void schur_inplace(Mat<eT>& out, const subview_elem1& in);
|
||||
inline static void div_inplace(Mat<eT>& out, const subview_elem1& in);
|
||||
|
||||
template<typename eT2>
|
||||
inline bool is_alias(const Mat<eT2>& X) const;
|
||||
|
||||
|
||||
friend class Mat<eT>;
|
||||
friend class Cube<eT>;
|
||||
|
||||
@@ -67,11 +67,10 @@ subview_elem1<eT,T1>::inplace_op(const eT val)
|
||||
const unwrap_check_mixed<T1> tmp(a.get_ref(), m_local);
|
||||
const umat& aa = tmp.M;
|
||||
|
||||
arma_conform_check
|
||||
(
|
||||
( (aa.is_vec() == false) && (aa.is_empty() == false) ),
|
||||
"Mat::elem(): given object must be a vector"
|
||||
);
|
||||
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;
|
||||
@@ -220,11 +219,10 @@ subview_elem1<eT,T1>::inplace_op(const Base<eT,T2>& x)
|
||||
const unwrap_check_mixed<T1> aa_tmp(a.get_ref(), m_local);
|
||||
const umat& aa = aa_tmp.M;
|
||||
|
||||
arma_conform_check
|
||||
(
|
||||
( (aa.is_vec() == false) && (aa.is_empty() == false) ),
|
||||
"Mat::elem(): given object must be a vector"
|
||||
);
|
||||
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;
|
||||
@@ -233,9 +231,9 @@ subview_elem1<eT,T1>::inplace_op(const Base<eT,T2>& x)
|
||||
|
||||
arma_conform_check( (aa_n_elem != P.get_n_elem()), "Mat::elem(): size mismatch" );
|
||||
|
||||
const bool is_alias = P.is_alias(m);
|
||||
const bool have_alias = P.is_alias(m);
|
||||
|
||||
if( (is_alias == false) && (Proxy<T2>::use_at == false) )
|
||||
if( (have_alias == false) && (Proxy<T2>::use_at == false) )
|
||||
{
|
||||
typename Proxy<T2>::ea_type X = P.get_ea();
|
||||
|
||||
@@ -271,7 +269,7 @@ subview_elem1<eT,T1>::inplace_op(const Base<eT,T2>& x)
|
||||
{
|
||||
arma_debug_print("subview_elem1::inplace_op(): aliasing or use_at detected");
|
||||
|
||||
const unwrap_check<typename Proxy<T2>::stored_type> tmp(P.Q, is_alias);
|
||||
const unwrap_check<typename Proxy<T2>::stored_type> tmp(P.Q, have_alias);
|
||||
const Mat<eT>& M = tmp.M;
|
||||
|
||||
const eT* X = M.memptr();
|
||||
@@ -358,11 +356,10 @@ subview_elem1<eT,T1>::replace(const eT old_val, const eT new_val)
|
||||
const unwrap_check_mixed<T1> tmp(a.get_ref(), m_local);
|
||||
const umat& aa = tmp.M;
|
||||
|
||||
arma_conform_check
|
||||
(
|
||||
( (aa.is_vec() == false) && (aa.is_empty() == false) ),
|
||||
"Mat::elem(): given object must be a vector"
|
||||
);
|
||||
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;
|
||||
@@ -480,11 +477,10 @@ subview_elem1<eT,T1>::randu()
|
||||
const unwrap_check_mixed<T1> tmp(a.get_ref(), m_local);
|
||||
const umat& aa = tmp.M;
|
||||
|
||||
arma_conform_check
|
||||
(
|
||||
( (aa.is_vec() == false) && (aa.is_empty() == false) ),
|
||||
"Mat::elem(): given object must be a vector"
|
||||
);
|
||||
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;
|
||||
@@ -531,11 +527,10 @@ subview_elem1<eT,T1>::randn()
|
||||
const unwrap_check_mixed<T1> tmp(a.get_ref(), m_local);
|
||||
const umat& aa = tmp.M;
|
||||
|
||||
arma_conform_check
|
||||
(
|
||||
( (aa.is_vec() == false) && (aa.is_empty() == false) ),
|
||||
"Mat::elem(): given object must be a vector"
|
||||
);
|
||||
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;
|
||||
@@ -788,11 +783,10 @@ subview_elem1<eT,T1>::extract(Mat<eT>& actual_out, const subview_elem1<eT,T1>& i
|
||||
const unwrap_check_mixed<T1> tmp1(in.a.get_ref(), actual_out);
|
||||
const umat& aa = tmp1.M;
|
||||
|
||||
arma_conform_check
|
||||
(
|
||||
( (aa.is_vec() == false) && (aa.is_empty() == false) ),
|
||||
"Mat::elem(): given object must be a vector"
|
||||
);
|
||||
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;
|
||||
@@ -854,11 +848,10 @@ subview_elem1<eT,T1>::mat_inplace_op(Mat<eT>& out, const subview_elem1& in)
|
||||
const unwrap<T1> tmp1(in.a.get_ref());
|
||||
const umat& aa = tmp1.M;
|
||||
|
||||
arma_conform_check
|
||||
(
|
||||
( (aa.is_vec() == false) && (aa.is_empty() == false) ),
|
||||
"Mat::elem(): given object must be a vector"
|
||||
);
|
||||
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;
|
||||
@@ -950,4 +943,17 @@ subview_elem1<eT,T1>::div_inplace(Mat<eT>& out, const subview_elem1& in)
|
||||
|
||||
|
||||
|
||||
template<typename eT, typename T1>
|
||||
template<typename eT2>
|
||||
inline
|
||||
bool
|
||||
subview_elem1<eT,T1>::is_alias(const Mat<eT2>& X) const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
return (m.is_alias(X) || a.get_ref().is_alias(X));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
@@ -103,6 +103,9 @@ class subview_elem2 : public Base< eT, subview_elem2<eT,T1,T2> >
|
||||
inline static void schur_inplace(Mat<eT>& out, const subview_elem2& in);
|
||||
inline static void div_inplace(Mat<eT>& out, const subview_elem2& in);
|
||||
|
||||
template<typename eT2>
|
||||
inline bool is_alias(const Mat<eT2>& X) const;
|
||||
|
||||
|
||||
friend class Mat<eT>;
|
||||
};
|
||||
|
||||
@@ -870,4 +870,17 @@ subview_elem2<eT,T1,T2>::div_inplace(Mat<eT>& out, const subview_elem2& in)
|
||||
|
||||
|
||||
|
||||
template<typename eT, typename T1, typename T2>
|
||||
template<typename eT2>
|
||||
inline
|
||||
bool
|
||||
subview_elem2<eT,T1,T2>::is_alias(const Mat<eT2>& X) const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
return (m.is_alias(X) || base_ri.get_ref().is_alias(X) || base_ci.get_ref().is_alias(X));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
@@ -2617,6 +2617,19 @@ subview<eT>::swap_cols(const uword in_col1, const uword in_col2)
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
template<typename eT2>
|
||||
inline
|
||||
bool
|
||||
subview<eT>::is_alias(const Mat<eT2>& X) const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
return m.is_alias(X);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
typename subview<eT>::iterator
|
||||
|
||||
@@ -50,19 +50,26 @@ guess_sympd_worker(const Mat<eT>& A)
|
||||
const eT* A_mem = A.memptr();
|
||||
const eT* A_col = A_mem;
|
||||
|
||||
bool diag_below_tol = true;
|
||||
|
||||
eT max_diag = eT(0);
|
||||
|
||||
for(uword j=0; j < N; ++j)
|
||||
{
|
||||
const eT A_jj = A_col[j];
|
||||
|
||||
if(A_jj <= eT(0)) { return false; }
|
||||
if( A_jj <= eT(0)) { return false; }
|
||||
if(arma_isfinite(A_jj) == false) { return false; }
|
||||
|
||||
if(A_jj >= tol) { diag_below_tol = false; }
|
||||
|
||||
max_diag = (A_jj > max_diag) ? A_jj : max_diag;
|
||||
|
||||
A_col += N;
|
||||
}
|
||||
|
||||
if(diag_below_tol) { return false; } // assume matrix is suspect if all diagonal elements are close to zero
|
||||
|
||||
A_col = A_mem;
|
||||
|
||||
const uword Nm1 = N-1;
|
||||
@@ -117,6 +124,8 @@ guess_sympd_worker(const Mat<eT>& A)
|
||||
|
||||
// NOTE: assuming A is square-sized
|
||||
|
||||
// NOTE: the function name is required for overloading, but is a misnomer: it processes complex hermitian matrices
|
||||
|
||||
typedef typename get_pod_type<eT>::result T;
|
||||
|
||||
const T tol = T(100) * std::numeric_limits<T>::epsilon(); // allow some leeway
|
||||
@@ -126,21 +135,33 @@ guess_sympd_worker(const Mat<eT>& A)
|
||||
const eT* A_mem = A.memptr();
|
||||
const eT* A_col = A_mem;
|
||||
|
||||
bool diag_below_tol = true;
|
||||
|
||||
T max_diag = T(0);
|
||||
|
||||
for(uword j=0; j < N; ++j)
|
||||
{
|
||||
const eT& A_jj = A_col[j];
|
||||
const T A_jj_real = std::real(A_jj);
|
||||
const T A_jj_imag = std::imag(A_jj);
|
||||
const T A_jj_r = std::real(A_jj );
|
||||
const T A_jj_i = std::imag(A_jj );
|
||||
const T A_jj_rabs = std::abs(A_jj_r);
|
||||
const T A_jj_iabs = std::abs(A_jj_i);
|
||||
|
||||
if( (A_jj_real <= T(0)) || (std::abs(A_jj_imag) > tol) ) { return false; }
|
||||
if( A_jj_r <= T(0) ) { return false; } // real should be positive
|
||||
if(arma_isfinite(A_jj_r) == false) { return false; }
|
||||
|
||||
max_diag = (A_jj_real > max_diag) ? A_jj_real : max_diag;
|
||||
if(A_jj_iabs > tol ) { return false; } // imag should be approx zero
|
||||
if(A_jj_iabs > A_jj_rabs) { return false; } // corner case: real and imag are close to zero, and imag is dominant
|
||||
|
||||
if(A_jj_r >= tol) { diag_below_tol = false; }
|
||||
|
||||
max_diag = (A_jj_r > max_diag) ? A_jj_r : max_diag;
|
||||
|
||||
A_col += N;
|
||||
}
|
||||
|
||||
if(diag_below_tol) { return false; } // assume matrix is suspect if all diagonal elements are close to zero
|
||||
|
||||
const T square_max_diag = max_diag * max_diag;
|
||||
|
||||
if(arma_isfinite(square_max_diag) == false) { return false; }
|
||||
@@ -246,14 +267,11 @@ guess_sympd(const Mat<eT>& A, const uword min_n_rows)
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
typename enable_if2<is_cx<eT>::no, void>::result
|
||||
analyse_matrix_worker(bool& is_approx_sym, bool& is_approx_sympd, const Mat<eT>& A)
|
||||
typename enable_if2<is_cx<eT>::no, bool>::result
|
||||
is_approx_sym_worker(const Mat<eT>& A)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
is_approx_sym = true;
|
||||
is_approx_sympd = true;
|
||||
|
||||
const eT tol = eT(100) * std::numeric_limits<eT>::epsilon(); // allow some leeway
|
||||
|
||||
const uword N = A.n_rows;
|
||||
@@ -261,31 +279,29 @@ analyse_matrix_worker(bool& is_approx_sym, bool& is_approx_sympd, const Mat<eT>&
|
||||
const eT* A_mem = A.memptr();
|
||||
const eT* A_col = A_mem;
|
||||
|
||||
eT max_diag = eT(0);
|
||||
bool diag_below_tol = true;
|
||||
|
||||
for(uword j=0; j < N; ++j)
|
||||
{
|
||||
const eT A_jj = A_col[j];
|
||||
|
||||
if(A_jj <= eT(0)) { is_approx_sympd = false; }
|
||||
if(arma_isfinite(A_jj) == false) { return false; }
|
||||
|
||||
max_diag = (A_jj > max_diag) ? A_jj : max_diag;
|
||||
if(std::abs(A_jj) >= tol) { diag_below_tol = false; }
|
||||
|
||||
A_col += N;
|
||||
}
|
||||
|
||||
if(diag_below_tol) { return false; } // assume matrix is suspect if all diagonal elements are close to zero
|
||||
|
||||
A_col = A_mem;
|
||||
|
||||
const uword Nm1 = N-1;
|
||||
const uword Np1 = N+1;
|
||||
|
||||
for(uword j=0; j < Nm1; ++j)
|
||||
{
|
||||
const eT A_jj = A_col[j];
|
||||
|
||||
const uword jp1 = j+1;
|
||||
const eT* A_ji_ptr = &(A_mem[j + jp1*N]); // &(A.at(j,jp1));
|
||||
const eT* A_ii_ptr = &(A_mem[jp1 + jp1*N]);
|
||||
const eT* A_ji_ptr = &(A_mem[j + jp1*N]); // &(A.at(j,jp1));
|
||||
|
||||
for(uword i=jp1; i < N; ++i)
|
||||
{
|
||||
@@ -298,39 +314,29 @@ analyse_matrix_worker(bool& is_approx_sym, bool& is_approx_sympd, const Mat<eT>&
|
||||
const eT A_delta = (std::abs)(A_ij - A_ji);
|
||||
const eT A_abs_max = (std::max)(A_ij_abs, A_ji_abs);
|
||||
|
||||
if( (A_delta > tol) && (A_delta > (A_abs_max*tol)) ) { is_approx_sym = false; return; }
|
||||
|
||||
if(is_approx_sympd)
|
||||
{
|
||||
// if( (A_ij_abs >= max_diag) || (A_ji_abs >= max_diag) ) { is_approx_sympd = false; }
|
||||
if(A_ij_abs >= max_diag) { is_approx_sympd = false; }
|
||||
|
||||
const eT A_ii = (*A_ii_ptr);
|
||||
|
||||
if( (A_ij_abs + A_ij_abs) >= (A_ii + A_jj) ) { is_approx_sympd = false; }
|
||||
}
|
||||
if( (A_delta > tol) && (A_delta > (A_abs_max*tol)) ) { return false; }
|
||||
|
||||
A_ji_ptr += N;
|
||||
A_ii_ptr += Np1;
|
||||
}
|
||||
|
||||
A_col += N;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
typename enable_if2<is_cx<eT>::yes, void>::result
|
||||
analyse_matrix_worker(bool& is_approx_sym, bool& is_approx_sympd, const Mat<eT>& A)
|
||||
typename enable_if2<is_cx<eT>::yes, bool>::result
|
||||
is_approx_sym_worker(const Mat<eT>& A)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
typedef typename get_pod_type<eT>::result T;
|
||||
// NOTE: the function name is required for overloading, but is a misnomer: it processes complex hermitian matrices
|
||||
|
||||
is_approx_sym = true;
|
||||
is_approx_sympd = true;
|
||||
typedef typename get_pod_type<eT>::result T;
|
||||
|
||||
const T tol = T(100) * std::numeric_limits<T>::epsilon(); // allow some leeway
|
||||
|
||||
@@ -339,37 +345,37 @@ analyse_matrix_worker(bool& is_approx_sym, bool& is_approx_sympd, const Mat<eT>&
|
||||
const eT* A_mem = A.memptr();
|
||||
const eT* A_col = A_mem;
|
||||
|
||||
T max_diag = T(0);
|
||||
bool diag_below_tol = true;
|
||||
|
||||
// ensure diagonal has approx real-only elements
|
||||
for(uword j=0; j < N; ++j)
|
||||
{
|
||||
const eT& A_jj = A_col[j];
|
||||
const T A_jj_real = std::real(A_jj);
|
||||
const T A_jj_imag = std::imag(A_jj);
|
||||
const T A_jj_r = std::real(A_jj );
|
||||
const T A_jj_i = std::imag(A_jj );
|
||||
const T A_jj_rabs = std::abs(A_jj_r);
|
||||
const T A_jj_iabs = std::abs(A_jj_i);
|
||||
|
||||
if( (A_jj_real <= T(0)) || (std::abs(A_jj_imag) > tol) ) { is_approx_sympd = false; }
|
||||
if(A_jj_iabs > tol ) { return false; } // imag should be approx zero
|
||||
if(A_jj_iabs > A_jj_rabs) { return false; } // corner case: real and imag are close to zero, and imag is dominant
|
||||
|
||||
max_diag = (A_jj_real > max_diag) ? A_jj_real : max_diag;
|
||||
if(arma_isfinite(A_jj_r) == false) { return false; }
|
||||
|
||||
if(A_jj_rabs >= tol) { diag_below_tol = false; }
|
||||
|
||||
A_col += N;
|
||||
}
|
||||
|
||||
const T square_max_diag = max_diag * max_diag;
|
||||
|
||||
if(arma_isfinite(square_max_diag) == false) { is_approx_sympd = false; }
|
||||
if(diag_below_tol) { return false; } // assume matrix is suspect if all diagonal elements are close to zero
|
||||
|
||||
A_col = A_mem;
|
||||
|
||||
const uword Nm1 = N-1;
|
||||
const uword Np1 = N+1;
|
||||
|
||||
for(uword j=0; j < Nm1; ++j)
|
||||
{
|
||||
const uword jp1 = j+1;
|
||||
const eT* A_ji_ptr = &(A_mem[j + jp1*N]); // &(A.at(j,jp1));
|
||||
const eT* A_ii_ptr = &(A_mem[jp1 + jp1*N]);
|
||||
|
||||
const T A_jj_real = std::real(A_col[j]);
|
||||
const uword jp1 = j+1;
|
||||
const eT* A_ji_ptr = &(A_mem[j + jp1*N]); // &(A.at(j,jp1));
|
||||
|
||||
for(uword i=jp1; i < N; ++i)
|
||||
{
|
||||
@@ -390,63 +396,58 @@ analyse_matrix_worker(bool& is_approx_sym, bool& is_approx_sympd, const Mat<eT>&
|
||||
const T A_real_delta = (std::abs)(A_ij_real - A_ji_real);
|
||||
const T A_real_abs_max = (std::max)(A_ij_real_abs, A_ji_real_abs);
|
||||
|
||||
if( (A_real_delta > tol) && (A_real_delta > (A_real_abs_max*tol)) ) { is_approx_sym = false; return; }
|
||||
|
||||
if( (A_real_delta > tol) && (A_real_delta > (A_real_abs_max*tol)) ) { return false; }
|
||||
|
||||
const T A_imag_delta = (std::abs)(A_ij_imag + A_ji_imag); // take into account complex conjugate
|
||||
const T A_imag_abs_max = (std::max)(A_ij_imag_abs, A_ji_imag_abs);
|
||||
|
||||
if( (A_imag_delta > tol) && (A_imag_delta > (A_imag_abs_max*tol)) ) { is_approx_sym = false; return; }
|
||||
|
||||
if(is_approx_sympd)
|
||||
{
|
||||
// avoid using std::abs(), as that is time consuming due to division and std::sqrt()
|
||||
const T square_A_ij_abs = (A_ij_real * A_ij_real) + (A_ij_imag * A_ij_imag);
|
||||
|
||||
if(arma_isfinite(square_A_ij_abs) == false)
|
||||
{
|
||||
is_approx_sympd = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
const T A_ii_real = std::real(*A_ii_ptr);
|
||||
|
||||
if( (A_ij_real_abs + A_ij_real_abs) >= (A_ii_real + A_jj_real) ) { is_approx_sympd = false; }
|
||||
|
||||
if(square_A_ij_abs >= square_max_diag) { is_approx_sympd = false; }
|
||||
}
|
||||
}
|
||||
if( (A_imag_delta > tol) && (A_imag_delta > (A_imag_abs_max*tol)) ) { return false; }
|
||||
|
||||
A_ji_ptr += N;
|
||||
A_ii_ptr += Np1;
|
||||
}
|
||||
|
||||
A_col += N;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
analyse_matrix(bool& is_approx_sym, bool& is_approx_sympd, const Mat<eT>& A)
|
||||
bool
|
||||
is_approx_sym(const Mat<eT>& A)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
if((A.n_rows != A.n_cols) || (A.n_rows < uword(4)))
|
||||
{
|
||||
is_approx_sym = false;
|
||||
is_approx_sympd = false;
|
||||
return;
|
||||
}
|
||||
// analyse matrices with size >= 4x4
|
||||
|
||||
analyse_matrix_worker(is_approx_sym, is_approx_sympd, A);
|
||||
if((A.n_rows != A.n_cols) || (A.n_rows < uword(4))) { return false; }
|
||||
|
||||
if(is_approx_sym == false) { is_approx_sympd = false; }
|
||||
return is_approx_sym_worker(A);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
is_approx_sym(const Mat<eT>& A, const uword min_n_rows)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
if((A.n_rows != A.n_cols) || (A.n_rows < min_n_rows)) { return false; }
|
||||
|
||||
return is_approx_sym_worker(A);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
|
||||
@@ -1343,5 +1343,29 @@ struct is_sym_expr< Glue< Op<Mat<eT>, op_htrans>, Mat<eT>, glue_times > >
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T1>
|
||||
struct is_sym_expr< Op<T1, op_symmatu> >
|
||||
{
|
||||
static
|
||||
arma_inline
|
||||
bool
|
||||
eval(const Op<T1, op_symmatu>&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T1>
|
||||
struct is_sym_expr< Op<T1, op_symmatl> >
|
||||
{
|
||||
static
|
||||
arma_inline
|
||||
bool
|
||||
eval(const Op<T1, op_symmatl>&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//! @}
|
||||
|
||||
@@ -1341,6 +1341,150 @@ namespace lapack
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
sytrf(const char* uplo, const blas_int* n, eT* a, const blas_int* lda, blas_int* ipiv, eT* work, const blas_int* lwork, blas_int* info)
|
||||
{
|
||||
arma_type_check(( is_supported_blas_type<eT>::value == false ));
|
||||
|
||||
#if defined(ARMA_USE_FORTRAN_HIDDEN_ARGS)
|
||||
if( is_float<eT>::value) { typedef float T; arma_fortran(arma_ssytrf)(uplo, n, (T*)a, lda, ipiv, (T*)work, lwork, info, 1); }
|
||||
else if(is_double<eT>::value) { typedef double T; arma_fortran(arma_dsytrf)(uplo, n, (T*)a, lda, ipiv, (T*)work, lwork, info, 1); }
|
||||
#else
|
||||
if( is_float<eT>::value) { typedef float T; arma_fortran(arma_ssytrf)(uplo, n, (T*)a, lda, ipiv, (T*)work, lwork, info); }
|
||||
else if(is_double<eT>::value) { typedef double T; arma_fortran(arma_dsytrf)(uplo, n, (T*)a, lda, ipiv, (T*)work, lwork, info); }
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
hetrf(const char* uplo, const blas_int* n, eT* a, const blas_int* lda, blas_int* ipiv, eT* work, const blas_int* lwork, blas_int* info)
|
||||
{
|
||||
arma_type_check(( is_supported_blas_type<eT>::value == false ));
|
||||
|
||||
#if defined(ARMA_USE_FORTRAN_HIDDEN_ARGS)
|
||||
if( is_cx_float<eT>::value) { typedef blas_cxf T; arma_fortran(arma_chetrf)(uplo, n, (T*)a, lda, ipiv, (T*)work, lwork, info, 1); }
|
||||
else if(is_cx_double<eT>::value) { typedef blas_cxd T; arma_fortran(arma_zhetrf)(uplo, n, (T*)a, lda, ipiv, (T*)work, lwork, info, 1); }
|
||||
#else
|
||||
if( is_cx_float<eT>::value) { typedef blas_cxf T; arma_fortran(arma_chetrf)(uplo, n, (T*)a, lda, ipiv, (T*)work, lwork, info); }
|
||||
else if(is_cx_double<eT>::value) { typedef blas_cxd T; arma_fortran(arma_zhetrf)(uplo, n, (T*)a, lda, ipiv, (T*)work, lwork, info); }
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
sytrs(const char* uplo, const blas_int* n, const blas_int* nrhs, const eT* a, const blas_int* lda, const blas_int* ipiv, eT* b, const blas_int* ldb, blas_int* info)
|
||||
{
|
||||
arma_type_check(( is_supported_blas_type<eT>::value == false ));
|
||||
|
||||
#if defined(ARMA_USE_FORTRAN_HIDDEN_ARGS)
|
||||
if( is_float<eT>::value) { typedef float T; arma_fortran(arma_ssytrs)(uplo, n, nrhs, (T*)a, lda, ipiv, (T*)b, ldb, info, 1); }
|
||||
else if(is_double<eT>::value) { typedef double T; arma_fortran(arma_dsytrs)(uplo, n, nrhs, (T*)a, lda, ipiv, (T*)b, ldb, info, 1); }
|
||||
#else
|
||||
if( is_float<eT>::value) { typedef float T; arma_fortran(arma_ssytrs)(uplo, n, nrhs, (T*)a, lda, ipiv, (T*)b, ldb, info); }
|
||||
else if(is_double<eT>::value) { typedef double T; arma_fortran(arma_dsytrs)(uplo, n, nrhs, (T*)a, lda, ipiv, (T*)b, ldb, info); }
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
hetrs(const char* uplo, const blas_int* n, const blas_int* nrhs, const eT* a, const blas_int* lda, const blas_int* ipiv, eT* b, const blas_int* ldb, blas_int* info)
|
||||
{
|
||||
arma_type_check(( is_supported_blas_type<eT>::value == false ));
|
||||
|
||||
#if defined(ARMA_USE_FORTRAN_HIDDEN_ARGS)
|
||||
if( is_cx_float<eT>::value) { typedef blas_cxf T; arma_fortran(arma_chetrs)(uplo, n, nrhs, (T*)a, lda, ipiv, (T*)b, ldb, info, 1); }
|
||||
else if(is_cx_double<eT>::value) { typedef blas_cxd T; arma_fortran(arma_zhetrs)(uplo, n, nrhs, (T*)a, lda, ipiv, (T*)b, ldb, info, 1); }
|
||||
#else
|
||||
if( is_cx_float<eT>::value) { typedef blas_cxf T; arma_fortran(arma_chetrs)(uplo, n, nrhs, (T*)a, lda, ipiv, (T*)b, ldb, info); }
|
||||
else if(is_cx_double<eT>::value) { typedef blas_cxd T; arma_fortran(arma_zhetrs)(uplo, n, nrhs, (T*)a, lda, ipiv, (T*)b, ldb, info); }
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
sytri(const char* uplo, const blas_int* n, eT* a, const blas_int* lda, const blas_int* ipiv, eT* work, blas_int* info)
|
||||
{
|
||||
arma_type_check(( is_supported_blas_type<eT>::value == false ));
|
||||
|
||||
#if defined(ARMA_USE_FORTRAN_HIDDEN_ARGS)
|
||||
if( is_float<eT>::value) { typedef float T; arma_fortran(arma_ssytri)(uplo, n, (T*)a, lda, ipiv, (T*)work, info, 1); }
|
||||
else if(is_double<eT>::value) { typedef double T; arma_fortran(arma_dsytri)(uplo, n, (T*)a, lda, ipiv, (T*)work, info, 1); }
|
||||
#else
|
||||
if( is_float<eT>::value) { typedef float T; arma_fortran(arma_ssytri)(uplo, n, (T*)a, lda, ipiv, (T*)work, info); }
|
||||
else if(is_double<eT>::value) { typedef double T; arma_fortran(arma_dsytri)(uplo, n, (T*)a, lda, ipiv, (T*)work, info); }
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
hetri(const char* uplo, const blas_int* n, eT* a, const blas_int* lda, const blas_int* ipiv, eT* work, blas_int* info)
|
||||
{
|
||||
arma_type_check(( is_supported_blas_type<eT>::value == false ));
|
||||
|
||||
#if defined(ARMA_USE_FORTRAN_HIDDEN_ARGS)
|
||||
if( is_cx_float<eT>::value) { typedef blas_cxf T; arma_fortran(arma_chetri)(uplo, n, (T*)a, lda, ipiv, (T*)work, info, 1); }
|
||||
else if(is_cx_double<eT>::value) { typedef blas_cxd T; arma_fortran(arma_zhetri)(uplo, n, (T*)a, lda, ipiv, (T*)work, info, 1); }
|
||||
#else
|
||||
if( is_cx_float<eT>::value) { typedef blas_cxf T; arma_fortran(arma_chetri)(uplo, n, (T*)a, lda, ipiv, (T*)work, info); }
|
||||
else if(is_cx_double<eT>::value) { typedef blas_cxd T; arma_fortran(arma_zhetri)(uplo, n, (T*)a, lda, ipiv, (T*)work, info); }
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
sycon(const char* uplo, const blas_int* n, const eT* a, const blas_int* lda, const blas_int* ipiv, const eT* anorm, eT* rcond, eT* work, blas_int* iwork, blas_int* info)
|
||||
{
|
||||
arma_type_check(( is_supported_blas_type<eT>::value == false ));
|
||||
|
||||
#if defined(ARMA_USE_FORTRAN_HIDDEN_ARGS)
|
||||
if( is_float<eT>::value) { typedef float T; arma_fortran(arma_ssycon)(uplo, n, (const T*)a, lda, ipiv, (const T*)anorm, (T*)rcond, (T*)work, iwork, info, 1); }
|
||||
else if(is_double<eT>::value) { typedef double T; arma_fortran(arma_dsycon)(uplo, n, (const T*)a, lda, ipiv, (const T*)anorm, (T*)rcond, (T*)work, iwork, info, 1); }
|
||||
#else
|
||||
if( is_float<eT>::value) { typedef float T; arma_fortran(arma_ssycon)(uplo, n, (const T*)a, lda, ipiv, (const T*)anorm, (T*)rcond, (T*)work, iwork, info); }
|
||||
else if(is_double<eT>::value) { typedef double T; arma_fortran(arma_dsycon)(uplo, n, (const T*)a, lda, ipiv, (const T*)anorm, (T*)rcond, (T*)work, iwork, info); }
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline
|
||||
void
|
||||
hecon(const char* uplo, const blas_int* n, const std::complex<T>* a, const blas_int* lda, const blas_int* ipiv, const T* anorm, T* rcond, std::complex<T>* work, blas_int* info)
|
||||
{
|
||||
arma_type_check(( is_supported_blas_type<T>::value == false ));
|
||||
|
||||
#if defined(ARMA_USE_FORTRAN_HIDDEN_ARGS)
|
||||
if( is_float<T>::value) { typedef float pod_T; typedef blas_cxf cx_T; arma_fortran(arma_checon)(uplo, n, (const cx_T*)a, lda, ipiv, (const pod_T*)anorm, (pod_T*)rcond, (cx_T*)work, info, 1); }
|
||||
else if(is_double<T>::value) { typedef double pod_T; typedef blas_cxd cx_T; arma_fortran(arma_zhecon)(uplo, n, (const cx_T*)a, lda, ipiv, (const pod_T*)anorm, (pod_T*)rcond, (cx_T*)work, info, 1); }
|
||||
#else
|
||||
if( is_float<T>::value) { typedef float pod_T; typedef blas_cxf cx_T; arma_fortran(arma_checon)(uplo, n, (const cx_T*)a, lda, ipiv, (const pod_T*)anorm, (pod_T*)rcond, (cx_T*)work, info); }
|
||||
else if(is_double<T>::value) { typedef double pod_T; typedef blas_cxd cx_T; arma_fortran(arma_zhecon)(uplo, n, (const cx_T*)a, lda, ipiv, (const pod_T*)anorm, (pod_T*)rcond, (cx_T*)work, info); }
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -107,12 +107,9 @@ typedef void* void_ptr;
|
||||
//
|
||||
|
||||
|
||||
#if defined(ARMA_BLAS_LONG_LONG)
|
||||
#if defined(ARMA_BLAS_64BIT_INT)
|
||||
typedef long long blas_int;
|
||||
#define ARMA_MAX_BLAS_INT 0x7fffffffffffffffULL
|
||||
#elif defined(ARMA_BLAS_LONG)
|
||||
typedef long blas_int;
|
||||
#define ARMA_MAX_BLAS_INT 0x7fffffffffffffffUL
|
||||
#else
|
||||
typedef int blas_int;
|
||||
#define ARMA_MAX_BLAS_INT 0x7fffffffU
|
||||
|
||||
@@ -1075,8 +1075,8 @@ struct unwrap_check_mixed< Mat<eT1> >
|
||||
template<typename eT2>
|
||||
inline
|
||||
unwrap_check_mixed(const Mat<eT1>& A, const Mat<eT2>& B)
|
||||
: M_local( (void_ptr(&A) == void_ptr(&B)) ? new Mat<eT1>(A) : nullptr )
|
||||
, M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A )
|
||||
: M_local( ((is_same_type<eT1,eT2>::yes) && (void_ptr(&A) == void_ptr(&B))) ? new Mat<eT1>(A) : nullptr )
|
||||
, M ( ((is_same_type<eT1,eT2>::yes) && (void_ptr(&A) == void_ptr(&B))) ? (*M_local) : A )
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
}
|
||||
@@ -1112,8 +1112,8 @@ struct unwrap_check_mixed< Row<eT1> >
|
||||
template<typename eT2>
|
||||
inline
|
||||
unwrap_check_mixed(const Row<eT1>& A, const Mat<eT2>& B)
|
||||
: M_local( (void_ptr(&A) == void_ptr(&B)) ? new Row<eT1>(A) : nullptr )
|
||||
, M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A )
|
||||
: M_local( ((is_same_type<eT1,eT2>::yes) && (void_ptr(&A) == void_ptr(&B))) ? new Row<eT1>(A) : nullptr )
|
||||
, M ( ((is_same_type<eT1,eT2>::yes) && (void_ptr(&A) == void_ptr(&B))) ? (*M_local) : A )
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
}
|
||||
@@ -1150,8 +1150,8 @@ struct unwrap_check_mixed< Col<eT1> >
|
||||
template<typename eT2>
|
||||
inline
|
||||
unwrap_check_mixed(const Col<eT1>& A, const Mat<eT2>& B)
|
||||
: M_local( (void_ptr(&A) == void_ptr(&B)) ? new Col<eT1>(A) : nullptr )
|
||||
, M ( (void_ptr(&A) == void_ptr(&B)) ? (*M_local) : A )
|
||||
: M_local( ((is_same_type<eT1,eT2>::yes) && (void_ptr(&A) == void_ptr(&B))) ? new Col<eT1>(A) : nullptr )
|
||||
, M ( ((is_same_type<eT1,eT2>::yes) && (void_ptr(&A) == void_ptr(&B))) ? (*M_local) : A )
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
}
|
||||
|
||||
@@ -1287,6 +1287,102 @@ extern "C"
|
||||
arma_fortran_sans_prefix(arma_zpstrf)(uplo, n, a, lda, piv, rank, tol, work, info);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void arma_fortran_with_prefix(arma_ssytrf)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, blas_int* ipiv, float* work, const blas_int* lwork, blas_int* info)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_ssytrf)(uplo, n, a, lda, ipiv, work, lwork, info);
|
||||
}
|
||||
|
||||
void arma_fortran_with_prefix(arma_dsytrf)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, blas_int* ipiv, double* work, const blas_int* lwork, blas_int* info)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_dsytrf)(uplo, n, a, lda, ipiv, work, lwork, info);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void arma_fortran_with_prefix(arma_chetrf)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* ipiv, blas_cxf* work, const blas_int* lwork, blas_int* info)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_chetrf)(uplo, n, a, lda, ipiv, work, lwork, info);
|
||||
}
|
||||
|
||||
void arma_fortran_with_prefix(arma_zhetrf)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* ipiv, blas_cxd* work, const blas_int* lwork, blas_int* info)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_zhetrf)(uplo, n, a, lda, ipiv, work, lwork, info);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void arma_fortran_with_prefix(arma_ssytrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const float* a, const blas_int* lda, const blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_ssytrs)(uplo, n, nrhs, a, lda, ipiv, b, ldb, info);
|
||||
}
|
||||
|
||||
void arma_fortran_with_prefix(arma_dsytrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const double* a, const blas_int* lda, const blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_dsytrs)(uplo, n, nrhs, a, lda, ipiv, b, ldb, info);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void arma_fortran_with_prefix(arma_chetrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const blas_cxf* a, const blas_int* lda, const blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_chetrs)(uplo, n, nrhs, a, lda, ipiv, b, ldb, info);
|
||||
}
|
||||
|
||||
void arma_fortran_with_prefix(arma_zhetrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const blas_cxd* a, const blas_int* lda, const blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_zhetrs)(uplo, n, nrhs, a, lda, ipiv, b, ldb, info);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void arma_fortran_with_prefix(arma_ssytri)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, const blas_int* ipiv, float* work, blas_int* info)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_ssytri)(uplo, n, a, lda, ipiv, work, info);
|
||||
}
|
||||
|
||||
void arma_fortran_with_prefix(arma_dsytri)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, const blas_int* ipiv, double* work, blas_int* info)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_dsytri)(uplo, n, a, lda, ipiv, work, info);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void arma_fortran_with_prefix(arma_chetri)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, const blas_int* ipiv, blas_cxf* work, blas_int* info)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_chetri)(uplo, n, a, lda, ipiv, work, info);
|
||||
}
|
||||
|
||||
void arma_fortran_with_prefix(arma_zhetri)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, const blas_int* ipiv, blas_cxd* work, blas_int* info)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_zhetri)(uplo, n, a, lda, ipiv, work, info);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void arma_fortran_with_prefix(arma_ssycon)(const char* uplo, const blas_int* n, const float* a, const blas_int* lda, const blas_int* ipiv, const float* anorm, float* rcond, float* work, blas_int* iwork, blas_int* info)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_ssycon)(uplo, n, a, lda, ipiv, anorm, rcond, work, iwork, info);
|
||||
}
|
||||
|
||||
void arma_fortran_with_prefix(arma_dsycon)(const char* uplo, const blas_int* n, const double* a, const blas_int* lda, const blas_int* ipiv, const double* anorm, double* rcond, double* work, blas_int* iwork, blas_int* info)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_dsycon)(uplo, n, a, lda, ipiv, anorm, rcond, work, iwork, info);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void arma_fortran_with_prefix(arma_checon)(const char* uplo, const blas_int* n, const blas_cxf* a, const blas_int* lda, const blas_int* ipiv, const float* anorm, float* rcond, blas_cxf* work, blas_int* info)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_checon)(uplo, n, a, lda, ipiv, anorm, rcond, work, info);
|
||||
}
|
||||
|
||||
void arma_fortran_with_prefix(arma_zhecon)(const char* uplo, const blas_int* n, const blas_cxd* a, const blas_int* lda, const blas_int* ipiv, const double* anorm, double* rcond, blas_cxd* work, blas_int* info)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_zhecon)(uplo, n, a, lda, ipiv, anorm, rcond, work, info);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -1156,6 +1156,102 @@ extern "C"
|
||||
arma_fortran_sans_prefix(arma_zpstrf)(uplo, n, a, lda, piv, rank, tol, work, info, uplo_len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void arma_fortran_with_prefix(arma_ssytrf)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, blas_int* ipiv, float* work, const blas_int* lwork, blas_int* info, blas_len uplo_len)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_ssytrf)(uplo, n, a, lda, ipiv, work, lwork, info, uplo_len);
|
||||
}
|
||||
|
||||
void arma_fortran_with_prefix(arma_dsytrf)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, blas_int* ipiv, double* work, const blas_int* lwork, blas_int* info, blas_len uplo_len)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_dsytrf)(uplo, n, a, lda, ipiv, work, lwork, info, uplo_len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void arma_fortran_with_prefix(arma_chetrf)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, blas_int* ipiv, blas_cxf* work, const blas_int* lwork, blas_int* info, blas_len uplo_len)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_chetrf)(uplo, n, a, lda, ipiv, work, lwork, info, uplo_len);
|
||||
}
|
||||
|
||||
void arma_fortran_with_prefix(arma_zhetrf)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, blas_int* ipiv, blas_cxd* work, const blas_int* lwork, blas_int* info, blas_len uplo_len)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_zhetrf)(uplo, n, a, lda, ipiv, work, lwork, info, uplo_len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void arma_fortran_with_prefix(arma_ssytrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const float* a, const blas_int* lda, const blas_int* ipiv, float* b, const blas_int* ldb, blas_int* info, blas_len uplo_len)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_ssytrs)(uplo, n, nrhs, a, lda, ipiv, b, ldb, info, uplo_len);
|
||||
}
|
||||
|
||||
void arma_fortran_with_prefix(arma_dsytrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const double* a, const blas_int* lda, const blas_int* ipiv, double* b, const blas_int* ldb, blas_int* info, blas_len uplo_len)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_dsytrs)(uplo, n, nrhs, a, lda, ipiv, b, ldb, info, uplo_len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void arma_fortran_with_prefix(arma_chetrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const blas_cxf* a, const blas_int* lda, const blas_int* ipiv, blas_cxf* b, const blas_int* ldb, blas_int* info, blas_len uplo_len)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_chetrs)(uplo, n, nrhs, a, lda, ipiv, b, ldb, info, uplo_len);
|
||||
}
|
||||
|
||||
void arma_fortran_with_prefix(arma_zhetrs)(const char* uplo, const blas_int* n, const blas_int* nrhs, const blas_cxd* a, const blas_int* lda, const blas_int* ipiv, blas_cxd* b, const blas_int* ldb, blas_int* info, blas_len uplo_len)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_zhetrs)(uplo, n, nrhs, a, lda, ipiv, b, ldb, info, uplo_len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void arma_fortran_with_prefix(arma_ssytri)(const char* uplo, const blas_int* n, float* a, const blas_int* lda, const blas_int* ipiv, float* work, blas_int* info, blas_len uplo_len)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_ssytri)(uplo, n, a, lda, ipiv, work, info, uplo_len);
|
||||
}
|
||||
|
||||
void arma_fortran_with_prefix(arma_dsytri)(const char* uplo, const blas_int* n, double* a, const blas_int* lda, const blas_int* ipiv, double* work, blas_int* info, blas_len uplo_len)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_dsytri)(uplo, n, a, lda, ipiv, work, info, uplo_len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void arma_fortran_with_prefix(arma_chetri)(const char* uplo, const blas_int* n, blas_cxf* a, const blas_int* lda, const blas_int* ipiv, blas_cxf* work, blas_int* info, blas_len uplo_len)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_chetri)(uplo, n, a, lda, ipiv, work, info, uplo_len);
|
||||
}
|
||||
|
||||
void arma_fortran_with_prefix(arma_zhetri)(const char* uplo, const blas_int* n, blas_cxd* a, const blas_int* lda, const blas_int* ipiv, blas_cxd* work, blas_int* info, blas_len uplo_len)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_zhetri)(uplo, n, a, lda, ipiv, work, info, uplo_len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void arma_fortran_with_prefix(arma_ssycon)(const char* uplo, const blas_int* n, const float* a, const blas_int* lda, const blas_int* ipiv, const float* anorm, float* rcond, float* work, blas_int* iwork, blas_int* info, blas_len uplo_len)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_ssycon)(uplo, n, a, lda, ipiv, anorm, rcond, work, iwork, info, uplo_len);
|
||||
}
|
||||
|
||||
void arma_fortran_with_prefix(arma_dsycon)(const char* uplo, const blas_int* n, const double* a, const blas_int* lda, const blas_int* ipiv, const double* anorm, double* rcond, double* work, blas_int* iwork, blas_int* info, blas_len uplo_len)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_dsycon)(uplo, n, a, lda, ipiv, anorm, rcond, work, iwork, info, uplo_len);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void arma_fortran_with_prefix(arma_checon)(const char* uplo, const blas_int* n, const blas_cxf* a, const blas_int* lda, const blas_int* ipiv, const float* anorm, float* rcond, blas_cxf* work, blas_int* info, blas_len uplo_len)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_checon)(uplo, n, a, lda, ipiv, anorm, rcond, work, info, uplo_len);
|
||||
}
|
||||
|
||||
void arma_fortran_with_prefix(arma_zhecon)(const char* uplo, const blas_int* n, const blas_cxd* a, const blas_int* lda, const blas_int* ipiv, const double* anorm, double* rcond, blas_cxd* work, blas_int* info, blas_len uplo_len)
|
||||
{
|
||||
arma_fortran_sans_prefix(arma_zhecon)(uplo, n, a, lda, ipiv, anorm, rcond, work, info, uplo_len);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+356
-335
@@ -28,18 +28,17 @@ TEST_CASE("fn_max_subview_test")
|
||||
// Mat.max()...
|
||||
for (size_t r = 50; r < 150; ++r)
|
||||
{
|
||||
mat x;
|
||||
x.randu(r, r);
|
||||
mat x(r, r, fill::randn);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_subview_max3;
|
||||
uword x_max = x.index_max();
|
||||
uword x_subview_max1 = x.submat(0, 0, r - 1, r - 1).index_max();
|
||||
uword x_subview_max2 = x.cols(0, r - 1).index_max();
|
||||
uword x_subview_max3 = x.rows(0, r - 1).index_max();
|
||||
|
||||
const double mval = x.max(x_max);
|
||||
const double mval1 = x.submat(0, 0, r - 1, r - 1).max(x_subview_max1);
|
||||
const double mval2 = x.cols(0, r - 1).max(x_subview_max2);
|
||||
const double mval3 = x.rows(0, r - 1).max(x_subview_max3);
|
||||
const double mval = x.max();
|
||||
const double mval1 = x.submat(0, 0, r - 1, r - 1).max();
|
||||
const double mval2 = x.cols(0, r - 1).max();
|
||||
const double mval3 = x.rows(0, r - 1).max();
|
||||
|
||||
REQUIRE( x_max == x_subview_max1 );
|
||||
REQUIRE( x_max == x_subview_max2 );
|
||||
@@ -48,6 +47,8 @@ TEST_CASE("fn_max_subview_test")
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
REQUIRE( mval == Approx(mval3) );
|
||||
|
||||
REQUIRE( mval == Approx(x(x_max)) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,22 +58,23 @@ TEST_CASE("fn_max_subview_col_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
vec x;
|
||||
x.randu(r);
|
||||
vec x(r, fill::randn);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_max = x.index_max();
|
||||
uword x_subview_max1 = x.submat(0, 0, r - 1, 0).index_max();
|
||||
uword x_subview_max2 = x.rows(0, r - 1).index_max();
|
||||
|
||||
const double mval = x.max(x_max);
|
||||
const double mval1 = x.submat(0, 0, r - 1, 0).max(x_subview_max1);
|
||||
const double mval2 = x.rows(0, r - 1).max(x_subview_max2);
|
||||
const double mval = x.max();
|
||||
const double mval1 = x.submat(0, 0, r - 1, 0).max();
|
||||
const double mval2 = x.rows(0, r - 1).max();
|
||||
|
||||
REQUIRE( x_max == x_subview_max1 );
|
||||
REQUIRE( x_max == x_subview_max2 );
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
|
||||
REQUIRE( mval == Approx(x(x_max)) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,66 +84,66 @@ TEST_CASE("fn_max_subview_row_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
rowvec x;
|
||||
x.randu(r);
|
||||
rowvec x(r, fill::randn);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_max = x.index_max();
|
||||
uword x_subview_max1 = x.submat(0, 0, 0, r - 1).index_max();
|
||||
uword x_subview_max2 = x.cols(0, r - 1).index_max();
|
||||
|
||||
const double mval = x.max(x_max);
|
||||
const double mval1 = x.submat(0, 0, 0, r - 1).max(x_subview_max1);
|
||||
const double mval2 = x.cols(0, r - 1).max(x_subview_max2);
|
||||
const double mval = x.max();
|
||||
const double mval1 = x.submat(0, 0, 0, r - 1).max();
|
||||
const double mval2 = x.cols(0, r - 1).max();
|
||||
|
||||
REQUIRE( x_max == x_subview_max1 );
|
||||
REQUIRE( x_max == x_subview_max2 );
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
|
||||
REQUIRE( mval == Approx(x(x_max)) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_max_incomplete_subview_test")
|
||||
{
|
||||
for (size_t r = 50; r < 150; ++r)
|
||||
{
|
||||
mat x;
|
||||
x.randu(r, r);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_subview_max3;
|
||||
|
||||
const double mval = x.max(x_max);
|
||||
const double mval1 = x.submat(1, 1, r - 2, r - 2).max(x_subview_max1);
|
||||
const double mval2 = x.cols(1, r - 2).max(x_subview_max2);
|
||||
const double mval3 = x.rows(1, r - 2).max(x_subview_max3);
|
||||
|
||||
uword row, col;
|
||||
x.max(row, col);
|
||||
|
||||
if (row != 0 && row != r - 1 && col != 0 && col != r - 1)
|
||||
{
|
||||
uword srow, scol;
|
||||
|
||||
srow = x_subview_max1 % (r - 2);
|
||||
scol = x_subview_max1 / (r - 2);
|
||||
REQUIRE( x_max == (srow + 1) + r * (scol + 1) );
|
||||
REQUIRE( x_max == x_subview_max2 + r );
|
||||
|
||||
srow = x_subview_max3 % (r - 2);
|
||||
scol = x_subview_max3 / (r - 2);
|
||||
REQUIRE( x_max == (srow + 1) + r * scol );
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
REQUIRE( mval == Approx(mval3) );
|
||||
}
|
||||
}
|
||||
}
|
||||
// TEST_CASE("fn_max_incomplete_subview_test")
|
||||
// {
|
||||
// for (size_t r = 50; r < 150; ++r)
|
||||
// {
|
||||
// mat x(r, r, fill::randn);
|
||||
//
|
||||
// uword x_max;
|
||||
// uword x_subview_max1;
|
||||
// uword x_subview_max2;
|
||||
// uword x_subview_max3;
|
||||
//
|
||||
// const double mval = x.max(x_max);
|
||||
// const double mval1 = x.submat(1, 1, r - 2, r - 2).max(x_subview_max1);
|
||||
// const double mval2 = x.cols(1, r - 2).max(x_subview_max2);
|
||||
// const double mval3 = x.rows(1, r - 2).max(x_subview_max3);
|
||||
//
|
||||
// uword row, col;
|
||||
// x.max(row, col);
|
||||
//
|
||||
// if (row != 0 && row != r - 1 && col != 0 && col != r - 1)
|
||||
// {
|
||||
// uword srow, scol;
|
||||
//
|
||||
// srow = x_subview_max1 % (r - 2);
|
||||
// scol = x_subview_max1 / (r - 2);
|
||||
// REQUIRE( x_max == (srow + 1) + r * (scol + 1) );
|
||||
// REQUIRE( x_max == x_subview_max2 + r );
|
||||
//
|
||||
// srow = x_subview_max3 % (r - 2);
|
||||
// scol = x_subview_max3 / (r - 2);
|
||||
// REQUIRE( x_max == (srow + 1) + r * scol );
|
||||
//
|
||||
// REQUIRE( mval == Approx(mval1) );
|
||||
// REQUIRE( mval == Approx(mval2) );
|
||||
// REQUIRE( mval == Approx(mval3) );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
@@ -149,16 +151,15 @@ TEST_CASE("fn_max_incomplete_subview_col_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
vec x;
|
||||
x.randu(r);
|
||||
vec x(r, fill::randn);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_max = x.index_max();
|
||||
uword x_subview_max1 = x.submat(1, 0, r - 2, 0).index_max();
|
||||
uword x_subview_max2 = x.rows(1, r - 2).index_max();
|
||||
|
||||
const double mval = x.max(x_max);
|
||||
const double mval1 = x.submat(1, 0, r - 2, 0).max(x_subview_max1);
|
||||
const double mval2 = x.rows(1, r - 2).max(x_subview_max2);
|
||||
const double mval = x.max();
|
||||
const double mval1 = x.submat(1, 0, r - 2, 0).max();
|
||||
const double mval2 = x.rows(1, r - 2).max();
|
||||
|
||||
if (x_max != 0 && x_max != r - 1)
|
||||
{
|
||||
@@ -167,6 +168,8 @@ TEST_CASE("fn_max_incomplete_subview_col_test")
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
|
||||
REQUIRE( mval == Approx(x(x_max)) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -177,16 +180,15 @@ TEST_CASE("fn_max_cx_subview_row_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
cx_rowvec x;
|
||||
x.randu(r);
|
||||
cx_rowvec x(r, fill::randn);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_max = x.index_max();
|
||||
uword x_subview_max1 = x.submat(0, 0, 0, r - 1).index_max();
|
||||
uword x_subview_max2 = x.cols(0, r - 1).index_max();
|
||||
|
||||
const std::complex<double> mval = x.max(x_max);
|
||||
const std::complex<double> mval1 = x.submat(0, 0, 0, r - 1).max(x_subview_max1);
|
||||
const std::complex<double> mval2 = x.cols(0, r - 1).max(x_subview_max2);
|
||||
const std::complex<double> mval = x.max();
|
||||
const std::complex<double> mval1 = x.submat(0, 0, 0, r - 1).max();
|
||||
const std::complex<double> mval2 = x.cols(0, r - 1).max();
|
||||
|
||||
REQUIRE( x_max == x_subview_max1 );
|
||||
REQUIRE( x_max == x_subview_max2 );
|
||||
@@ -195,53 +197,55 @@ TEST_CASE("fn_max_cx_subview_row_test")
|
||||
REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
|
||||
REQUIRE( mval.real() == Approx(x(x_max).real()) );
|
||||
REQUIRE( mval.imag() == Approx(x(x_max).imag()) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_max_cx_incomplete_subview_test")
|
||||
{
|
||||
for (size_t r = 50; r < 150; ++r)
|
||||
{
|
||||
cx_mat x;
|
||||
x.randu(r, r);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_subview_max3;
|
||||
|
||||
const std::complex<double> mval = x.max(x_max);
|
||||
const std::complex<double> mval1 = x.submat(1, 1, r - 2, r - 2).max(x_subview_max1);
|
||||
const std::complex<double> mval2 = x.cols(1, r - 2).max(x_subview_max2);
|
||||
const std::complex<double> mval3 = x.rows(1, r - 2).max(x_subview_max3);
|
||||
|
||||
uword row, col;
|
||||
x.max(row, col);
|
||||
|
||||
if (row != 0 && row != r - 1 && col != 0 && col != r - 1)
|
||||
{
|
||||
uword srow, scol;
|
||||
|
||||
srow = x_subview_max1 % (r - 2);
|
||||
scol = x_subview_max1 / (r - 2);
|
||||
REQUIRE( x_max == (srow + 1) + r * (scol + 1) );
|
||||
REQUIRE( x_max == x_subview_max2 + r );
|
||||
|
||||
srow = x_subview_max3 % (r - 2);
|
||||
scol = x_subview_max3 / (r - 2);
|
||||
REQUIRE( x_max == (srow + 1) + r * scol );
|
||||
|
||||
REQUIRE( mval.real() == Approx(mval1.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval3.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval3.imag()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
// TEST_CASE("fn_max_cx_incomplete_subview_test")
|
||||
// {
|
||||
// for (size_t r = 50; r < 150; ++r)
|
||||
// {
|
||||
// cx_mat x(r, r, fill::randn);
|
||||
//
|
||||
// uword x_max;
|
||||
// uword x_subview_max1;
|
||||
// uword x_subview_max2;
|
||||
// uword x_subview_max3;
|
||||
//
|
||||
// const std::complex<double> mval = x.max(x_max);
|
||||
// const std::complex<double> mval1 = x.submat(1, 1, r - 2, r - 2).max(x_subview_max1);
|
||||
// const std::complex<double> mval2 = x.cols(1, r - 2).max(x_subview_max2);
|
||||
// const std::complex<double> mval3 = x.rows(1, r - 2).max(x_subview_max3);
|
||||
//
|
||||
// uword row, col;
|
||||
// x.max(row, col);
|
||||
//
|
||||
// if (row != 0 && row != r - 1 && col != 0 && col != r - 1)
|
||||
// {
|
||||
// uword srow, scol;
|
||||
//
|
||||
// srow = x_subview_max1 % (r - 2);
|
||||
// scol = x_subview_max1 / (r - 2);
|
||||
// REQUIRE( x_max == (srow + 1) + r * (scol + 1) );
|
||||
// REQUIRE( x_max == x_subview_max2 + r );
|
||||
//
|
||||
// srow = x_subview_max3 % (r - 2);
|
||||
// scol = x_subview_max3 / (r - 2);
|
||||
// REQUIRE( x_max == (srow + 1) + r * scol );
|
||||
//
|
||||
// REQUIRE( mval.real() == Approx(mval1.real()) );
|
||||
// REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
// REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
// REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
// REQUIRE( mval.real() == Approx(mval3.real()) );
|
||||
// REQUIRE( mval.imag() == Approx(mval3.imag()) );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
@@ -249,16 +253,15 @@ TEST_CASE("fn_max_cx_incomplete_subview_col_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
cx_vec x;
|
||||
x.randu(r);
|
||||
cx_vec x(r, fill::randn);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_max = x.index_max();
|
||||
uword x_subview_max1 = x.submat(1, 0, r - 2, 0).index_max();
|
||||
uword x_subview_max2 = x.rows(1, r - 2).index_max();
|
||||
|
||||
const std::complex<double> mval = x.max(x_max);
|
||||
const std::complex<double> mval1 = x.submat(1, 0, r - 2, 0).max(x_subview_max1);
|
||||
const std::complex<double> mval2 = x.rows(1, r - 2).max(x_subview_max2);
|
||||
const std::complex<double> mval = x.max();
|
||||
const std::complex<double> mval1 = x.submat(1, 0, r - 2, 0).max();
|
||||
const std::complex<double> mval2 = x.rows(1, r - 2).max();
|
||||
|
||||
if (x_max != 0 && x_max != r - 1)
|
||||
{
|
||||
@@ -269,6 +272,9 @@ TEST_CASE("fn_max_cx_incomplete_subview_col_test")
|
||||
REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
|
||||
REQUIRE( mval.real() == Approx(x(x_max).real()) );
|
||||
REQUIRE( mval.imag() == Approx(x(x_max).imag()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -279,16 +285,15 @@ TEST_CASE("fn_max_cx_incomplete_subview_row_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
cx_rowvec x;
|
||||
x.randu(r);
|
||||
cx_rowvec x(r, fill::randn);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_max = x.index_max();
|
||||
uword x_subview_max1 = x.submat(0, 1, 0, r - 2).index_max();
|
||||
uword x_subview_max2 = x.cols(1, r - 2).index_max();
|
||||
|
||||
const std::complex<double> mval = x.max(x_max);
|
||||
const std::complex<double> mval1 = x.submat(0, 1, 0, r - 2).max(x_subview_max1);
|
||||
const std::complex<double> mval2 = x.cols(1, r - 2).max(x_subview_max2);
|
||||
const std::complex<double> mval = x.max();
|
||||
const std::complex<double> mval1 = x.submat(0, 1, 0, r - 2).max();
|
||||
const std::complex<double> mval2 = x.cols(1, r - 2).max();
|
||||
|
||||
if (x_max != 0 && x_max != r - 1)
|
||||
{
|
||||
@@ -299,73 +304,73 @@ TEST_CASE("fn_max_cx_incomplete_subview_row_test")
|
||||
REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
|
||||
REQUIRE( mval.real() == Approx(x(x_max).real()) );
|
||||
REQUIRE( mval.imag() == Approx(x(x_max).imag()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_max_weird_operation_test")
|
||||
TEST_CASE("fn_max_weird_operation")
|
||||
{
|
||||
mat a(10, 10);
|
||||
mat b(25, 10);
|
||||
a.randn();
|
||||
b.randn();
|
||||
mat a(10, 10, fill::randn);
|
||||
mat b(25, 10, fill::randn);
|
||||
|
||||
mat output = a * b.t();
|
||||
|
||||
uword real_max;
|
||||
uword operation_max;
|
||||
uword real_max = output.index_max();
|
||||
uword operation_max = (a * b.t()).index_max();
|
||||
|
||||
const double mval = output.max(real_max);
|
||||
const double other_mval = (a * b.t()).max(operation_max);
|
||||
const double mval = output.max();
|
||||
const double other_mval = (a * b.t()).max();
|
||||
|
||||
REQUIRE( real_max == operation_max );
|
||||
REQUIRE( mval == Approx(other_mval) );
|
||||
REQUIRE( real_max == operation_max );
|
||||
REQUIRE( mval == Approx(other_mval) );
|
||||
REQUIRE( mval == Approx(output(real_max)) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_max_weird_sparse_operation_test")
|
||||
TEST_CASE("fn_max_weird_sparse_operation")
|
||||
{
|
||||
sp_mat a(10, 10);
|
||||
sp_mat b(25, 10);
|
||||
a.sprandn(10, 10, 0.3);
|
||||
b.sprandn(25, 10, 0.3);
|
||||
sp_mat a; a.sprandn(10, 10, 0.3);
|
||||
sp_mat b; b.sprandn(25, 10, 0.3);
|
||||
|
||||
sp_mat output = a * b.t();
|
||||
|
||||
uword real_max;
|
||||
uword operation_max;
|
||||
uword real_max = output.index_max();
|
||||
uword operation_max = (a * b.t()).index_max();
|
||||
|
||||
const double mval = output.max(real_max);
|
||||
const double other_mval = (a * b.t()).max(operation_max);
|
||||
const double mval = output.max();
|
||||
const double other_mval = (a * b.t()).max();
|
||||
|
||||
REQUIRE( real_max == operation_max );
|
||||
REQUIRE( mval == Approx(other_mval) );
|
||||
REQUIRE( real_max == operation_max );
|
||||
REQUIRE( mval == Approx(other_mval) );
|
||||
REQUIRE( mval == Approx(output(real_max)) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_max_spsubview_test")
|
||||
TEST_CASE("fn_max_sp_subview_test")
|
||||
{
|
||||
// We will assume subview.at() works and returns points within the bounds of
|
||||
// the matrix, so we just have to ensure the results are the same as
|
||||
// Mat.max()...
|
||||
for (size_t r = 50; r < 150; ++r)
|
||||
{
|
||||
sp_mat x;
|
||||
x.sprandn(r, r, 0.3);
|
||||
sp_mat x; x.sprandn(r, r, 0.3);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_subview_max3;
|
||||
uword x_max = x.index_max();
|
||||
uword x_subview_max1 = x.submat(0, 0, r - 1, r - 1).index_max();
|
||||
uword x_subview_max2 = x.cols(0, r - 1).index_max();
|
||||
uword x_subview_max3 = x.rows(0, r - 1).index_max();
|
||||
|
||||
const double mval = x.max(x_max);
|
||||
const double mval1 = x.submat(0, 0, r - 1, r - 1).max(x_subview_max1);
|
||||
const double mval2 = x.cols(0, r - 1).max(x_subview_max2);
|
||||
const double mval3 = x.rows(0, r - 1).max(x_subview_max3);
|
||||
const double mval = x.max();
|
||||
const double mval1 = x.submat(0, 0, r - 1, r - 1).max();
|
||||
const double mval2 = x.cols(0, r - 1).max();
|
||||
const double mval3 = x.rows(0, r - 1).max();
|
||||
|
||||
if (mval != 0.0)
|
||||
{
|
||||
@@ -376,6 +381,8 @@ TEST_CASE("fn_max_spsubview_test")
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
REQUIRE( mval == Approx(mval3) );
|
||||
|
||||
REQUIRE( mval == Approx(x(x_max)) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -386,16 +393,15 @@ TEST_CASE("fn_max_spsubview_col_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
sp_vec x;
|
||||
x.sprandn(r, 1, 0.3);
|
||||
sp_vec x; x.sprandn(r, 1, 0.3);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_max = x.index_max();
|
||||
uword x_subview_max1 = x.submat(0, 0, r - 1, 0).index_max();
|
||||
uword x_subview_max2 = x.rows(0, r - 1).index_max();
|
||||
|
||||
const double mval = x.max(x_max);
|
||||
const double mval1 = x.submat(0, 0, r - 1, 0).max(x_subview_max1);
|
||||
const double mval2 = x.rows(0, r - 1).max(x_subview_max2);
|
||||
const double mval = x.max();
|
||||
const double mval1 = x.submat(0, 0, r - 1, 0).max();
|
||||
const double mval2 = x.rows(0, r - 1).max();
|
||||
|
||||
if (mval != 0.0)
|
||||
{
|
||||
@@ -404,26 +410,27 @@ TEST_CASE("fn_max_spsubview_col_test")
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
|
||||
REQUIRE( mval == Approx(x(x_max)) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_max_spsubview_row_test")
|
||||
TEST_CASE("fn_max_spsubview_row_max_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
sp_rowvec x;
|
||||
x.sprandn(1, r, 0.3);
|
||||
sp_rowvec x; x.sprandn(1, r, 0.3);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_max = x.index_max();
|
||||
uword x_subview_max1 = x.submat(0, 0, 0, r - 1).index_max();
|
||||
uword x_subview_max2 = x.cols(0, r - 1).index_max();
|
||||
|
||||
const double mval = x.max(x_max);
|
||||
const double mval1 = x.submat(0, 0, 0, r - 1).max(x_subview_max1);
|
||||
const double mval2 = x.cols(0, r - 1).max(x_subview_max2);
|
||||
const double mval = x.max();
|
||||
const double mval1 = x.submat(0, 0, 0, r - 1).max();
|
||||
const double mval2 = x.cols(0, r - 1).max();
|
||||
|
||||
if (mval != 0.0)
|
||||
{
|
||||
@@ -432,68 +439,69 @@ TEST_CASE("fn_max_spsubview_row_test")
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
|
||||
REQUIRE( mval == Approx(x(x_max)) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_max_spincompletesubview_test")
|
||||
{
|
||||
for (size_t r = 50; r < 150; ++r)
|
||||
{
|
||||
sp_mat x;
|
||||
x.sprandn(r, r, 0.3);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_subview_max3;
|
||||
|
||||
const double mval = x.max(x_max);
|
||||
const double mval1 = x.submat(1, 1, r - 2, r - 2).max(x_subview_max1);
|
||||
const double mval2 = x.cols(1, r - 2).max(x_subview_max2);
|
||||
const double mval3 = x.rows(1, r - 2).max(x_subview_max3);
|
||||
|
||||
uword row, col;
|
||||
x.max(row, col);
|
||||
|
||||
if (row != 0 && row != r - 1 && col != 0 && col != r - 1 && mval != 0.0)
|
||||
{
|
||||
uword srow, scol;
|
||||
|
||||
srow = x_subview_max1 % (r - 2);
|
||||
scol = x_subview_max1 / (r - 2);
|
||||
REQUIRE( x_max == (srow + 1) + r * (scol + 1) );
|
||||
REQUIRE( x_max == x_subview_max2 + r );
|
||||
|
||||
srow = x_subview_max3 % (r - 2);
|
||||
scol = x_subview_max3 / (r - 2);
|
||||
REQUIRE( x_max == (srow + 1) + r * scol );
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
REQUIRE( mval == Approx(mval3) );
|
||||
}
|
||||
}
|
||||
}
|
||||
// TEST_CASE("fn_max_spincompletesubview_max_test")
|
||||
// {
|
||||
// for (size_t r = 50; r < 150; ++r)
|
||||
// {
|
||||
// sp_mat x;
|
||||
// x.sprandn(r, r, 0.3);
|
||||
//
|
||||
// uword x_max;
|
||||
// uword x_subview_max1;
|
||||
// uword x_subview_max2;
|
||||
// uword x_subview_max3;
|
||||
//
|
||||
// const double mval = x.max(x_max);
|
||||
// const double mval1 = x.submat(1, 1, r - 2, r - 2).max(x_subview_max1);
|
||||
// const double mval2 = x.cols(1, r - 2).max(x_subview_max2);
|
||||
// const double mval3 = x.rows(1, r - 2).max(x_subview_max3);
|
||||
//
|
||||
// uword row, col;
|
||||
// x.max(row, col);
|
||||
//
|
||||
// if (row != 0 && row != r - 1 && col != 0 && col != r - 1 && mval != 0.0)
|
||||
// {
|
||||
// uword srow, scol;
|
||||
//
|
||||
// srow = x_subview_max1 % (r - 2);
|
||||
// scol = x_subview_max1 / (r - 2);
|
||||
// REQUIRE( x_max == (srow + 1) + r * (scol + 1) );
|
||||
// REQUIRE( x_max == x_subview_max2 + r );
|
||||
//
|
||||
// srow = x_subview_max3 % (r - 2);
|
||||
// scol = x_subview_max3 / (r - 2);
|
||||
// REQUIRE( x_max == (srow + 1) + r * scol );
|
||||
//
|
||||
// REQUIRE( mval == Approx(mval1) );
|
||||
// REQUIRE( mval == Approx(mval2) );
|
||||
// REQUIRE( mval == Approx(mval3) );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_max_spincompletesubview_col_test")
|
||||
TEST_CASE("fn_max_spincompletesubview_col_max_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
sp_vec x;
|
||||
x.sprandu(r, 1, 0.3);
|
||||
sp_vec x; x.sprandu(r, 1, 0.3);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_max = x.index_max();
|
||||
uword x_subview_max1 = x.submat(1, 0, r - 2, 0).index_max();
|
||||
uword x_subview_max2 = x.rows(1, r - 2).index_max();
|
||||
|
||||
const double mval = x.max(x_max);
|
||||
const double mval1 = x.submat(1, 0, r - 2, 0).max(x_subview_max1);
|
||||
const double mval2 = x.rows(1, r - 2).max(x_subview_max2);
|
||||
const double mval = x.max();
|
||||
const double mval1 = x.submat(1, 0, r - 2, 0).max();
|
||||
const double mval2 = x.rows(1, r - 2).max();
|
||||
|
||||
if (x_max != 0 && x_max != r - 1 && mval != 0.0)
|
||||
{
|
||||
@@ -502,26 +510,27 @@ TEST_CASE("fn_max_spincompletesubview_col_test")
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
|
||||
REQUIRE( mval == Approx(x(x_max)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_max_spincompletesubview_row_test")
|
||||
TEST_CASE("fn_max_spincompletesubview_row_max_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
sp_rowvec x;
|
||||
x.sprandn(1, r, 0.3);
|
||||
sp_rowvec x; x.sprandn(1, r, 0.3);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_max = x.index_max();
|
||||
uword x_subview_max1 = x.submat(0, 1, 0, r - 2).index_max();
|
||||
uword x_subview_max2 = x.cols(1, r - 2).index_max();
|
||||
|
||||
const double mval = x.max(x_max);
|
||||
const double mval1 = x.submat(0, 1, 0, r - 2).max(x_subview_max1);
|
||||
const double mval2 = x.cols(1, r - 2).max(x_subview_max2);
|
||||
const double mval = x.max();
|
||||
const double mval1 = x.submat(0, 1, 0, r - 2).max();
|
||||
const double mval2 = x.cols(1, r - 2).max();
|
||||
|
||||
if (mval != 0.0 && x_max != 0 && x_max != r - 1)
|
||||
{
|
||||
@@ -530,31 +539,32 @@ TEST_CASE("fn_max_spincompletesubview_row_test")
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
|
||||
REQUIRE( mval == Approx( x(x_max) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_max_cx_spsubview_test")
|
||||
TEST_CASE("fn_max_sp_cx_subview_max_test")
|
||||
{
|
||||
// We will assume subview.at() works and returns points within the bounds of
|
||||
// the matrix, so we just have to ensure the results are the same as
|
||||
// Mat.max()...
|
||||
for (size_t r = 50; r < 150; ++r)
|
||||
{
|
||||
sp_cx_mat x;
|
||||
x.sprandn(r, r, 0.3);
|
||||
sp_cx_mat x; x.sprandn(r, r, 0.3);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_subview_max3;
|
||||
uword x_max = x.index_max();
|
||||
uword x_subview_max1 = x.submat(0, 0, r - 1, r - 1).index_max();
|
||||
uword x_subview_max2 = x.cols(0, r - 1).index_max();
|
||||
uword x_subview_max3 = x.rows(0, r - 1).index_max();
|
||||
|
||||
const std::complex<double> mval = x.max(x_max);
|
||||
const std::complex<double> mval1 = x.submat(0, 0, r - 1, r - 1).max(x_subview_max1);
|
||||
const std::complex<double> mval2 = x.cols(0, r - 1).max(x_subview_max2);
|
||||
const std::complex<double> mval3 = x.rows(0, r - 1).max(x_subview_max3);
|
||||
const std::complex<double> mval = x.max();
|
||||
const std::complex<double> mval1 = x.submat(0, 0, r - 1, r - 1).max();
|
||||
const std::complex<double> mval2 = x.cols(0, r - 1).max();
|
||||
const std::complex<double> mval3 = x.rows(0, r - 1).max();
|
||||
|
||||
if (mval != std::complex<double>(0.0))
|
||||
{
|
||||
@@ -568,26 +578,28 @@ TEST_CASE("fn_max_cx_spsubview_test")
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval3.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval3.imag()) );
|
||||
|
||||
REQUIRE( mval.real() == Approx(x(x_max).real()) );
|
||||
REQUIRE( mval.imag() == Approx(x(x_max).imag()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_max_cx_spsubview_col_test")
|
||||
TEST_CASE("fn_max_sp_cx_subview_col_max_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
sp_cx_vec x;
|
||||
x.sprandn(r, 1, 0.3);
|
||||
sp_cx_vec x; x.sprandn(r, 1, 0.3);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_max = x.index_max();
|
||||
uword x_subview_max1 = x.submat(0, 0, r - 1, 0).index_max();
|
||||
uword x_subview_max2 = x.rows(0, r - 1).index_max();
|
||||
|
||||
const std::complex<double> mval = x.max(x_max);
|
||||
const std::complex<double> mval1 = x.submat(0, 0, r - 1, 0).max(x_subview_max1);
|
||||
const std::complex<double> mval2 = x.rows(0, r - 1).max(x_subview_max2);
|
||||
const std::complex<double> mval = x.max();
|
||||
const std::complex<double> mval1 = x.submat(0, 0, r - 1, 0).max();
|
||||
const std::complex<double> mval2 = x.rows(0, r - 1).max();
|
||||
|
||||
if (mval != std::complex<double>(0.0))
|
||||
{
|
||||
@@ -598,26 +610,28 @@ TEST_CASE("fn_max_cx_spsubview_col_test")
|
||||
REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
|
||||
REQUIRE( mval.real() == Approx(x(x_max).real()) );
|
||||
REQUIRE( mval.imag() == Approx(x(x_max).imag()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_max_cx_spsubview_row_test")
|
||||
TEST_CASE("fn_max_sp_cx_subview_row_max_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
sp_cx_rowvec x;
|
||||
x.sprandn(1, r, 0.3);
|
||||
sp_cx_rowvec x; x.sprandn(1, r, 0.3);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_max = x.index_max();
|
||||
uword x_subview_max1 = x.submat(0, 0, 0, r - 1).index_max();
|
||||
uword x_subview_max2 = x.cols(0, r - 1).index_max();
|
||||
|
||||
const std::complex<double> mval = x.max(x_max);
|
||||
const std::complex<double> mval1 = x.submat(0, 0, 0, r - 1).max(x_subview_max1);
|
||||
const std::complex<double> mval2 = x.cols(0, r - 1).max(x_subview_max2);
|
||||
const std::complex<double> mval = x.max();
|
||||
const std::complex<double> mval1 = x.submat(0, 0, 0, r - 1).max();
|
||||
const std::complex<double> mval2 = x.cols(0, r - 1).max();
|
||||
|
||||
if (mval != std::complex<double>(0.0))
|
||||
{
|
||||
@@ -628,71 +642,73 @@ TEST_CASE("fn_max_cx_spsubview_row_test")
|
||||
REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
|
||||
REQUIRE( mval.real() == Approx(x(x_max).real()) );
|
||||
REQUIRE( mval.imag() == Approx(x(x_max).imag()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_max_cx_spincompletesubview_test")
|
||||
{
|
||||
for (size_t r = 50; r < 150; ++r)
|
||||
{
|
||||
sp_cx_mat x;
|
||||
x.sprandn(r, r, 0.3);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_subview_max3;
|
||||
|
||||
const std::complex<double> mval = x.max(x_max);
|
||||
const std::complex<double> mval1 = x.submat(1, 1, r - 2, r - 2).max(x_subview_max1);
|
||||
const std::complex<double> mval2 = x.cols(1, r - 2).max(x_subview_max2);
|
||||
const std::complex<double> mval3 = x.rows(1, r - 2).max(x_subview_max3);
|
||||
|
||||
uword row, col;
|
||||
x.max(row, col);
|
||||
|
||||
if (row != 0 && row != r - 1 && col != 0 && col != r - 1 && mval != std::complex<double>(0.0))
|
||||
{
|
||||
uword srow, scol;
|
||||
|
||||
srow = x_subview_max1 % (r - 2);
|
||||
scol = x_subview_max1 / (r - 2);
|
||||
REQUIRE( x_max == (srow + 1) + r * (scol + 1) );
|
||||
REQUIRE( x_max == x_subview_max2 + r );
|
||||
|
||||
srow = x_subview_max3 % (r - 2);
|
||||
scol = x_subview_max3 / (r - 2);
|
||||
REQUIRE( x_max == (srow + 1) + r * scol );
|
||||
|
||||
REQUIRE( mval.real() == Approx(mval1.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval3.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval3.imag()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
// TEST_CASE("fn_max_sp_cx_incomplete_subview_max_test")
|
||||
// {
|
||||
// for (size_t r = 50; r < 150; ++r)
|
||||
// {
|
||||
// sp_cx_mat x;
|
||||
// x.sprandn(r, r, 0.3);
|
||||
//
|
||||
// uword x_max;
|
||||
// uword x_subview_max1;
|
||||
// uword x_subview_max2;
|
||||
// uword x_subview_max3;
|
||||
//
|
||||
// const std::complex<double> mval = x.max(x_max);
|
||||
// const std::complex<double> mval1 = x.submat(1, 1, r - 2, r - 2).max(x_subview_max1);
|
||||
// const std::complex<double> mval2 = x.cols(1, r - 2).max(x_subview_max2);
|
||||
// const std::complex<double> mval3 = x.rows(1, r - 2).max(x_subview_max3);
|
||||
//
|
||||
// uword row, col;
|
||||
// x.max(row, col);
|
||||
//
|
||||
// if (row != 0 && row != r - 1 && col != 0 && col != r - 1 && mval != std::complex<double>(0.0))
|
||||
// {
|
||||
// uword srow, scol;
|
||||
//
|
||||
// srow = x_subview_max1 % (r - 2);
|
||||
// scol = x_subview_max1 / (r - 2);
|
||||
// REQUIRE( x_max == (srow + 1) + r * (scol + 1) );
|
||||
// REQUIRE( x_max == x_subview_max2 + r );
|
||||
//
|
||||
// srow = x_subview_max3 % (r - 2);
|
||||
// scol = x_subview_max3 / (r - 2);
|
||||
// REQUIRE( x_max == (srow + 1) + r * scol );
|
||||
//
|
||||
// REQUIRE( mval.real() == Approx(mval1.real()) );
|
||||
// REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
// REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
// REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
// REQUIRE( mval.real() == Approx(mval3.real()) );
|
||||
// REQUIRE( mval.imag() == Approx(mval3.imag()) );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_max_cx_spincompletesubview_col_test")
|
||||
TEST_CASE("fn_max_sp_cx_incomplete_subview_col_max_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
sp_cx_vec x;
|
||||
x.sprandn(r, 1, 0.3);
|
||||
arma::sp_cx_vec x; x.sprandn(r, 1, 0.3);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_max = x.index_max();
|
||||
uword x_subview_max1 = x.submat(1, 0, r - 2, 0).index_max();
|
||||
uword x_subview_max2 = x.rows(1, r - 2).index_max();
|
||||
|
||||
const std::complex<double> mval = x.max(x_max);
|
||||
const std::complex<double> mval1 = x.submat(1, 0, r - 2, 0).max(x_subview_max1);
|
||||
const std::complex<double> mval2 = x.rows(1, r - 2).max(x_subview_max2);
|
||||
const std::complex<double> mval = x.max();
|
||||
const std::complex<double> mval1 = x.submat(1, 0, r - 2, 0).max();
|
||||
const std::complex<double> mval2 = x.rows(1, r - 2).max();
|
||||
|
||||
if (x_max != 0 && x_max != r - 1 && mval != std::complex<double>(0.0))
|
||||
{
|
||||
@@ -703,26 +719,28 @@ TEST_CASE("fn_max_cx_spincompletesubview_col_test")
|
||||
REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
|
||||
REQUIRE( mval.real() == Approx(x(x_max).real()) );
|
||||
REQUIRE( mval.imag() == Approx(x(x_max).imag()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_max_cx_spincompletesubview_row_test")
|
||||
TEST_CASE("fn_max_sp_cx_incomplete_subview_row_max_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
sp_cx_rowvec x;
|
||||
x.sprandn(1, r, 0.3);
|
||||
sp_cx_rowvec x; x.sprandn(1, r, 0.3);
|
||||
|
||||
uword x_max;
|
||||
uword x_subview_max1;
|
||||
uword x_subview_max2;
|
||||
uword x_max = x.index_max();
|
||||
uword x_subview_max1 = x.submat(0, 1, 0, r - 2).index_max();
|
||||
uword x_subview_max2 = x.cols(1, r - 2).index_max();
|
||||
|
||||
const std::complex<double> mval = x.max(x_max);
|
||||
const std::complex<double> mval1 = x.submat(0, 1, 0, r - 2).max(x_subview_max1);
|
||||
const std::complex<double> mval2 = x.cols(1, r - 2).max(x_subview_max2);
|
||||
const std::complex<double> mval = x.max();
|
||||
const std::complex<double> mval1 = x.submat(0, 1, 0, r - 2).max();
|
||||
const std::complex<double> mval2 = x.cols(1, r - 2).max();
|
||||
|
||||
if (x_max != 0 && x_max != r - 1 && mval != std::complex<double>(0.0))
|
||||
{
|
||||
@@ -733,6 +751,9 @@ TEST_CASE("fn_max_cx_spincompletesubview_row_test")
|
||||
REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
|
||||
REQUIRE( mval.real() == Approx(x(x_max).real()) );
|
||||
REQUIRE( mval.imag() == Approx(x(x_max).imag()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+490
-185
@@ -21,44 +21,334 @@
|
||||
|
||||
using namespace arma;
|
||||
|
||||
TEST_CASE("fn_min_subview_test")
|
||||
{
|
||||
// We will assume subview.at() works and returns points within the bounds of
|
||||
// the matrix, so we just have to ensure the results are the same as
|
||||
// Mat.min()...
|
||||
for (size_t r = 50; r < 150; ++r)
|
||||
{
|
||||
mat x(r, r, fill::randn);
|
||||
|
||||
uword x_min = x.index_min();
|
||||
uword x_subview_min1 = x.submat(0, 0, r - 1, r - 1).index_min();
|
||||
uword x_subview_min2 = x.cols(0, r - 1).index_min();
|
||||
uword x_subview_min3 = x.rows(0, r - 1).index_min();
|
||||
|
||||
const double mval = x.min();
|
||||
const double mval1 = x.submat(0, 0, r - 1, r - 1).min();
|
||||
const double mval2 = x.cols(0, r - 1).min();
|
||||
const double mval3 = x.rows(0, r - 1).min();
|
||||
|
||||
REQUIRE( x_min == x_subview_min1 );
|
||||
REQUIRE( x_min == x_subview_min2 );
|
||||
REQUIRE( x_min == x_subview_min3 );
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
REQUIRE( mval == Approx(mval3) );
|
||||
|
||||
REQUIRE( mval == Approx(x(x_min)) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_min_subview_col_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
vec x(r, fill::randn);
|
||||
|
||||
uword x_min = x.index_min();
|
||||
uword x_subview_min1 = x.submat(0, 0, r - 1, 0).index_min();
|
||||
uword x_subview_min2 = x.rows(0, r - 1).index_min();
|
||||
|
||||
const double mval = x.min();
|
||||
const double mval1 = x.submat(0, 0, r - 1, 0).min();
|
||||
const double mval2 = x.rows(0, r - 1).min();
|
||||
|
||||
REQUIRE( x_min == x_subview_min1 );
|
||||
REQUIRE( x_min == x_subview_min2 );
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
|
||||
REQUIRE( mval == Approx(x(x_min)) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_min_subview_row_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
rowvec x(r, fill::randn);
|
||||
|
||||
uword x_min = x.index_min();
|
||||
uword x_subview_min1 = x.submat(0, 0, 0, r - 1).index_min();
|
||||
uword x_subview_min2 = x.cols(0, r - 1).index_min();
|
||||
|
||||
const double mval = x.min();
|
||||
const double mval1 = x.submat(0, 0, 0, r - 1).min();
|
||||
const double mval2 = x.cols(0, r - 1).min();
|
||||
|
||||
REQUIRE( x_min == x_subview_min1 );
|
||||
REQUIRE( x_min == x_subview_min2 );
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
|
||||
REQUIRE( mval == Approx(x(x_min)) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TEST_CASE("fn_min_incomplete_subview_test")
|
||||
// {
|
||||
// for (size_t r = 50; r < 150; ++r)
|
||||
// {
|
||||
// mat x(r, r, fill::randn);
|
||||
//
|
||||
// uword x_min;
|
||||
// uword x_subview_min1;
|
||||
// uword x_subview_min2;
|
||||
// uword x_subview_min3;
|
||||
//
|
||||
// const double mval = x.min(x_min);
|
||||
// const double mval1 = x.submat(1, 1, r - 2, r - 2).min(x_subview_min1);
|
||||
// const double mval2 = x.cols(1, r - 2).min(x_subview_min2);
|
||||
// const double mval3 = x.rows(1, r - 2).min(x_subview_min3);
|
||||
//
|
||||
// uword row, col;
|
||||
// x.min(row, col);
|
||||
//
|
||||
// if (row != 0 && row != r - 1 && col != 0 && col != r - 1)
|
||||
// {
|
||||
// uword srow, scol;
|
||||
//
|
||||
// srow = x_subview_min1 % (r - 2);
|
||||
// scol = x_subview_min1 / (r - 2);
|
||||
// REQUIRE( x_min == (srow + 1) + r * (scol + 1) );
|
||||
// REQUIRE( x_min == x_subview_min2 + r );
|
||||
//
|
||||
// srow = x_subview_min3 % (r - 2);
|
||||
// scol = x_subview_min3 / (r - 2);
|
||||
// REQUIRE( x_min == (srow + 1) + r * scol );
|
||||
//
|
||||
// REQUIRE( mval == Approx(mval1) );
|
||||
// REQUIRE( mval == Approx(mval2) );
|
||||
// REQUIRE( mval == Approx(mval3) );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_min_incomplete_subview_col_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
vec x(r, fill::randn);
|
||||
|
||||
uword x_min = x.index_min();
|
||||
uword x_subview_min1 = x.submat(1, 0, r - 2, 0).index_min();
|
||||
uword x_subview_min2 = x.rows(1, r - 2).index_min();
|
||||
|
||||
const double mval = x.min();
|
||||
const double mval1 = x.submat(1, 0, r - 2, 0).min();
|
||||
const double mval2 = x.rows(1, r - 2).min();
|
||||
|
||||
if (x_min != 0 && x_min != r - 1)
|
||||
{
|
||||
REQUIRE( x_min == x_subview_min1 + 1 );
|
||||
REQUIRE( x_min == x_subview_min2 + 1 );
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
|
||||
REQUIRE( mval == Approx(x(x_min)) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_min_cx_subview_row_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
cx_rowvec x(r, fill::randn);
|
||||
|
||||
uword x_min = x.index_min();
|
||||
uword x_subview_min1 = x.submat(0, 0, 0, r - 1).index_min();
|
||||
uword x_subview_min2 = x.cols(0, r - 1).index_min();
|
||||
|
||||
const std::complex<double> mval = x.min();
|
||||
const std::complex<double> mval1 = x.submat(0, 0, 0, r - 1).min();
|
||||
const std::complex<double> mval2 = x.cols(0, r - 1).min();
|
||||
|
||||
REQUIRE( x_min == x_subview_min1 );
|
||||
REQUIRE( x_min == x_subview_min2 );
|
||||
|
||||
REQUIRE( mval.real() == Approx(mval1.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
|
||||
REQUIRE( mval.real() == Approx(x(x_min).real()) );
|
||||
REQUIRE( mval.imag() == Approx(x(x_min).imag()) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// TEST_CASE("fn_min_cx_incomplete_subview_test")
|
||||
// {
|
||||
// for (size_t r = 50; r < 150; ++r)
|
||||
// {
|
||||
// cx_mat x(r, r, fill::randn);
|
||||
//
|
||||
// uword x_min;
|
||||
// uword x_subview_min1;
|
||||
// uword x_subview_min2;
|
||||
// uword x_subview_min3;
|
||||
//
|
||||
// const std::complex<double> mval = x.min(x_min);
|
||||
// const std::complex<double> mval1 = x.submat(1, 1, r - 2, r - 2).min(x_subview_min1);
|
||||
// const std::complex<double> mval2 = x.cols(1, r - 2).min(x_subview_min2);
|
||||
// const std::complex<double> mval3 = x.rows(1, r - 2).min(x_subview_min3);
|
||||
//
|
||||
// uword row, col;
|
||||
// x.min(row, col);
|
||||
//
|
||||
// if (row != 0 && row != r - 1 && col != 0 && col != r - 1)
|
||||
// {
|
||||
// uword srow, scol;
|
||||
//
|
||||
// srow = x_subview_min1 % (r - 2);
|
||||
// scol = x_subview_min1 / (r - 2);
|
||||
// REQUIRE( x_min == (srow + 1) + r * (scol + 1) );
|
||||
// REQUIRE( x_min == x_subview_min2 + r );
|
||||
//
|
||||
// srow = x_subview_min3 % (r - 2);
|
||||
// scol = x_subview_min3 / (r - 2);
|
||||
// REQUIRE( x_min == (srow + 1) + r * scol );
|
||||
//
|
||||
// REQUIRE( mval.real() == Approx(mval1.real()) );
|
||||
// REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
// REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
// REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
// REQUIRE( mval.real() == Approx(mval3.real()) );
|
||||
// REQUIRE( mval.imag() == Approx(mval3.imag()) );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_min_cx_incomplete_subview_col_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
cx_vec x(r, fill::randn);
|
||||
|
||||
uword x_min = x.index_min();
|
||||
uword x_subview_min1 = x.submat(1, 0, r - 2, 0).index_min();
|
||||
uword x_subview_min2 = x.rows(1, r - 2).index_min();
|
||||
|
||||
const std::complex<double> mval = x.min();
|
||||
const std::complex<double> mval1 = x.submat(1, 0, r - 2, 0).min();
|
||||
const std::complex<double> mval2 = x.rows(1, r - 2).min();
|
||||
|
||||
if (x_min != 0 && x_min != r - 1)
|
||||
{
|
||||
REQUIRE( x_min == x_subview_min1 + 1 );
|
||||
REQUIRE( x_min == x_subview_min2 + 1 );
|
||||
|
||||
REQUIRE( mval.real() == Approx(mval1.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
|
||||
REQUIRE( mval.real() == Approx(x(x_min).real()) );
|
||||
REQUIRE( mval.imag() == Approx(x(x_min).imag()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_min_cx_incomplete_subview_row_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
cx_rowvec x(r, fill::randn);
|
||||
|
||||
uword x_min = x.index_min();
|
||||
uword x_subview_min1 = x.submat(0, 1, 0, r - 2).index_min();
|
||||
uword x_subview_min2 = x.cols(1, r - 2).index_min();
|
||||
|
||||
const std::complex<double> mval = x.min();
|
||||
const std::complex<double> mval1 = x.submat(0, 1, 0, r - 2).min();
|
||||
const std::complex<double> mval2 = x.cols(1, r - 2).min();
|
||||
|
||||
if (x_min != 0 && x_min != r - 1)
|
||||
{
|
||||
REQUIRE( x_min == x_subview_min1 + 1 );
|
||||
REQUIRE( x_min == x_subview_min2 + 1 );
|
||||
|
||||
REQUIRE( mval.real() == Approx(mval1.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
|
||||
REQUIRE( mval.real() == Approx(x(x_min).real()) );
|
||||
REQUIRE( mval.imag() == Approx(x(x_min).imag()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_min_weird_operation")
|
||||
{
|
||||
mat a(10, 10);
|
||||
mat b(25, 10);
|
||||
a.randn();
|
||||
b.randn();
|
||||
mat a(10, 10, fill::randn);
|
||||
mat b(25, 10, fill::randn);
|
||||
|
||||
mat output = a * b.t();
|
||||
|
||||
uword real_min;
|
||||
uword operation_min;
|
||||
uword real_min = output.index_min();
|
||||
uword operation_min = (a * b.t()).index_min();
|
||||
|
||||
const double mval = output.min(real_min);
|
||||
const double other_mval = (a * b.t()).min(operation_min);
|
||||
const double mval = output.min();
|
||||
const double other_mval = (a * b.t()).min();
|
||||
|
||||
REQUIRE( real_min == operation_min );
|
||||
REQUIRE( mval == Approx(other_mval) );
|
||||
REQUIRE( real_min == operation_min );
|
||||
REQUIRE( mval == Approx(other_mval) );
|
||||
REQUIRE( mval == Approx(output(real_min)) );
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_min_weird_sparse_operation")
|
||||
{
|
||||
sp_mat a(10, 10);
|
||||
sp_mat b(25, 10);
|
||||
a.sprandn(10, 10, 0.3);
|
||||
b.sprandn(25, 10, 0.3);
|
||||
sp_mat a; a.sprandn(10, 10, 0.3);
|
||||
sp_mat b; b.sprandn(25, 10, 0.3);
|
||||
|
||||
sp_mat output = a * b.t();
|
||||
|
||||
uword real_min;
|
||||
uword operation_min;
|
||||
uword real_min = output.index_min();
|
||||
uword operation_min = (a * b.t()).index_min();
|
||||
|
||||
const double mval = output.min(real_min);
|
||||
const double other_mval = (a * b.t()).min(operation_min);
|
||||
const double mval = output.min();
|
||||
const double other_mval = (a * b.t()).min();
|
||||
|
||||
REQUIRE( real_min == operation_min );
|
||||
REQUIRE( mval == Approx(other_mval) );
|
||||
REQUIRE( real_min == operation_min );
|
||||
REQUIRE( mval == Approx(other_mval) );
|
||||
REQUIRE( mval == Approx(output(real_min)) );
|
||||
}
|
||||
|
||||
|
||||
@@ -70,18 +360,17 @@ TEST_CASE("fn_min_sp_subview_test")
|
||||
// Mat.min()...
|
||||
for (size_t r = 50; r < 150; ++r)
|
||||
{
|
||||
sp_mat x;
|
||||
x.sprandn(r, r, 0.3);
|
||||
sp_mat x; x.sprandn(r, r, 0.3);
|
||||
|
||||
uword x_min;
|
||||
uword x_subview_min1;
|
||||
uword x_subview_min2;
|
||||
uword x_subview_min3;
|
||||
uword x_min = x.index_min();
|
||||
uword x_subview_min1 = x.submat(0, 0, r - 1, r - 1).index_min();
|
||||
uword x_subview_min2 = x.cols(0, r - 1).index_min();
|
||||
uword x_subview_min3 = x.rows(0, r - 1).index_min();
|
||||
|
||||
const double mval = x.min(x_min);
|
||||
const double mval1 = x.submat(0, 0, r - 1, r - 1).min(x_subview_min1);
|
||||
const double mval2 = x.cols(0, r - 1).min(x_subview_min2);
|
||||
const double mval3 = x.rows(0, r - 1).min(x_subview_min3);
|
||||
const double mval = x.min();
|
||||
const double mval1 = x.submat(0, 0, r - 1, r - 1).min();
|
||||
const double mval2 = x.cols(0, r - 1).min();
|
||||
const double mval3 = x.rows(0, r - 1).min();
|
||||
|
||||
if (mval != 0.0)
|
||||
{
|
||||
@@ -92,6 +381,8 @@ TEST_CASE("fn_min_sp_subview_test")
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
REQUIRE( mval == Approx(mval3) );
|
||||
|
||||
REQUIRE( mval == Approx(x(x_min)) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,16 +393,15 @@ TEST_CASE("fn_min_spsubview_col_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
sp_vec x;
|
||||
x.sprandn(r, 1, 0.3);
|
||||
sp_vec x; x.sprandn(r, 1, 0.3);
|
||||
|
||||
uword x_min;
|
||||
uword x_subview_min1;
|
||||
uword x_subview_min2;
|
||||
uword x_min = x.index_min();
|
||||
uword x_subview_min1 = x.submat(0, 0, r - 1, 0).index_min();
|
||||
uword x_subview_min2 = x.rows(0, r - 1).index_min();
|
||||
|
||||
const double mval = x.min(x_min);
|
||||
const double mval1 = x.submat(0, 0, r - 1, 0).min(x_subview_min1);
|
||||
const double mval2 = x.rows(0, r - 1).min(x_subview_min2);
|
||||
const double mval = x.min();
|
||||
const double mval1 = x.submat(0, 0, r - 1, 0).min();
|
||||
const double mval2 = x.rows(0, r - 1).min();
|
||||
|
||||
if (mval != 0.0)
|
||||
{
|
||||
@@ -120,6 +410,8 @@ TEST_CASE("fn_min_spsubview_col_test")
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
|
||||
REQUIRE( mval == Approx(x(x_min)) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -130,16 +422,15 @@ TEST_CASE("fn_min_spsubview_row_min_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
sp_rowvec x;
|
||||
x.sprandn(1, r, 0.3);
|
||||
sp_rowvec x; x.sprandn(1, r, 0.3);
|
||||
|
||||
uword x_min;
|
||||
uword x_subview_min1;
|
||||
uword x_subview_min2;
|
||||
uword x_min = x.index_min();
|
||||
uword x_subview_min1 = x.submat(0, 0, 0, r - 1).index_min();
|
||||
uword x_subview_min2 = x.cols(0, r - 1).index_min();
|
||||
|
||||
const double mval = x.min(x_min);
|
||||
const double mval1 = x.submat(0, 0, 0, r - 1).min(x_subview_min1);
|
||||
const double mval2 = x.cols(0, r - 1).min(x_subview_min2);
|
||||
const double mval = x.min();
|
||||
const double mval1 = x.submat(0, 0, 0, r - 1).min();
|
||||
const double mval2 = x.cols(0, r - 1).min();
|
||||
|
||||
if (mval != 0.0)
|
||||
{
|
||||
@@ -148,51 +439,53 @@ TEST_CASE("fn_min_spsubview_row_min_test")
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
|
||||
REQUIRE( mval == Approx(x(x_min)) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_min_spincompletesubview_min_test")
|
||||
{
|
||||
for (size_t r = 50; r < 150; ++r)
|
||||
{
|
||||
sp_mat x;
|
||||
x.sprandn(r, r, 0.3);
|
||||
|
||||
uword x_min;
|
||||
uword x_subview_min1;
|
||||
uword x_subview_min2;
|
||||
uword x_subview_min3;
|
||||
|
||||
const double mval = x.min(x_min);
|
||||
const double mval1 = x.submat(1, 1, r - 2, r - 2).min(x_subview_min1);
|
||||
const double mval2 = x.cols(1, r - 2).min(x_subview_min2);
|
||||
const double mval3 = x.rows(1, r - 2).min(x_subview_min3);
|
||||
|
||||
uword row, col;
|
||||
x.min(row, col);
|
||||
|
||||
if (row != 0 && row != r - 1 && col != 0 && col != r - 1 && mval != 0.0)
|
||||
{
|
||||
uword srow, scol;
|
||||
|
||||
srow = x_subview_min1 % (r - 2);
|
||||
scol = x_subview_min1 / (r - 2);
|
||||
REQUIRE( x_min == (srow + 1) + r * (scol + 1) );
|
||||
REQUIRE( x_min == x_subview_min2 + r );
|
||||
|
||||
srow = x_subview_min3 % (r - 2);
|
||||
scol = x_subview_min3 / (r - 2);
|
||||
REQUIRE( x_min == (srow + 1) + r * scol );
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
REQUIRE( mval == Approx(mval3) );
|
||||
}
|
||||
}
|
||||
}
|
||||
// TEST_CASE("fn_min_spincompletesubview_min_test")
|
||||
// {
|
||||
// for (size_t r = 50; r < 150; ++r)
|
||||
// {
|
||||
// sp_mat x;
|
||||
// x.sprandn(r, r, 0.3);
|
||||
//
|
||||
// uword x_min;
|
||||
// uword x_subview_min1;
|
||||
// uword x_subview_min2;
|
||||
// uword x_subview_min3;
|
||||
//
|
||||
// const double mval = x.min(x_min);
|
||||
// const double mval1 = x.submat(1, 1, r - 2, r - 2).min(x_subview_min1);
|
||||
// const double mval2 = x.cols(1, r - 2).min(x_subview_min2);
|
||||
// const double mval3 = x.rows(1, r - 2).min(x_subview_min3);
|
||||
//
|
||||
// uword row, col;
|
||||
// x.min(row, col);
|
||||
//
|
||||
// if (row != 0 && row != r - 1 && col != 0 && col != r - 1 && mval != 0.0)
|
||||
// {
|
||||
// uword srow, scol;
|
||||
//
|
||||
// srow = x_subview_min1 % (r - 2);
|
||||
// scol = x_subview_min1 / (r - 2);
|
||||
// REQUIRE( x_min == (srow + 1) + r * (scol + 1) );
|
||||
// REQUIRE( x_min == x_subview_min2 + r );
|
||||
//
|
||||
// srow = x_subview_min3 % (r - 2);
|
||||
// scol = x_subview_min3 / (r - 2);
|
||||
// REQUIRE( x_min == (srow + 1) + r * scol );
|
||||
//
|
||||
// REQUIRE( mval == Approx(mval1) );
|
||||
// REQUIRE( mval == Approx(mval2) );
|
||||
// REQUIRE( mval == Approx(mval3) );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
@@ -200,16 +493,15 @@ TEST_CASE("fn_min_spincompletesubview_col_min_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
sp_vec x;
|
||||
x.sprandu(r, 1, 0.3);
|
||||
sp_vec x; x.sprandu(r, 1, 0.3);
|
||||
|
||||
uword x_min;
|
||||
uword x_subview_min1;
|
||||
uword x_subview_min2;
|
||||
uword x_min = x.index_min();
|
||||
uword x_subview_min1 = x.submat(1, 0, r - 2, 0).index_min();
|
||||
uword x_subview_min2 = x.rows(1, r - 2).index_min();
|
||||
|
||||
const double mval = x.min(x_min);
|
||||
const double mval1 = x.submat(1, 0, r - 2, 0).min(x_subview_min1);
|
||||
const double mval2 = x.rows(1, r - 2).min(x_subview_min2);
|
||||
const double mval = x.min();
|
||||
const double mval1 = x.submat(1, 0, r - 2, 0).min();
|
||||
const double mval2 = x.rows(1, r - 2).min();
|
||||
|
||||
if (x_min != 0 && x_min != r - 1 && mval != 0.0)
|
||||
{
|
||||
@@ -218,6 +510,8 @@ TEST_CASE("fn_min_spincompletesubview_col_min_test")
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
|
||||
REQUIRE( mval == Approx(x(x_min)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -228,16 +522,15 @@ TEST_CASE("fn_min_spincompletesubview_row_min_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
sp_rowvec x;
|
||||
x.sprandn(1, r, 0.3);
|
||||
sp_rowvec x; x.sprandn(1, r, 0.3);
|
||||
|
||||
uword x_min;
|
||||
uword x_subview_min1;
|
||||
uword x_subview_min2;
|
||||
uword x_min = x.index_min();
|
||||
uword x_subview_min1 = x.submat(0, 1, 0, r - 2).index_min();
|
||||
uword x_subview_min2 = x.cols(1, r - 2).index_min();
|
||||
|
||||
const double mval = x.min(x_min);
|
||||
const double mval1 = x.submat(0, 1, 0, r - 2).min(x_subview_min1);
|
||||
const double mval2 = x.cols(1, r - 2).min(x_subview_min2);
|
||||
const double mval = x.min();
|
||||
const double mval1 = x.submat(0, 1, 0, r - 2).min();
|
||||
const double mval2 = x.cols(1, r - 2).min();
|
||||
|
||||
if (mval != 0.0 && x_min != 0 && x_min != r - 1)
|
||||
{
|
||||
@@ -246,6 +539,8 @@ TEST_CASE("fn_min_spincompletesubview_row_min_test")
|
||||
|
||||
REQUIRE( mval == Approx(mval1) );
|
||||
REQUIRE( mval == Approx(mval2) );
|
||||
|
||||
REQUIRE( mval == Approx( x(x_min) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -259,18 +554,17 @@ TEST_CASE("fn_min_sp_cx_subview_min_test")
|
||||
// Mat.min()...
|
||||
for (size_t r = 50; r < 150; ++r)
|
||||
{
|
||||
sp_cx_mat x;
|
||||
x.sprandn(r, r, 0.3);
|
||||
sp_cx_mat x; x.sprandn(r, r, 0.3);
|
||||
|
||||
uword x_min;
|
||||
uword x_subview_min1;
|
||||
uword x_subview_min2;
|
||||
uword x_subview_min3;
|
||||
uword x_min = x.index_min();
|
||||
uword x_subview_min1 = x.submat(0, 0, r - 1, r - 1).index_min();
|
||||
uword x_subview_min2 = x.cols(0, r - 1).index_min();
|
||||
uword x_subview_min3 = x.rows(0, r - 1).index_min();
|
||||
|
||||
const std::complex<double> mval = x.min(x_min);
|
||||
const std::complex<double> mval1 = x.submat(0, 0, r - 1, r - 1).min(x_subview_min1);
|
||||
const std::complex<double> mval2 = x.cols(0, r - 1).min(x_subview_min2);
|
||||
const std::complex<double> mval3 = x.rows(0, r - 1).min(x_subview_min3);
|
||||
const std::complex<double> mval = x.min();
|
||||
const std::complex<double> mval1 = x.submat(0, 0, r - 1, r - 1).min();
|
||||
const std::complex<double> mval2 = x.cols(0, r - 1).min();
|
||||
const std::complex<double> mval3 = x.rows(0, r - 1).min();
|
||||
|
||||
if (mval != std::complex<double>(0.0))
|
||||
{
|
||||
@@ -284,6 +578,9 @@ TEST_CASE("fn_min_sp_cx_subview_min_test")
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval3.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval3.imag()) );
|
||||
|
||||
REQUIRE( mval.real() == Approx(x(x_min).real()) );
|
||||
REQUIRE( mval.imag() == Approx(x(x_min).imag()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -294,16 +591,15 @@ TEST_CASE("fn_min_sp_cx_subview_col_min_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
sp_cx_vec x;
|
||||
x.sprandn(r, 1, 0.3);
|
||||
sp_cx_vec x; x.sprandn(r, 1, 0.3);
|
||||
|
||||
uword x_min;
|
||||
uword x_subview_min1;
|
||||
uword x_subview_min2;
|
||||
uword x_min = x.index_min();
|
||||
uword x_subview_min1 = x.submat(0, 0, r - 1, 0).index_min();
|
||||
uword x_subview_min2 = x.rows(0, r - 1).index_min();
|
||||
|
||||
const std::complex<double> mval = x.min(x_min);
|
||||
const std::complex<double> mval1 = x.submat(0, 0, r - 1, 0).min(x_subview_min1);
|
||||
const std::complex<double> mval2 = x.rows(0, r - 1).min(x_subview_min2);
|
||||
const std::complex<double> mval = x.min();
|
||||
const std::complex<double> mval1 = x.submat(0, 0, r - 1, 0).min();
|
||||
const std::complex<double> mval2 = x.rows(0, r - 1).min();
|
||||
|
||||
if (mval != std::complex<double>(0.0))
|
||||
{
|
||||
@@ -314,6 +610,9 @@ TEST_CASE("fn_min_sp_cx_subview_col_min_test")
|
||||
REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
|
||||
REQUIRE( mval.real() == Approx(x(x_min).real()) );
|
||||
REQUIRE( mval.imag() == Approx(x(x_min).imag()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -324,16 +623,15 @@ TEST_CASE("fn_min_sp_cx_subview_row_min_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
sp_cx_rowvec x;
|
||||
x.sprandn(1, r, 0.3);
|
||||
sp_cx_rowvec x; x.sprandn(1, r, 0.3);
|
||||
|
||||
uword x_min;
|
||||
uword x_subview_min1;
|
||||
uword x_subview_min2;
|
||||
uword x_min = x.index_min();
|
||||
uword x_subview_min1 = x.submat(0, 0, 0, r - 1).index_min();
|
||||
uword x_subview_min2 = x.cols(0, r - 1).index_min();
|
||||
|
||||
const std::complex<double> mval = x.min(x_min);
|
||||
const std::complex<double> mval1 = x.submat(0, 0, 0, r - 1).min(x_subview_min1);
|
||||
const std::complex<double> mval2 = x.cols(0, r - 1).min(x_subview_min2);
|
||||
const std::complex<double> mval = x.min();
|
||||
const std::complex<double> mval1 = x.submat(0, 0, 0, r - 1).min();
|
||||
const std::complex<double> mval2 = x.cols(0, r - 1).min();
|
||||
|
||||
if (mval != std::complex<double>(0.0))
|
||||
{
|
||||
@@ -344,54 +642,57 @@ TEST_CASE("fn_min_sp_cx_subview_row_min_test")
|
||||
REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
|
||||
REQUIRE( mval.real() == Approx(x(x_min).real()) );
|
||||
REQUIRE( mval.imag() == Approx(x(x_min).imag()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_CASE("fn_min_sp_cx_incomplete_subview_min_test")
|
||||
{
|
||||
for (size_t r = 50; r < 150; ++r)
|
||||
{
|
||||
sp_cx_mat x;
|
||||
x.sprandn(r, r, 0.3);
|
||||
|
||||
uword x_min;
|
||||
uword x_subview_min1;
|
||||
uword x_subview_min2;
|
||||
uword x_subview_min3;
|
||||
|
||||
const std::complex<double> mval = x.min(x_min);
|
||||
const std::complex<double> mval1 = x.submat(1, 1, r - 2, r - 2).min(x_subview_min1);
|
||||
const std::complex<double> mval2 = x.cols(1, r - 2).min(x_subview_min2);
|
||||
const std::complex<double> mval3 = x.rows(1, r - 2).min(x_subview_min3);
|
||||
|
||||
uword row, col;
|
||||
x.min(row, col);
|
||||
|
||||
if (row != 0 && row != r - 1 && col != 0 && col != r - 1 && mval != std::complex<double>(0.0))
|
||||
{
|
||||
uword srow, scol;
|
||||
|
||||
srow = x_subview_min1 % (r - 2);
|
||||
scol = x_subview_min1 / (r - 2);
|
||||
REQUIRE( x_min == (srow + 1) + r * (scol + 1) );
|
||||
REQUIRE( x_min == x_subview_min2 + r );
|
||||
|
||||
srow = x_subview_min3 % (r - 2);
|
||||
scol = x_subview_min3 / (r - 2);
|
||||
REQUIRE( x_min == (srow + 1) + r * scol );
|
||||
|
||||
REQUIRE( mval.real() == Approx(mval1.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval3.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval3.imag()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
// TEST_CASE("fn_min_sp_cx_incomplete_subview_min_test")
|
||||
// {
|
||||
// for (size_t r = 50; r < 150; ++r)
|
||||
// {
|
||||
// sp_cx_mat x;
|
||||
// x.sprandn(r, r, 0.3);
|
||||
//
|
||||
// uword x_min;
|
||||
// uword x_subview_min1;
|
||||
// uword x_subview_min2;
|
||||
// uword x_subview_min3;
|
||||
//
|
||||
// const std::complex<double> mval = x.min(x_min);
|
||||
// const std::complex<double> mval1 = x.submat(1, 1, r - 2, r - 2).min(x_subview_min1);
|
||||
// const std::complex<double> mval2 = x.cols(1, r - 2).min(x_subview_min2);
|
||||
// const std::complex<double> mval3 = x.rows(1, r - 2).min(x_subview_min3);
|
||||
//
|
||||
// uword row, col;
|
||||
// x.min(row, col);
|
||||
//
|
||||
// if (row != 0 && row != r - 1 && col != 0 && col != r - 1 && mval != std::complex<double>(0.0))
|
||||
// {
|
||||
// uword srow, scol;
|
||||
//
|
||||
// srow = x_subview_min1 % (r - 2);
|
||||
// scol = x_subview_min1 / (r - 2);
|
||||
// REQUIRE( x_min == (srow + 1) + r * (scol + 1) );
|
||||
// REQUIRE( x_min == x_subview_min2 + r );
|
||||
//
|
||||
// srow = x_subview_min3 % (r - 2);
|
||||
// scol = x_subview_min3 / (r - 2);
|
||||
// REQUIRE( x_min == (srow + 1) + r * scol );
|
||||
//
|
||||
// REQUIRE( mval.real() == Approx(mval1.real()) );
|
||||
// REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
// REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
// REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
// REQUIRE( mval.real() == Approx(mval3.real()) );
|
||||
// REQUIRE( mval.imag() == Approx(mval3.imag()) );
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
@@ -399,16 +700,15 @@ TEST_CASE("fn_min_sp_cx_incomplete_subview_col_min_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
arma::sp_cx_vec x;
|
||||
x.sprandn(r, 1, 0.3);
|
||||
arma::sp_cx_vec x; x.sprandn(r, 1, 0.3);
|
||||
|
||||
uword x_min;
|
||||
uword x_subview_min1;
|
||||
uword x_subview_min2;
|
||||
uword x_min = x.index_min();
|
||||
uword x_subview_min1 = x.submat(1, 0, r - 2, 0).index_min();
|
||||
uword x_subview_min2 = x.rows(1, r - 2).index_min();
|
||||
|
||||
const std::complex<double> mval = x.min(x_min);
|
||||
const std::complex<double> mval1 = x.submat(1, 0, r - 2, 0).min(x_subview_min1);
|
||||
const std::complex<double> mval2 = x.rows(1, r - 2).min(x_subview_min2);
|
||||
const std::complex<double> mval = x.min();
|
||||
const std::complex<double> mval1 = x.submat(1, 0, r - 2, 0).min();
|
||||
const std::complex<double> mval2 = x.rows(1, r - 2).min();
|
||||
|
||||
if (x_min != 0 && x_min != r - 1 && mval != std::complex<double>(0.0))
|
||||
{
|
||||
@@ -419,6 +719,9 @@ TEST_CASE("fn_min_sp_cx_incomplete_subview_col_min_test")
|
||||
REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
|
||||
REQUIRE( mval.real() == Approx(x(x_min).real()) );
|
||||
REQUIRE( mval.imag() == Approx(x(x_min).imag()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -429,16 +732,15 @@ TEST_CASE("fn_min_sp_cx_incomplete_subview_row_min_test")
|
||||
{
|
||||
for (size_t r = 10; r < 50; ++r)
|
||||
{
|
||||
sp_cx_rowvec x;
|
||||
x.sprandn(1, r, 0.3);
|
||||
sp_cx_rowvec x; x.sprandn(1, r, 0.3);
|
||||
|
||||
uword x_min;
|
||||
uword x_subview_min1;
|
||||
uword x_subview_min2;
|
||||
uword x_min = x.index_min();
|
||||
uword x_subview_min1 = x.submat(0, 1, 0, r - 2).index_min();
|
||||
uword x_subview_min2 = x.cols(1, r - 2).index_min();
|
||||
|
||||
const std::complex<double> mval = x.min(x_min);
|
||||
const std::complex<double> mval1 = x.submat(0, 1, 0, r - 2).min(x_subview_min1);
|
||||
const std::complex<double> mval2 = x.cols(1, r - 2).min(x_subview_min2);
|
||||
const std::complex<double> mval = x.min();
|
||||
const std::complex<double> mval1 = x.submat(0, 1, 0, r - 2).min();
|
||||
const std::complex<double> mval2 = x.cols(1, r - 2).min();
|
||||
|
||||
if (x_min != 0 && x_min != r - 1 && mval != std::complex<double>(0.0))
|
||||
{
|
||||
@@ -449,6 +751,9 @@ TEST_CASE("fn_min_sp_cx_incomplete_subview_row_min_test")
|
||||
REQUIRE( mval.imag() == Approx(mval1.imag()) );
|
||||
REQUIRE( mval.real() == Approx(mval2.real()) );
|
||||
REQUIRE( mval.imag() == Approx(mval2.imag()) );
|
||||
|
||||
REQUIRE( mval.real() == Approx(x(x_min).real()) );
|
||||
REQUIRE( mval.imag() == Approx(x(x_min).imag()) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-13
@@ -510,20 +510,14 @@ TEST_CASE("min_max_test")
|
||||
a(4, 4) = 0.2;
|
||||
a(5, 4) = 8.3;
|
||||
|
||||
uword index, row, col;
|
||||
REQUIRE( a.min() == Approx(-0.2) );
|
||||
REQUIRE( a.min(index) == Approx(-0.2) );
|
||||
REQUIRE( index == 27 );
|
||||
REQUIRE( a.min(row, col) == Approx(-0.2) );
|
||||
REQUIRE( row == 3 );
|
||||
REQUIRE( col == 4 );
|
||||
|
||||
REQUIRE( a.max() == Approx(9.8) );
|
||||
REQUIRE( a.max(index) == Approx(9.8) );
|
||||
REQUIRE( index == 19 );
|
||||
REQUIRE( a.max(row, col) == Approx(9.8) );
|
||||
REQUIRE( row == 1 );
|
||||
REQUIRE( col == 3 );
|
||||
REQUIRE( a.max() == Approx( 9.8) );
|
||||
|
||||
uword index1 = a.index_min();
|
||||
uword index2 = a.index_max();
|
||||
|
||||
REQUIRE( index1 == 27 );
|
||||
REQUIRE( index2 == 19 );
|
||||
}
|
||||
|
||||
TEST_CASE("swap_row_test")
|
||||
|
||||
Reference in New Issue
Block a user