Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c2b1eea864 | ||
|
|
6eb9394e13 | ||
|
|
391a1df2e8 | ||
|
|
7b718b1ae9 | ||
|
|
bc18db7a51 | ||
|
|
505339b6e5 | ||
|
|
f015fac562 | ||
|
|
502cbca4ba | ||
|
|
5e5331acd4 | ||
|
|
2dddc1367e | ||
|
|
5ca720b31f | ||
|
|
f72922fa68 | ||
|
|
c18e7f0aff | ||
|
|
0c40604508 | ||
|
|
f16c95c5c5 | ||
|
|
65c42d01cd |
@@ -778,7 +778,7 @@ which is one of:
|
||||
<ul>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr><td><code>fill::zeros</code></td><td> ↦ </td><td>set all elements to 0 (default in Armadillo >= 10.5)</td></tr>
|
||||
<tr><td><code>fill::zeros</code></td><td> ↦ </td><td>set all elements to 0</td></tr>
|
||||
<tr><td><code>fill::ones</code></td><td> ↦ </td><td>set all elements to 1</td></tr>
|
||||
<tr><td><code>fill::eye</code></td><td> ↦ </td><td>set the elements on the main diagonal to 1 and off-diagonal elements to 0</td></tr>
|
||||
<tr><td><code>fill::randu</code></td><td> ↦ </td><td>set all elements to random values from a uniform distribution in the [0,1] interval</td></tr>
|
||||
@@ -790,13 +790,7 @@ which is one of:
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
<b>Caveat:</b>
|
||||
<ul>
|
||||
<li>in Armadillo >= 10.5, the default initialisation is <code>fill::zeros</code></li>
|
||||
<li>in Armadillo <= 10.4, the default initialisation is <code>fill::none</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Default element initialisation is <code>fill::zeros</code> (since Armadillo 10.5)</li>
|
||||
<br>
|
||||
<li>
|
||||
For the <i>mat(string)</i> constructor, the format is elements separated by spaces, and rows denoted by semicolons;
|
||||
@@ -1722,7 +1716,7 @@ which is one of:
|
||||
<ul>
|
||||
<table>
|
||||
<tbody>
|
||||
<tr><td><code>fill::zeros</code></td><td> ↦ </td><td>set all elements to 0 (default in Armadillo >= 10.5)</td></tr>
|
||||
<tr><td><code>fill::zeros</code></td><td> ↦ </td><td>set all elements to 0</td></tr>
|
||||
<tr><td><code>fill::ones</code></td><td> ↦ </td><td>set all elements to 1</td></tr>
|
||||
<tr><td><code>fill::randu</code></td><td> ↦ </td><td>set all elements to random values from a uniform distribution in the [0,1] interval</td></tr>
|
||||
<tr><td><code>fill::randn</code></td><td> ↦ </td><td>set all elements to random values from a normal/Gaussian distribution with zero mean and unit variance</td></tr>
|
||||
@@ -1733,13 +1727,7 @@ which is one of:
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
<b>Caveat:</b>
|
||||
<ul>
|
||||
<li>in Armadillo >= 10.5, the default initialisation is <code>fill::zeros</code></li>
|
||||
<li>in Armadillo <= 10.4, the default initialisation is <code>fill::none</code></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Default element initialisation is <code>fill::zeros</code> (since Armadillo 10.5)</li>
|
||||
<br>
|
||||
<li>
|
||||
Each instance of <i>cube</i> automatically allocates and releases internal memory.
|
||||
@@ -4299,7 +4287,7 @@ Similar to "broadcasting" in Matlab / Octave
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
Supported operations for forms 1 and 2:
|
||||
Supported operations for forms 1 and 2:
|
||||
<br>
|
||||
<br>
|
||||
<ul>
|
||||
@@ -4314,7 +4302,7 @@ Supported operations for forms 1 and 2:
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
For form 2:
|
||||
For form 2:
|
||||
<ul>
|
||||
<li>the argument <i>vector_of_indices</i> contains a list of indices of the columns/rows to be used; it must evaluate to a vector of type <i><a href="#Col">uvec</a></i></li>
|
||||
<li>arithmetic operations as per form 1 are supported</li>
|
||||
@@ -4322,7 +4310,7 @@ For form 2:
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
For form 3:
|
||||
For form 3:
|
||||
<ul>
|
||||
<li>apply the given <i>lambda_function</i> to each column vector or row vector</li>
|
||||
<li>the function must accept a reference to a <a href="#Col">Col</a> or <a href="#Row">Row</a> object with the same element type as the underlying matrix</li>
|
||||
@@ -4395,7 +4383,7 @@ Similar to "broadcasting" in Matlab / Octave
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
Supported operations for form 1:
|
||||
Supported operations for form 1:
|
||||
<br>
|
||||
<br>
|
||||
<ul>
|
||||
@@ -4411,7 +4399,7 @@ Supported operations for form 1:
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
For form 2:
|
||||
For form 2:
|
||||
<ul>
|
||||
<li>the argument <i>vector_of_indices</i> contains a list of indices of the slices to be used; it must evaluate to a vector of type <i><a href="#Col">uvec</a></i></li>
|
||||
<li>arithmetic operations as per form 1 are supported, except for <code><b>*</b></code> and <code><b>*=</b></code> (ie. matrix multiplication)</li>
|
||||
@@ -4419,7 +4407,7 @@ For form 2:
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
For form 3:
|
||||
For form 3:
|
||||
<ul>
|
||||
<li>apply the given <i>lambda_function</i> to each slice</li>
|
||||
<li>the function must accept a reference to a <a href="#Mat">Mat</a> object with the same element type as the underlying cube</li>
|
||||
@@ -4427,7 +4415,7 @@ For form 3:
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
For form 4:
|
||||
For form 4:
|
||||
<ul>
|
||||
<li>apply the given <i>lambda_function</i> to each slice, as per form 3</li>
|
||||
<li>the argument <i>use_mp</i> is a bool to enable the use of OpenMP for multi-threaded execution of <i>lambda_function</i> on multiple slices at the same time</li>
|
||||
@@ -6822,6 +6810,7 @@ See also:
|
||||
<li><a href="#has_nan">.has_nan()</a></li>
|
||||
<li><a href="#find_finite_nonfinite">find_finite() / find_nonfinite()</a></li>
|
||||
<li><a href="#find_nan_nonnan">find_nan() / find_nonnan()</a></li>
|
||||
<li><a href="#omit_nan_nonfinite">omit_nan() / omit_nonfinite()</a></li>
|
||||
<li><a href="#constants">constants (pi, nan, inf, ...)</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -6864,6 +6853,7 @@ See also:
|
||||
<li><a href="#replace">.replace()</a></li>
|
||||
<li><a href="#is_finite">.is_finite()</a>
|
||||
<li><a href="#find_finite_nonfinite">find_finite() / find_nonfinite()</a></li>
|
||||
<li><a href="#omit_nan_nonfinite">omit_nonfinite()</a></li>
|
||||
<li><a href="#constants">constants (pi, nan, inf, ...)</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -6911,6 +6901,7 @@ See also:
|
||||
<li><a href="#replace">.replace()</a></li>
|
||||
<li><a href="#is_finite">.is_finite()</a>
|
||||
<li><a href="#find_nan_nonnan">find_nan() / find_nonnan()</a></li>
|
||||
<li><a href="#omit_nan_nonfinite">omit_nan()</a></li>
|
||||
<li><a href="#constants">constants (pi, nan, inf, ...)</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
@@ -7129,58 +7120,58 @@ A.brief_print("A:");
|
||||
<br>
|
||||
<br>
|
||||
<ul>
|
||||
<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>auto_detect</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>auto_detect</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Used only by <i>.load()</i> only: attempt to automatically detect the file type as one of the formats described below;
|
||||
<br>[ default operation for <i>.load()</i> ]<br><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>arma_binary</b><br></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>arma_binary</b><br></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Numerical data stored in machine dependent binary format, with a simple header to speed up loading.
|
||||
The header indicates the type and size of matrix/cube.
|
||||
<br>[ default operation for <i>.save()</i> ]
|
||||
<br>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>arma_ascii</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>arma_ascii</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Numerical data stored in human readable text format, with a simple header to speed up loading.
|
||||
The header indicates the type and size of matrix/cube.
|
||||
<br>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>raw_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>raw_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Numerical data stored in machine dependent raw binary format, without a header.
|
||||
Matrices are loaded to have one column,
|
||||
while cubes are loaded to have one slice with one column.
|
||||
The <a href="#reshape_member">.reshape()</a> function can be used to alter the size of the loaded matrix/cube without losing data.
|
||||
<br>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>raw_ascii</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>raw_ascii</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Numerical data stored in raw ASCII format, without a header.
|
||||
The numbers are separated by whitespace.
|
||||
The number of columns must be the same in each row.
|
||||
@@ -7189,26 +7180,26 @@ Data which was saved in Matlab/Octave using the <i>-ascii</i> option can be read
|
||||
Complex numbers are stored in standard C++ notation, which is a tuple surrounded by brackets: eg. (1.23,4.56) indicates 1.24 + 4.56i.
|
||||
<br>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>csv_ascii</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>csv_ascii</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Numerical data stored in comma separated value (CSV) text format, <b>without</b> a header.
|
||||
To save/load <b>with</b> a header, use the <b>csv_name(</b>filename,header<b>)</b> specification instead (more details below).
|
||||
Handles complex numbers stored in the compound form of 1.24+4.56i.
|
||||
Applicable to <i>Mat</i> and <i>SpMat</i>.
|
||||
<br>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>coord_ascii</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>coord_ascii</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Numerical data stored as a text file in coordinate list format, without a header.
|
||||
Only non-zero values are stored.
|
||||
<br>
|
||||
@@ -7219,39 +7210,39 @@ For real matrices, each line contains information in the following format:
|
||||
<br><b>Caveat:</b> not supported by <i>auto_detect</i>.
|
||||
<br>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>pgm_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>pgm_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Image data stored in Portable Gray Map (PGM) format.
|
||||
Applicable to <i>Mat</i> only.
|
||||
Saving <i>int</i>, <i>float</i> or <i>double</i> matrices is a lossy operation, as each element is copied and converted to an 8 bit representation.
|
||||
As such the matrix should have values in the [0,255] interval, otherwise the resulting image may not display correctly.
|
||||
<br>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>ppm_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>ppm_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Image data stored in Portable Pixel Map (PPM) format.
|
||||
Applicable to <i>Cube</i> only.
|
||||
Saving <i>int</i>, <i>float</i> or <i>double</i> matrices is a lossy operation, as each element is copied and converted to an 8 bit representation.
|
||||
As such the cube/field should have values in the [0,255] interval, otherwise the resulting image may not display correctly.
|
||||
<br>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>hdf5_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>hdf5_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
Numerical data stored in portable <a href="https://en.wikipedia.org/wiki/Hierarchical_Data_Format">HDF5</a> binary format.
|
||||
<ul>
|
||||
<li>
|
||||
@@ -7267,10 +7258,10 @@ for loading, the order of operations is:
|
||||
to explicitly control the dataset name, specify it via the <b>hdf5_name()</b> argument (more details below)
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
@@ -7387,6 +7378,7 @@ if(ok == false)
|
||||
<li><a href="https://en.wikipedia.org/wiki/Hierarchical_Data_Format">HDF</a> in Wikipedia</li>
|
||||
<li><a href="https://en.wikipedia.org/wiki/Comma-separated_values">CSV</a> in Wikipedia
|
||||
<li><a href="#save_load_field">saving / loading fields</a></li>
|
||||
<li><a href="#element_initialisation">element initialisation</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
@@ -7439,26 +7431,26 @@ Other than storing string fields as text files, the following file formats are s
|
||||
<br>
|
||||
<br>
|
||||
<ul>
|
||||
<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>auto_detect</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
<table style="text-align: left; width: 100%;" border="0" cellpadding="2" cellspacing="2">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>auto_detect</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
<br>
|
||||
<li>
|
||||
<i>.load()</i>: attempt to automatically detect the field format type as one of the formats described below;
|
||||
this is the default operation
|
||||
</li>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>arma_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>arma_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
<br>
|
||||
<li>
|
||||
objects are stored in machine dependent binary format
|
||||
@@ -7469,13 +7461,13 @@ default type for fields of type <i>Mat</i>, <i>Col</i>, <i>Row</i> or <i>Cube</i
|
||||
only applicable to fields of type <i>Mat</i>, <i>Col</i>, <i>Row</i> or <i>Cube</i>
|
||||
</li>
|
||||
<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>ppm_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="vertical-align: top;"><b>ppm_binary</b></td>
|
||||
<td style="vertical-align: top;"><br>
|
||||
</td>
|
||||
<td style="vertical-align: top;">
|
||||
<br>
|
||||
<li>
|
||||
image data stored in Portable Pixmap Map (PPM) format
|
||||
@@ -7494,11 +7486,10 @@ it is assumed that the red, green and blue components are stored in the first, s
|
||||
saving <i>int</i>, <i>float</i> or <i>double</i> matrices is a lossy operation,
|
||||
as each matrix element is copied and converted to an 8 bit representation
|
||||
</li>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
@@ -11092,6 +11083,9 @@ See also:
|
||||
<li><a href="#nonzeros">nonzeros()</a>
|
||||
<li><a href="#vectorise">vectorise()</a>
|
||||
<li><a href="#for_each">.for_each()</a>
|
||||
<li><a href="#is_finite">.is_finite()</a>
|
||||
<li><a href="#has_inf">.has_inf()</a>
|
||||
<li><a href="#has_nan">.has_nan()</a>
|
||||
</ul>
|
||||
</li>
|
||||
<br>
|
||||
@@ -18490,7 +18484,7 @@ See also:
|
||||
<b>RNG seed setting</b>
|
||||
<ul>
|
||||
<li>
|
||||
There are two functions to change the seed used by the random number generator (RNG):
|
||||
Functions to change the seed used by the random number generator (RNG):
|
||||
<br>
|
||||
<br>
|
||||
<table style="text-align: left;" border="0" cellpadding="2" cellspacing="2">
|
||||
@@ -18559,6 +18553,7 @@ See also:
|
||||
<li>
|
||||
<a href="#randu">randu()</a>,
|
||||
<a href="#randn">randn()</a>,
|
||||
<a href="#rande">rande()</a>,
|
||||
<a href="#randg">randg()</a>,
|
||||
<a href="#randi">randi()</a>,
|
||||
<a href="#sprandu_sprandn">sprandu()</a>,
|
||||
@@ -18780,7 +18775,7 @@ rudimentary <i>fp16</i> hardware support is present on x86-64 CPUs with the F16C
|
||||
<br>
|
||||
</ul>
|
||||
<li>
|
||||
If no compiler or hardware support is detected, support for <i>fp16</i> element types is <b>not</b> automatically enableds
|
||||
If no compiler or hardware support is detected, support for <i>fp16</i> element types is <b>not</b> automatically enabled
|
||||
</li>
|
||||
<br>
|
||||
<li>
|
||||
|
||||
@@ -26,6 +26,9 @@
|
||||
#undef ARMA_USE_THREAD_LOCAL
|
||||
#define ARMA_USE_THREAD_LOCAL
|
||||
|
||||
#undef ARMA_USE_THREAD_UNIQUE_RNG_SEED
|
||||
#define ARMA_USE_THREAD_UNIQUE_RNG_SEED
|
||||
|
||||
#if (defined(ARMA_RNG_ALT) || defined(ARMA_DONT_USE_CXX11_RNG))
|
||||
#undef ARMA_USE_CXX11_RNG
|
||||
#endif
|
||||
@@ -34,6 +37,10 @@
|
||||
#undef ARMA_USE_THREAD_LOCAL
|
||||
#endif
|
||||
|
||||
#if defined(ARMA_DONT_USE_THREAD_UNIQUE_RNG_SEED)
|
||||
#undef ARMA_USE_THREAD_UNIQUE_RNG_SEED
|
||||
#endif
|
||||
|
||||
|
||||
// NOTE: ARMA_WARMUP_PRODUCER enables a workaround
|
||||
// NOTE: for thread_local issue on macOS 11 and/or AppleClang 12.0
|
||||
@@ -129,24 +136,42 @@ arma_rng::get_producer()
|
||||
{
|
||||
#if defined(ARMA_USE_THREAD_LOCAL)
|
||||
|
||||
// use a thread-safe RNG, with each thread having its own unique starting seed
|
||||
// thread-safe RNG
|
||||
|
||||
static std::atomic<std::size_t> mt19937_64_producer_counter(0);
|
||||
|
||||
static thread_local std::mt19937_64 mt19937_64_producer( std::mt19937_64::default_seed + mt19937_64_producer_counter++ );
|
||||
|
||||
arma_rng::warmup_producer(mt19937_64_producer);
|
||||
#if defined(ARMA_USE_THREAD_UNIQUE_RNG_SEED)
|
||||
|
||||
// each thread has unique starting seed
|
||||
|
||||
#if defined(ARMA_USE_OPENMP)
|
||||
|
||||
static thread_local std::mt19937_64 mt19937_64_producer( std::mt19937_64::default_seed + arma_rng::seed_type(omp_get_thread_num()) );
|
||||
|
||||
#else
|
||||
|
||||
static std::atomic<std::size_t> mt19937_64_producer_counter(0);
|
||||
|
||||
static thread_local std::mt19937_64 mt19937_64_producer( std::mt19937_64::default_seed + mt19937_64_producer_counter++ );
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// each thread has the same starting seed
|
||||
|
||||
static thread_local std::mt19937_64 mt19937_64_producer( std::mt19937_64::default_seed );
|
||||
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
// use a plain RNG in case we don't have thread_local
|
||||
// plain RNG in case we don't have thread_local
|
||||
|
||||
static std::mt19937_64 mt19937_64_producer( std::mt19937_64::default_seed );
|
||||
|
||||
arma_rng::warmup_producer(mt19937_64_producer);
|
||||
|
||||
#endif
|
||||
|
||||
arma_rng::warmup_producer(mt19937_64_producer);
|
||||
|
||||
return mt19937_64_producer;
|
||||
}
|
||||
|
||||
@@ -226,9 +251,45 @@ arma_rng::set_seed(const arma_rng::seed_type val)
|
||||
}
|
||||
#elif defined(ARMA_USE_CXX11_RNG)
|
||||
{
|
||||
arma_rng::lock_producer();
|
||||
arma_rng::get_producer().seed(val);
|
||||
arma_rng::unlock_producer();
|
||||
#if defined(ARMA_USE_OPENMP) && defined(ARMA_USE_THREAD_LOCAL)
|
||||
{
|
||||
arma_rng::lock_producer();
|
||||
|
||||
#if defined(ARMA_USE_THREAD_UNIQUE_RNG_SEED)
|
||||
constexpr bool thread_unique_rng_seed = true;
|
||||
#else
|
||||
constexpr bool thread_unique_rng_seed = false;
|
||||
#endif
|
||||
|
||||
// if we're already in a parallel region, assume the user is setting the seed for each thread
|
||||
|
||||
if( (thread_unique_rng_seed == false) || bool(omp_in_parallel()) )
|
||||
{
|
||||
arma_rng::get_producer().seed(val);
|
||||
}
|
||||
else
|
||||
{
|
||||
const int n_threads = int( (std::max)( int(1), int(omp_get_max_threads()) ) );
|
||||
|
||||
#pragma omp parallel for ordered schedule(static) num_threads(n_threads)
|
||||
for(int t=0; t < n_threads; ++t)
|
||||
{
|
||||
#pragma omp ordered
|
||||
{
|
||||
arma_rng::get_producer().seed(val + arma_rng::seed_type(omp_get_thread_num()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
arma_rng::unlock_producer();
|
||||
}
|
||||
#else
|
||||
{
|
||||
arma_rng::lock_producer();
|
||||
arma_rng::get_producer().seed(val);
|
||||
arma_rng::unlock_producer();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
{
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
#define ARMA_VERSION_MAJOR 15
|
||||
#define ARMA_VERSION_MINOR 2
|
||||
#define ARMA_VERSION_PATCH 0
|
||||
#define ARMA_VERSION_PATCH 2
|
||||
#define ARMA_VERSION_NAME "Medium Roast Deluxe"
|
||||
|
||||
|
||||
|
||||
@@ -602,7 +602,30 @@ op_accu_mat::apply(const subview<eT>& X)
|
||||
const uword X_n_rows = X.n_rows;
|
||||
const uword X_n_cols = X.n_cols;
|
||||
|
||||
if(X_n_rows == 1) { return op_accu_mat::apply( static_cast< const subview_row<eT>& >(X) ); }
|
||||
if(X_n_rows == 1)
|
||||
{
|
||||
const uword X_m_n_rows = X.m.n_rows;
|
||||
|
||||
const eT* mem_ptr = X.colptr(0);
|
||||
|
||||
eT val1 = eT(0);
|
||||
eT val2 = eT(0);
|
||||
|
||||
uword j;
|
||||
|
||||
for(j=1; j < X_n_cols; j+=2)
|
||||
{
|
||||
val1 += (*mem_ptr); mem_ptr += X_m_n_rows;
|
||||
val2 += (*mem_ptr); mem_ptr += X_m_n_rows;
|
||||
}
|
||||
|
||||
if((j-1) < X_n_cols)
|
||||
{
|
||||
val1 += (*mem_ptr);
|
||||
}
|
||||
|
||||
return val1 + val2;
|
||||
}
|
||||
|
||||
if(X_n_cols == 1) { return arrayops::accumulate( X.colptr(0), X_n_rows ); }
|
||||
|
||||
@@ -640,7 +663,7 @@ op_accu_mat::apply(const subview_row<eT>& X)
|
||||
const uword X_m_n_rows = X.m.n_rows;
|
||||
const uword X_n_cols = X.n_cols;
|
||||
|
||||
const eT* row_mem = &(X.m.at(X.aux_row1,X.aux_col1));
|
||||
const eT* mem_ptr = X.rowmem;
|
||||
|
||||
eT val1 = eT(0);
|
||||
eT val2 = eT(0);
|
||||
@@ -649,13 +672,13 @@ op_accu_mat::apply(const subview_row<eT>& X)
|
||||
|
||||
for(j=1; j < X_n_cols; j+=2)
|
||||
{
|
||||
val1 += (*row_mem); row_mem += X_m_n_rows;
|
||||
val2 += (*row_mem); row_mem += X_m_n_rows;
|
||||
val1 += (*mem_ptr); mem_ptr += X_m_n_rows;
|
||||
val2 += (*mem_ptr); mem_ptr += X_m_n_rows;
|
||||
}
|
||||
|
||||
if((j-1) < X_n_cols)
|
||||
{
|
||||
val1 += (*row_mem);
|
||||
val1 += (*mem_ptr);
|
||||
}
|
||||
|
||||
return val1 + val2;
|
||||
|
||||
@@ -85,7 +85,7 @@ class subview : public Base< eT, subview<eT> >
|
||||
template<typename T1> inline void operator-= (const SpBase<eT,T1>& x);
|
||||
template<typename T1> inline void operator%= (const SpBase<eT,T1>& x);
|
||||
template<typename T1> inline void operator/= (const SpBase<eT,T1>& x);
|
||||
|
||||
|
||||
template<typename T1, typename gen_type>
|
||||
inline typename enable_if2< is_same_type<typename T1::elem_type, eT>::value, void>::result operator=(const Gen<T1,gen_type>& x);
|
||||
|
||||
@@ -396,6 +396,11 @@ class subview_col : public subview<eT>
|
||||
inline void zeros();
|
||||
inline void ones();
|
||||
|
||||
arma_warn_unused inline bool is_finite() const;
|
||||
|
||||
arma_warn_unused inline bool has_inf() const;
|
||||
arma_warn_unused inline bool has_nan() const;
|
||||
|
||||
arma_inline eT at_alt (const uword i) const;
|
||||
|
||||
arma_inline eT& operator[](const uword i);
|
||||
@@ -528,6 +533,8 @@ class subview_row : public subview<eT>
|
||||
static constexpr bool is_col = false;
|
||||
static constexpr bool is_xvec = false;
|
||||
|
||||
const eT* rowmem;
|
||||
|
||||
inline void operator= (const subview<eT>& x);
|
||||
inline void operator= (const subview_row& x);
|
||||
inline void operator= (const eT val);
|
||||
@@ -545,6 +552,15 @@ class subview_row : public subview<eT>
|
||||
|
||||
arma_warn_unused arma_inline const Op<subview_row<eT>,op_strans> as_col() const;
|
||||
|
||||
inline void fill(const eT val);
|
||||
inline void zeros();
|
||||
inline void ones();
|
||||
|
||||
arma_warn_unused inline bool is_finite() const;
|
||||
|
||||
arma_warn_unused inline bool has_inf() const;
|
||||
arma_warn_unused inline bool has_nan() const;
|
||||
|
||||
inline eT at_alt (const uword i) const;
|
||||
|
||||
inline eT& operator[](const uword i);
|
||||
|
||||
@@ -1079,16 +1079,9 @@ subview<eT>::fill(const eT val)
|
||||
|
||||
eT* Aptr = &(A.at(s.aux_row1,s.aux_col1));
|
||||
|
||||
uword jj;
|
||||
for(jj=1; jj < s_n_cols; jj+=2)
|
||||
for(uword ii=0; ii < s_n_cols; ++ii)
|
||||
{
|
||||
(*Aptr) = val; Aptr += A_n_rows;
|
||||
(*Aptr) = val; Aptr += A_n_rows;
|
||||
}
|
||||
|
||||
if((jj-1) < s_n_cols)
|
||||
{
|
||||
(*Aptr) = val;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -3380,7 +3373,7 @@ subview_col<eT>::operator=(const Base<eT,T1>& expr)
|
||||
|
||||
if(is_Mat<T1>::value)
|
||||
{
|
||||
const unwrap<T1> U(expr.get_ref());
|
||||
const unwrap<T1> U(expr.get_ref()); // deliberately not using quasi_unwrap
|
||||
|
||||
arma_conform_assert_same_size(subview<eT>::n_rows, uword(1), U.M.n_rows, U.M.n_cols, "copy into submatrix");
|
||||
|
||||
@@ -3498,6 +3491,48 @@ subview_col<eT>::ones()
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
subview_col<eT>::is_finite() const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
if(arma_config::fast_math_warn) { arma_warn(1, "is_finite(): detection of non-finite values is not reliable in fast math mode"); }
|
||||
|
||||
return arrayops::is_finite(colmem, subview<eT>::n_rows);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
subview_col<eT>::has_inf() const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
if(arma_config::fast_math_warn) { arma_warn(1, "has_inf(): detection of non-finite values is not reliable in fast math mode"); }
|
||||
|
||||
return arrayops::has_inf(colmem, subview<eT>::n_rows);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
subview_col<eT>::has_nan() const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
if(arma_config::fast_math_warn) { arma_warn(1, "has_nan(): detection of non-finite values is not reliable in fast math mode"); }
|
||||
|
||||
return arrayops::has_nan(colmem, subview<eT>::n_rows);
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
arma_inline
|
||||
eT
|
||||
@@ -4233,6 +4268,7 @@ template<typename eT>
|
||||
inline
|
||||
subview_row<eT>::subview_row(const Mat<eT>& in_m, const uword in_row)
|
||||
: subview<eT>(in_m, in_row, 0, 1, in_m.n_cols)
|
||||
, rowmem(subview<eT>::colptr(0))
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
}
|
||||
@@ -4243,6 +4279,7 @@ template<typename eT>
|
||||
inline
|
||||
subview_row<eT>::subview_row(const Mat<eT>& in_m, const uword in_row, const uword in_col1, const uword in_n_cols)
|
||||
: subview<eT>(in_m, in_row, in_col1, 1, in_n_cols)
|
||||
, rowmem(subview<eT>::colptr(0))
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
}
|
||||
@@ -4253,6 +4290,7 @@ template<typename eT>
|
||||
inline
|
||||
subview_row<eT>::subview_row(const subview_row<eT>& in)
|
||||
: subview<eT>(in) // interprets 'subview_row' as 'subview'
|
||||
, rowmem(in.rowmem)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
}
|
||||
@@ -4263,8 +4301,11 @@ template<typename eT>
|
||||
inline
|
||||
subview_row<eT>::subview_row(subview_row<eT>&& in)
|
||||
: subview<eT>(std::move(in)) // interprets 'subview_row' as 'subview'
|
||||
, rowmem(in.rowmem)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
access::rw(in.rowmem) = nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -4300,7 +4341,12 @@ subview_row<eT>::operator=(const eT val)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
subview<eT>::operator=(val); // interprets 'subview_row' as 'subview'
|
||||
if(subview<eT>::n_elem != 1)
|
||||
{
|
||||
arma_conform_assert_same_size(subview<eT>::n_rows, subview<eT>::n_cols, 1, 1, "copy into submatrix");
|
||||
}
|
||||
|
||||
access::rw( rowmem[0] ) = val;
|
||||
}
|
||||
|
||||
|
||||
@@ -4335,7 +4381,39 @@ subview_row<eT>::operator=(const Base<eT,T1>& X)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
subview<eT>::operator=(X);
|
||||
if(is_Mat<T1>::value)
|
||||
{
|
||||
const unwrap<T1> U(X.get_ref()); // deliberately not using quasi_unwrap
|
||||
|
||||
arma_conform_assert_same_size(uword(1), subview<eT>::n_cols, U.M.n_rows, U.M.n_cols, "copy into submatrix");
|
||||
|
||||
const eT* UM_mem = U.M.memptr();
|
||||
|
||||
eT* mem_ptr = access::rwp(rowmem);
|
||||
|
||||
const uword local_s_n_cols = subview<eT>::n_cols;
|
||||
const uword local_m_n_rows = subview<eT>::m.n_rows;
|
||||
|
||||
uword j;
|
||||
|
||||
for(j=1; j < local_s_n_cols; j+=2)
|
||||
{
|
||||
const eT val_i = (*UM_mem); UM_mem++;
|
||||
const eT val_j = (*UM_mem); UM_mem++;
|
||||
|
||||
(*mem_ptr) = val_i; mem_ptr += local_m_n_rows;
|
||||
(*mem_ptr) = val_j; mem_ptr += local_m_n_rows;
|
||||
}
|
||||
|
||||
if((j-1) < local_s_n_cols)
|
||||
{
|
||||
(*mem_ptr) = (*UM_mem);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
subview<eT>::operator=(X);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4408,14 +4486,134 @@ subview_row<eT>::as_col() const
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
subview_row<eT>::fill(const eT val)
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
eT* mem_ptr = access::rwp(rowmem);
|
||||
|
||||
const uword local_s_n_cols = subview<eT>::n_cols;
|
||||
const uword local_m_n_rows = subview<eT>::m.n_rows;
|
||||
|
||||
for(uword ii=0; ii < local_s_n_cols; ++ii)
|
||||
{
|
||||
(*mem_ptr) = val; mem_ptr += local_m_n_rows;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
subview_row<eT>::zeros()
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
(*this).fill(eT(0));
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
void
|
||||
subview_row<eT>::ones()
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
(*this).fill(eT(1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
subview_row<eT>::is_finite() const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
if(arma_config::fast_math_warn) { arma_warn(1, "is_finite(): detection of non-finite values is not reliable in fast math mode"); }
|
||||
|
||||
const eT* mem_ptr = rowmem;
|
||||
|
||||
const uword local_s_n_cols = subview<eT>::n_cols;
|
||||
const uword local_m_n_rows = subview<eT>::m.n_rows;
|
||||
|
||||
for(uword ii=0; ii < local_s_n_cols; ++ii)
|
||||
{
|
||||
const eT val = (*mem_ptr); mem_ptr += local_m_n_rows;
|
||||
|
||||
if(arma_isnonfinite(val)) { return false; }
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
subview_row<eT>::has_inf() const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
if(arma_config::fast_math_warn) { arma_warn(1, "has_inf(): detection of non-finite values is not reliable in fast math mode"); }
|
||||
|
||||
const eT* mem_ptr = rowmem;
|
||||
|
||||
const uword local_s_n_cols = subview<eT>::n_cols;
|
||||
const uword local_m_n_rows = subview<eT>::m.n_rows;
|
||||
|
||||
for(uword ii=0; ii < local_s_n_cols; ++ii)
|
||||
{
|
||||
const eT val = (*mem_ptr); mem_ptr += local_m_n_rows;
|
||||
|
||||
if(arma_isinf(val)) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
bool
|
||||
subview_row<eT>::has_nan() const
|
||||
{
|
||||
arma_debug_sigprint();
|
||||
|
||||
if(arma_config::fast_math_warn) { arma_warn(1, "has_nan(): detection of non-finite values is not reliable in fast math mode"); }
|
||||
|
||||
const eT* mem_ptr = rowmem;
|
||||
|
||||
const uword local_s_n_cols = subview<eT>::n_cols;
|
||||
const uword local_m_n_rows = subview<eT>::m.n_rows;
|
||||
|
||||
for(uword ii=0; ii < local_s_n_cols; ++ii)
|
||||
{
|
||||
const eT val = (*mem_ptr); mem_ptr += local_m_n_rows;
|
||||
|
||||
if(arma_isnan(val)) { return true; }
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<typename eT>
|
||||
inline
|
||||
eT
|
||||
subview_row<eT>::at_alt(const uword ii) const
|
||||
{
|
||||
const uword index = (ii + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
|
||||
|
||||
return subview<eT>::m.mem[index];
|
||||
return rowmem[ii * subview<eT>::m.n_rows];
|
||||
}
|
||||
|
||||
|
||||
@@ -4425,9 +4623,7 @@ inline
|
||||
eT&
|
||||
subview_row<eT>::operator[](const uword ii)
|
||||
{
|
||||
const uword index = (ii + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
|
||||
|
||||
return access::rw( (const_cast< Mat<eT>& >(subview<eT>::m)).mem[index] );
|
||||
return access::rw( rowmem[ii * subview<eT>::m.n_rows] );
|
||||
}
|
||||
|
||||
|
||||
@@ -4437,9 +4633,7 @@ inline
|
||||
eT
|
||||
subview_row<eT>::operator[](const uword ii) const
|
||||
{
|
||||
const uword index = (ii + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
|
||||
|
||||
return subview<eT>::m.mem[index];
|
||||
return rowmem[ii * subview<eT>::m.n_rows];
|
||||
}
|
||||
|
||||
|
||||
@@ -4450,10 +4644,8 @@ eT&
|
||||
subview_row<eT>::operator()(const uword ii)
|
||||
{
|
||||
arma_conform_check_bounds( (ii >= subview<eT>::n_elem), "subview::operator(): index out of bounds" );
|
||||
|
||||
const uword index = (ii + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
|
||||
|
||||
return access::rw( (const_cast< Mat<eT>& >(subview<eT>::m)).mem[index] );
|
||||
return access::rw( rowmem[ii * subview<eT>::m.n_rows] );
|
||||
}
|
||||
|
||||
|
||||
@@ -4465,9 +4657,7 @@ subview_row<eT>::operator()(const uword ii) const
|
||||
{
|
||||
arma_conform_check_bounds( (ii >= subview<eT>::n_elem), "subview::operator(): index out of bounds" );
|
||||
|
||||
const uword index = (ii + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
|
||||
|
||||
return subview<eT>::m.mem[index];
|
||||
return rowmem[ii * subview<eT>::m.n_rows];
|
||||
}
|
||||
|
||||
|
||||
@@ -4479,9 +4669,7 @@ subview_row<eT>::operator()(const uword in_row, const uword in_col)
|
||||
{
|
||||
arma_conform_check_bounds( ((in_row > 0) || (in_col >= subview<eT>::n_cols)), "subview::operator(): index out of bounds" );
|
||||
|
||||
const uword index = (in_col + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
|
||||
|
||||
return access::rw( (const_cast< Mat<eT>& >(subview<eT>::m)).mem[index] );
|
||||
return access::rw( rowmem[in_col * subview<eT>::m.n_rows] );
|
||||
}
|
||||
|
||||
|
||||
@@ -4493,9 +4681,7 @@ subview_row<eT>::operator()(const uword in_row, const uword in_col) const
|
||||
{
|
||||
arma_conform_check_bounds( ((in_row > 0) || (in_col >= subview<eT>::n_cols)), "subview::operator(): index out of bounds" );
|
||||
|
||||
const uword index = (in_col + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
|
||||
|
||||
return subview<eT>::m.mem[index];
|
||||
return rowmem[in_col * subview<eT>::m.n_rows];
|
||||
}
|
||||
|
||||
|
||||
@@ -4505,9 +4691,7 @@ inline
|
||||
eT&
|
||||
subview_row<eT>::at(const uword, const uword in_col)
|
||||
{
|
||||
const uword index = (in_col + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
|
||||
|
||||
return access::rw( (const_cast< Mat<eT>& >(subview<eT>::m)).mem[index] );
|
||||
return access::rw( rowmem[in_col * subview<eT>::m.n_rows] );
|
||||
}
|
||||
|
||||
|
||||
@@ -4517,9 +4701,7 @@ inline
|
||||
eT
|
||||
subview_row<eT>::at(const uword, const uword in_col) const
|
||||
{
|
||||
const uword index = (in_col + (subview<eT>::aux_col1))*(subview<eT>::m).n_rows + (subview<eT>::aux_row1);
|
||||
|
||||
return subview<eT>::m.mem[index];
|
||||
return rowmem[in_col * subview<eT>::m.n_rows];
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user