Compare commits

...
176 Commits
Author SHA1 Message Date
conrad bc2e8d5fcc patch bump 2026-07-23 23:23:18 +10:00
conrad c8b3ac8df1 fix speed regression for diagmat(glue_times) 2026-07-21 14:58:50 +10:00
conrad fef5c5954d fix speed regression for diagvec(glue_times) 2026-07-21 14:24:50 +10:00
conrad 9ce600b03b patch bump 2026-07-09 14:34:39 +10:00
conrad 37744f9a3c fix: unwrap the given object 2026-07-09 13:56:55 +10:00
conrad 1954f4a1d8 minor cleanup 2026-07-08 11:31:26 +10:00
conrad 9d731a6565 workaround for false positive warnings in GCC 15 2026-07-06 12:52:44 +10:00
conrad c7ffb88d54 more efficient handling of aliasing 2026-07-02 22:34:59 +10:00
conrad fe2930b966 fix: unwrap the given object 2026-07-02 21:23:15 +10:00
conrad 25aca17550 remove redundant code 2026-07-01 15:04:22 +10:00
conrad 23f652e542 simplification + speedup 2026-07-01 14:45:17 +10:00
conrad c6f4af01d8 more efficient handling of aliasing 2026-06-29 23:12:20 +10:00
conrad 1441e9f1a0 fix for handling .is_alias() 2026-06-29 23:07:24 +10:00
conrad f41149d528 more efficient handling of aliasing 2026-06-29 12:51:40 +10:00
conrad 3d7fd53b53 fill only non-integer matrices with NaN 2026-06-26 12:27:57 +10:00
conrad 340a1b3592 expand Mat::fixed with .row() and .col() specialisations 2026-06-25 12:04:18 +10:00
conrad 07414596d4 version bump 2026-06-18 13:21:37 +10:00
conrad 585b369988 fix layout 2026-06-18 12:56:19 +10:00
conrad a957b25a29 explicitly ignore unused value 2026-06-17 12:18:45 +10:00
conrad 61bb3e0ae8 change fill::pos_inf to shorter fill::inf 2026-06-17 11:36:30 +10:00
conrad d5f00fd4a8 mark as RC1 2026-06-16 14:42:41 +10:00
conrad 4dc011f5d3 keep requested mem_state even if n_elem is zero 2026-06-16 14:12:08 +10:00
conrad 922ccf9154 rearrange 2026-06-16 13:24:10 +10:00
conrad ba33c24e8a simpler conversion of std::vector 2026-06-16 13:19:00 +10:00
conrad fea46c6f84 more robust handling of aux_mem 2026-06-16 13:02:05 +10:00
conrad 033c93196c more robust handling of aux_mem 2026-06-16 12:33:54 +10:00
conrad 453bef9283 update list of changes 2026-06-15 15:37:28 +10:00
conrad 598df0100e minor cleanup 2026-06-15 15:35:38 +10:00
conrad 45347ce825 avoid copying when element types are the same 2026-06-15 15:12:11 +10:00
conrad 3318e018d0 faster initial vector growth 2026-06-15 12:07:45 +10:00
conrad 8d350a1534 remove unused code 2026-06-15 11:52:45 +10:00
conrad 11b885085a update list of changes 2026-06-13 00:56:07 +10:00
conrad 724dc98eb8 speedp for contiguous subcubes 2026-06-13 00:51:39 +10:00
conrad 452a6c1b49 use partially unrolled loops 2026-06-13 00:29:21 +10:00
conrad 5c2892a2b5 add specialised handling of find() within .elem() 2026-06-13 00:26:17 +10:00
conrad 88003f8ab8 obtain memory pointers earlier 2026-06-13 00:20:14 +10:00
conrad 248ce5fe7f use same variable name for definition and implementation 2026-06-13 00:14:14 +10:00
conrad e493eb3b34 simplify bounds checks 2026-06-13 00:11:16 +10:00
conrad 03411c40a6 add stored_type typedef to quasi_unwrap<> 2026-06-13 00:06:27 +10:00
conrad 3c6c443be6 more precise alias check 2026-06-12 23:54:07 +10:00
conrad a638683e6f remove unnecessary alignment attribute 2026-06-12 22:02:22 +10:00
conrad e299f5e189 simplify by reusing extract_noalias() 2026-06-12 21:59:36 +10:00
conrad 053de98101 rename unwrap objects 2026-06-12 21:56:57 +10:00
conrad 6b1ce2116b remove rarely used specialisations 2026-06-12 21:48:17 +10:00
conrad b7afc7e5fb add has_subview trait 2026-06-12 20:25:01 +10:00
conrad 1e61d46e5b rename op_find to op_find_generic; rename op_find_simple to op_find_default 2026-06-12 20:13:50 +10:00
conrad 139d9f4d62 user better name and constexpr variable to indicate half threshold 2026-06-12 20:09:12 +10:00
conrad f123904e82 add docs for .push_back() 2026-06-12 20:04:24 +10:00
conrad 6e224f38bd add .push_back() 2026-06-12 20:02:11 +10:00
conrad c088151876 remove unnecessary forced inlines 2026-06-12 19:52:15 +10:00
conrad a839bc49d3 expand deprecation notices 2026-06-12 19:45:34 +10:00
conrad c13b71fc69 rename unwrap<> to plain_unwrap<> for consistency with bandicoot 2026-06-12 19:08:54 +10:00
conrad 69fc9f29a0 mark as experimental 2026-06-12 16:17:33 +10:00
conrad 730594f6da mark as experimental 2026-06-12 16:17:20 +10:00
conrad 80087a3a55 patch bump 2026-05-28 15:12:21 +10:00
conrad d0b07c02a3 skip alias checks when extracting subfield into a fresh field 2026-05-26 22:58:36 +10:00
conrad 1716a6b531 more efficient alias checks 2026-05-26 15:08:10 +10:00
conrad a86cfc932b don't strip const 2026-05-26 12:37:27 +10:00
conrad 8ce3f3aa7d skip alias checks when extracting subview_elem2 into a fresh matrix 2026-05-25 12:49:06 +10:00
conrad 89158f7777 skip alias checks when extracting subview_elem1 into a fresh matrix 2026-05-25 12:29:45 +10:00
conrad cedbd0eb89 simplifications 2026-04-27 10:46:05 +10:00
conrad fd38c47657 better wording 2026-04-27 10:40:02 +10:00
conrad bb5c4469b3 minor fix in error message 2026-04-21 13:50:08 +10:00
conrad 36b0cd37ec patch bump 2026-04-20 00:15:11 +10:00
conrad 59fbefc095 simplifications 2026-04-19 22:59:46 +10:00
conrad b1f3a185bf distinguish between default and user supplied tolerance 2026-04-18 23:48:32 +10:00
conrad adcbf1380a ensure intermediate results are not NaN 2026-04-18 17:45:48 +10:00
conrad 733533f089 ensure intermediate results are not NaN 2026-04-18 17:09:20 +10:00
conrad ae6f216a82 ensure suppled tolerances are not NaN 2026-04-18 17:08:51 +10:00
conrad 417bb37042 ensure default tolerances are not NaN 2026-04-18 16:45:02 +10:00
conrad 95cad27904 ensure default tolerance is finite 2026-04-18 14:13:49 +10:00
conrad 3e66e7b1f0 cleanup 2026-04-16 21:39:49 +10:00
conrad 4a6cc3e9a8 patch bump 2026-04-16 15:14:57 +10:00
conrad 0260b7f1dc fix warning message 2026-04-16 15:09:11 +10:00
conrad 6b180e1943 cleanup 2026-04-16 15:07:09 +10:00
conrad afec1a5f5a use the Proxy only when necessary 2026-04-15 14:10:24 +10:00
conrad 7ab5657470 faster handling of compound vector expressions 2026-04-15 13:42:44 +10:00
conrad fa63e6d717 distinguish between default and user supplied tolerance 2026-04-07 11:33:04 +10:00
conrad bf69c85cb8 show rcond earlier to avoid potential confusion 2026-04-07 10:56:08 +10:00
conrad 5e888a2fc7 simplifications 2026-04-06 21:14:45 +10:00
conrad f0db911a5c handle NaNs when checking ranges 2026-04-06 20:36:34 +10:00
conrad efff7a8f3f simplify warning messages 2026-04-06 19:48:48 +10:00
conrad 7f5569ffba handle NaNs when checking ranges 2026-04-06 19:35:29 +10:00
conrad 7c9ef72802 handle NaNs when checking tolerances 2026-04-05 23:06:49 +10:00
conrad c75af66d72 ensure consistency with subview_row::randu() and subview_row::randn() 2026-04-05 19:40:55 +10:00
conrad ce769c625f handle NaNs when checking tolerances 2026-04-05 02:30:59 +10:00
conrad f1e65e55de handle NaNs when checking conformance 2026-04-05 02:22:30 +10:00
conrad 7e4a956dbd specialisations for randu() and randn() 2026-04-04 19:47:20 +10:00
conrad 43b071020a handle NaNs when checking tolerances 2026-04-02 13:49:58 +10:00
conrad f548057ee7 simplifications 2026-04-02 13:44:30 +10:00
conrad e260407a3e handle NaNs when checking tolerances 2026-04-02 13:09:39 +10:00
conrad f049b04688 simplification: implicit handling of NaNs 2026-04-02 12:33:44 +10:00
conrad 8af4d74bd4 rearrange for consistency with other code 2026-04-01 16:33:36 +10:00
conrad a039d60a47 simplification 2026-03-31 12:42:59 +10:00
conrad a4634e8888 use correct element type 2026-03-31 12:36:05 +10:00
conrad df1eec4fb9 add note on how to enable support for std::int8_t and std::uint8_t 2026-03-30 00:26:09 +10:00
conrad 4524c7580f rearrange ::is_zero() to follow same pattern as arrayops::is_zero() 2026-03-30 00:24:49 +10:00
conrad 536a642b64 add compatibility note 2026-03-28 16:23:34 +10:00
conrad 80e1faa764 shorten temporary suffix and increase its randomness 2026-03-27 11:25:59 +10:00
conrad 4e8e1564e0 simplifications 2026-03-24 12:36:32 +10:00
conrad cd0a21d242 specialisations for .replace() 2026-03-24 12:27:35 +10:00
conrad e43f4f7ef9 fix corner case in is_zero(): explicitly handle nan 2026-03-23 15:23:14 +10:00
conrad f2691c6beb fix corner case in is_zero(): explicitly handle nan 2026-03-23 15:12:22 +10:00
conrad 825dbf7e60 fix corner case in is_zero(): explicitly handle nan 2026-03-23 12:42:46 +10:00
conrad ed078509da fixes for corner cases 2026-03-23 12:17:44 +10:00
conrad 759a36d0b3 fix + specialisations for .is_zero() 2026-03-23 11:59:52 +10:00
conrad e0d2196ae5 faster scalar operations on diagview 2026-03-21 20:06:48 +10:00
conrad 998c7814bc use proper function names in error messages 2026-03-21 11:39:52 +10:00
conrad ebd9209b31 simplify warning messages 2026-03-20 15:34:13 +10:00
conrad 745b02d4d7 simplifications 2026-03-20 14:49:29 +10:00
conrad b28fd1456c update list of changes 2026-03-20 12:54:13 +10:00
conrad 44a7a9cfed add note on arma prefix for span() 2026-03-20 12:38:38 +10:00
conrad ee9e26902f increase randomness of temporary filenames 2026-03-19 14:35:44 +10:00
conrad c14a60deec update year 2026-03-18 11:50:47 +10:00
conrad 33e382b623 simplifications 2026-03-17 12:07:46 +10:00
conrad 7334664999 patch bump 2026-03-15 18:42:19 +10:00
conrad f021766215 speedups for blank sparse submatrices 2026-03-15 17:33:41 +10:00
conrad 5491a20833 simplifications 2026-03-13 12:16:51 +10:00
conrad 1cab3be4df simplifications 2026-03-13 11:52:44 +10:00
conrad 08e1cb5211 specialisation for subview::zeros() 2026-03-13 11:33:39 +10:00
conrad 70c45a2f17 workarounds for ASAN false positives 2026-03-12 18:21:38 +10:00
conrad 2dfed59b94 simplifications 2026-03-12 15:57:37 +10:00
conrad 8bf7834041 simplifications 2026-03-12 15:48:04 +10:00
conrad 1461d33045 simplifications 2026-03-12 15:32:54 +10:00
conrad e05bc82e7b speedups for empty subcubes 2026-03-12 15:30:34 +10:00
conrad 9201e8ddd0 speedups for empty cubes 2026-03-12 15:23:18 +10:00
conrad 30dd62780b speedups for empty cubes 2026-03-12 12:21:15 +10:00
conrad 5dd6c665a5 speedups for empty cubes 2026-03-12 11:55:26 +10:00
conrad 2e6b4ed0a3 speedups for empty cubes 2026-03-11 17:09:31 +10:00
conrad 08c0647e54 speedups for empty matrices 2026-03-11 16:55:26 +10:00
conrad ff7f5d63e6 speedups for empty matrices 2026-03-11 15:12:59 +10:00
conrad 2288ec1497 remove superfluous comments 2026-03-11 15:12:32 +10:00
conrad 1df5fc83b7 speedups for blank sparse matrices 2026-03-10 15:58:00 +10:00
conrad 81df0a1f93 simplifications 2026-03-10 15:51:02 +10:00
conrad bceaf09865 speedups for blank sparse submatrices 2026-03-10 13:14:08 +10:00
conrad 3992546579 speedups for blank sparse submatrices 2026-03-10 12:31:16 +10:00
conrad 602f6217e0 speedups for blank sparse submatrices 2026-03-10 12:01:54 +10:00
conrad 449e6f682f speedups for blank sparse matrices 2026-03-10 11:51:20 +10:00
conrad 03df540096 fix error message 2026-03-09 13:29:19 +10:00
conrad b21700fc85 check if sizes are the same 2026-03-09 13:25:32 +10:00
conrad 02438fff53 speedups for blank sparse submatrices 2026-03-09 13:17:36 +10:00
conrad 451d5d2cec speedups for empty submatrices 2026-03-05 15:50:01 +10:00
conrad 534f135ef5 speedups for empty submatrices 2026-03-04 15:32:54 +10:00
conrad 8bd0d6692a speedups for empty subcubes 2026-03-04 15:24:34 +10:00
conrad ad1bed2686 speedups for empty submatrices 2026-02-28 14:11:47 +10:00
conrad 36e3d67a28 speedups for empty submatrices 2026-02-27 13:35:17 +10:00
conrad e3db651df7 speedup for empty submatrices 2026-02-27 13:07:40 +10:00
conrad fa52e3f5ef speedup for empty subcubes 2026-02-25 13:11:14 +10:00
conrad e6b06b21da speedup for empty matrices 2026-02-23 17:04:55 +10:00
conrad 252708e389 get pointer to first element via dedicated function 2026-02-20 13:17:43 +10:00
conrad 4b468f5009 simplifications 2026-02-20 10:47:28 +10:00
conrad 1244651dda simpler wording 2026-02-11 17:26:57 +10:00
conrad e4b96542b3 improve docs for .col_as_mat() and .row_as_mat() 2026-02-10 12:22:25 +10:00
conrad 5701dd07a8 avoid potentially confusing debug message 2026-02-05 15:21:14 +10:00
conrad bdc89797cd improved wording 2026-02-03 12:15:10 +10:00
conrad 2110b7d82c improved wording and layout 2026-02-03 11:53:05 +10:00
conrad 3bcfde3238 avoid repetition 2026-02-02 16:51:23 +10:00
conrad 3495f87581 better wording 2026-02-02 16:49:09 +10:00
conrad 8a24c0d724 expand fill types 2026-02-02 13:33:39 +10:00
conrad ec75a6107c expand docs for .fill() with notes on element initialisation during construction 2026-01-30 13:29:45 +10:00
conrad 450e1ba8a5 use explicit initialisation 2026-01-29 13:39:36 +10:00
conrad a0dcf97054 use explicit initialisation 2026-01-28 17:11:43 +10:00
conrad cd96c0d9e2 update paper 2026-01-02 12:25:10 +10:00
conrad 5e4ce67bf4 patch bump 2025-12-16 13:25:46 +10:00
conrad 7dbe9fa6c3 add LLM prohibition section 2025-12-16 13:03:19 +10:00
conrad 7da30298dd add RSL section to head 2025-12-15 14:19:05 +10:00
conrad f347a5640e simplification 2025-12-11 19:07:05 +10:00
conrad c7433b6e60 allow memory reuse with size growth 2025-12-11 16:22:29 +10:00
conrad e712b832e8 simplification 2025-12-11 15:14:55 +10:00
conrad 8a736f85a3 reuse memory where possible 2025-12-11 15:09:16 +10:00
conrad 9f8bf056c2 simplification 2025-12-11 14:20:05 +10:00
conrad b79a7e005c use explicit initialisation 2025-12-10 18:57:17 +10:00
conrad cae3a6a4bf optimise .resize() for small vectors that fit within pre-allocated memory 2025-12-10 15:12:17 +10:00
conrad fb6278f692 return early if resized matrix is empty 2025-12-10 15:11:10 +10:00
conrad 8622e81b8a faster repcube() 2025-12-10 12:31:03 +10:00
conrad f788d4032f emit more info on linker config 2025-12-10 12:28:19 +10:00
150 changed files with 4230 additions and 2209 deletions
+4 -2
View File
@@ -381,10 +381,11 @@ else()
set(ARMA_LIBS ${ARMA_LIBS} ${MKL_LIBRARIES})
message(STATUS "")
message(STATUS "*** If the MKL libraries are installed in non-standard locations such as")
message(STATUS "*** If the MKL libraries are installed in a non-standard location such as")
message(STATUS "*** /opt/intel/mkl, /opt/intel/composerxe/, /usr/local/intel/mkl")
message(STATUS "*** make sure the run-time linker can find them.")
message(STATUS "*** On Linux systems this can be done by editing /etc/ld.so.conf")
message(STATUS "*** or specifying the location through a file in /etc/ld.so.conf.d/")
message(STATUS "*** or modifying the LD_LIBRARY_PATH environment variable.")
message(STATUS "")
message(STATUS "*** On systems with SELinux enabled (eg. Fedora, RHEL),")
@@ -419,10 +420,11 @@ else()
endif()
message(STATUS "")
message(STATUS "*** If the OpenBLAS library is installed in")
message(STATUS "*** If the OpenBLAS library is installed in a location such as")
message(STATUS "*** /usr/local/lib or /usr/local/lib64")
message(STATUS "*** make sure the run-time linker can find it.")
message(STATUS "*** On Linux systems this can be done by editing /etc/ld.so.conf")
message(STATUS "*** or specifying the location through a file in /etc/ld.so.conf.d/")
message(STATUS "*** or modifying the LD_LIBRARY_PATH environment variable.")
message(STATUS "")
+2 -2
View File
@@ -1,7 +1,7 @@
Armadillo C++ Linear Algebra Library
Copyright 2008-2025 Conrad Sanderson (https://conradsanderson.id.au)
Copyright 2008-2026 Conrad Sanderson (https://conradsanderson.id.au)
Copyright 2008-2016 National ICT Australia (NICTA)
Copyright 2017-2025 Data61 / CSIRO
Copyright 2017-2026 Data61 / CSIRO
This product includes software developed by Conrad Sanderson (https://conradsanderson.id.au)
This product includes software developed at National ICT Australia (NICTA)
+16 -6
View File
@@ -1,9 +1,9 @@
### Armadillo: C++ Library for Linear Algebra & Scientific Computing
https://arma.sourceforge.net
Copyright 2008-2025 Conrad Sanderson (https://conradsanderson.id.au)
Copyright 2008-2026 Conrad Sanderson (https://conradsanderson.id.au)
Copyright 2008-2016 National ICT Australia (NICTA)
Copyright 2017-2025 Data61 / CSIRO
Copyright 2017-2026 Data61 / CSIRO
---
@@ -38,7 +38,8 @@ Copyright 2017-2025 Data61 / CSIRO
13. [API Stability and Version Policy](#13-api-stability-and-version-policy)
14. [Bug Reports and Frequently Asked Questions](#14-bug-reports-and-frequently-asked-questions)
15. [Related Software Using Armadillo](#15-related-software-using-armadillo)
15. [Prohibition on Use of Large Language Models (LLMs)](#15-prohibition-on-use-of-large-language-models-llms)
16. [Related Software Using Armadillo](#16-related-software-using-armadillo)
---
@@ -390,8 +391,8 @@ Use a web browser to view it.
Use of the C++11 `auto` keyword is not recommended with Armadillo objects and expressions.
Armadillo has a template meta-programming framework which creates short-lived temporaries
that are not properly handled by `auto`.
Armadillo has a template meta-programming framework which creates short-lived
temporary objects that are not properly handled by `auto`.
---
@@ -451,7 +452,16 @@ https://arma.sourceforge.net/faq.html
---
### 15: Related Software Using Armadillo
### 15: Prohibition on Use of Large Language Models (LLMs)
The Armadillo codebase has been developed entirely without the use of LLMs.
We do not accept any code which has been created (directly or indirectly)
with the aid of LLMs. This is due to issues with code provenance and low quality
of LLM generated code.
---
### 16: Related Software Using Armadillo
* MLPACK: extensive library of machine learning algorithms
https://mlpack.org
Binary file not shown.
+153 -177
View File
@@ -21,6 +21,15 @@ limitations under the License.
<meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
<title>Armadillo: API Documentation</title>
<link rel="icon" type="image/png" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAAlwSFlzAAALEwAACxMBAJqcGAAAARpJREFUOMtjYMABzFuiGYE4BohPA/FvIP6Phv8CMTcuzVxAvAGqeTYQT0HCd6AG3MSlmRWIdwNxLhY5MyC+ADVgLS4DyqAK2NDEBaAuiobKt+Ay4CZUgQRaeKwCYj8gTofKR+My4CNUQSSSWCYQT4ay+6HyprgMOADEs4BYFso3AOITQMwB5W+HGsCPMxCR2LxAfA6INZHE7gHxGwZCAOrvFUDcCsQqUKwFxP+A+CQxBpRgSTwwvIKQZm8gfgbEVkCsgYRToQZ049NsBtVshEUuA2pAAYpfoTQzEEcB8QsgtsdheA/UgFhkwV1AfBuIPwDxOyC2xeO6jVAD5kBd6gQS/AbEX4F4JRDLEwgbUHp4CsRboLETzkApAADMF8+Pl3d18QAAAABJRU5ErkJggg==">
<script type="application/rsl+xml">
<rsl xmlns="https://rslstandard.org/rsl">
<content url="">
<license>
<prohibits type="usage">ai-train ai-input</prohibits>
</license>
</content>
</rsl>
</script>
<style type="text/css">
<!--
body
@@ -150,7 +159,7 @@ hr.greyline
<a class="noprint" style="display:scroll; position:fixed; bottom:5px; right:5px;" href="#top"><font size=-1>[top]</font></a>
<a name="top"></a>
<big><b>API Documentation for Armadillo 15.2</b></big>
<big><b>API Documentation for Armadillo 15.4</b></big>
<br>
<br>
<br>
@@ -245,8 +254,9 @@ Conrad Sanderson and Ryan Curtin.
<tr><td><a href="#Col">Col&lt;<i>type</i>&gt;, colvec, vec</a></td><td>&nbsp;</td><td>dense column vector class</td></tr>
<tr><td><a href="#Row">Row&lt;<i>type</i>&gt;, rowvec</a></td><td>&nbsp;</td><td>dense row vector class</td></tr>
<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
<tr><td><a href="#Cube">Cube&lt;<i>type</i>&gt;, cube, cx_cube</a></td><td>&nbsp;</td><td>dense cube class ("3D matrix")</td></tr>
<tr><td><a href="#Cube">Cube&lt;<i>type</i>&gt;, cube, cx_cube</a></td><td>&nbsp;</td><td>dense cube class (quasi third-order tensor, aka "3D matrix")</td></tr>
<tr><td><a href="#field">field&lt;<i>object&nbsp;type</i>&gt;</a></td><td>&nbsp;</td><td>class for storing arbitrary objects in matrix-like or cube-like layouts</td></tr>
<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
<tr><td><a href="#SpMat">SpMat&lt;<i>type</i>&gt;, sp_mat, sp_cx_mat</a></td><td>&nbsp;</td><td>sparse matrix class</td></tr>
<tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td></tr>
<tr><td><a href="#operators">operators</a></td><td>&nbsp;</td><td><code><big>+</big>&nbsp; <big>&minus;</big>&nbsp; <big>*</big>&nbsp; %&nbsp; /&nbsp; ==&nbsp; !=&nbsp; &lt;=&nbsp; &gt;=&nbsp; &lt;&nbsp; &gt;&nbsp; &amp;&amp;&nbsp; ||</code></td></tr>
@@ -261,6 +271,7 @@ Conrad Sanderson and Ryan Curtin.
<table>
<tbody>
<tr><td><a href="#attributes">attributes</a></td><td>&nbsp;</td><td>.n_rows, .n_cols, .n_elem, .n_slices, ...</td></tr>
<tr><td><small><small>&nbsp;</small></small></td><td><small><small>&nbsp;</small></small></td><td><small><small>&nbsp;</small></small></td></tr>
<tr><td><a href="#element_access">element&nbsp;access</a></td><td>&nbsp;</td><td>element/object access via (), [] and .at()</td></tr>
<tr><td><a href="#element_initialisation">element&nbsp;initialisation</a></td><td>&nbsp;</td><td>set elements via initialiser lists</td></tr>
<tr><td><small><small>&nbsp;</small></small></td><td><small><small>&nbsp;</small></small></td><td><small><small>&nbsp;</small></small></td></tr>
@@ -271,6 +282,7 @@ Conrad Sanderson and Ryan Curtin.
<tr><td><small><small>&nbsp;</small></small></td><td><small><small>&nbsp;</small></small></td><td><small><small>&nbsp;</small></small></td></tr>
<tr><td><a href="#fill">.fill</a></td><td>&nbsp;</td><td>set all elements to specified value</td></tr>
<tr><td><a href="#imbue">.imbue</a></td><td>&nbsp;</td><td>imbue (fill) with values provided by functor or lambda function</td></tr>
<tr><td><a href="#push_back">.push_back</a></td><td>&nbsp;</td><td>append elements to vectors</td></tr>
<tr><td><small><small>&nbsp;</small></small></td><td><small><small>&nbsp;</small></small></td><td><small><small>&nbsp;</small></small></td></tr>
<tr><td><a href="#clean">.clean</a></td><td>&nbsp;</td><td>replace elements below a threshold with zeros</td></tr>
<tr><td><a href="#replace_member">.replace</a></td><td>&nbsp;</td><td>replace specific elements with a new value</td></tr>
@@ -569,8 +581,6 @@ Conrad Sanderson and Ryan Curtin.
<tr style="background-color: #F5F5F5;"><td><a href="#example_prog">example&nbsp;program</a></td><td>&nbsp;</td><td>short example program</td></tr>
<tr><td><a href="#config_hpp">config.hpp</a></td><td>&nbsp;</td><td>configuration options</td></tr>
<tr><td><a href="#changelog">API&nbsp;additions</a></td><td>&nbsp;</td><td>API stability and list of API additions</td></tr>
<!--<tr><td><a href="#log_add">log_add</a></td><td>&nbsp;</td><td>TODO</td></tr>-->
<!--<tr><td><a href="#catching_exceptions">catching exceptions</a></td><td>&nbsp;</td><td>TODO</td></tr>-->
</tbody>
</table>
</ul>
@@ -751,6 +761,8 @@ Functions which use LAPACK (generally matrix decompositions) are only valid for
<a name="constructors_mat"></a>
<li>
Constructors:
<br>
<br>
<ul>
<table>
<tbody>
@@ -775,22 +787,27 @@ Constructors:
<li>
Matrix elements can be explicitly initialised during construction by specifying <i>fill_form</i>,
which is one of:
<br>
<br>
<ul>
<table>
<tbody>
<tr><td><code>fill::zeros</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to 0</td></tr>
<tr><td><code>fill::ones</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to 1</td></tr>
<tr><td><code>fill::eye</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set the elements on the main diagonal to 1 and off-diagonal elements to 0</td></tr>
<tr><td><code>fill::randu</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to random values from a uniform distribution in the [0,1] interval</td></tr>
<tr><td><code>fill::randn</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to random values from a normal/Gaussian distribution with zero mean and unit variance</td></tr>
<tr><td><code>fill::value(scalar)</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to specified scalar</td></tr>
<tr><td><code>fill::none</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>do not initialise the elements &nbsp; (matrix may have garbage values)</td></tr>
<tr><td><code>fill::zeros</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to 0 &nbsp; (default operation)</td></tr>
<tr><td><code>fill::ones</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to 1</td></tr>
<tr><td><code>fill::nan</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to NaN</td></tr>
<tr><td><code>fill::inf</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to +infinity</td></tr>
<tr><td><code>fill::neg_inf</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to -infinity</td></tr>
<tr><td><code>fill::value(scalar)</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to the specified scalar</td></tr>
<tr><td><code>fill::eye</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set elements on the main diagonal to 1 and off-diagonal elements to 0</td></tr>
<tr><td><code>fill::randu</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set elements to random values from a uniform distribution in the [0,1] interval</td></tr>
<tr><td><code>fill::randn</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set elements to random values from a normal/Gaussian distribution with mean&thinsp;=&thinsp;0 and variance&thinsp;=&thinsp;1</td></tr>
</tbody>
</table>
</ul>
</li>
<br>
<li>Default element initialisation is <code>fill::zeros</code> (since Armadillo 10.5)</li>
<li>If <i>fill_form</i> is not specified, <i>fill::zeros</i> is used by default (since Armadillo 10.5)</li>
<br>
<li>
For the <i>mat(string)</i> constructor, the format is elements separated by spaces, and rows denoted by semicolons;
@@ -878,6 +895,16 @@ data is copied from auxiliary memory, where <i>ptr_aux_mem</i> is a pointer to t
</ul>
</li>
<br>
<li>
Support for the <i>std::uint8_t</i> and <i>std::int8_t</i> element types can be enabled by defining both <code>ARMA_U8_TYPE</code> and <code>ARMA_S8_TYPE</code> before including the armadillo header:
<ul>
<pre>
#define ARMA_U8_TYPE std::uint8_t
#define ARMA_S8_TYPE std::int8_t
#include &lt;armadillo&gt;
</pre>
</ul>
</li>
<br>
<li>
Examples:
@@ -1145,6 +1172,8 @@ main exceptions are functions which require square matrices
<br>
<li>
Constructors:
<br>
<br>
<ul>
<table>
<tbody>
@@ -1417,6 +1446,8 @@ main exceptions are functions which require square matrices
<br>
<li>
Constructors:
<br>
<br>
<ul>
<table>
<tbody>
@@ -1543,11 +1574,11 @@ rowvec z = A.row(5); // extract a row vector
<br><b>cx_cube</b>
<ul>
<li>
Classes for cubes (quasi 3rd order tensors), also known as "3D matrices"
Classes for cubes (quasi third-order tensors, aka "3D matrices")
</li>
<br>
<li>
Data is stored as a set of slices (matrices) stored contiguously within memory;
Data is stored as an ordered set of slices (matrices) placed contiguously within memory;
within each slice, elements are stored with column-major ordering (ie. column by column)
</li>
<br>
@@ -1695,6 +1726,8 @@ it is possible to use other types instead, eg. <i>fcube</i>
<a name="constructors_cube"></a>
<li>
Constructors:
<br>
<br>
<ul>
<table>
<tbody>
@@ -1713,21 +1746,26 @@ Constructors:
<li>
Cube elements can be explicitly initialised during construction by specifying <i>fill_form</i>,
which is one of:
<br>
<br>
<ul>
<table>
<tbody>
<tr><td><code>fill::zeros</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to 0</td></tr>
<tr><td><code>fill::ones</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to 1</td></tr>
<tr><td><code>fill::randu</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to random values from a uniform distribution in the [0,1] interval</td></tr>
<tr><td><code>fill::randn</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to random values from a normal/Gaussian distribution with zero mean and unit variance</td></tr>
<tr><td><code>fill::value(scalar)</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to specified scalar</td></tr>
<tr><td><code>fill::none</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>do not initialise the elements &nbsp; (cube may have garbage values)</td></tr>
<tr><td><code>fill::zeros</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to 0 &nbsp; (default operation)</td></tr>
<tr><td><code>fill::ones</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to 1</td></tr>
<tr><td><code>fill::nan</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to NaN</td></tr>
<tr><td><code>fill::inf</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to +infinity</td></tr>
<tr><td><code>fill::neg_inf</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to -infinity</td></tr>
<tr><td><code>fill::value(scalar)</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set all elements to the specified scalar</td></tr>
<tr><td><code>fill::randu</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set elements to random values from a uniform distribution in the [0,1] interval</td></tr>
<tr><td><code>fill::randn</code></td><td>&nbsp;&mapsto;&nbsp;</td><td>set elements to random values from a normal/Gaussian distribution with mean&thinsp;=&thinsp;0 and variance&thinsp;=&thinsp;1</td></tr>
</tbody>
</table>
</ul>
</li>
<br>
<li>Default element initialisation is <code>fill::zeros</code> (since Armadillo 10.5)</li>
<li>If <i>fill_form</i> is not specified, <i>fill::zeros</i> is used by default (since Armadillo 10.5)</li>
<br>
<li>
Each instance of <i>cube</i> automatically allocates and releases internal memory.
@@ -1863,6 +1901,8 @@ Each element can have an arbitrary size (eg. in a field of matrices, each matrix
<br>
<li>
Constructors, where <i>object_type</i> is another class, eg. <i>vec</i>, <i>mat</i>, <i>std::string</i>, etc:
<br>
<br>
<ul>
<table>
<tbody>
@@ -1889,6 +1929,7 @@ mat A = randn(2,3);
mat B = randn(4,5);
field&lt;mat&gt; F(2,1);
F(0,0) = A;
F(1,0) = B;
@@ -2063,6 +2104,8 @@ it is possible to use other types instead, eg. <i>sp_fmat</i>
<a name="constructors_sp_mat"></a>
<li>
Constructors:
<br>
<br>
<ul>
<table>
<tbody>
@@ -2100,6 +2143,8 @@ for small matrices use the <a href="#Mat">Mat</a> class, even if most of the ele
<li>
<a name="batch_constructors_sp_mat"></a>
Batch insertion constructors:
<br>
<br>
<ul>
<li>form&nbsp;1: <code>sp_mat(<i>locations</i>, <i>values</i>, <i>sort_locations&thinsp;=&thinsp;true</i>)</code></li>
<li>form&nbsp;2: <code>sp_mat(<i>locations</i>, <i>values</i>, <i>n_rows</i>, <i>n_cols</i>, <i>sort_locations&thinsp;=&thinsp;true</i>, <i>check_for_zeros&thinsp;=&thinsp;true</i>)</code></li>
@@ -2153,6 +2198,8 @@ If <i>check_for_zeros</i> is set to <i>false</i>, the <i>values</i> vector is as
<br>
<li>
The following subset of operations &amp; functions is available for sparse matrices:
<br>
<br>
<ul>
<li>fundamental arithmetic <a href="#operators">operations</a> (such as addition and multiplication)</li>
<li><a href="#submat">submatrix views</a>: most contiguous forms and the non-contiguous form of <i>X.cols(vector_of_column_indices)</i></li>
@@ -2202,10 +2249,6 @@ See also:
<li><a href="#element_access">element access</a></li>
<li><a href="#iterators_spmat">element iterators (sparse matrices)</a></li>
<li><a href="#print">printing matrices</a></li>
<!--
<li><a href="#SpCol">SpCol class</a> (TODO: add to documentation)</li>
<li><a href="#SpRow">SpRow class</a> (TODO: add to documentation)</li>
-->
<li><a href="https://en.wikipedia.org/wiki/Sparse_matrix">Sparse Matrix in Wikipedia</a></li>
<li><a href="#Mat">Mat class</a> (dense matrix)</li>
</ul>
@@ -2675,6 +2718,7 @@ double y = v(0);
<ul>
<li><a href="#in_range">.in_range()</a></li>
<li><a href="#element_initialisation">element initialisation</a></li>
<li><a href="#push_back">.push_back()</a></li>
<li><a href="#ind2sub">ind2sub()</a></li>
<li><a href="#sub2ind">sub2ind()</a></li>
<li><a href="#index_min_and_index_max_member">.index_min()&nbsp;/&nbsp;.index_max()</a></li>
@@ -2714,6 +2758,7 @@ mat A = { {1, 3, 5},
See also:
<ul>
<li><a href="#element_access">element access</a></li>
<li><a href="#push_back">.push_back()</a></li>
<li><a href="#reshape_member">.reshape()</a></li>
<li><a href="#print">.print()</a></li>
<li><a href="#save_load_mat">saving &amp; loading matrices</a></li>
@@ -2932,6 +2977,7 @@ C.eye();
<li>See also:
<ul>
<li><a href="#ones_member">.ones()</a></li>
<li><a href="#fill">.fill()</a></li>
<li><a href="#diag">.diag()</a></li>
<li><a href="#diagmat">diagmat()</a></li>
<li><a href="#diagvec">diagvec()</a></li>
@@ -3090,7 +3136,7 @@ See also:
Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i>, <i>Cube</i>, <i>field</i>
</li>
<br>
<li>Sets the elements to a specified value</li>
<li>Sets all elements to a specified value</li>
<br>
<li>The type of value must match the type of elements used by the container object (eg. for <i>mat</i> the type is <i>double</i>)
</li>
@@ -3101,29 +3147,39 @@ Examples:
<pre>
mat A(5, 6);
A.fill(123.0); // or: mat A(5, 6, fill::value(123.0));
A.fill(123.0);
</pre>
</ul>
</li>
<br>
<li>
<b>Note:</b> to set all elements to zero during matrix construction, use the following more compact form:
<b>Caveats:</b>
<ul>
<li>To initialise all elements during matrix construction, it is more efficient to use a <i><a href="#Mat">fill_form</a></i>:
<ul>
<pre>
mat A(5, 6, fill::zeros);
mat B(5, 6, fill::ones);
mat C(5, 6, fill::value(123.0));
</pre>
</ul>
</li>
<li>If <i>fill_form</i> is not specified, <i>fill::zeros</i> is used by default (since Armadillo 10.5)</li>
</ul>
</li>
<br>
<li>
See also:
<ul>
<li><a href="#imbue">.imbue()</a></li>
<li><a href="#ones_member">.ones()</a></li>
<li><a href="#push_back">.push_back()</a></li>
<li><a href="#zeros_member">.zeros()</a></li>
<li><a href="#ones_member">.ones()</a></li>
<li><a href="#eye_member">.eye()</a></li>
<li><a href="#randu_randn_member">.randu() &amp; .randn()</a></li>
<li><a href="#replace">.replace()</a></li>
<li><a href="#constants">constants (pi, nan, inf, ...)</a></li>
<li><a href="#Mat">matrix constructors</a></li>
</ul>
</li>
<br>
@@ -3171,6 +3227,7 @@ A.imbue( [&amp;]() { return distr(engine); } );
See also:
<ul>
<li><a href="#fill">.fill()</a></li>
<li><a href="#push_back">.push_back()</a></li>
<li><a href="#transform">.transform()</a></li>
<li><a href="#element_access">element access</a></li>
<li><a href="https://en.wikipedia.org/wiki/Function_object">function object</a> at Wikipedia</li>
@@ -3181,6 +3238,48 @@ See also:
<br>
</ul>
<div class="pagebreak"></div><div class="noprint"><hr class="greyline"><br></div>
<a name="push_back"></a>
<b>.push_back(&nbsp;value&nbsp;)</b>
<ul>
<li>
Member function of <i>Mat</i>, <i>Col</i>, <i>Row</i>
</li>
<br>
<li>
Append the given <i>value</i> to the end of the object,
under the assumption of a column or row vector layout
</li>
<br>
<li>
<b>Caveat:</b> it is faster to directly set the elements via <a href="#element_access">element accessors</a>
or <a href="#element_initialisation">braced initialiser lists</a>
</li>
<br>
<li>
Examples:
<ul>
<pre>
vec v;
v.push_back(1.23);
v.push_back(4.56);
v.push_back(7.89);
</pre>
</ul>
</li>
<br>
<li>See also:
<ul>
<li><a href="#element_access">element accessors</a></li>
<li><a href="#element_initialisation">element initialisation</a></li>
<li><a href="#fill">.fill()</a></li>
<li><a href="#imbue">.imbue()</a></li>
</ul>
</li>
<br>
</ul>
<div class="pagebreak"></div><div class="noprint"><hr class="greyline"><br></div>
<a name="clean"></a>
<b>.clean(&nbsp;</b>threshold<b>&nbsp;)</b>
@@ -3908,6 +4007,10 @@ Instances of <i>span(start,end)</i> can be replaced by <i>span::all</i> to indic
</li>
<br>
<li>
To distinguish <i>span(start,end)</i> from <i>std::span</i>, use the <i>arma::</i> prefix, ie. <i>arma::span(start,end)</i>
</li>
<br>
<li>
For functions requiring one or more vector of indices,
eg. <i>X.submat(vector_of_row_indices,&nbsp;vector_of_column_indices)</i>,
each vector of indices must be of type <i><a href="#Col">uvec</a></i>
@@ -4071,8 +4174,8 @@ Instances of <i>span(a,b)</i> can be replaced by:
</li>
<br>
<li>
An individual slice, accessed via <i>.slice()</i>, is an instance of the <i>Mat</i> class
(a reference to a matrix is provided)
A single slice, accessed via <i>.slice(slice_number)</i>, is an instance of the <i>Mat</i> class (a reference to a matrix is provided);
<br>see also <i>.<a href="#col_row_as_mat">col_as_mat()</a></i> and <i>.<a href="#col_row_as_mat">row_as_mat()</a></i>
</li>
<br>
<li>
@@ -5770,6 +5873,7 @@ See also:
<li><a href="#iterators_cube">iterators (cubes)</a></li>
<li><a href="#iterators_spmat">iterators (sparse matrices)</a></li>
<li><a href="#attributes">matrix and vector attributes</a></li>
<li><a href="#push_back">.push_back()</a></li>
<li><a href="#is_empty">.is_empty()</a></li>
<li><a href="#reset">.reset()</a></li>
</ul>
@@ -5805,6 +5909,7 @@ Examples:
<ul>
<pre>
mat X(4, 5, fill::randu);
vec v = X.as_col();
</pre>
</ul>
@@ -5858,9 +5963,11 @@ Examples:
<pre>
cube Q(5, 4, 3, fill::randu);
mat A = Q.col_as_mat(2); // size of A: 5x3
mat A = Q.slice(2); // size of A: 5x4
mat B = Q.row_as_mat(2); // size of B: 3x4
mat B = Q.col_as_mat(2); // size of B: 5x3
mat C = Q.row_as_mat(2); // size of C: 3x4
</pre>
</ul>
</li>
@@ -9597,7 +9704,7 @@ vec b = diff(a);
</li>
<br>
<li>
<b>Caveat:</b> <a href="#norm">norm()</a> is preferred for calculating the 2-norm, as it reduces the incidence of numerical underflows and overflows
<b>Caveat:</b> to obtain the Euclidean norm, use the more robust <a href="#norm">norm(x)</a> instead of <i>sqrt(dot(x,x))</i>
</li>
<br>
<li>
@@ -9723,10 +9830,6 @@ See also:
<li><i>expmat_sym(B,A)</i> resets <i>B</i> and returns a bool set to <i>false</i> (exception is not thrown)</li>
</ul>
</li>
<!--
<br>
<li><b>Caveat:</b> there is no explicit check whether <i>A</i> is symmetric/hermitian</li>
-->
<br>
<li><b>Caveat:</b> the matrix exponential operation is generally <b>not</b> the same as applying the <a href="#misc_fns">exp()</a> function to each element</li>
<br>
@@ -10697,10 +10800,6 @@ See also:
<li><i>logmat_sympd(B,A)</i> resets <i>B</i> and returns a bool set to <i>false</i> (exception is not thrown)</li>
</ul>
</li>
<!--
<br>
<li><b>Caveat:</b> there is no explicit check whether <i>A</i> is symmetric/hermitian positive definite</li>
-->
<br>
<li><b>Caveat:</b> the matrix logarithm operation is generally <b>not</b> the same as applying the <a href="#misc_fns">log()</a> function to each element</li>
<br>
@@ -11097,11 +11196,6 @@ See also:
<tbody>
<tr><td><b>pow( A, scalar )</b></td><td>&nbsp;&nbsp;&nbsp;</td><td>(form&nbsp;1)</td></tr>
<tr><td><b>pow( A, B )</b></td><td>&nbsp;&nbsp;&nbsp;</td><td>(form&nbsp;2)</td></tr>
<!--
<tr><td><b>pow( M.each_col(), C )</b></td><td>&nbsp;&nbsp;&nbsp;</td><td>(form&nbsp;3)</td></tr>
<tr><td><b>pow( M.each_row(), R )</b></td><td>&nbsp;&nbsp;&nbsp;</td><td>(form&nbsp;4)</td></tr>
<tr><td><b>pow( Q.each_slice(), M )</b></td><td>&nbsp;&nbsp;&nbsp;</td><td>(form&nbsp;5)</td></tr>
-->
</tbody>
</table>
<ul>
@@ -11111,17 +11205,6 @@ See also:
<br>
<li>form 2: raise each element in <i>A</i> to the power denoted by the corresponding element in <i>B</i>; sizes of <i>A</i> and <i>B</i> must be the same</li>
<br>
<!--
<li>form 3: for each column vector of matrix <i>M</i>, raise each element to the power denoted by the corresponding element in column vector <i>C</i>;
<br>the number of rows in <i>M</i> and <i>C</i> must be the same</li>
<br>
<li>form 4: for each row vector of matrix <i>M</i>, raise each element to the power denoted by the corresponding element in row vector <i>R</i>;
<br>the number of columns in <i>M</i> and <i>R</i> must be the same</li>
<br>
<li>form 5: for each slice of cube <i>Q</i>, raise each element to the power denoted by the corresponding element in matrix <i>M</i>;
<br>the number of rows and columns in <i>Q</i> and <i>M</i> must be the same</li>
<br>
-->
<li><b>Caveats</b>:
<ul>
<li>to raise all elements to the power 2, use <a href="#misc_fns">square()</a> instead</li>
@@ -11138,13 +11221,6 @@ mat B(5, 6, fill::randu);
mat X = pow(A, 3.45);
mat Y = pow(A, B);
</pre>
<!--
vec C(5, fill::randu);
rowvec R(6, fill::randu);
mat Z1 = pow(A.each_col(), C);
mat Z2 = pow(A.each_row(), R);
-->
</ul>
</li>
<br>
@@ -11153,10 +11229,6 @@ See also:
<ul>
<li><a href="#powmat">powmat()</a></li>
<li><a href="#misc_fns">miscellaneous element-wise functions</a></li>
<!--
<li><a href="#each_colrow">.each_col() &amp; .each_row()</a></li>
<li><a href="#each_slice">.each_slice()</a></li>
-->
</ul>
</li>
<br>
@@ -12041,10 +12113,6 @@ See also:
<li><i>sqrtmat_sympd(B,A)</i> resets <i>B</i> and returns a bool set to <i>false</i> (exception is not thrown)</li>
</ul>
</li>
<!--
<br>
<li><b>Caveat:</b> there is no explicit check whether <i>A</i> is symmetric/hermitian positive definite</li>
-->
<br>
<li><b>Caveat:</b> the matrix square root operation is generally <b>not</b> the same as applying the <a href="#misc_fns">sqrt()</a> function to each element</li>
<br>
@@ -13185,10 +13253,6 @@ the divide-and-conquer method provides slightly different results than the stand
<li><i>eig_sym(eigval,eigvec,X)</i> resets <i>eigval</i> &amp; <i>eigvec</i> and returns a bool set to <i>false</i> (exception is not thrown)</li>
</ul>
</li>
<!--
<br>
<li><b>Caveat:</b> there is no explicit check whether <i>X</i> is symmetric/hermitian</li>
-->
<br>
<li>
Examples:
@@ -13566,10 +13630,6 @@ If <i>A</i> is not square sized, a <i>std::logic_error</i> exception is thrown
<li><i>inv_sympd(B,rcond,A)</i> resets <i>B</i>, sets rcond to zero, and returns a bool set to <i>false</i> (exception is not thrown)</li>
</ul>
</li>
<!--
<br>
<li><b>Caveat:</b> there is no explicit check whether <i>A</i> is symmetric/hermitian positive definite</li>
-->
<br>
<li>
<b>Caveat:</b>
@@ -14961,7 +15021,6 @@ See also:
<ul>
<li><a href="#spsolve_factoriser">spsolve_factoriser</a></li>
<li><a href="#solve">solve()</a> - solve dense system of linear equations</li>
<!-- <li><a href="http://crd-legacy.lbl.gov/~xiaoye/SuperLU/">SuperLU home page</a> -->
<li><a href="https://portal.nersc.gov/project/sparse/superlu/">SuperLU home page</a>
<li><a href="https://mathworld.wolfram.com/LinearSystemofEquations.html">linear system of equations in MathWorld</a></li>
<li><a href="https://en.wikipedia.org/wiki/Linear_system_of_equations">system of linear equations in Wikipedia</a></li>
@@ -17882,7 +17941,6 @@ model.save("my_model.gmm");
</td>
<td style="vertical-align: top;">
machine epsilon; approximately 2.2204e-16; difference between 1 and the next representable value
<!-- machine epsilon: the difference between 1 and the value least greater than 1 that is representable (type and machine dependent) -->
</td>
</tr>
<tr>
@@ -18427,7 +18485,7 @@ An instance of the class has the following member functions:
</td>
<td style="vertical-align: top;">
return the number of seconds since the last call to <code>.tic()</code>,
with the returned number of seconds reduced by any freeze/unfreeze durations
with the number of seconds reduced by any freeze/unfreeze durations
</td>
</tr>
<tr>
@@ -18608,33 +18666,6 @@ See also:
<br>
</ul>
<!--
<div class="pagebreak"></div><div class="noprint"><hr class="greyline"><br></div>
<a name="log_add"></a>
<b>log_add(log_a, log_b)</b>
<ul>
<li>
Safe replacement for log(exp(log_a) + exp(log_b))
</li>
<br>
<li>
Usage:
<ul>
<li>
<i>scalar_type</i> log_c = log_add(log_a, log_b)
</li>
<li>
<i>scalar_type</i> is either <i>float</i> or <i>double</i>
</li>
<li>
log_a, log_b and log_c must have the same type
</li>
</ul>
</li>
</ul>
<br>
-->
<div class="pagebreak"></div><div class="noprint"><hr class="greyline"><br></div>
<a name="uword"></a>
<b>uword</b>, <b>sword</b>
@@ -18810,7 +18841,6 @@ fp16 val = X(2,3);
<li><a href="#Mat">hmat</a> matrix type
<li><a href="#Col">hvec</a> vector type
<li><a href="https://en.cppreference.com/w/cpp/types/floating-point.html">std::float16_t</a> in cppreference.com</li>
<!-- <li><a href="https://en.cppreference.com/w/cpp/header/stdfloat.html">std::float16_t</a> in cppreference.com</li> -->
<li><a href="https://en.wikipedia.org/wiki/Half-precision_floating-point_format">half-precision floating point format in Wikipedia</a></li>
<li><a href="https://en.wikipedia.org/wiki/AVX-512">AVX-512 extensions in Wikipedia</a></li>
<!-- <li><a href="https://gcc.gnu.org/onlinedocs/gcc/Half-Precision.html">gcc half-precision documentation</a></li> -->
@@ -20682,60 +20712,6 @@ See also:
<br>
</ul>
<!--
<div class="pagebreak"></div><div class="noprint"><hr class="greyline"><br></div>
<a name="catching_exceptions"></a>
<br>
<b>how to catch std::runtime_error exceptions</b>
<br>
<br>
<ul>
<li>
If a function such as <a href="#inv">inv()</a> fails to find a solution,
an error message is printed and a <i>std::runtime_error</i> exception is thrown.
If the exception is not caught, the program typically terminates.
Below is an example of how to catch exceptions:
<ul>
<pre>
#include &lt;iostream&gt;
#include &lt;armadillo&gt;
using namespace std;
using namespace arma;
int main(int argc, char** argv)
{
// create a non-invertible matrix
mat A(5, 5, fill::zeros);
mat B;
try
{
B = inv(A);
}
catch (std::runtime_error&amp; x)
{
cout &lt;&lt; "caught an exception" &lt;&lt; endl;
}
return 0;
}
</pre>
</ul>
<li>
See also:
<ul>
<li><a href="#logging">logging of warnings and errors</a></li>
<li><a href="https://cplusplus.com/doc/tutorial/exceptions/">tutorial on exceptions</a></li>
<li><a href="https://cplusplus.com/reference/stdexcept/runtime_error/">std::runtime_error</a></li>
</ul>
</li>
<br>
</ul>
<br>
-->
<div class="pagebreak"></div><div class="noprint"><hr class="greyline"><br></div>
<a name="api_additions"></a>
<a name="changelog"></a>
@@ -20783,19 +20759,6 @@ and may be changed or removed without notice.
</ul>
</li>
<!--
<br>
<li>
<a name="deprecated"></a>
List of deprecated functionality; this functionality will be <b>removed</b> in version A.B:
<ul>
<li>
...
</li>
</ul>
</li>
-->
<br>
<br>
<li>
@@ -20806,12 +20769,24 @@ List of additions and changes for each version:
<a name="version_154"></a>
<li>Version 15.4:
<ul>
<li>added <i>fill::nan</i>, <i>fill::inf</i>, <i>fill::neg_inf</i> as optional fill forms for the <a href="#Mat">Mat</a> class</li>
<li>added <a href="#push_back">.push_back()</a> for appending elements to vectors</li>
<li>faster handling of <a href="#find">find()</a> within <a href="#submat">.elem()</a></li>
<li>faster element-wise <a href="#min_and_max">min()</a> and <a href="#min_and_max">max()</a></li>
<li>faster <a href="#conv_to">conv_to</a> when element types of input and output objects are the same</li>
</ul>
</li>
<br>
<a name="version_152"></a>
<li>Version 15.2:
<ul>
<li>added <a href="#rande">rande()</a> for generating matrices with elements from exponential distributions</li>
<li>shift() has been deprecated in favour of <a href="#circshift">circshift()</a>, for consistency with Matlab/Octave</li>
<li>reworked detection of aliasing, leading to more efficient compiled code</li>
<li>faster handling of submatrices with one row</li>
</ul>
</li>
<br>
@@ -21920,6 +21895,7 @@ use <i>my_function(&nbsp;mat(A+B)&nbsp;)</i>.
<br>
</ul>
<!-- END CONTENT -->
+2
View File
@@ -306,6 +306,7 @@ namespace arma
#include "armadillo_bits/op_orth_null_bones.hpp"
#include "armadillo_bits/op_relational_bones.hpp"
#include "armadillo_bits/op_find_bones.hpp"
#include "armadillo_bits/op_find_aux_bones.hpp"
#include "armadillo_bits/op_find_unique_bones.hpp"
#include "armadillo_bits/op_chol_bones.hpp"
#include "armadillo_bits/op_cx_scalar_bones.hpp"
@@ -765,6 +766,7 @@ namespace arma
#include "armadillo_bits/op_orth_null_meat.hpp"
#include "armadillo_bits/op_relational_meat.hpp"
#include "armadillo_bits/op_find_meat.hpp"
#include "armadillo_bits/op_find_aux_meat.hpp"
#include "armadillo_bits/op_find_unique_meat.hpp"
#include "armadillo_bits/op_chol_meat.hpp"
#include "armadillo_bits/op_cx_scalar_meat.hpp"
+42 -12
View File
@@ -244,9 +244,9 @@ BaseCube<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::res
typedef typename get_pod_type<elem_type>::result T;
arma_conform_check( (tol < T(0)), "is_zero(): parameter 'tol' must be >= 0" );
arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" );
if(ProxyCube<derived>::use_at || is_Cube<typename ProxyCube<derived>::stored_type>::value)
if(is_Cube<typename ProxyCube<derived>::stored_type>::value || ProxyCube<derived>::use_at)
{
const unwrap_cube<derived> U( (*this).get_ref() );
@@ -263,22 +263,52 @@ BaseCube<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::res
if(is_cx<elem_type>::yes)
{
for(uword i=0; i<n_elem; ++i)
if(tol == T(0))
{
const elem_type val = Pea[i];
const T val_real = access::tmp_real(val);
const T val_imag = access::tmp_imag(val);
if(eop_aux::arma_abs(val_real) > tol) { return false; }
if(eop_aux::arma_abs(val_imag) > tol) { return false; }
for(uword i=0; i < n_elem; ++i)
{
const elem_type val = Pea[i];
const T val_real = access::tmp_real(val);
const T val_imag = access::tmp_imag(val);
if(eop_aux::arma_abs(val_real) != T(0)) { return false; }
if(eop_aux::arma_abs(val_imag) != T(0)) { return false; }
}
}
else
{
for(uword i=0; i < n_elem; ++i)
{
const elem_type val = Pea[i];
const T val_real = access::tmp_real(val);
const T val_imag = access::tmp_imag(val);
if( (eop_aux::arma_abs(val_real) <= tol) == false ) { return false; }
if( (eop_aux::arma_abs(val_imag) <= tol) == false ) { return false; }
}
}
}
else // not complex
{
for(uword i=0; i < n_elem; ++i)
if(tol == T(0))
{
if(eop_aux::arma_abs(Pea[i]) > tol) { return false; }
for(uword i=0; i < n_elem; ++i)
{
const elem_type val = Pea[i];
if(val != elem_type(0)) { return false; }
}
}
else
{
for(uword i=0; i < n_elem; ++i)
{
const elem_type val = Pea[i];
if( (eop_aux::arma_abs(val) <= tol) == false ) { return false; }
}
}
}
+55 -15
View File
@@ -352,7 +352,7 @@ Base<elem_type,derived>::is_symmetric(const typename get_pod_type<elem_type>::re
if(tol == T(0)) { return (*this).is_symmetric(); }
arma_conform_check( (tol < T(0)), "is_symmetric(): parameter 'tol' must be >= 0" );
arma_conform_check( ((tol >= T(0)) == false), "is_symmetric(): parameter 'tol' must be > 0" );
const quasi_unwrap<derived> U( (*this).get_ref() );
@@ -365,8 +365,12 @@ Base<elem_type,derived>::is_symmetric(const typename get_pod_type<elem_type>::re
if(norm_A == T(0)) { return true; }
if(arma_isnan(norm_A)) { return false; }
const T norm_A_Ast = as_scalar( arma::max(sum(abs(A - A.st()), 1), 0) );
if(arma_isnan(norm_A_Ast)) { return false; }
return ( (norm_A_Ast / norm_A) <= tol );
}
@@ -435,7 +439,7 @@ Base<elem_type,derived>::is_hermitian(const typename get_pod_type<elem_type>::re
if(tol == T(0)) { return (*this).is_hermitian(); }
arma_conform_check( (tol < T(0)), "is_hermitian(): parameter 'tol' must be >= 0" );
arma_conform_check( ((tol >= T(0)) == false), "is_hermitian(): parameter 'tol' must be > 0" );
const quasi_unwrap<derived> U( (*this).get_ref() );
@@ -448,8 +452,12 @@ Base<elem_type,derived>::is_hermitian(const typename get_pod_type<elem_type>::re
if(norm_A == T(0)) { return true; }
if(arma_isnan(norm_A)) { return false; }
const T norm_A_At = as_scalar( arma::max(sum(abs(A - A.t()), 1), 0) );
if(arma_isnan(norm_A_At)) { return false; }
return ( (norm_A_At / norm_A) <= tol );
}
@@ -464,9 +472,9 @@ Base<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::result
typedef typename get_pod_type<elem_type>::result T;
arma_conform_check( (tol < T(0)), "is_zero(): parameter 'tol' must be >= 0" );
arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" );
if(Proxy<derived>::use_at || is_Mat<typename Proxy<derived>::stored_type>::value)
if( (quasi_unwrap<derived>::has_orig_mem) || (is_Mat<typename Proxy<derived>::stored_type>::value) || (Proxy<derived>::use_at) )
{
const quasi_unwrap<derived> U( (*this).get_ref() );
@@ -483,22 +491,52 @@ Base<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::result
if(is_cx<elem_type>::yes)
{
for(uword i=0; i<n_elem; ++i)
if(tol == T(0))
{
const elem_type val = Pea[i];
const T val_real = access::tmp_real(val);
const T val_imag = access::tmp_imag(val);
if(eop_aux::arma_abs(val_real) > tol) { return false; }
if(eop_aux::arma_abs(val_imag) > tol) { return false; }
for(uword i=0; i < n_elem; ++i)
{
const elem_type val = Pea[i];
const T val_real = access::tmp_real(val);
const T val_imag = access::tmp_imag(val);
if(eop_aux::arma_abs(val_real) != T(0)) { return false; }
if(eop_aux::arma_abs(val_imag) != T(0)) { return false; }
}
}
else
{
for(uword i=0; i < n_elem; ++i)
{
const elem_type val = Pea[i];
const T val_real = access::tmp_real(val);
const T val_imag = access::tmp_imag(val);
if( (eop_aux::arma_abs(val_real) <= tol) == false ) { return false; }
if( (eop_aux::arma_abs(val_imag) <= tol) == false ) { return false; }
}
}
}
else // not complex
{
for(uword i=0; i<n_elem; ++i)
if(tol == T(0))
{
if(eop_aux::arma_abs(Pea[i]) > tol) { return false; }
for(uword i=0; i < n_elem; ++i)
{
const elem_type val = Pea[i];
if(val != elem_type(0)) { return false; }
}
}
else
{
for(uword i=0; i < n_elem; ++i)
{
const elem_type val = Pea[i];
if( (eop_aux::arma_abs(val) <= tol) == false ) { return false; }
}
}
}
@@ -897,6 +935,8 @@ Base_extra_yes<elem_type,derived>::is_sympd() const
// default value for tol
const T tol = T(100) * std::numeric_limits<T>::epsilon() * norm(X, "fro");
if(arma_isnan(tol)) { return false; }
if(X.is_hermitian(tol) == false) { return false; }
if(X.is_empty()) { return false; }
@@ -917,7 +957,7 @@ Base_extra_yes<elem_type,derived>::is_sympd(typename get_pod_type<elem_type>::re
typedef typename get_pod_type<elem_type>::result T;
arma_conform_check( (tol < T(0)), "is_sympd(): parameter 'tol' must be >= 0" );
arma_conform_check( ((tol >= T(0)) == false), "is_sympd(): parameter 'tol' must be >= 0" );
Mat<elem_type> X = static_cast<const derived&>(*this);
+7 -3
View File
@@ -33,6 +33,8 @@ class Col : public Mat<eT>
static constexpr bool is_row = false;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = false;
inline Col();
inline Col(const Col<eT>& X);
@@ -67,9 +69,6 @@ class Col : public Mat<eT>
inline Col(Col&& m);
inline Col& operator=(Col&& m);
// inline Col(Mat<eT>&& m);
// inline Col& operator=(Mat<eT>&& m);
inline Col& operator=(const eT val);
inline Col& operator=(const Col& m);
@@ -153,6 +152,7 @@ class Col : public Mat<eT>
arma_warn_unused arma_inline eT& at(const uword in_row, const uword in_col);
arma_warn_unused arma_inline const eT& at(const uword in_row, const uword in_col) const;
inline void push_back(const eT val);
inline constexpr bool is_vec() const { return true; }
inline constexpr bool is_rowvec() const { return false; }
@@ -210,6 +210,8 @@ class Col<eT>::fixed : public Col<eT>
static constexpr bool is_row = false;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = false;
static const uword n_rows; // value provided below the class definition
static const uword n_cols; // value provided below the class definition
static const uword n_elem; // value provided below the class definition
@@ -265,6 +267,8 @@ class Col<eT>::fixed : public Col<eT>
arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col);
arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col) const;
inline void push_back(const eT) = delete;
arma_warn_unused arma_inline eT* memptr();
arma_warn_unused arma_inline const eT* memptr() const;
+23 -58
View File
@@ -431,64 +431,6 @@ Col<eT>::operator=(Col<eT>&& X)
// template<typename eT>
// inline
// Col<eT>::Col(Mat<eT>&& X)
// : Mat<eT>(arma_vec_indicator(), 1)
// {
// arma_debug_sigprint(arma_str::format("this: %x; X: %x") % this % &X);
//
// if(X.n_cols != 1) { const Mat<eT>& XX = X; Mat<eT>::operator=(XX); return; }
//
// access::rw(Mat<eT>::n_rows) = X.n_rows;
// access::rw(Mat<eT>::n_cols) = 1;
// access::rw(Mat<eT>::n_elem) = X.n_elem;
// access::rw(Mat<eT>::n_alloc) = X.n_alloc;
//
// if( (X.n_alloc > arma_config::mat_prealloc) || (X.mem_state == 1) || (X.mem_state == 2) )
// {
// access::rw(Mat<eT>::mem_state) = X.mem_state;
// access::rw(Mat<eT>::mem) = X.mem;
//
// access::rw(X.n_rows) = 0;
// access::rw(X.n_elem) = 0;
// access::rw(X.n_alloc) = 0;
// access::rw(X.mem_state) = 0;
// access::rw(X.mem) = nullptr;
// }
// else // condition: (X.n_alloc <= arma_config::mat_prealloc) || (X.mem_state == 0) || (X.mem_state == 3)
// {
// (*this).init_cold();
//
// arrayops::copy( (*this).memptr(), X.mem, X.n_elem );
//
// if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) )
// {
// access::rw(X.n_rows) = 0;
// access::rw(X.n_elem) = 0;
// access::rw(X.mem) = nullptr;
// }
// }
// }
//
//
//
// template<typename eT>
// inline
// Col<eT>&
// Col<eT>::operator=(Mat<eT>&& X)
// {
// arma_debug_sigprint(arma_str::format("this: %x; X: %x") % this % &X);
//
// if(X.n_cols != 1) { const Mat<eT>& XX = X; Mat<eT>::operator=(XX); return *this; }
//
// (*this).steal_mem(X, true);
//
// return *this;
// }
template<typename eT>
inline
Col<eT>&
@@ -1208,6 +1150,25 @@ Col<eT>::at(const uword in_row, const uword) const
template<typename eT>
inline
void
Col<eT>::push_back(const eT val)
{
arma_debug_sigprint();
if(Mat<eT>::mem_state != 0)
{
arma_conform_check(true, "Col::push_back(): unsupported operation as auxiliary memory is in use");
return;
}
Mat<eT>::vec_push_back(val, arma_colvec_indicator());
}
template<typename eT>
inline
typename Col<eT>::row_iterator
@@ -1344,6 +1305,10 @@ Col<eT>::fixed<fixed_n_elem>::fixed(const fill::fill_class<fill_type>&)
if(is_same_type<fill_type, fill::fill_eye >::yes) { Mat<eT>::eye(); }
if(is_same_type<fill_type, fill::fill_randu>::yes) { Mat<eT>::randu(); }
if(is_same_type<fill_type, fill::fill_randn>::yes) { Mat<eT>::randn(); }
if(is_same_type<fill_type, fill::fill_nan >::yes) { (*this).fill( priv::Datum_helper::nan <eT>() ); }
if(is_same_type<fill_type, fill::fill_pos_inf>::yes) { (*this).fill( priv::Datum_helper::pos_inf<eT>() ); }
if(is_same_type<fill_type, fill::fill_neg_inf>::yes) { (*this).fill( priv::Datum_helper::neg_inf<eT>() ); }
}
@@ -40,6 +40,8 @@ struct CubeToMatOp : public Base< typename T1::elem_type, CubeToMatOp<T1, op_typ
static constexpr bool is_row = op_type::template traits<T1>::is_row;
static constexpr bool is_col = op_type::template traits<T1>::is_col;
static constexpr bool is_xvec = op_type::template traits<T1>::is_xvec;
static constexpr bool has_subview = T1::has_subview;
};
+5
View File
@@ -82,6 +82,8 @@ class Cube : public BaseCube< eT, Cube<eT> >
public:
static constexpr bool has_subview = false;
inline ~Cube();
inline Cube();
@@ -360,6 +362,9 @@ class Cube : public BaseCube< eT, Cube<eT> >
inline Cube& fill(const eT val);
template<typename fill_type>
inline Cube& fill(const fill::fill_class<fill_type>& f);
inline Cube& zeros();
inline Cube& zeros(const uword new_n_rows, const uword new_n_cols, const uword new_n_slices);
inline Cube& zeros(const SizeCube& s);
+72 -38
View File
@@ -52,7 +52,7 @@ Cube<eT>::Cube()
, n_elem(0)
, n_alloc(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
}
@@ -172,7 +172,7 @@ Cube<eT>::Cube(const SizeCube& s, const arma_initmode_indicator<do_zeros>&)
template<typename eT>
template<typename fill_type>
inline
Cube<eT>::Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices, const fill::fill_class<fill_type>&)
Cube<eT>::Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_slices, const fill::fill_class<fill_type>& f)
: n_rows(in_n_rows)
, n_cols(in_n_cols)
, n_elem_slice(in_n_rows*in_n_cols)
@@ -186,12 +186,7 @@ Cube<eT>::Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_sl
init_cold();
if(is_same_type<fill_type, fill::fill_zeros>::yes) { (*this).zeros(); }
if(is_same_type<fill_type, fill::fill_ones >::yes) { (*this).ones(); }
if(is_same_type<fill_type, fill::fill_randu>::yes) { (*this).randu(); }
if(is_same_type<fill_type, fill::fill_randn>::yes) { (*this).randn(); }
arma_static_check( (is_same_type<fill_type, fill::fill_eye>::yes), "Cube::Cube(): unsupported fill type" );
(*this).fill(f);
}
@@ -199,7 +194,7 @@ Cube<eT>::Cube(const uword in_n_rows, const uword in_n_cols, const uword in_n_sl
template<typename eT>
template<typename fill_type>
inline
Cube<eT>::Cube(const SizeCube& s, const fill::fill_class<fill_type>&)
Cube<eT>::Cube(const SizeCube& s, const fill::fill_class<fill_type>& f)
: n_rows(s.n_rows)
, n_cols(s.n_cols)
, n_elem_slice(s.n_rows*s.n_cols)
@@ -213,12 +208,7 @@ Cube<eT>::Cube(const SizeCube& s, const fill::fill_class<fill_type>&)
init_cold();
if(is_same_type<fill_type, fill::fill_zeros>::yes) { (*this).zeros(); }
if(is_same_type<fill_type, fill::fill_ones >::yes) { (*this).ones(); }
if(is_same_type<fill_type, fill::fill_randu>::yes) { (*this).randu(); }
if(is_same_type<fill_type, fill::fill_randn>::yes) { (*this).randn(); }
arma_static_check( (is_same_type<fill_type, fill::fill_eye>::yes), "Cube::Cube(): unsupported fill type" );
(*this).fill(f);
}
@@ -817,11 +807,29 @@ Cube<eT>::Cube(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, cons
{
init_cold();
arrayops::copy( memptr(), aux_mem, n_elem );
if(aux_mem == nullptr)
{
arrayops::fill_zeros(memptr(), n_elem);
}
else
{
arrayops::copy( memptr(), aux_mem, n_elem );
}
}
else
{
create_mat();
if(aux_mem == nullptr)
{
access::rw(mem_state) = 0;
init_cold();
arrayops::fill_zeros(memptr(), n_elem);
}
else
{
create_mat();
}
}
}
@@ -845,7 +853,14 @@ Cube<eT>::Cube(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols
init_cold();
arrayops::copy( memptr(), aux_mem, n_elem );
if(aux_mem == nullptr)
{
arrayops::fill_zeros(memptr(), n_elem);
}
else
{
arrayops::copy( memptr(), aux_mem, n_elem );
}
}
@@ -934,7 +949,7 @@ Cube<eT>::Cube
, n_elem(0)
, n_alloc(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -1064,7 +1079,7 @@ Cube<eT>::Cube(const subview_cube_slices<eT,T1>& X)
, n_elem(0)
, n_alloc(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2751,7 +2766,7 @@ Cube<eT>::Cube(const OpCube<T1, op_type>& X)
, n_elem(0)
, n_alloc(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -3048,7 +3063,7 @@ Cube<eT>::Cube(const mtOpCube<eT, T1, op_type>& X)
, n_elem(0)
, n_alloc(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -3144,7 +3159,7 @@ Cube<eT>::Cube(const GlueCube<T1, T2, glue_type>& X)
, n_elem(0)
, n_alloc(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -3401,7 +3416,7 @@ Cube<eT>::Cube(const mtGlueCube<eT, T1, T2, glue_type>& X)
, n_elem(0)
, n_alloc(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -3887,7 +3902,7 @@ arma_inline
eT*
Cube<eT>::slice_memptr(const uword uslice)
{
return const_cast<eT*>( &mem[ uslice*n_elem_slice ] );
return access::rwp( mem + (uslice*n_elem_slice) );
}
@@ -3898,7 +3913,7 @@ arma_inline
const eT*
Cube<eT>::slice_memptr(const uword uslice) const
{
return &mem[ uslice*n_elem_slice ];
return mem + (uslice*n_elem_slice);
}
@@ -3909,7 +3924,7 @@ arma_inline
eT*
Cube<eT>::slice_colptr(const uword uslice, const uword col)
{
return const_cast<eT*>( &mem[ uslice*n_elem_slice + col*n_rows] );
return access::rwp( mem + (uslice*n_elem_slice + col*n_rows) );
}
@@ -3920,7 +3935,7 @@ arma_inline
const eT*
Cube<eT>::slice_colptr(const uword uslice, const uword col) const
{
return &mem[ uslice*n_elem_slice + col*n_rows ];
return mem + (uslice*n_elem_slice + col*n_rows);
}
@@ -4197,12 +4212,12 @@ Cube<eT>::clamp(const eT min_val, const eT max_val)
if(is_cx<eT>::no)
{
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Cube::clamp(): min_val must be less than max_val" );
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "Cube::clamp(): min_val must be less than max_val" );
}
else
{
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Cube::clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "Cube::clamp(): imag(min_val) must be less than imag(max_val)" );
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "Cube::clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "Cube::clamp(): imag(min_val) must be less than imag(max_val)" );
}
arrayops::clamp(memptr(), n_elem, min_val, max_val);
@@ -4227,6 +4242,30 @@ Cube<eT>::fill(const eT val)
template<typename eT>
template<typename fill_type>
inline
Cube<eT>&
Cube<eT>::fill(const fill::fill_class<fill_type>&)
{
arma_debug_sigprint();
arma_static_check( (is_same_type<fill_type, fill::fill_eye>::yes), "Cube::fill(): unsupported fill type" );
if(is_same_type<fill_type, fill::fill_zeros>::yes) { (*this).zeros(); }
if(is_same_type<fill_type, fill::fill_ones >::yes) { (*this).ones(); }
if(is_same_type<fill_type, fill::fill_randu>::yes) { (*this).randu(); }
if(is_same_type<fill_type, fill::fill_randn>::yes) { (*this).randn(); }
if(is_same_type<fill_type, fill::fill_nan >::yes) { (*this).fill( priv::Datum_helper::nan <eT>() ); }
if(is_same_type<fill_type, fill::fill_pos_inf>::yes) { (*this).fill( priv::Datum_helper::pos_inf<eT>() ); }
if(is_same_type<fill_type, fill::fill_neg_inf>::yes) { (*this).fill( priv::Datum_helper::neg_inf<eT>() ); }
return *this;
}
template<typename eT>
inline
Cube<eT>&
@@ -5458,18 +5497,13 @@ template<typename eT>
template<uword fixed_n_rows, uword fixed_n_cols, uword fixed_n_slices>
template<typename fill_type>
inline
Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::fixed(const fill::fill_class<fill_type>&)
Cube<eT>::fixed<fixed_n_rows, fixed_n_cols, fixed_n_slices>::fixed(const fill::fill_class<fill_type>& f)
{
arma_debug_sigprint_this(this);
mem_setup();
if(is_same_type<fill_type, fill::fill_zeros>::yes) { Cube<eT>::zeros(); }
if(is_same_type<fill_type, fill::fill_ones >::yes) { Cube<eT>::ones(); }
if(is_same_type<fill_type, fill::fill_randu>::yes) { Cube<eT>::randu(); }
if(is_same_type<fill_type, fill::fill_randn>::yes) { Cube<eT>::randn(); }
arma_static_check( (is_same_type<fill_type, fill::fill_eye>::yes), "Cube::fixed::fixed(): unsupported fill type" );
(*this).fill(f);
}
+3 -2
View File
@@ -28,8 +28,9 @@ struct GenCube
typedef eT elem_type;
typedef typename get_pod_type<elem_type>::result pod_type;
static constexpr bool use_at = false;
static constexpr bool is_simple = (is_same_type<gen_type, gen_ones>::value) || (is_same_type<gen_type, gen_zeros>::value);
static constexpr bool use_at = false;
static constexpr bool is_simple = (is_same_type<gen_type, gen_ones>::value) || (is_same_type<gen_type, gen_zeros>::value);
static constexpr bool has_subview = false;
const uword n_rows;
const uword n_cols;
+2
View File
@@ -35,6 +35,8 @@ struct Gen
static constexpr bool is_col = T1::is_col;
static constexpr bool is_xvec = T1::is_xvec;
static constexpr bool has_subview = false;
const uword n_rows;
const uword n_cols;
@@ -28,6 +28,8 @@ struct GlueCube : public BaseCube< typename T1::elem_type, GlueCube<T1, T2, glue
typedef typename T1::elem_type elem_type;
typedef typename get_pod_type<elem_type>::result pod_type;
static constexpr bool has_subview = T1::has_subview || T2::has_subview;
inline GlueCube(const BaseCube<typename T1::elem_type, T1>& in_A, const BaseCube<typename T1::elem_type, T2>& in_B);
inline ~GlueCube();
+2
View File
@@ -50,6 +50,8 @@ struct Glue
typedef typename T1::elem_type elem_type;
typedef typename get_pod_type<elem_type>::result pod_type;
static constexpr bool has_subview = T1::has_subview || T2::has_subview;
inline Glue(const T1& in_A, const T2& in_B);
inline Glue(const T1& in_A, const T2& in_B, const uword in_aux_uword);
inline ~Glue();
+17 -1
View File
@@ -57,6 +57,8 @@ class Mat : public Base< eT, Mat<eT> >
static constexpr bool is_row = false;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = false;
inline ~Mat();
inline Mat();
@@ -452,6 +454,8 @@ class Mat : public Base< eT, Mat<eT> >
arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col);
arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col) const;
inline void push_back(const eT val);
arma_inline const Mat& operator++();
arma_inline void operator++(int);
@@ -819,6 +823,8 @@ class Mat : public Base< eT, Mat<eT> >
inline Mat(const arma_fixed_indicator&, const uword in_n_rows, const uword in_n_cols, const uhword in_vec_state, const eT* in_mem);
template<int vec_mode> inline void vec_push_back(const eT val, const arma_vec_mode_indicator<vec_mode>&);
friend class Cube<eT>;
friend class subview_cube<eT>;
@@ -830,7 +836,7 @@ class Mat : public Base< eT, Mat<eT> >
friend struct op_mean;
friend struct op_max;
friend struct op_min;
public:
@@ -866,6 +872,8 @@ class Mat<eT>::fixed : public Mat<eT>
static constexpr bool is_row = (fixed_n_rows == 1);
static constexpr bool is_xvec = false;
static constexpr bool has_subview = false;
static const uword n_rows; // value provided below the class definition
static const uword n_cols; // value provided below the class definition
static const uword n_elem; // value provided below the class definition
@@ -922,12 +930,20 @@ class Mat<eT>::fixed : public Mat<eT>
arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col);
arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col) const;
inline void push_back(const eT) = delete;
arma_warn_unused arma_inline eT* colptr(const uword in_col);
arma_warn_unused arma_inline const eT* colptr(const uword in_col) const;
arma_warn_unused arma_inline eT* memptr();
arma_warn_unused arma_inline const eT* memptr() const;
arma_inline subview_row<eT> row(const uword row_num);
arma_inline const subview_row<eT> row(const uword row_num) const;
arma_inline subview_col<eT> col(const uword col_num);
arma_inline const subview_col<eT> col(const uword col_num) const;
arma_warn_unused arma_inline bool is_vec() const;
inline const Mat<eT>& fill(const eT val);
+358 -107
View File
@@ -49,7 +49,7 @@ Mat<eT>::Mat()
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
}
@@ -255,7 +255,7 @@ Mat<eT>::Mat(const arma_vec_indicator&, const uhword in_vec_state)
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
}
@@ -312,15 +312,10 @@ Mat<eT>::init_cold()
const char* error_message = "Mat::init(): requested size is too large; suggest to enable ARMA_64BIT_WORD";
#endif
arma_conform_check
(
(
( (n_rows > ARMA_MAX_UHWORD) || (n_cols > ARMA_MAX_UHWORD) )
? ( (double(n_rows) * double(n_cols)) > double(ARMA_MAX_UWORD) )
: false
),
error_message
);
if( (n_rows > ARMA_MAX_UHWORD) || (n_cols > ARMA_MAX_UHWORD) )
{
arma_conform_check( ( (double(n_rows) * double(n_cols)) > double(ARMA_MAX_UWORD) ), error_message );
}
if(n_elem <= arma_config::mat_prealloc)
{
@@ -383,17 +378,10 @@ Mat<eT>::init_warm(uword in_n_rows, uword in_n_cols)
const char* error_message_4 = "Mat::init(): requested size is too large; suggest to enable ARMA_64BIT_WORD";
#endif
arma_conform_set_error
(
err_state,
err_msg,
(
( (in_n_rows > ARMA_MAX_UHWORD) || (in_n_cols > ARMA_MAX_UHWORD) )
? ( (double(in_n_rows) * double(in_n_cols)) > double(ARMA_MAX_UWORD) )
: false
),
error_message_4
);
if( (in_n_rows > ARMA_MAX_UHWORD) || (in_n_cols > ARMA_MAX_UHWORD) )
{
arma_conform_set_error( err_state, err_msg, ( (double(in_n_rows) * double(in_n_cols)) > double(ARMA_MAX_UWORD) ), error_message_4 );
}
arma_conform_check(err_state, err_msg);
@@ -468,7 +456,7 @@ Mat<eT>::Mat(const char* text)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -502,7 +490,7 @@ Mat<eT>::Mat(const std::string& text)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -690,7 +678,7 @@ Mat<eT>::Mat(const std::initializer_list<eT>& list)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -722,7 +710,7 @@ Mat<eT>::Mat(const std::initializer_list< std::initializer_list<eT> >& list)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -889,7 +877,7 @@ Mat<eT>::Mat(const Mat<eT>& in_mat, const arma_vec_indicator&, const uhword in_v
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint(arma_str::format("this: %x; in_mat: %x") % this % &in_mat);
@@ -1381,7 +1369,23 @@ Mat<eT>::Mat(eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols, const
{
init_cold();
arrayops::copy( memptr(), aux_mem, n_elem );
if(aux_mem == nullptr)
{
arrayops::fill_zeros(memptr(), n_elem);
}
else
{
arrayops::copy( memptr(), aux_mem, n_elem );
}
}
else
if(aux_mem == nullptr)
{
access::rw(mem_state) = 0;
init_cold();
arrayops::fill_zeros(memptr(), n_elem);
}
}
@@ -1404,7 +1408,14 @@ Mat<eT>::Mat(const eT* aux_mem, const uword aux_n_rows, const uword aux_n_cols)
init_cold();
arrayops::copy( memptr(), aux_mem, n_elem );
if(aux_mem == nullptr)
{
arrayops::fill_zeros(memptr(), n_elem);
}
else
{
arrayops::copy( memptr(), aux_mem, n_elem );
}
}
@@ -1524,7 +1535,7 @@ Mat<eT>::Mat(const BaseCube<eT,T1>& X, const arma_vec_indicator&, const uhword i
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -1543,7 +1554,7 @@ Mat<eT>::Mat(const BaseCube<eT,T1>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -1990,7 +2001,7 @@ Mat<eT>::Mat(const Base<typename Mat<eT>::pod_type,T1>& A, const Base<typename M
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2010,7 +2021,7 @@ Mat<eT>::Mat(const Base<typename Mat<eT>::pod_type,T1>& A, const Base<typename M
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2055,7 +2066,7 @@ Mat<eT>::Mat(const subview<eT>& X, const arma_vec_indicator&, const uhword in_ve
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2278,7 +2289,7 @@ Mat<eT>::Mat(const subview_cube<eT>& x, const arma_vec_indicator&, const uhword
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2297,7 +2308,7 @@ Mat<eT>::Mat(const subview_cube<eT>& x)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2407,7 +2418,7 @@ Mat<eT>::Mat(const diagview<eT>& X, const arma_vec_indicator&, const uhword in_v
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2552,11 +2563,11 @@ Mat<eT>::Mat(const subview_elem1<eT,T1>& X, const arma_vec_indicator&, const uhw
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
(*this).operator=(X);
subview_elem1<eT,T1>::extract_noalias(*this, X);
}
@@ -2571,11 +2582,11 @@ Mat<eT>::Mat(const subview_elem1<eT,T1>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
(*this).operator=(X);
subview_elem1<eT,T1>::extract_noalias(*this, X);
}
@@ -2603,9 +2614,9 @@ Mat<eT>::operator+=(const subview_elem1<eT,T1>& X)
{
arma_debug_sigprint();
subview_elem1<eT,T1>::plus_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator+=(tmp);
}
@@ -2618,9 +2629,9 @@ Mat<eT>::operator-=(const subview_elem1<eT,T1>& X)
{
arma_debug_sigprint();
subview_elem1<eT,T1>::minus_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator-=(tmp);
}
@@ -2633,9 +2644,9 @@ Mat<eT>::operator*=(const subview_elem1<eT,T1>& X)
{
arma_debug_sigprint();
glue_times::apply_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator*=(tmp);
}
@@ -2648,9 +2659,9 @@ Mat<eT>::operator%=(const subview_elem1<eT,T1>& X)
{
arma_debug_sigprint();
subview_elem1<eT,T1>::schur_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator%=(tmp);
}
@@ -2663,9 +2674,9 @@ Mat<eT>::operator/=(const subview_elem1<eT,T1>& X)
{
arma_debug_sigprint();
subview_elem1<eT,T1>::div_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator/=(tmp);
}
@@ -2680,11 +2691,11 @@ Mat<eT>::Mat(const subview_elem2<eT,T1,T2>& X, const arma_vec_indicator&, const
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
(*this).operator=(X);
subview_elem2<eT,T1,T2>::extract_noalias(*this, X);
}
@@ -2699,11 +2710,11 @@ Mat<eT>::Mat(const subview_elem2<eT,T1,T2>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
(*this).operator=(X);
subview_elem2<eT,T1,T2>::extract_noalias(*this, X);
}
@@ -2731,9 +2742,9 @@ Mat<eT>::operator+=(const subview_elem2<eT,T1,T2>& X)
{
arma_debug_sigprint();
subview_elem2<eT,T1,T2>::plus_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator+=(tmp);
}
@@ -2746,9 +2757,9 @@ Mat<eT>::operator-=(const subview_elem2<eT,T1,T2>& X)
{
arma_debug_sigprint();
subview_elem2<eT,T1,T2>::minus_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator-=(tmp);
}
@@ -2761,9 +2772,9 @@ Mat<eT>::operator*=(const subview_elem2<eT,T1,T2>& X)
{
arma_debug_sigprint();
glue_times::apply_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator*=(tmp);
}
@@ -2776,9 +2787,9 @@ Mat<eT>::operator%=(const subview_elem2<eT,T1,T2>& X)
{
arma_debug_sigprint();
subview_elem2<eT,T1,T2>::schur_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator%=(tmp);
}
@@ -2791,9 +2802,9 @@ Mat<eT>::operator/=(const subview_elem2<eT,T1,T2>& X)
{
arma_debug_sigprint();
subview_elem2<eT,T1,T2>::div_inplace(*this, X);
const Mat<eT> tmp(X);
return *this;
return (*this).operator/=(tmp);
}
@@ -2808,7 +2819,7 @@ Mat<eT>::Mat(const SpBase<eT, T1>& m, const arma_vec_indicator&, const uhword in
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2827,7 +2838,7 @@ Mat<eT>::Mat(const SpBase<eT, T1>& m)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -2888,6 +2899,8 @@ Mat<eT>::operator+=(const SpBase<eT, T1>& m)
arma_conform_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "addition");
if(p.get_n_nonzero() == 0) { return *this; }
typename SpProxy<T1>::const_iterator_type it = p.begin();
typename SpProxy<T1>::const_iterator_type it_end = p.end();
@@ -2910,6 +2923,8 @@ Mat<eT>::operator-=(const SpBase<eT, T1>& m)
arma_conform_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "subtraction");
if(p.get_n_nonzero() == 0) { return *this; }
typename SpProxy<T1>::const_iterator_type it = p.begin();
typename SpProxy<T1>::const_iterator_type it_end = p.end();
@@ -2928,9 +2943,9 @@ Mat<eT>::operator*=(const SpBase<eT, T1>& m)
{
arma_debug_sigprint();
Mat<eT> z = (*this) * m.get_ref();
Mat<eT> tmp = (*this) * m.get_ref();
steal_mem(z);
steal_mem(tmp);
return *this;
}
@@ -3011,7 +3026,7 @@ Mat<eT>::Mat(const SpSubview<eT>& X, const arma_vec_indicator&, const uhword in_
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -3029,7 +3044,7 @@ Mat<eT>::Mat(const SpSubview<eT>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -3212,7 +3227,7 @@ Mat<eT>::Mat(const spdiagview<eT>& X, const arma_vec_indicator&, const uhword in
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -4988,8 +5003,8 @@ Mat<eT>::insert_rows(const uword row_num, const Base<eT,T1>& X)
{
arma_debug_sigprint();
const unwrap<T1> tmp(X.get_ref());
const Mat<eT>& C = tmp.M;
const plain_unwrap<T1> tmp(X.get_ref());
const Mat<eT>& C = tmp.M;
const uword C_n_rows = C.n_rows;
const uword C_n_cols = C.n_cols;
@@ -5064,8 +5079,8 @@ Mat<eT>::insert_cols(const uword col_num, const Base<eT,T1>& X)
{
arma_debug_sigprint();
const unwrap<T1> tmp(X.get_ref());
const Mat<eT>& C = tmp.M;
const plain_unwrap<T1> tmp(X.get_ref());
const Mat<eT>& C = tmp.M;
const uword C_n_rows = C.n_rows;
const uword C_n_cols = C.n_cols;
@@ -5140,7 +5155,7 @@ Mat<eT>::Mat(const Gen<T1, gen_type>& X, const arma_vec_indicator&, const uhword
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5290,7 +5305,7 @@ Mat<eT>::Mat(const Op<T1, op_type>& X, const arma_vec_indicator&, const uhword i
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5312,7 +5327,7 @@ Mat<eT>::Mat(const Op<T1, op_type>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5441,7 +5456,7 @@ Mat<eT>::Mat(const eOp<T1, eop_type>& X, const arma_vec_indicator&, const uhword
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5669,7 +5684,7 @@ Mat<eT>::Mat(const mtOp<eT, T1, op_type>& X, const arma_vec_indicator&, const uh
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5688,7 +5703,7 @@ Mat<eT>::Mat(const mtOp<eT, T1, op_type>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5797,7 +5812,7 @@ Mat<eT>::Mat(const CubeToMatOp<T1, op_type>& X, const arma_vec_indicator&, const
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5818,7 +5833,7 @@ Mat<eT>::Mat(const CubeToMatOp<T1, op_type>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5941,7 +5956,7 @@ Mat<eT>::Mat(const SpToDOp<T1, op_type>& X, const arma_vec_indicator&, const uhw
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -5962,7 +5977,7 @@ Mat<eT>::Mat(const SpToDOp<T1, op_type>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6091,7 +6106,7 @@ Mat<eT>::Mat(const mtSpReduceOp<eT, T1, op_type>& X, const arma_vec_indicator&,
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6110,7 +6125,7 @@ Mat<eT>::Mat(const mtSpReduceOp<eT, T1, op_type>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6219,7 +6234,7 @@ Mat<eT>::Mat(const Glue<T1, T2, glue_type>& X, const arma_vec_indicator&, const
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6242,7 +6257,7 @@ Mat<eT>::Mat(const Glue<T1, T2, glue_type>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6408,7 +6423,7 @@ Mat<eT>::Mat(const eGlue<T1, T2, eglue_type>& X, const arma_vec_indicator&, cons
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6615,7 +6630,7 @@ Mat<eT>::Mat(const mtGlue<eT, T1, T2, glue_type>& X, const arma_vec_indicator&,
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6634,7 +6649,7 @@ Mat<eT>::Mat(const mtGlue<eT, T1, T2, glue_type>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6745,7 +6760,7 @@ Mat<eT>::Mat(const SpToDGlue<T1, T2, glue_type>& X, const arma_vec_indicator&, c
, n_alloc(0)
, vec_state(in_vec_state)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -6767,7 +6782,7 @@ Mat<eT>::Mat(const SpToDGlue<T1, T2, glue_type>& X)
, n_alloc(0)
, vec_state(0)
, mem_state(0)
, mem()
, mem(nullptr)
{
arma_debug_sigprint_this(this);
@@ -7045,6 +7060,31 @@ Mat<eT>::at(const uword in_row, const uword in_col) const
template<typename eT>
inline
void
Mat<eT>::push_back(const eT val)
{
arma_debug_sigprint();
if(mem_state != 0)
{
arma_conform_check(true, "Mat::push_back(): unsupported operation as auxiliary memory is in use");
return;
}
const uword t_n_rows = n_rows;
const uword t_n_cols = n_cols;
if( (vec_state == 1) || (t_n_cols == 1) || ((t_n_cols == 0) && (t_n_rows == 0)) ) { (*this).vec_push_back(val, arma_colvec_indicator()); return; }
if( (vec_state == 2) || (t_n_rows == 1) ) { (*this).vec_push_back(val, arma_rowvec_indicator()); return; }
arma_conform_check(true, "Mat::push_back(): column or row vector layout required");
}
//! prefix ++
template<typename eT>
arma_inline
@@ -7487,7 +7527,7 @@ arma_inline
eT*
Mat<eT>::colptr(const uword in_col)
{
return & access::rw(mem[in_col*n_rows]);
return access::rwp( mem + (in_col*n_rows) );
}
@@ -7498,7 +7538,7 @@ arma_inline
const eT*
Mat<eT>::colptr(const uword in_col) const
{
return & mem[in_col*n_rows];
return mem + (in_col*n_rows);
}
@@ -7580,10 +7620,40 @@ Mat<eT>::resize(const uword new_n_elem)
{
arma_debug_sigprint();
const uword new_n_rows = (vec_state == 2) ? uword(1 ) : uword(new_n_elem);
const uword new_n_cols = (vec_state == 2) ? uword(new_n_elem) : uword(1 );
const bool reuse_mem =
( is_vec() && (mem_state == 0) )
&&
(
( (new_n_elem <= arma_config::mat_prealloc) && (n_elem <= arma_config::mat_prealloc) && ( n_elem > 0 ) )
|| ( (new_n_elem > arma_config::mat_prealloc) && (n_elem > arma_config::mat_prealloc) && (new_n_elem <= n_alloc) )
);
return (*this).resize(new_n_rows, new_n_cols);
if(reuse_mem)
{
arma_debug_print("Mat::resize(): reusing memory");
if(new_n_elem > n_elem)
{
arma_debug_print("Mat::resize(): zeroing memory");
eT* t_mem = (*this).memptr(); // the (n_elem > 0) check above ensures that (*this).memptr() is a valid pointer
for(uword ii = n_elem; ii < new_n_elem; ++ii) { t_mem[ii] = eT(0); }
}
access::rw(n_rows) = (vec_state == 2) ? uword(1 ) : uword(new_n_elem);
access::rw(n_cols) = (vec_state == 2) ? uword(new_n_elem) : uword(1 );
access::rw(n_elem) = new_n_elem;
}
else
{
const uword new_n_rows = (vec_state == 2) ? uword(1 ) : uword(new_n_elem);
const uword new_n_cols = (vec_state == 2) ? uword(new_n_elem) : uword(1 );
(*this).resize(new_n_rows, new_n_cols);
}
return (*this);
}
@@ -7863,12 +7933,12 @@ Mat<eT>::clamp(const eT min_val, const eT max_val)
if(is_cx<eT>::no)
{
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Mat::clamp(): min_val must be less than max_val" );
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "Mat::clamp(): min_val must be less than max_val" );
}
else
{
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "Mat::clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "Mat::clamp(): imag(min_val) must be less than imag(max_val)" );
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "Mat::clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "Mat::clamp(): imag(min_val) must be less than imag(max_val)" );
}
arrayops::clamp(memptr(), n_elem, min_val, max_val);
@@ -7908,6 +7978,10 @@ Mat<eT>::fill(const fill::fill_class<fill_type>&)
if(is_same_type<fill_type, fill::fill_randu>::yes) { (*this).randu(); }
if(is_same_type<fill_type, fill::fill_randn>::yes) { (*this).randn(); }
if(is_same_type<fill_type, fill::fill_nan >::yes) { (*this).fill( priv::Datum_helper::nan <eT>() ); }
if(is_same_type<fill_type, fill::fill_pos_inf>::yes) { (*this).fill( priv::Datum_helper::pos_inf<eT>() ); }
if(is_same_type<fill_type, fill::fill_neg_inf>::yes) { (*this).fill( priv::Datum_helper::neg_inf<eT>() ); }
return *this;
}
@@ -10021,6 +10095,119 @@ Mat<eT>::back() const
template<typename eT>
template<int vec_mode>
inline
void
Mat<eT>::vec_push_back(const eT val, const arma_vec_mode_indicator<vec_mode>&)
{
arma_debug_sigprint( arma_str::format("n_elem: %u; n_alloc: %u") % n_elem % n_alloc );
// vec_mode = 1 means col vector layout
// vec_mode = 2 means row vector layout
const uword old_n_elem = n_elem;
const uword new_n_elem = old_n_elem + 1;
if(old_n_elem <= arma_config::mat_prealloc)
{
if(old_n_elem == 0)
{
mem_local[0] = val;
access::rw(mem ) = mem_local;
access::rw(n_rows) = 1;
access::rw(n_cols) = 1;
access::rw(n_elem) = 1;
}
else
if(old_n_elem < arma_config::mat_prealloc)
{
// condition: (old_n_elem >= 1) && (old_n_elem < arma_config::mat_prealloc)
mem_local[old_n_elem] = val;
if(vec_mode == 1) { access::rw(n_rows) = new_n_elem; }
if(vec_mode == 2) { access::rw(n_cols) = new_n_elem; }
access::rw(n_elem) = new_n_elem;
}
else
{
// condition: old_n_elem == arma_config::mat_prealloc
const uword new_n_alloc = (std::max)(uword(64), uword(arma_config::mat_prealloc + arma_config::mat_prealloc/2));
arma_debug_print( arma_str::format("acquiring new memory; new_n_alloc: %u") % new_n_alloc );
eT* new_mem_ptr = memory::acquire<eT>(new_n_alloc);
if(new_mem_ptr == nullptr) { return; }
arma_debug_print("copying memory");
arrayops::copy(new_mem_ptr, mem_local, arma_config::mat_prealloc);
new_mem_ptr[old_n_elem] = val;
access::rw(mem) = new_mem_ptr;
if(vec_mode == 1) { access::rw(n_rows) = new_n_elem; }
if(vec_mode == 2) { access::rw(n_cols) = new_n_elem; }
access::rw(n_elem) = new_n_elem;
access::rw(n_alloc) = new_n_alloc;
}
}
else
{
// condition: old_n_elem > arma_config::mat_prealloc
if(n_alloc >= new_n_elem)
{
access::rw(mem[old_n_elem]) = val;
if(vec_mode == 1) { access::rw(n_rows) = new_n_elem; }
if(vec_mode == 2) { access::rw(n_cols) = new_n_elem; }
access::rw(n_elem) = new_n_elem;
}
else
{
// condition: n_alloc < new_n_elem
const uword new_n_alloc = (std::max)(uword(256), uword(n_alloc + n_alloc/2));
arma_debug_print( arma_str::format("acquiring new memory; new_n_alloc: %u") % new_n_alloc );
const eT* old_mem_ptr = mem;
eT* new_mem_ptr = memory::acquire<eT>(new_n_alloc);
if(new_mem_ptr == nullptr) { return; }
arma_debug_print("copying memory");
arrayops::copy(new_mem_ptr, old_mem_ptr, n_elem);
new_mem_ptr[old_n_elem] = val;
access::rw(mem) = new_mem_ptr;
if(vec_mode == 1) { access::rw(n_rows) = new_n_elem; }
if(vec_mode == 2) { access::rw(n_cols) = new_n_elem; }
access::rw(n_elem ) = new_n_elem;
access::rw(n_alloc) = new_n_alloc;
arma_debug_print("releasing old memory");
memory::release(old_mem_ptr);
}
}
}
template<typename eT>
template<uword fixed_n_rows, uword fixed_n_cols>
arma_inline
@@ -10081,6 +10268,10 @@ Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::fixed(const fill::fill_class<fill_ty
if(is_same_type<fill_type, fill::fill_eye >::yes) { Mat<eT>::eye(); }
if(is_same_type<fill_type, fill::fill_randu>::yes) { Mat<eT>::randu(); }
if(is_same_type<fill_type, fill::fill_randn>::yes) { Mat<eT>::randn(); }
if(is_same_type<fill_type, fill::fill_nan >::yes) { (*this).fill( priv::Datum_helper::nan <eT>() ); }
if(is_same_type<fill_type, fill::fill_pos_inf>::yes) { (*this).fill( priv::Datum_helper::pos_inf<eT>() ); }
if(is_same_type<fill_type, fill::fill_neg_inf>::yes) { (*this).fill( priv::Datum_helper::neg_inf<eT>() ); }
}
@@ -10515,7 +10706,7 @@ Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::colptr(const uword in_col)
{
eT* mem_actual = (use_extra) ? mem_local_extra : mem_local;
return & access::rw(mem_actual[in_col*fixed_n_rows]);
return access::rwp( mem_actual + (in_col*fixed_n_rows) );
}
@@ -10528,7 +10719,7 @@ Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::colptr(const uword in_col) const
{
const eT* mem_actual = (use_extra) ? mem_local_extra : mem_local;
return & mem_actual[in_col*fixed_n_rows];
return mem_actual + (in_col*fixed_n_rows);
}
@@ -10555,6 +10746,66 @@ Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::memptr() const
template<typename eT>
template<uword fixed_n_rows, uword fixed_n_cols>
arma_inline
subview_row<eT>
Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::row(const uword row_num)
{
arma_debug_sigprint();
arma_conform_check_bounds( row_num >= fixed_n_rows, "Mat::row(): index out of bounds" );
return subview_row<eT>(*this, row_num);
}
template<typename eT>
template<uword fixed_n_rows, uword fixed_n_cols>
arma_inline
const subview_row<eT>
Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::row(const uword row_num) const
{
arma_debug_sigprint();
arma_conform_check_bounds( row_num >= fixed_n_rows, "Mat::row(): index out of bounds" );
return subview_row<eT>(*this, row_num);
}
template<typename eT>
template<uword fixed_n_rows, uword fixed_n_cols>
arma_inline
subview_col<eT>
Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::col(const uword col_num)
{
arma_debug_sigprint();
arma_conform_check_bounds( col_num >= fixed_n_cols, "Mat::col(): index out of bounds" );
return subview_col<eT>(*this, col_num);
}
template<typename eT>
template<uword fixed_n_rows, uword fixed_n_cols>
arma_inline
const subview_col<eT>
Mat<eT>::fixed<fixed_n_rows, fixed_n_cols>::col(const uword col_num) const
{
arma_debug_sigprint();
arma_conform_check_bounds( col_num >= fixed_n_cols, "Mat::col(): index out of bounds" );
return subview_col<eT>(*this, col_num);
}
template<typename eT>
template<uword fixed_n_rows, uword fixed_n_cols>
arma_inline
@@ -10768,8 +11019,8 @@ Mat_aux::set_real(Mat<eT>& out, const Base<eT,T1>& X)
{
arma_debug_sigprint();
const unwrap<T1> tmp(X.get_ref());
const Mat<eT>& A = tmp.M;
const plain_unwrap<T1> tmp(X.get_ref());
const Mat<eT>& A = tmp.M;
arma_conform_assert_same_size( out, A, "Mat::set_real()" );
+2
View File
@@ -26,6 +26,8 @@ struct OpCube : public BaseCube< typename T1::elem_type, OpCube<T1, op_type> >
typedef typename T1::elem_type elem_type;
typedef typename get_pod_type<elem_type>::result pod_type;
static constexpr bool has_subview = T1::has_subview;
inline explicit OpCube(const BaseCube<typename T1::elem_type, T1>& in_m);
inline OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const elem_type in_aux);
inline OpCube(const BaseCube<typename T1::elem_type, T1>& in_m, const elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c);
+2
View File
@@ -50,6 +50,8 @@ struct Op
typedef typename T1::elem_type elem_type;
typedef typename get_pod_type<elem_type>::result pod_type;
static constexpr bool has_subview = T1::has_subview;
inline explicit Op(const T1& in_m);
inline Op(const T1& in_m, const elem_type in_aux);
inline Op(const T1& in_m, const elem_type in_aux, const uword in_aux_uword_a, const uword in_aux_uword_b);
+7 -7
View File
@@ -1523,7 +1523,7 @@ struct Proxy_xtrans_default< Op<T1, op_htrans> >
static constexpr bool is_col = false;
static constexpr bool is_xvec = false;
const unwrap<T1> U;
const plain_unwrap<T1> U;
const xtrans_mat<elem_type,true> Q;
inline explicit Proxy_xtrans_default(const Op<T1, op_htrans>& A)
@@ -1537,7 +1537,7 @@ struct Proxy_xtrans_default< Op<T1, op_htrans> >
arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
template<typename eT2>
arma_inline bool is_alias(const Mat<eT2>& X) const { return void_ptr(&(U.M)) == void_ptr(&X); }
arma_inline bool is_alias(const Mat<eT2>& X) const { return U.is_alias(X); }
template<typename eT2>
arma_inline bool has_overlap(const subview<eT2>& X) const { return is_alias(X.m); }
@@ -1564,7 +1564,7 @@ struct Proxy_xtrans_default< Op<T1, op_strans> >
static constexpr bool is_col = false;
static constexpr bool is_xvec = false;
const unwrap<T1> U;
const plain_unwrap<T1> U;
const xtrans_mat<elem_type,false> Q;
inline explicit Proxy_xtrans_default(const Op<T1, op_strans>& A)
@@ -1578,7 +1578,7 @@ struct Proxy_xtrans_default< Op<T1, op_strans> >
arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
template<typename eT2>
arma_inline bool is_alias(const Mat<eT2>& X) const { return void_ptr(&(U.M)) == void_ptr(&X); }
arma_inline bool is_alias(const Mat<eT2>& X) const { return U.is_alias(X); }
template<typename eT2>
arma_inline bool has_overlap(const subview<eT2>& X) const { return is_alias(X.m); }
@@ -2419,8 +2419,8 @@ struct Proxy_vectorise_col_mat< Op<T1, op_vectorise_col> >
static constexpr bool is_col = true;
static constexpr bool is_xvec = false;
const unwrap<T1> U;
const Mat<elem_type> Q;
const plain_unwrap<T1> U;
const Mat<elem_type> Q;
inline explicit Proxy_vectorise_col_mat(const Op<T1, op_vectorise_col>& A)
: U(A.m)
@@ -2441,7 +2441,7 @@ struct Proxy_vectorise_col_mat< Op<T1, op_vectorise_col> >
arma_inline aligned_ea_type get_aligned_ea() const { return Q; }
template<typename eT2>
arma_inline bool is_alias(const Mat<eT2>& X) const { return ( void_ptr(&X) == void_ptr(&(U.M)) ); }
arma_inline bool is_alias(const Mat<eT2>& X) const { return U.is_alias(X); }
template<typename eT2>
arma_inline bool has_overlap(const subview<eT2>& X) const { return is_alias(X.m); }
+7 -3
View File
@@ -33,6 +33,8 @@ class Row : public Mat<eT>
static constexpr bool is_row = true;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = false;
inline Row();
inline Row(const Row<eT>& X);
@@ -67,9 +69,6 @@ class Row : public Mat<eT>
inline Row(Row&& m);
inline Row& operator=(Row&& m);
// inline Row(Mat<eT>&& m);
// inline Row& operator=(Mat<eT>&& m);
inline Row& operator=(const eT val);
inline Row& operator=(const Row& X);
@@ -153,6 +152,7 @@ class Row : public Mat<eT>
arma_warn_unused arma_inline eT& at(const uword in_row, const uword in_col);
arma_warn_unused arma_inline const eT& at(const uword in_row, const uword in_col) const;
inline void push_back(const eT val);
inline constexpr bool is_vec() const { return true; }
inline constexpr bool is_rowvec() const { return true; }
@@ -213,6 +213,8 @@ class Row<eT>::fixed : public Row<eT>
static constexpr bool is_row = true;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = false;
static const uword n_rows; // value provided below the class definition
static const uword n_cols; // value provided below the class definition
static const uword n_elem; // value provided below the class definition
@@ -268,6 +270,8 @@ class Row<eT>::fixed : public Row<eT>
arma_warn_unused arma_inline eT& operator() (const uword in_row, const uword in_col);
arma_warn_unused arma_inline const eT& operator() (const uword in_row, const uword in_col) const;
inline void push_back(const eT) = delete;
arma_warn_unused arma_inline eT* memptr();
arma_warn_unused arma_inline const eT* memptr() const;
+23 -58
View File
@@ -431,64 +431,6 @@ Row<eT>::operator=(Row<eT>&& X)
// template<typename eT>
// inline
// Row<eT>::Row(Mat<eT>&& X)
// : Mat<eT>(arma_vec_indicator(), 2)
// {
// arma_debug_sigprint(arma_str::format("this: %x; X: %x") % this % &X);
//
// if(X.n_rows != 1) { const Mat<eT>& XX = X; Mat<eT>::operator=(XX); return; }
//
// access::rw(Mat<eT>::n_rows) = 1;
// access::rw(Mat<eT>::n_cols) = X.n_cols;
// access::rw(Mat<eT>::n_elem) = X.n_elem;
// access::rw(Mat<eT>::n_alloc) = X.n_alloc;
//
// if( (X.n_alloc > arma_config::mat_prealloc) || (X.mem_state == 1) || (X.mem_state == 2) )
// {
// access::rw(Mat<eT>::mem_state) = X.mem_state;
// access::rw(Mat<eT>::mem) = X.mem;
//
// access::rw(X.n_cols) = 0;
// access::rw(X.n_elem) = 0;
// access::rw(X.n_alloc) = 0;
// access::rw(X.mem_state) = 0;
// access::rw(X.mem) = nullptr;
// }
// else // condition: (X.n_alloc <= arma_config::mat_prealloc) || (X.mem_state == 0) || (X.mem_state == 3)
// {
// (*this).init_cold();
//
// arrayops::copy( (*this).memptr(), X.mem, X.n_elem );
//
// if( (X.mem_state == 0) && (X.n_alloc <= arma_config::mat_prealloc) )
// {
// access::rw(X.n_cols) = 0;
// access::rw(X.n_elem) = 0;
// access::rw(X.mem) = nullptr;
// }
// }
// }
//
//
//
// template<typename eT>
// inline
// Row<eT>&
// Row<eT>::operator=(Mat<eT>&& X)
// {
// arma_debug_sigprint(arma_str::format("this: %x; X: %x") % this % &X);
//
// if(X.n_rows != 1) { const Mat<eT>& XX = X; Mat<eT>::operator=(XX); return *this; }
//
// (*this).steal_mem(X, true);
//
// return *this;
// }
template<typename eT>
inline
Row<eT>&
@@ -1208,6 +1150,25 @@ Row<eT>::at(const uword, const uword in_col) const
template<typename eT>
inline
void
Row<eT>::push_back(const eT val)
{
arma_debug_sigprint();
if(Mat<eT>::mem_state != 0)
{
arma_conform_check(true, "Row::push_back(): unsupported operation as auxiliary memory is in use");
return;
}
Mat<eT>::vec_push_back(val, arma_rowvec_indicator());
}
template<typename eT>
inline
typename Row<eT>::row_iterator
@@ -1351,6 +1312,10 @@ Row<eT>::fixed<fixed_n_elem>::fixed(const fill::fill_class<fill_type>&)
if(is_same_type<fill_type, fill::fill_eye >::yes) { Mat<eT>::eye(); }
if(is_same_type<fill_type, fill::fill_randu>::yes) { Mat<eT>::randu(); }
if(is_same_type<fill_type, fill::fill_randn>::yes) { Mat<eT>::randn(); }
if(is_same_type<fill_type, fill::fill_nan >::yes) { (*this).fill( priv::Datum_helper::nan <eT>() ); }
if(is_same_type<fill_type, fill::fill_pos_inf>::yes) { (*this).fill( priv::Datum_helper::pos_inf<eT>() ); }
if(is_same_type<fill_type, fill::fill_neg_inf>::yes) { (*this).fill( priv::Datum_helper::neg_inf<eT>() ); }
}
-2
View File
@@ -52,8 +52,6 @@ struct SpBase
{
arma_inline const derived& get_ref() const;
arma_inline bool is_alias(const SpMat<elem_type>& X) const;
arma_warn_unused inline const SpOp<derived,spop_htrans> t() const; //!< Hermitian transpose
arma_warn_unused inline const SpOp<derived,spop_htrans> ht() const; //!< Hermitian transpose
arma_warn_unused inline const SpOp<derived,spop_strans> st() const; //!< simple transpose
+4 -14
View File
@@ -31,16 +31,6 @@ SpBase<elem_type,derived>::get_ref() const
template<typename elem_type, typename derived>
arma_inline
bool
SpBase<elem_type,derived>::is_alias(const SpMat<elem_type>& X) const
{
return (*this).get_ref().is_alias(X);
}
template<typename elem_type, typename derived>
inline
const SpOp<derived, spop_htrans>
@@ -527,7 +517,7 @@ SpBase<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::resul
typedef typename get_pod_type<elem_type>::result T;
arma_conform_check( (tol < T(0)), "is_zero(): parameter 'tol' must be >= 0" );
arma_conform_check( ((tol >= T(0)) == false), "is_zero(): parameter 'tol' must be >= 0" );
const SpProxy<derived> P( (*this).get_ref() );
@@ -554,8 +544,8 @@ SpBase<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::resul
const T val_real = access::tmp_real(val);
const T val_imag = access::tmp_imag(val);
if(eop_aux::arma_abs(val_real) > tol) { return false; }
if(eop_aux::arma_abs(val_imag) > tol) { return false; }
if( (eop_aux::arma_abs(val_real) <= tol) == false ) { return false; }
if( (eop_aux::arma_abs(val_imag) <= tol) == false ) { return false; }
++it;
}
@@ -564,7 +554,7 @@ SpBase<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::resul
{
while(it != it_end)
{
if(eop_aux::arma_abs(*it) > tol) { return false; }
if( (eop_aux::arma_abs(*it) <= tol) == false ) { return false; }
++it;
}
+4 -1
View File
@@ -31,11 +31,14 @@ struct SpGlue : public SpBase< typename T1::elem_type, SpGlue<T1, T2, spglue_typ
static constexpr bool is_col = spglue_type::template traits<T1,T2>::is_col;
static constexpr bool is_xvec = spglue_type::template traits<T1,T2>::is_xvec;
static constexpr bool has_subview = T1::has_subview || T2::has_subview;
inline SpGlue(const T1& in_A, const T2& in_B);
inline SpGlue(const T1& in_A, const T2& in_B, const elem_type in_aux);
inline ~SpGlue();
arma_inline bool is_alias(const SpMat<elem_type>& X) const;
template<typename eT2>
arma_inline bool is_alias(const SpMat<eT2>& X) const;
const T1& A; //!< first operand; must be derived from SpBase
const T2& B; //!< second operand; must be derived from SpBase
+2 -1
View File
@@ -54,9 +54,10 @@ SpGlue<T1,T2,spglue_type>::~SpGlue()
template<typename T1, typename T2, typename spglue_type>
template<typename eT2>
arma_inline
bool
SpGlue<T1,T2,spglue_type>::is_alias(const SpMat<typename T1::elem_type>& X) const
SpGlue<T1,T2,spglue_type>::is_alias(const SpMat<eT2>& X) const
{
return (A.is_alias(X) || B.is_alias(X));
}
+4 -1
View File
@@ -33,6 +33,8 @@ class SpMat : public SpBase< eT, SpMat<eT> >
static constexpr bool is_col = false;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = false;
const uword n_rows; //!< number of rows (read-only)
const uword n_cols; //!< number of columns (read-only)
const uword n_elem; //!< number of elements (read-only)
@@ -647,7 +649,8 @@ class SpMat : public SpBase< eT, SpMat<eT> >
template<typename eT2, typename T1, typename Functor> inline void init_xform_mt(const SpBase<eT2,T1>& x, const Functor& func);
//! don't use this unless you're writing internal Armadillo code
arma_inline bool is_alias(const SpMat<eT>& X) const;
template<typename eT2>
arma_inline bool is_alias(const SpMat<eT2>& X) const;
protected:
+145 -86
View File
@@ -688,15 +688,22 @@ SpMat<eT>::operator=(const SpMat<eT>& x)
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator+=(const SpMat<eT>& x)
SpMat<eT>::operator+=(const SpMat<eT>& X)
{
arma_debug_sigprint();
sync_csc();
SpMat<eT> out = (*this) + x;
steal_mem(out);
if(X.n_nonzero == 0)
{
arma_conform_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "addition");
}
else
{
SpMat<eT> tmp = (*this) + X;
steal_mem(tmp);
}
return *this;
}
@@ -706,15 +713,22 @@ SpMat<eT>::operator+=(const SpMat<eT>& x)
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator-=(const SpMat<eT>& x)
SpMat<eT>::operator-=(const SpMat<eT>& X)
{
arma_debug_sigprint();
sync_csc();
SpMat<eT> out = (*this) - x;
steal_mem(out);
if(X.n_nonzero == 0)
{
arma_conform_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "subtraction");
}
else
{
SpMat<eT> tmp = (*this) - X;
steal_mem(tmp);
}
return *this;
}
@@ -724,15 +738,15 @@ SpMat<eT>::operator-=(const SpMat<eT>& x)
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator*=(const SpMat<eT>& y)
SpMat<eT>::operator*=(const SpMat<eT>& X)
{
arma_debug_sigprint();
sync_csc();
SpMat<eT> z = (*this) * y;
SpMat<eT> tmp = (*this) * X;
steal_mem(z);
steal_mem(tmp);
return *this;
}
@@ -743,15 +757,24 @@ SpMat<eT>::operator*=(const SpMat<eT>& y)
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator%=(const SpMat<eT>& y)
SpMat<eT>::operator%=(const SpMat<eT>& X)
{
arma_debug_sigprint();
sync_csc();
SpMat<eT> z = (*this) % y;
steal_mem(z);
if(X.n_nonzero == 0)
{
arma_conform_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "element-wise multiplication");
(*this).zeros();
}
else
{
SpMat<eT> tmp = (*this) % X;
steal_mem(tmp);
}
return *this;
}
@@ -1338,9 +1361,16 @@ SpMat<eT>::operator+=(const SpSubview<eT>& X)
sync_csc();
SpMat<eT> tmp = (*this) + X;
steal_mem(tmp);
if(X.n_nonzero == 0)
{
arma_conform_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "addition");
}
else
{
SpMat<eT> tmp = (*this) + X;
steal_mem(tmp);
}
return *this;
}
@@ -1356,64 +1386,82 @@ SpMat<eT>::operator-=(const SpSubview<eT>& X)
sync_csc();
SpMat<eT> tmp = (*this) - X;
steal_mem(tmp);
return *this;
}
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator*=(const SpSubview<eT>& y)
{
arma_debug_sigprint();
sync_csc();
SpMat<eT> z = (*this) * y;
steal_mem(z);
return *this;
}
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator%=(const SpSubview<eT>& x)
{
arma_debug_sigprint();
sync_csc();
SpMat<eT> tmp = (*this) % x;
steal_mem(tmp);
return *this;
}
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator/=(const SpSubview<eT>& x)
{
arma_debug_sigprint();
arma_conform_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-wise division");
// There is no pretty way to do this.
for(uword elem = 0; elem < n_elem; elem++)
if(X.n_nonzero == 0)
{
at(elem) /= x(elem);
arma_conform_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "subtraction");
}
else
{
SpMat<eT> tmp = (*this) - X;
steal_mem(tmp);
}
return *this;
}
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator*=(const SpSubview<eT>& X)
{
arma_debug_sigprint();
sync_csc();
SpMat<eT> tmp = (*this) * X;
steal_mem(tmp);
return *this;
}
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator%=(const SpSubview<eT>& X)
{
arma_debug_sigprint();
sync_csc();
if(X.n_nonzero == 0)
{
arma_conform_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "element-wise multiplication");
(*this).zeros();
}
else
{
SpMat<eT> tmp = (*this) % X;
steal_mem(tmp);
}
return *this;
}
template<typename eT>
inline
SpMat<eT>&
SpMat<eT>::operator/=(const SpSubview<eT>& X)
{
arma_debug_sigprint();
// NOTE: use of this function is not advised; it is implemented only for completeness
arma_conform_assert_same_size(n_rows, n_cols, X.n_rows, X.n_cols, "element-wise division");
for(uword c = 0; c < n_cols; ++c)
for(uword r = 0; r < n_rows; ++r)
{
at(r, c) /= X.at(r, c);
}
return *this;
@@ -1507,9 +1555,9 @@ SpMat<eT>::operator*=(const SpSubview_col_list<eT,T1>& X)
sync_csc();
SpMat<eT> z = (*this) * X;
SpMat<eT> tmp = (*this) * X;
steal_mem(z);
steal_mem(tmp);
return *this;
}
@@ -3517,7 +3565,7 @@ SpMat<eT>::is_symmetric(const typename get_pod_type<elem_type>::result tol) cons
if(tol == T(0)) { return (*this).is_symmetric(); }
arma_conform_check( (tol < T(0)), "is_symmetric(): parameter 'tol' must be >= 0" );
arma_conform_check( ((tol >= T(0)) == false), "is_symmetric(): parameter 'tol' must be > 0" );
const SpMat<eT>& A = (*this);
@@ -3527,8 +3575,12 @@ SpMat<eT>::is_symmetric(const typename get_pod_type<elem_type>::result tol) cons
if(norm_A == T(0)) { return true; }
if(arma_isnan(norm_A)) { return false; }
const T norm_A_Ast = as_scalar( arma::max(sum(abs(A - A.st()), 1), 0) );
if(arma_isnan(norm_A_Ast)) { return false; }
return ( (norm_A_Ast / norm_A) <= tol );
}
@@ -3563,7 +3615,7 @@ SpMat<eT>::is_hermitian(const typename get_pod_type<elem_type>::result tol) cons
if(tol == T(0)) { return (*this).is_hermitian(); }
arma_conform_check( (tol < T(0)), "is_hermitian(): parameter 'tol' must be >= 0" );
arma_conform_check( ((tol >= T(0)) == false), "is_hermitian(): parameter 'tol' must be > 0" );
const SpMat<eT>& A = (*this);
@@ -3573,8 +3625,12 @@ SpMat<eT>::is_hermitian(const typename get_pod_type<elem_type>::result tol) cons
if(norm_A == T(0)) { return true; }
if(arma_isnan(norm_A)) { return false; }
const T norm_A_At = as_scalar( arma::max(sum(abs(A - A.t()), 1), 0) );
if(arma_isnan(norm_A_At)) { return false; }
return ( (norm_A_At / norm_A) <= tol );
}
@@ -4156,12 +4212,12 @@ SpMat<eT>::clamp(const eT min_val, const eT max_val)
if(is_cx<eT>::no)
{
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpMat::clamp(): min_val must be less than max_val" );
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "SpMat::clamp(): min_val must be less than max_val" );
}
else
{
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpMat::clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "SpMat::clamp(): imag(min_val) must be less than imag(max_val)" );
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "SpMat::clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "SpMat::clamp(): imag(min_val) must be less than imag(max_val)" );
}
if(n_nonzero == 0) { return *this; }
@@ -4341,7 +4397,7 @@ SpMat<eT>::sprandu(const uword in_rows, const uword in_cols, const double densit
{
arma_debug_sigprint();
arma_conform_check( ( (density < double(0)) || (density > double(1)) ), "sprandu(): density must be in the [0,1] interval" );
arma_conform_check( ( ((density >= double(0)) == false) || ((density <= double(1)) == false) ), "sprandu(): density must be in the [0,1] interval" );
const uword new_n_nonzero = uword(density * double(in_rows) * double(in_cols) + 0.5);
@@ -4418,7 +4474,7 @@ SpMat<eT>::sprandn(const uword in_rows, const uword in_cols, const double densit
{
arma_debug_sigprint();
arma_conform_check( ( (density < double(0)) || (density > double(1)) ), "sprandn(): density must be in the [0,1] interval" );
arma_conform_check( ( ((density >= double(0)) == false) || ((density <= double(1)) == false) ), "sprandn(): density must be in the [0,1] interval" );
const uword new_n_nonzero = uword(density * double(in_rows) * double(in_cols) + 0.5);
@@ -5959,11 +6015,14 @@ SpMat<eT>::init_xform_mt(const SpBase<eT2,T1>& A, const Functor& func)
template<typename eT>
template<typename eT2>
arma_inline
bool
SpMat<eT>::is_alias(const SpMat<eT>& X) const
SpMat<eT>::is_alias(const SpMat<eT2>& X) const
{
return (&X == this);
arma_debug_sigprint();
return (is_same_type<eT,eT2>::yes) && (void_ptr(this) == void_ptr(&X));
}
+4 -1
View File
@@ -31,12 +31,15 @@ struct SpOp : public SpBase< typename T1::elem_type, SpOp<T1, op_type> >
static constexpr bool is_col = op_type::template traits<T1>::is_col;
static constexpr bool is_xvec = op_type::template traits<T1>::is_xvec;
static constexpr bool has_subview = T1::has_subview;
inline explicit SpOp(const T1& in_m);
inline SpOp(const T1& in_m, const elem_type in_aux);
inline SpOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
inline ~SpOp();
arma_inline bool is_alias(const SpMat<elem_type>& X) const;
template<typename eT2>
arma_inline bool is_alias(const SpMat<eT2>& X) const;
const T1& m; //!< the operand; must be derived from SpBase
elem_type aux; //!< auxiliary data, using the element type as used by T1
+2 -1
View File
@@ -64,9 +64,10 @@ SpOp<T1, op_type>::~SpOp()
template<typename T1, typename op_type>
template<typename eT2>
arma_inline
bool
SpOp<T1, op_type>::is_alias(const SpMat<typename T1::elem_type>& X) const
SpOp<T1, op_type>::is_alias(const SpMat<eT2>& X) const
{
return m.is_alias(X);
}
+8 -1
View File
@@ -34,6 +34,8 @@ class SpSubview : public SpBase< eT, SpSubview<eT> >
static constexpr bool is_col = false;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = true;
const uword aux_row1;
const uword aux_col1;
const uword n_rows;
@@ -321,7 +323,8 @@ class SpSubview : public SpBase< eT, SpSubview<eT> >
inline const_row_iterator end_row(const uword row_num) const;
//! don't use this unless you're writing internal Armadillo code
arma_inline bool is_alias(const SpMat<eT>& X) const;
template<typename eT2>
arma_inline bool is_alias(const SpMat<eT2>& X) const;
private:
@@ -351,6 +354,8 @@ class SpSubview_col : public SpSubview<eT>
static constexpr bool is_col = true;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = true;
inline void operator= (const SpSubview<eT>& x);
inline void operator= (const SpSubview_col& x);
@@ -391,6 +396,8 @@ class SpSubview_row : public SpSubview<eT>
static constexpr bool is_col = false;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = true;
inline void operator= (const SpSubview<eT>& x);
inline void operator= (const SpSubview_row& x);
@@ -33,6 +33,8 @@ class SpSubview_col_list : public SpBase< eT, SpSubview_col_list<eT,T1> >
static constexpr bool is_col = false;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = true;
const SpMat<eT>& m;
const quasi_unwrap<T1> U_ci;
@@ -87,6 +89,8 @@ class SpSubview_col_list : public SpBase< eT, SpSubview_col_list<eT,T1> >
inline static void schur_inplace(SpMat<eT>& out, const SpSubview_col_list& in);
inline static void div_inplace(SpMat<eT>& out, const SpSubview_col_list& in);
template<typename eT2>
arma_inline bool is_alias(const SpMat<eT2>& X) const;
friend class SpMat<eT>;
};
@@ -714,4 +714,15 @@ SpSubview_col_list<eT,T1>::div_inplace(SpMat<eT>& out, const SpSubview_col_list&
template<typename eT, typename T1>
template<typename eT2>
arma_inline
bool
SpSubview_col_list<eT,T1>::is_alias(const SpMat<eT2>& X) const
{
return m.is_alias(X);
}
//! @}
+46 -4
View File
@@ -44,6 +44,8 @@ SpSubview<eT>::SpSubview(const SpMat<eT>& in_m, const uword in_row1, const uword
m.sync_csc();
if( (n_elem == 0) || (m.n_nonzero == 0) ) { return; } // (*this).n_nonzero already set to zero
// count the number of non-zeros in the subview
uword count = 0;
@@ -127,6 +129,8 @@ SpSubview<eT>::operator+=(const eT val)
tmp.fill(val);
if(n_nonzero == 0) { return (*this).operator=(tmp); }
return (*this).operator=( (*this) + tmp );
}
@@ -319,6 +323,15 @@ SpSubview<eT>::operator+=(const Base<eT, T1>& x)
{
arma_debug_sigprint();
if(n_nonzero == 0)
{
const quasi_unwrap<T1> U(x.get_ref());
arma_conform_assert_same_size(n_rows, n_cols, U.M.n_rows, U.M.n_cols, "addition");
return (*this).operator=(U.M);
}
return (*this).operator=( (*this) + x.get_ref() );
}
@@ -369,6 +382,8 @@ SpSubview<eT>::operator%=(const Base<eT, T1>& x)
arma_conform_assert_same_size(sv.n_rows, sv.n_cols, B.n_rows, B.n_cols, "element-wise multiplication");
if(n_nonzero == 0) { return *this; }
SpMat<eT>& sv_m = access::rw(sv.m);
sv_m.sync_csc();
@@ -555,6 +570,15 @@ SpSubview<eT>::operator+=(const SpBase<eT, T1>& x)
{
arma_debug_sigprint();
if(n_nonzero == 0)
{
const unwrap_spmat<T1> U(x.get_ref());
arma_conform_assert_same_size(n_rows, n_cols, U.M.n_rows, U.M.n_cols, "addition");
return (*this).operator_equ_common(U.M);
}
// TODO: implement dedicated machinery
return (*this).operator=( (*this) + x.get_ref() );
}
@@ -596,6 +620,15 @@ SpSubview<eT>::operator%=(const SpBase<eT, T1>& x)
{
arma_debug_sigprint();
if(n_nonzero == 0)
{
const SpProxy<T1> P(x.get_ref());
arma_conform_assert_same_size(n_rows, n_cols, P.get_n_rows(), P.get_n_cols(), "element-wise multiplication");
return *this;
}
// TODO: implement dedicated machinery
return (*this).operator=( (*this) % x.get_ref() );
}
@@ -648,6 +681,8 @@ SpSubview<eT>::for_each(functor F)
m.sync_csc();
m.invalidate_cache();
if(n_nonzero == 0) { return; }
const uword lstart_row = aux_row1;
const uword lend_row = aux_row1 + n_rows;
@@ -704,6 +739,8 @@ SpSubview<eT>::for_each(functor F) const
m.sync_csc();
if(n_nonzero == 0) { return; }
const uword lstart_row = aux_row1;
const uword lend_row = aux_row1 + n_rows;
@@ -743,6 +780,8 @@ SpSubview<eT>::transform(functor F)
m.sync_csc();
m.invalidate_cache();
if(n_nonzero == 0) { return; }
const uword lstart_row = aux_row1;
const uword lend_row = aux_row1 + n_rows;
@@ -813,6 +852,8 @@ SpSubview<eT>::replace(const eT old_val, const eT new_val)
m.sync_csc();
m.invalidate_cache();
if(n_nonzero == 0) { return; }
const uword lstart_row = aux_row1;
const uword lend_row = aux_row1 + n_rows;
@@ -905,12 +946,12 @@ SpSubview<eT>::clamp(const eT min_val, const eT max_val)
if(is_cx<eT>::no)
{
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpSubview::clamp(): min_val must be less than max_val" );
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "SpSubview::clamp(): min_val must be less than max_val" );
}
else
{
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "SpSubview::clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "SpSubview::clamp(): imag(min_val) must be less than imag(max_val)" );
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "SpSubview::clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "SpSubview::clamp(): imag(min_val) must be less than imag(max_val)" );
}
if((n_elem == 0) || (n_nonzero == 0)) { return; }
@@ -1745,9 +1786,10 @@ SpSubview<eT>::end_row(const uword row_num) const
template<typename eT>
template<typename eT2>
arma_inline
bool
SpSubview<eT>::is_alias(const SpMat<eT>& X) const
SpSubview<eT>::is_alias(const SpMat<eT2>& X) const
{
return m.is_alias(X);
}
@@ -31,6 +31,8 @@ struct SpToDGlue : public Base< typename T1::elem_type, SpToDGlue<T1, T2, glue_t
static constexpr bool is_col = glue_type::template traits<T1,T2>::is_col;
static constexpr bool is_xvec = glue_type::template traits<T1,T2>::is_xvec;
static constexpr bool has_subview = T1::has_subview || T2::has_subview;
inline explicit SpToDGlue(const T1& in_A, const T2& in_B);
inline ~SpToDGlue();
+2
View File
@@ -32,6 +32,8 @@ struct SpToDOp : public Base< typename T1::elem_type, SpToDOp<T1, op_type> >
static constexpr bool is_col = op_type::template traits<T1>::is_col;
static constexpr bool is_xvec = op_type::template traits<T1>::is_xvec;
static constexpr bool has_subview = T1::has_subview;
inline explicit SpToDOp(const T1& in_m);
inline SpToDOp(const T1& in_m, const elem_type in_aux);
inline SpToDOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
+8 -1
View File
@@ -286,8 +286,9 @@ template<typename T1> struct ProxyCube;
template<typename T1> struct diagmat_proxy;
template<typename T1> struct unwrap;
template<typename T1> struct plain_unwrap;
template<typename T1> struct quasi_unwrap;
template<typename T1> struct unwrap_cube;
template<typename T1> struct unwrap_spmat;
@@ -365,6 +366,12 @@ struct arma_zeros_indicator : public arma_initmode_indicator<true > {};
struct arma_nozeros_indicator : public arma_initmode_indicator<false> {};
template<int vec_mode> struct arma_vec_mode_indicator {};
struct arma_colvec_indicator : public arma_vec_mode_indicator<1> {};
struct arma_rowvec_indicator : public arma_vec_mode_indicator<2> {};
//! \addtogroup injector
//! @{
+2 -2
View File
@@ -22,9 +22,9 @@
#define ARMA_VERSION_MAJOR 15
#define ARMA_VERSION_MINOR 2
#define ARMA_VERSION_MINOR 4
#define ARMA_VERSION_PATCH 2
#define ARMA_VERSION_NAME "Medium Roast Deluxe"
#define ARMA_VERSION_NAME "Medium Roast Agave"
+3 -3
View File
@@ -994,7 +994,7 @@ arrayops::is_zero(const eT* mem, const uword n_elem, const eT abs_limit, const t
{
for(uword i=0; i<n_elem; ++i)
{
if(eop_aux::arma_abs(mem[i]) > abs_limit) { return false; }
if( (eop_aux::arma_abs(mem[i]) <= abs_limit) == false ) { return false; }
}
}
@@ -1028,8 +1028,8 @@ arrayops::is_zero(const std::complex<T>* mem, const uword n_elem, const T abs_li
{
const eT& val = mem[i];
if(std::abs(std::real(val)) > abs_limit) { return false; }
if(std::abs(std::imag(val)) > abs_limit) { return false; }
if( (std::abs(std::real(val)) <= abs_limit) == false ) { return false; }
if( (std::abs(std::imag(val)) <= abs_limit) == false ) { return false; }
}
}
+10 -10
View File
@@ -2932,8 +2932,8 @@ auxlib::qr_econ(Mat<eT>& Q, Mat<eT>& R, const Base<eT,T1>& X)
{
if(is_Mat<T1>::value)
{
const unwrap<T1> tmp(X.get_ref());
const Mat<eT>& M = tmp.M;
const plain_unwrap<T1> tmp(X.get_ref());
const Mat<eT>& M = tmp.M;
if(M.n_rows < M.n_cols) { return auxlib::qr(Q, R, X); }
}
@@ -5160,8 +5160,8 @@ auxlib::solve_rect_fast(Mat<typename T1::elem_type>& out, Mat<typename T1::elem_
{
typedef typename T1::elem_type eT;
const unwrap<T1> U(B_expr.get_ref());
const Mat<eT>& B = U.M;
const plain_unwrap<T1> U(B_expr.get_ref());
const Mat<eT>& B = U.M;
arma_conform_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" );
@@ -5254,8 +5254,8 @@ auxlib::solve_rect_rcond(Mat<typename T1::elem_type>& out, typename T1::pod_type
out_rcond = T(0);
const unwrap<T1> U(B_expr.get_ref());
const Mat<eT>& B = U.M;
const plain_unwrap<T1> U(B_expr.get_ref());
const Mat<eT>& B = U.M;
arma_conform_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" );
@@ -5387,8 +5387,8 @@ auxlib::solve_approx_svd(Mat<typename T1::pod_type>& out, Mat<typename T1::pod_t
{
typedef typename T1::pod_type eT;
const unwrap<T1> U(B_expr.get_ref());
const Mat<eT>& B = U.M;
const plain_unwrap<T1> U(B_expr.get_ref());
const Mat<eT>& B = U.M;
arma_conform_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" );
@@ -5509,8 +5509,8 @@ auxlib::solve_approx_svd(Mat< std::complex<typename T1::pod_type> >& out, Mat< s
typedef typename T1::pod_type T;
typedef typename std::complex<T> eT;
const unwrap<T1> U(B_expr.get_ref());
const Mat<eT>& B = U.M;
const plain_unwrap<T1> U(B_expr.get_ref());
const Mat<eT>& B = U.M;
arma_conform_check( (A.n_rows != B.n_rows), "solve(): number of rows in given matrices must be the same" );
+12 -12
View File
@@ -330,18 +330,6 @@
#undef ARMA_OPTIMISE_POWEXPR
#endif
#if defined(ARMA_DONT_CHECK_CONFORMANCE)
#if defined(ARMA_CHECK_CONFORMANCE) && (ARMA_WARN_LEVEL >= 2)
#pragma message ("WARNING: conformance checks disabled")
#endif
#undef ARMA_CHECK_CONFORMANCE
#endif
#if defined(ARMA_DONT_CHECK_NONFINITE)
#undef ARMA_CHECK_NONFINITE
#endif
#if defined(ARMA_NO_DEBUG)
#undef ARMA_DEBUG
#undef ARMA_EXTRA_DEBUG
@@ -361,6 +349,18 @@
#define ARMA_WARN_LEVEL 3
#endif
#if defined(ARMA_DONT_CHECK_CONFORMANCE)
#if defined(ARMA_CHECK_CONFORMANCE) && (ARMA_WARN_LEVEL >= 2)
#pragma message ("WARNING: conformance checks disabled")
#endif
#undef ARMA_CHECK_CONFORMANCE
#endif
#if defined(ARMA_DONT_CHECK_NONFINITE)
#undef ARMA_CHECK_NONFINITE
#endif
#if defined(ARMA_DONT_PRINT_EXCEPTIONS)
#undef ARMA_PRINT_EXCEPTIONS
#endif
+12 -12
View File
@@ -330,18 +330,6 @@
#undef ARMA_OPTIMISE_POWEXPR
#endif
#if defined(ARMA_DONT_CHECK_CONFORMANCE)
#if defined(ARMA_CHECK_CONFORMANCE) && (ARMA_WARN_LEVEL >= 2)
#pragma message ("WARNING: conformance checks disabled")
#endif
#undef ARMA_CHECK_CONFORMANCE
#endif
#if defined(ARMA_DONT_CHECK_NONFINITE)
#undef ARMA_CHECK_NONFINITE
#endif
#if defined(ARMA_NO_DEBUG)
#undef ARMA_DEBUG
#undef ARMA_EXTRA_DEBUG
@@ -361,6 +349,18 @@
#define ARMA_WARN_LEVEL 3
#endif
#if defined(ARMA_DONT_CHECK_CONFORMANCE)
#if defined(ARMA_CHECK_CONFORMANCE) && (ARMA_WARN_LEVEL >= 2)
#pragma message ("WARNING: conformance checks disabled")
#endif
#undef ARMA_CHECK_CONFORMANCE
#endif
#if defined(ARMA_DONT_CHECK_NONFINITE)
#undef ARMA_CHECK_NONFINITE
#endif
#if defined(ARMA_DONT_PRINT_EXCEPTIONS)
#undef ARMA_PRINT_EXCEPTIONS
#endif
+55 -6
View File
@@ -62,11 +62,14 @@ namespace priv
}
//
template<typename eT>
static
constexpr
typename arma_real_only<eT>::result
inf(typename arma_real_only<eT>::result* junk = nullptr)
pos_inf(typename arma_real_only<eT>::result* junk = nullptr)
{
arma_ignore(junk);
@@ -78,13 +81,13 @@ namespace priv
static
constexpr
typename arma_cx_only<eT>::result
inf(typename arma_cx_only<eT>::result* junk = nullptr)
pos_inf(typename arma_cx_only<eT>::result* junk = nullptr)
{
arma_ignore(junk);
typedef typename get_pod_type<eT>::result T;
return eT( Datum_helper::inf<T>(), Datum_helper::inf<T>() );
return eT( Datum_helper::pos_inf<T>(), Datum_helper::pos_inf<T>() );
}
@@ -92,12 +95,54 @@ namespace priv
static
constexpr
typename arma_integral_only<eT>::result
inf(typename arma_integral_only<eT>::result* junk = nullptr)
pos_inf(typename arma_integral_only<eT>::result* junk = nullptr)
{
arma_ignore(junk);
return std::numeric_limits<eT>::max();
}
//
template<typename eT>
static
constexpr
typename arma_real_only<eT>::result
neg_inf(typename arma_real_only<eT>::result* junk = nullptr)
{
arma_ignore(junk);
return (std::numeric_limits<eT>::has_infinity) ? eT(-std::numeric_limits<eT>::infinity()) : eT(std::numeric_limits<eT>::lowest());
}
template<typename eT>
static
constexpr
typename arma_cx_only<eT>::result
neg_inf(typename arma_cx_only<eT>::result* junk = nullptr)
{
arma_ignore(junk);
typedef typename get_pod_type<eT>::result T;
return eT( Datum_helper::neg_inf<T>(), Datum_helper::neg_inf<T>() );
}
template<typename eT>
static
constexpr
typename arma_integral_only<eT>::result
neg_inf(typename arma_integral_only<eT>::result* junk = nullptr)
{
arma_ignore(junk);
return std::numeric_limits<eT>::lowest();
}
};
}
@@ -125,7 +170,9 @@ struct Datum
static const eT log_min; //!< log of the minimum representable value
static const eT log_max; //!< log of the maximum representable value
static const eT nan; //!< "not a number"
static const eT inf; //!< infinity
static const eT inf; //!< positive infinity
static const eT pos_inf; //!< positive infinity
static const eT neg_inf; //!< negative infinity
//
@@ -176,7 +223,9 @@ template<typename eT> const eT Datum<eT>::eps = std::numeric_limits<eT>:
template<typename eT> const eT Datum<eT>::log_min = std::log(std::numeric_limits<eT>::min());
template<typename eT> const eT Datum<eT>::log_max = std::log(std::numeric_limits<eT>::max());
template<typename eT> const eT Datum<eT>::nan = priv::Datum_helper::nan<eT>();
template<typename eT> const eT Datum<eT>::inf = priv::Datum_helper::inf<eT>();
template<typename eT> const eT Datum<eT>::inf = priv::Datum_helper::pos_inf<eT>();
template<typename eT> const eT Datum<eT>::pos_inf = priv::Datum_helper::pos_inf<eT>();
template<typename eT> const eT Datum<eT>::neg_inf = priv::Datum_helper::neg_inf<eT>();
template<typename eT> const eT Datum<eT>::m_u = eT(1.66053906892e-27);
template<typename eT> const eT Datum<eT>::N_A = eT(6.02214076e23);
@@ -35,6 +35,8 @@ class diagview : public Base< eT, diagview<eT> >
static constexpr bool is_col = true;
static constexpr bool is_xvec = false;
static constexpr bool has_subview = true;
const uword row_offset;
const uword col_offset;
+86 -28
View File
@@ -134,15 +134,25 @@ diagview<eT>::operator+=(const eT val)
{
arma_debug_sigprint();
Mat<eT>& t_m = const_cast< Mat<eT>& >(m);
diagview<eT>& d = *this;
const uword t_n_elem = n_elem;
const uword t_row_offset = row_offset;
const uword t_col_offset = col_offset;
Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m);
for(uword ii=0; ii < t_n_elem; ++ii)
const uword d_n_elem = d.n_elem;
const uword d_row_offset = d.row_offset;
const uword d_col_offset = d.col_offset;
uword ii,jj;
for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
{
t_m.at( ii + t_row_offset, ii + t_col_offset) += val;
d_m.at( ii + d_row_offset, ii + d_col_offset) += val;
d_m.at( jj + d_row_offset, jj + d_col_offset) += val;
}
if(ii < d_n_elem)
{
d_m.at( ii + d_row_offset, ii + d_col_offset) += val;
}
}
@@ -155,15 +165,25 @@ diagview<eT>::operator-=(const eT val)
{
arma_debug_sigprint();
Mat<eT>& t_m = const_cast< Mat<eT>& >(m);
diagview<eT>& d = *this;
const uword t_n_elem = n_elem;
const uword t_row_offset = row_offset;
const uword t_col_offset = col_offset;
Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m);
for(uword ii=0; ii < t_n_elem; ++ii)
const uword d_n_elem = d.n_elem;
const uword d_row_offset = d.row_offset;
const uword d_col_offset = d.col_offset;
uword ii,jj;
for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
{
t_m.at( ii + t_row_offset, ii + t_col_offset) -= val;
d_m.at( ii + d_row_offset, ii + d_col_offset) -= val;
d_m.at( jj + d_row_offset, jj + d_col_offset) -= val;
}
if(ii < d_n_elem)
{
d_m.at( ii + d_row_offset, ii + d_col_offset) -= val;
}
}
@@ -176,15 +196,25 @@ diagview<eT>::operator*=(const eT val)
{
arma_debug_sigprint();
Mat<eT>& t_m = const_cast< Mat<eT>& >(m);
diagview<eT>& d = *this;
const uword t_n_elem = n_elem;
const uword t_row_offset = row_offset;
const uword t_col_offset = col_offset;
Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m);
for(uword ii=0; ii < t_n_elem; ++ii)
const uword d_n_elem = d.n_elem;
const uword d_row_offset = d.row_offset;
const uword d_col_offset = d.col_offset;
uword ii,jj;
for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
{
t_m.at( ii + t_row_offset, ii + t_col_offset) *= val;
d_m.at( ii + d_row_offset, ii + d_col_offset) *= val;
d_m.at( jj + d_row_offset, jj + d_col_offset) *= val;
}
if(ii < d_n_elem)
{
d_m.at( ii + d_row_offset, ii + d_col_offset) *= val;
}
}
@@ -197,15 +227,25 @@ diagview<eT>::operator/=(const eT val)
{
arma_debug_sigprint();
Mat<eT>& t_m = const_cast< Mat<eT>& >(m);
diagview<eT>& d = *this;
const uword t_n_elem = n_elem;
const uword t_row_offset = row_offset;
const uword t_col_offset = col_offset;
Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m);
for(uword ii=0; ii < t_n_elem; ++ii)
const uword d_n_elem = d.n_elem;
const uword d_row_offset = d.row_offset;
const uword d_col_offset = d.col_offset;
uword ii,jj;
for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
{
t_m.at( ii + t_row_offset, ii + t_col_offset) /= val;
d_m.at( ii + d_row_offset, ii + d_col_offset) /= val;
d_m.at( jj + d_row_offset, jj + d_col_offset) /= val;
}
if(ii < d_n_elem)
{
d_m.at( ii + d_row_offset, ii + d_col_offset) /= val;
}
}
@@ -236,6 +276,12 @@ diagview<eT>::operator= (const Base<eT,T1>& o)
"diagview: given object has incompatible size"
);
constexpr bool is_gen_zeros = (is_same_type< T1, Gen<Mat<eT>, gen_zeros> >::yes) || (is_same_type< T1, Gen<Col<eT>, gen_zeros> >::yes);
constexpr bool is_gen_ones = (is_same_type< T1, Gen<Mat<eT>, gen_ones > >::yes) || (is_same_type< T1, Gen<Col<eT>, gen_ones > >::yes);
if(is_gen_zeros) { d.zeros(); return; }
if(is_gen_ones ) { d.ones(); return; }
const bool have_alias = P.is_alias(d_m);
if(have_alias) { arma_debug_print("aliasing detected"); }
@@ -948,13 +994,25 @@ diagview<eT>::fill(const eT val)
{
arma_debug_sigprint();
Mat<eT>& x = const_cast< Mat<eT>& >(m);
diagview<eT>& d = *this;
const uword local_n_elem = n_elem;
Mat<eT>& d_m = const_cast< Mat<eT>& >(d.m);
for(uword ii=0; ii < local_n_elem; ++ii)
const uword d_n_elem = d.n_elem;
const uword d_row_offset = d.row_offset;
const uword d_col_offset = d.col_offset;
uword ii,jj;
for(ii=0, jj=1; jj < d_n_elem; ii+=2, jj+=2)
{
x.at(ii+row_offset, ii+col_offset) = val;
d_m.at( ii + d_row_offset, ii + d_col_offset) = val;
d_m.at( jj + d_row_offset, jj + d_col_offset) = val;
}
if(ii < d_n_elem)
{
d_m.at( ii + d_row_offset, ii + d_col_offset) = val;
}
}
+25 -16
View File
@@ -373,29 +373,38 @@ inline
std::string
diskio::gen_tmp_name(const std::string& x)
{
union { uword val; void* ptr; } u;
arma_debug_sigprint();
u.val = uword(0);
u.ptr = const_cast<std::string*>(&x);
const char* charlist = "0123456789abcdefghijklmnopqrstuvwxyz";
const char* suffix1 = ".!";
const u16 a = u16( (u.val >> 8) & 0xFFFF );
const u16 b = u16( (std::clock()) & 0xFFFF );
constexpr std::size_t charlist_length = 36;
constexpr std::size_t suffix1_length = 2;
constexpr std::size_t suffix2_length = 6;
std::ostringstream ss;
typedef typename std::minstd_rand::result_type local_seed_type;
ss << x << ".tmp_";
std::minstd_rand local_engine;
std::uniform_int_distribution<std::size_t> local_distr(0, charlist_length - 1);
ss.setf(std::ios_base::hex, std::ios_base::basefield);
local_engine.seed( static_cast<local_seed_type>( (std::clock()) & 0xFFFF ) );
ss.width(4);
ss.fill('0');
ss << a;
const std::size_t x_length = x.length();
ss.width(4);
ss.fill('0');
ss << b;
std::string out(x_length + suffix1_length + suffix2_length, '0'); // create string filled with char '0' (not 0)
return ss.str();
std::size_t count = 0;
for(; count < x_length; ++count) { out[count] = x[count]; }
for(std::size_t i=0; i < suffix1_length; ++i, ++count) { out[count] = suffix1[i]; }
const std::size_t junk = local_distr(local_engine); // ignore first random number
arma_ignore(junk);
for(std::size_t i=0; i < suffix2_length; ++i, ++count) { out[count] = charlist[ local_distr(local_engine) ]; }
return out;
}
@@ -1856,7 +1865,7 @@ diskio::load_csv_ascii(Mat<eT>& x, std::istream& f, std::string& err_msg, const
try { x.zeros(f_n_rows, f_n_cols); } catch(...) { err_msg = "not enough memory"; return false; }
if(strict) { x.fill(Datum<eT>::nan); } // take into account that each row may have a unique number of columns
if(strict && is_real<eT>::yes) { x.fill(Datum<eT>::nan); } // take into account that each row may have a unique number of columns
const bool use_mp = (arma_config::openmp) && (f_n_rows >= 2) && (f_n_cols >= 64);
+30 -20
View File
@@ -265,6 +265,7 @@ eglue_core<eglue_type>::apply(outT& out, const eGlue<T1, T2, eglue_type>& x)
constexpr bool use_at = (Proxy<T1>::use_at || Proxy<T2>::use_at);
constexpr bool use_mp = (Proxy<T1>::use_mp || Proxy<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (Proxy<T1>::use_mp && Proxy<T2>::use_mp);
// NOTE: we're assuming that the matrix has already been set to the correct size and there is no aliasing;
// size setting and alias checking is done by either the Mat constructor or operator=()
@@ -276,7 +277,7 @@ eglue_core<eglue_type>::apply(outT& out, const eGlue<T1, T2, eglue_type>& x)
{
const uword n_elem = x.get_n_elem();
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
@@ -333,7 +334,7 @@ eglue_core<eglue_type>::apply(outT& out, const eGlue<T1, T2, eglue_type>& x)
const Proxy<T1>& P1 = x.P1;
const Proxy<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_2_mp(=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_2_mp(=, -); }
@@ -371,12 +372,13 @@ eglue_core<eglue_type>::apply_inplace_plus(Mat<typename T1::elem_type>& out, con
constexpr bool use_at = (Proxy<T1>::use_at || Proxy<T2>::use_at);
constexpr bool use_mp = (Proxy<T1>::use_mp || Proxy<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (Proxy<T1>::use_mp && Proxy<T2>::use_mp);
if(use_at == false)
{
const uword n_elem = x.get_n_elem();
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
@@ -430,7 +432,7 @@ eglue_core<eglue_type>::apply_inplace_plus(Mat<typename T1::elem_type>& out, con
const Proxy<T1>& P1 = x.P1;
const Proxy<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_2_mp(+=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_2_mp(+=, -); }
@@ -468,12 +470,13 @@ eglue_core<eglue_type>::apply_inplace_minus(Mat<typename T1::elem_type>& out, co
constexpr bool use_at = (Proxy<T1>::use_at || Proxy<T2>::use_at);
constexpr bool use_mp = (Proxy<T1>::use_mp || Proxy<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (Proxy<T1>::use_mp && Proxy<T2>::use_mp);
if(use_at == false)
{
const uword n_elem = x.get_n_elem();
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
@@ -527,7 +530,7 @@ eglue_core<eglue_type>::apply_inplace_minus(Mat<typename T1::elem_type>& out, co
const Proxy<T1>& P1 = x.P1;
const Proxy<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_2_mp(-=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_2_mp(-=, -); }
@@ -565,12 +568,13 @@ eglue_core<eglue_type>::apply_inplace_schur(Mat<typename T1::elem_type>& out, co
constexpr bool use_at = (Proxy<T1>::use_at || Proxy<T2>::use_at);
constexpr bool use_mp = (Proxy<T1>::use_mp || Proxy<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (Proxy<T1>::use_mp && Proxy<T2>::use_mp);
if(use_at == false)
{
const uword n_elem = x.get_n_elem();
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
@@ -624,7 +628,7 @@ eglue_core<eglue_type>::apply_inplace_schur(Mat<typename T1::elem_type>& out, co
const Proxy<T1>& P1 = x.P1;
const Proxy<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_2_mp(*=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_2_mp(*=, -); }
@@ -662,12 +666,13 @@ eglue_core<eglue_type>::apply_inplace_div(Mat<typename T1::elem_type>& out, cons
constexpr bool use_at = (Proxy<T1>::use_at || Proxy<T2>::use_at);
constexpr bool use_mp = (Proxy<T1>::use_mp || Proxy<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (Proxy<T1>::use_mp && Proxy<T2>::use_mp);
if(use_at == false)
{
const uword n_elem = x.get_n_elem();
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename Proxy<T1>::ea_type P1 = x.P1.get_ea();
typename Proxy<T2>::ea_type P2 = x.P2.get_ea();
@@ -721,7 +726,7 @@ eglue_core<eglue_type>::apply_inplace_div(Mat<typename T1::elem_type>& out, cons
const Proxy<T1>& P1 = x.P1;
const Proxy<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (Proxy<T1>::use_mp && Proxy<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_2_mp(/=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_2_mp(/=, -); }
@@ -757,6 +762,7 @@ eglue_core<eglue_type>::apply(Cube<typename T1::elem_type>& out, const eGlueCube
constexpr bool use_at = (ProxyCube<T1>::use_at || ProxyCube<T2>::use_at);
constexpr bool use_mp = (ProxyCube<T1>::use_mp || ProxyCube<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp);
// NOTE: we're assuming that the cube has already been set to the correct size and there is no aliasing;
// size setting and alias checking is done by either the Cube constructor or operator=()
@@ -768,7 +774,7 @@ eglue_core<eglue_type>::apply(Cube<typename T1::elem_type>& out, const eGlueCube
{
const uword n_elem = out.n_elem;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
@@ -826,7 +832,7 @@ eglue_core<eglue_type>::apply(Cube<typename T1::elem_type>& out, const eGlueCube
const ProxyCube<T1>& P1 = x.P1;
const ProxyCube<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_3_mp(=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_3_mp(=, -); }
@@ -865,12 +871,13 @@ eglue_core<eglue_type>::apply_inplace_plus(Cube<typename T1::elem_type>& out, co
constexpr bool use_at = (ProxyCube<T1>::use_at || ProxyCube<T2>::use_at);
constexpr bool use_mp = (ProxyCube<T1>::use_mp || ProxyCube<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp);
if(use_at == false)
{
const uword n_elem = out.n_elem;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
@@ -924,7 +931,7 @@ eglue_core<eglue_type>::apply_inplace_plus(Cube<typename T1::elem_type>& out, co
const ProxyCube<T1>& P1 = x.P1;
const ProxyCube<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_3_mp(+=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_3_mp(+=, -); }
@@ -963,12 +970,13 @@ eglue_core<eglue_type>::apply_inplace_minus(Cube<typename T1::elem_type>& out, c
constexpr bool use_at = (ProxyCube<T1>::use_at || ProxyCube<T2>::use_at);
constexpr bool use_mp = (ProxyCube<T1>::use_mp || ProxyCube<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp);
if(use_at == false)
{
const uword n_elem = out.n_elem;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
@@ -1022,7 +1030,7 @@ eglue_core<eglue_type>::apply_inplace_minus(Cube<typename T1::elem_type>& out, c
const ProxyCube<T1>& P1 = x.P1;
const ProxyCube<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_3_mp(-=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_3_mp(-=, -); }
@@ -1061,12 +1069,13 @@ eglue_core<eglue_type>::apply_inplace_schur(Cube<typename T1::elem_type>& out, c
constexpr bool use_at = (ProxyCube<T1>::use_at || ProxyCube<T2>::use_at);
constexpr bool use_mp = (ProxyCube<T1>::use_mp || ProxyCube<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp);
if(use_at == false)
{
const uword n_elem = out.n_elem;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
@@ -1120,7 +1129,7 @@ eglue_core<eglue_type>::apply_inplace_schur(Cube<typename T1::elem_type>& out, c
const ProxyCube<T1>& P1 = x.P1;
const ProxyCube<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_3_mp(*=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_3_mp(*=, -); }
@@ -1159,12 +1168,13 @@ eglue_core<eglue_type>::apply_inplace_div(Cube<typename T1::elem_type>& out, con
constexpr bool use_at = (ProxyCube<T1>::use_at || ProxyCube<T2>::use_at);
constexpr bool use_mp = (ProxyCube<T1>::use_mp || ProxyCube<T2>::use_mp) && (arma_config::openmp);
constexpr bool use_ht = (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp);
if(use_at == false)
{
const uword n_elem = out.n_elem;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(n_elem))
if(use_mp && mp_gate<eT, use_ht>::eval(n_elem))
{
typename ProxyCube<T1>::ea_type P1 = x.P1.get_ea();
typename ProxyCube<T2>::ea_type P2 = x.P2.get_ea();
@@ -1218,7 +1228,7 @@ eglue_core<eglue_type>::apply_inplace_div(Cube<typename T1::elem_type>& out, con
const ProxyCube<T1>& P1 = x.P1;
const ProxyCube<T2>& P2 = x.P2;
if(use_mp && mp_gate<eT, (ProxyCube<T1>::use_mp && ProxyCube<T2>::use_mp)>::eval(x.get_n_elem()))
if(use_mp && mp_gate<eT, use_ht>::eval(x.get_n_elem()))
{
if(is_same_type<eglue_type, eglue_plus >::yes) { arma_applier_3_mp(/=, +); }
else if(is_same_type<eglue_type, eglue_minus>::yes) { arma_applier_3_mp(/=, -); }
+17 -2
View File
@@ -94,7 +94,9 @@ field<oT>::field(const subview_field<oT>& X)
{
arma_debug_sigprint_this(this);
(*this).operator=(X);
init(X.n_rows, X.n_cols, X.n_slices);
subview_field<oT>::extract(*this, X);
}
@@ -107,7 +109,20 @@ field<oT>::operator=(const subview_field<oT>& X)
{
arma_debug_sigprint();
subview_field<oT>::extract(*this, X);
const bool alias = (this == &(X.f));
if(alias == false)
{
(*this).init(X.n_rows, X.n_cols, X.n_slices);
subview_field<oT>::extract(*this, X);
}
else
{
field<oT> tmp(X);
(*this).operator=(std::move(tmp));
}
return *this;
}
+19 -12
View File
@@ -22,22 +22,29 @@
namespace fill
{
struct fill_none {};
struct fill_zeros {};
struct fill_ones {};
struct fill_eye {};
struct fill_randu {};
struct fill_randn {};
struct fill_none {};
struct fill_zeros {};
struct fill_ones {};
struct fill_eye {};
struct fill_randu {};
struct fill_randn {};
struct fill_nan {};
struct fill_pos_inf {};
struct fill_neg_inf {};
template<typename fill_type>
struct fill_class { inline constexpr fill_class() {} };
static constexpr fill_class<fill_none > none;
static constexpr fill_class<fill_zeros> zeros;
static constexpr fill_class<fill_ones > ones;
static constexpr fill_class<fill_eye > eye;
static constexpr fill_class<fill_randu> randu;
static constexpr fill_class<fill_randn> randn;
static constexpr fill_class<fill_none > none;
static constexpr fill_class<fill_zeros > zeros;
static constexpr fill_class<fill_ones > ones;
static constexpr fill_class<fill_eye > eye;
static constexpr fill_class<fill_randu > randu;
static constexpr fill_class<fill_randn > randn;
static constexpr fill_class<fill_nan > nan;
static constexpr fill_class<fill_pos_inf> inf;
static constexpr fill_class<fill_pos_inf> pos_inf;
static constexpr fill_class<fill_neg_inf> neg_inf;
//
+7 -7
View File
@@ -110,8 +110,8 @@ internal_approx_equal_worker
arma_conform_check( ((use_abs_diff == false) && (use_rel_diff == false)), "internal_approx_equal_worker(): both 'use_abs_diff' and 'use_rel_diff' are false" );
if(use_abs_diff) { arma_conform_check( cond_rel< is_signed<T>::value >::lt(abs_tol, T(0)), "approx_equal(): argument 'abs_tol' must be >= 0" ); }
if(use_rel_diff) { arma_conform_check( cond_rel< is_signed<T>::value >::lt(rel_tol, T(0)), "approx_equal(): argument 'rel_tol' must be >= 0" ); }
if(use_abs_diff) { arma_conform_check( (cond_rel< is_signed<T>::value >::lt(abs_tol, T(0)) || arma_isnan(abs_tol)), "approx_equal(): argument 'abs_tol' must be >= 0" ); }
if(use_rel_diff) { arma_conform_check( (cond_rel< is_signed<T>::value >::lt(rel_tol, T(0)) || arma_isnan(rel_tol)), "approx_equal(): argument 'rel_tol' must be >= 0" ); }
const Proxy<T1> PA(A.get_ref());
const Proxy<T2> PB(B.get_ref());
@@ -203,8 +203,8 @@ internal_approx_equal_worker
arma_conform_check( ((use_abs_diff == false) && (use_rel_diff == false)), "internal_approx_equal_worker(): both 'use_abs_diff' and 'use_rel_diff' are false" );
if(use_abs_diff) { arma_conform_check( cond_rel< is_signed<T>::value >::lt(abs_tol, T(0)), "approx_equal(): argument 'abs_tol' must be >= 0" ); }
if(use_rel_diff) { arma_conform_check( cond_rel< is_signed<T>::value >::lt(rel_tol, T(0)), "approx_equal(): argument 'rel_tol' must be >= 0" ); }
if(use_abs_diff) { arma_conform_check( (cond_rel< is_signed<T>::value >::lt(abs_tol, T(0)) || arma_isnan(abs_tol)), "approx_equal(): argument 'abs_tol' must be >= 0" ); }
if(use_rel_diff) { arma_conform_check( (cond_rel< is_signed<T>::value >::lt(rel_tol, T(0)) || arma_isnan(rel_tol)), "approx_equal(): argument 'rel_tol' must be >= 0" ); }
const ProxyCube<T1> PA(A.get_ref());
const ProxyCube<T2> PB(B.get_ref());
@@ -418,7 +418,7 @@ approx_equal(const SpBase<typename T1::elem_type,T1>& A, const SpBase<typename T
arma_conform_check( (sig == 'r'), "approx_equal(): only the \"absdiff\" method is currently implemented for sparse matrices" );
arma_conform_check( cond_rel< is_signed<T>::value >::lt(tol, T(0)), "approx_equal(): argument 'tol' must be >= 0" );
arma_conform_check( (cond_rel< is_signed<T>::value >::lt(tol, T(0)) || arma_isnan(tol)), "approx_equal(): argument 'tol' must be >= 0" );
const unwrap_spmat<T1> UA(A.get_ref());
const unwrap_spmat<T2> UB(B.get_ref());
@@ -460,8 +460,8 @@ approx_equal(const SpBase<typename T1::elem_type,T1>& A, const SpBase<typename T
arma_conform_check( ((sig == 'r') || (sig == 'b')), "approx_equal(): only the \"absdiff\" method is currently implemented for sparse matrices" );
arma_conform_check( cond_rel< is_signed<T>::value >::lt(abs_tol, T(0)), "approx_equal(): argument 'abs_tol' must be >= 0" );
arma_conform_check( cond_rel< is_signed<T>::value >::lt(rel_tol, T(0)), "approx_equal(): argument 'rel_tol' must be >= 0" );
arma_conform_check( (cond_rel< is_signed<T>::value >::lt(abs_tol, T(0)) || arma_isnan(abs_tol)), "approx_equal(): argument 'abs_tol' must be >= 0" );
arma_conform_check( (cond_rel< is_signed<T>::value >::lt(rel_tol, T(0)) || arma_isnan(rel_tol)), "approx_equal(): argument 'rel_tol' must be >= 0" );
return approx_equal(A.get_ref(), B.get_ref(), "abs", abs_tol);
}
+2 -2
View File
@@ -281,8 +281,8 @@ as_scalar_diag(const Base<typename T1::elem_type,T1>& X)
typedef typename T1::elem_type eT;
const unwrap<T1> tmp(X.get_ref());
const Mat<eT>& A = tmp.M;
const plain_unwrap<T1> tmp(X.get_ref());
const Mat<eT>& A = tmp.M;
arma_conform_check_bounds( (A.n_elem != 1), "as_scalar(): expected 1x1 matrix" );
+3 -3
View File
@@ -97,12 +97,12 @@ clamp(const SpBase<typename T1::elem_type,T1>& X, const typename T1::elem_type m
if(is_cx<eT>::no)
{
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "clamp(): min_val must be less than max_val" );
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "clamp(): min_val must be less than max_val" );
}
else
{
arma_conform_check( (access::tmp_real(min_val) > access::tmp_real(max_val)), "clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( (access::tmp_imag(min_val) > access::tmp_imag(max_val)), "clamp(): imag(min_val) must be less than imag(max_val)" );
arma_conform_check( ((access::tmp_real(min_val) <= access::tmp_real(max_val)) == false), "clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( ((access::tmp_imag(min_val) <= access::tmp_imag(max_val)) == false), "clamp(): imag(min_val) must be less than imag(max_val)" );
}
SpMat<eT> out = X.get_ref();
+282 -52
View File
@@ -21,6 +21,276 @@
template<typename in_eT>
struct conv_to_helper_Mat_same_type
{
template<typename T1>
inline
static
Mat<in_eT>
apply(const Base<in_eT, T1>& in)
{
arma_debug_sigprint();
return Mat<in_eT>(in.get_ref());
}
inline
static
Mat<in_eT>
apply(const std::vector<in_eT>& in)
{
arma_debug_sigprint();
const uword N = uword( in.size() );
const in_eT* in_memptr = (N > 0) ? &(in[0]) : nullptr;
return Mat<in_eT>(in_memptr, N, 1);
}
};
template<typename out_eT, typename in_eT>
struct conv_to_helper_Mat_diff_type
{
template<typename T1>
inline
static
Mat<out_eT>
apply(const Base<in_eT, T1>& in)
{
arma_debug_sigprint();
const quasi_unwrap<T1> tmp(in.get_ref());
const Mat<in_eT>& X = tmp.M;
Mat<out_eT> out(X.n_rows, X.n_cols, arma_nozeros_indicator());
arrayops::convert( out.memptr(), X.memptr(), X.n_elem );
return out;
}
inline
static
Mat<out_eT>
apply(const std::vector<in_eT>& in)
{
arma_debug_sigprint();
const uword N = uword( in.size() );
Mat<out_eT> out(N, 1, arma_nozeros_indicator());
if(N > 0) { arrayops::convert( out.memptr(), &(in[0]), N ); }
return out;
}
};
template<typename out_eT, typename in_eT, bool condition>
struct conv_to_helper_Mat_redirect {};
template<typename out_eT, typename in_eT>
struct conv_to_helper_Mat_redirect<out_eT, in_eT, true > { typedef conv_to_helper_Mat_same_type<in_eT> result; };
template<typename out_eT, typename in_eT>
struct conv_to_helper_Mat_redirect<out_eT, in_eT, false> { typedef conv_to_helper_Mat_diff_type<out_eT, in_eT> result; };
template<typename in_eT>
struct conv_to_helper_Row_same_type
{
template<typename T1>
inline
static
Row<in_eT>
apply(const Base<in_eT, T1>& in)
{
arma_debug_sigprint();
Mat<in_eT> X(in.get_ref());
arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" );
access::rw(X.n_rows ) = uword(1);
access::rw(X.n_cols ) = X.n_elem;
access::rw(X.vec_state) = uword(2);
Row<in_eT> out; out.steal_mem(X);
return out;
}
inline
static
Row<in_eT>
apply(const std::vector<in_eT>& in)
{
arma_debug_sigprint();
const uword N = uword( in.size() );
const in_eT* in_memptr = (N > 0) ? &(in[0]) : nullptr;
return Row<in_eT>(in_memptr, N);
}
};
template<typename out_eT, typename in_eT>
struct conv_to_helper_Row_diff_type
{
template<typename T1>
inline
static
Row<out_eT>
apply(const Base<in_eT, T1>& in)
{
arma_debug_sigprint();
const quasi_unwrap<T1> tmp(in.get_ref());
const Mat<in_eT>& X = tmp.M;
arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" );
Row<out_eT> out(X.n_elem, arma_nozeros_indicator());
arrayops::convert( out.memptr(), X.memptr(), X.n_elem );
return out;
}
inline
static
Row<out_eT>
apply(const std::vector<in_eT>& in)
{
arma_debug_sigprint();
const uword N = uword( in.size() );
Row<out_eT> out(N, arma_nozeros_indicator());
if(N > 0) { arrayops::convert( out.memptr(), &(in[0]), N ); }
return out;
}
};
template<typename out_eT, typename in_eT, bool condition>
struct conv_to_helper_Row_redirect {};
template<typename out_eT, typename in_eT>
struct conv_to_helper_Row_redirect<out_eT, in_eT, true > { typedef conv_to_helper_Row_same_type<in_eT> result; };
template<typename out_eT, typename in_eT>
struct conv_to_helper_Row_redirect<out_eT, in_eT, false> { typedef conv_to_helper_Row_diff_type<out_eT, in_eT> result; };
template<typename in_eT>
struct conv_to_helper_Col_same_type
{
template<typename T1>
inline
static
Col<in_eT>
apply(const Base<in_eT, T1>& in)
{
arma_debug_sigprint();
Mat<in_eT> X(in.get_ref());
arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" );
access::rw(X.n_rows ) = X.n_elem;
access::rw(X.n_cols ) = uword(1);
access::rw(X.vec_state) = uword(1);
Col<in_eT> out; out.steal_mem(X);
return out;
}
inline
static
Col<in_eT>
apply(const std::vector<in_eT>& in)
{
arma_debug_sigprint();
const uword N = uword( in.size() );
const in_eT* in_memptr = (N > 0) ? &(in[0]) : nullptr;
return Col<in_eT>(in_memptr, N);
}
};
template<typename out_eT, typename in_eT>
struct conv_to_helper_Col_diff_type
{
template<typename T1>
inline
static
Col<out_eT>
apply(const Base<in_eT, T1>& in)
{
arma_debug_sigprint();
const quasi_unwrap<T1> tmp(in.get_ref());
const Mat<in_eT>& X = tmp.M;
arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" );
Col<out_eT> out(X.n_elem, arma_nozeros_indicator());
arrayops::convert( out.memptr(), X.memptr(), X.n_elem );
return out;
}
inline
static
Col<out_eT>
apply(const std::vector<in_eT>& in)
{
arma_debug_sigprint();
const uword N = uword( in.size() );
Col<out_eT> out(N, arma_nozeros_indicator());
if(N > 0) { arrayops::convert( out.memptr(), &(in[0]), N ); }
return out;
}
};
template<typename out_eT, typename in_eT, bool condition>
struct conv_to_helper_Col_redirect {};
template<typename out_eT, typename in_eT>
struct conv_to_helper_Col_redirect<out_eT, in_eT, true > { typedef conv_to_helper_Col_same_type<in_eT> result; };
template<typename out_eT, typename in_eT>
struct conv_to_helper_Col_redirect<out_eT, in_eT, false> { typedef conv_to_helper_Col_diff_type<out_eT, in_eT> result; };
//! conversion from Armadillo Base and BaseCube objects to scalars
//! NOTE: use as_scalar() instead; this functionality is kept only for compatibility with old user code
template<typename out_eT>
@@ -195,14 +465,9 @@ conv_to< Mat<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_not_
arma_debug_sigprint();
arma_ignore(junk);
const quasi_unwrap<T1> tmp(in.get_ref());
const Mat<in_eT>& X = tmp.M;
typedef typename conv_to_helper_Mat_redirect<out_eT, in_eT, is_same_type<out_eT, in_eT>::value>::result helper_type;
Mat<out_eT> out(X.n_rows, X.n_cols, arma_nozeros_indicator());
arrayops::convert( out.memptr(), X.memptr(), X.n_elem );
return out;
return helper_type::apply(in.get_ref());
}
@@ -297,16 +562,9 @@ conv_to< Mat<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_n
arma_debug_sigprint();
arma_ignore(junk);
const uword N = uword( in.size() );
typedef typename conv_to_helper_Mat_redirect<out_eT, in_eT, is_same_type<out_eT, in_eT>::value>::result helper_type;
Mat<out_eT> out(N, 1, arma_nozeros_indicator());
if(N > 0)
{
arrayops::convert( out.memptr(), &(in[0]), N );
}
return out;
return helper_type::apply(in);
}
@@ -366,16 +624,9 @@ conv_to< Row<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_not_
arma_debug_sigprint();
arma_ignore(junk);
const quasi_unwrap<T1> tmp(in.get_ref());
const Mat<in_eT>& X = tmp.M;
typedef typename conv_to_helper_Row_redirect<out_eT, in_eT, is_same_type<out_eT, in_eT>::value>::result helper_type;
arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" );
Row<out_eT> out(X.n_elem, arma_nozeros_indicator());
arrayops::convert( out.memptr(), X.memptr(), X.n_elem );
return out;
return helper_type::apply(in.get_ref());
}
@@ -414,16 +665,9 @@ conv_to< Row<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_n
arma_debug_sigprint();
arma_ignore(junk);
const uword N = uword( in.size() );
typedef typename conv_to_helper_Row_redirect<out_eT, in_eT, is_same_type<out_eT, in_eT>::value>::result helper_type;
Row<out_eT> out(N, arma_nozeros_indicator());
if(N > 0)
{
arrayops::convert( out.memptr(), &(in[0]), N );
}
return out;
return helper_type::apply(in);
}
@@ -483,16 +727,9 @@ conv_to< Col<out_eT> >::from(const Base<in_eT, T1>& in, const typename arma_not_
arma_debug_sigprint();
arma_ignore(junk);
const quasi_unwrap<T1> tmp(in.get_ref());
const Mat<in_eT>& X = tmp.M;
typedef typename conv_to_helper_Col_redirect<out_eT, in_eT, is_same_type<out_eT, in_eT>::value>::result helper_type;
arma_conform_check( ( (X.is_vec() == false) && (X.is_empty() == false) ), "conv_to(): given object cannot be interpreted as a vector" );
Col<out_eT> out(X.n_elem, arma_nozeros_indicator());
arrayops::convert( out.memptr(), X.memptr(), X.n_elem );
return out;
return helper_type::apply(in.get_ref());
}
@@ -531,16 +768,9 @@ conv_to< Col<out_eT> >::from(const std::vector<in_eT>& in, const typename arma_n
arma_debug_sigprint();
arma_ignore(junk);
const uword N = uword( in.size() );
typedef typename conv_to_helper_Col_redirect<out_eT, in_eT, is_same_type<out_eT, in_eT>::value>::result helper_type;
Col<out_eT> out(N, arma_nozeros_indicator());
if(N > 0)
{
arrayops::convert( out.memptr(), &(in[0]), N );
}
return out;
return helper_type::apply(in);
}
+4 -4
View File
@@ -28,13 +28,13 @@ typename
enable_if2
<
is_arma_type<T1>::value,
const mtOp<uword, T1, op_find_simple>
const mtOp<uword, T1, op_find_default>
>::result
find(const T1& X)
{
arma_debug_sigprint();
return mtOp<uword, T1, op_find_simple>(X);
return mtOp<uword, T1, op_find_default>(X);
}
@@ -42,7 +42,7 @@ find(const T1& X)
template<typename T1>
arma_warn_unused
inline
const mtOp<uword, T1, op_find>
const mtOp<uword, T1, op_find_generic>
find(const Base<typename T1::elem_type,T1>& X, const uword k, const char* direction = "first")
{
arma_debug_sigprint();
@@ -57,7 +57,7 @@ find(const Base<typename T1::elem_type,T1>& X, const uword k, const char* direct
const uword type = ( (sig == 'f') || (sig == 'F') ) ? 0 : 1;
return mtOp<uword, T1, op_find>(X.get_ref(), k, type);
return mtOp<uword, T1, op_find_generic>(X.get_ref(), k, type);
}
+1 -1
View File
@@ -63,7 +63,7 @@ inv
template<typename T1>
arma_warn_unused
arma_inline
inline
typename enable_if2< is_blas_type<typename T1::elem_type>::value, const Op<T1, op_inv_gen_full> >::result
inv
(
+1 -1
View File
@@ -63,7 +63,7 @@ inv_sympd
template<typename T1>
arma_warn_unused
arma_inline
inline
typename enable_if2< is_blas_type<typename T1::elem_type>::value, const Op<T1, op_inv_spd_full> >::result
inv_sympd
(
+2 -2
View File
@@ -78,7 +78,7 @@ pow
template<typename eT, typename T2>
[[deprecated]]
[[deprecated("refactor your code to use pow() in conjunction with repcube()")]]
inline
Cube<eT>
pow
@@ -160,7 +160,7 @@ pow
template<typename T, typename T2>
[[deprecated]]
[[deprecated("refactor your code to use pow() in conjunction with repcube()")]]
inline
Cube< std::complex<T> >
pow
+4 -4
View File
@@ -47,7 +47,7 @@ rande(const uword n_rows, const uword n_cols, const distr_param& param = distr_p
param.get_double_vals(lambda, unused);
arma_conform_check( (lambda <= double(0)), "rande(): incorrect distribution parameters; lambda must be greater than zero" );
arma_conform_check( ((lambda > double(0)) == false), "rande(): incorrect distribution parameters; lambda must be greater than zero" );
obj_type out(n_rows, n_cols, arma_nozeros_indicator());
@@ -138,7 +138,7 @@ rande(const distr_param& param = distr_param())
param.get_double_vals(lambda, unused);
arma_conform_check( (lambda <= double(0)), "rande(): incorrect distribution parameters; lambda must be greater than zero" );
arma_conform_check( ((lambda > double(0)) == false), "rande(): incorrect distribution parameters; lambda must be greater than zero" );
double out_val = double(0);
@@ -162,7 +162,7 @@ rande(const distr_param& param = distr_param())
param.get_double_vals(lambda, unused);
arma_conform_check( (lambda <= double(0)), "rande(): incorrect distribution parameters; lambda must be greater than zero" );
arma_conform_check( ((lambda > double(0)) == false), "rande(): incorrect distribution parameters; lambda must be greater than zero" );
eT out_val = eT(0);
@@ -189,7 +189,7 @@ rande(const uword n_rows, const uword n_cols, const uword n_slices, const distr_
param.get_double_vals(lambda, unused);
arma_conform_check( (lambda <= double(0)), "rande(): incorrect distribution parameters; lambda must be greater than zero" );
arma_conform_check( ((lambda > double(0)) == false), "rande(): incorrect distribution parameters; lambda must be greater than zero" );
cube_type out(n_rows, n_cols, n_slices, arma_nozeros_indicator());
+4 -4
View File
@@ -47,7 +47,7 @@ randg(const uword n_rows, const uword n_cols, const distr_param& param = distr_p
param.get_double_vals(a,b);
arma_conform_check( ((a <= double(0)) || (b <= double(0))), "randg(): incorrect distribution parameters; a and b must be greater than zero" );
arma_conform_check( ( ((a > double(0)) == false) || ((b > double(0)) == false) ), "randg(): incorrect distribution parameters; a and b must be greater than zero" );
obj_type out(n_rows, n_cols, arma_nozeros_indicator());
@@ -138,7 +138,7 @@ randg(const distr_param& param = distr_param())
param.get_double_vals(a,b);
arma_conform_check( ((a <= double(0)) || (b <= double(0))), "randg(): incorrect distribution parameters; a and b must be greater than zero" );
arma_conform_check( ( ((a > double(0)) == false) || ((b > double(0)) == false) ), "randg(): incorrect distribution parameters; a and b must be greater than zero" );
double out_val = double(0);
@@ -162,7 +162,7 @@ randg(const distr_param& param = distr_param())
param.get_double_vals(a,b);
arma_conform_check( ((a <= double(0)) || (b <= double(0))), "randg(): incorrect distribution parameters; a and b must be greater than zero" );
arma_conform_check( ( ((a > double(0)) == false) || ((b > double(0)) == false) ), "randg(): incorrect distribution parameters; a and b must be greater than zero" );
eT out_val = eT(0);
@@ -189,7 +189,7 @@ randg(const uword n_rows, const uword n_cols, const uword n_slices, const distr_
param.get_double_vals(a,b);
arma_conform_check( ((a <= double(0)) || (b <= double(0))), "randg(): incorrect distribution parameters; a and b must be greater than zero" );
arma_conform_check( ( ((a > double(0)) == false) || ((b > double(0)) == false) ), "randg(): incorrect distribution parameters; a and b must be greater than zero" );
cube_type out(n_rows, n_cols, n_slices, arma_nozeros_indicator());
+4 -4
View File
@@ -47,7 +47,7 @@ randi(const uword n_rows, const uword n_cols, const distr_param& param = distr_p
param.get_int_vals(a,b);
arma_conform_check( (a > b), "randi(): incorrect distribution parameters; a must be less than b" );
arma_conform_check( ((a <= b) == false), "randi(): incorrect distribution parameters; a must be less than b" );
obj_type out(n_rows, n_cols, arma_nozeros_indicator());
@@ -142,7 +142,7 @@ randi(const distr_param& param)
param.get_int_vals(a,b);
arma_conform_check( (a > b), "randi(): incorrect distribution parameters; a must be less than b" );
arma_conform_check( ((a <= b) == false), "randi(): incorrect distribution parameters; a must be less than b" );
sword out_val = sword(0);
@@ -166,7 +166,7 @@ randi(const distr_param& param)
param.get_int_vals(a,b);
arma_conform_check( (a > b), "randi(): incorrect distribution parameters; a must be less than b" );
arma_conform_check( ((a <= b) == false), "randi(): incorrect distribution parameters; a must be less than b" );
eT out_val = eT(0);
@@ -218,7 +218,7 @@ randi(const uword n_rows, const uword n_cols, const uword n_slices, const distr_
param.get_int_vals(a,b);
arma_conform_check( (a > b), "randi(): incorrect distribution parameters; a must be less than b" );
arma_conform_check( ((a <= b) == false), "randi(): incorrect distribution parameters; a must be less than b" );
cube_type out(n_rows, n_cols, n_slices, arma_nozeros_indicator());
+8 -8
View File
@@ -62,7 +62,7 @@ randn(const distr_param& param)
param.get_double_vals(mu,sd);
arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
const double val = double(arma_rng::randn<double>());
@@ -86,7 +86,7 @@ randn(const distr_param& param)
param.get_double_vals(mu,sd);
arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
eT val = eT(0);
@@ -119,7 +119,7 @@ randn(const uword n_elem, const distr_param& param = distr_param())
param.get_double_vals(mu,sd);
arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
arma_rng::randn<double>::fill(out.memptr(), n_elem, mu, sd);
}
@@ -156,7 +156,7 @@ randn(const uword n_elem, const distr_param& param = distr_param(), const typena
param.get_double_vals(mu,sd);
arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
arma_rng::randn<eT>::fill(out.memptr(), out.n_elem, mu, sd);
}
@@ -188,7 +188,7 @@ randn(const uword n_rows, const uword n_cols, const distr_param& param = distr_p
param.get_double_vals(mu,sd);
arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
arma_rng::randn<double>::fill(out.memptr(), out.n_elem, mu, sd);
}
@@ -237,7 +237,7 @@ randn(const uword n_rows, const uword n_cols, const distr_param& param = distr_p
param.get_double_vals(mu,sd);
arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
arma_rng::randn<eT>::fill(out.memptr(), out.n_elem, mu, sd);
}
@@ -284,7 +284,7 @@ randn(const uword n_rows, const uword n_cols, const uword n_slices, const distr_
param.get_double_vals(mu,sd);
arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
arma_rng::randn<double>::fill(out.memptr(), out.n_elem, mu, sd);
}
@@ -330,7 +330,7 @@ randn(const uword n_rows, const uword n_cols, const uword n_slices, const distr_
param.get_double_vals(mu,sd);
arma_conform_check( (sd <= double(0)), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
arma_conform_check( ((sd > double(0)) == false), "randn(): incorrect distribution parameters; standard deviation must be > 0" );
arma_rng::randn<eT>::fill(out.memptr(), out.n_elem, mu, sd);
}
+8 -8
View File
@@ -62,7 +62,7 @@ randu(const distr_param& param)
param.get_double_vals(a,b);
arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" );
arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" );
const double val = double(arma_rng::randu<double>());
@@ -86,7 +86,7 @@ randu(const distr_param& param)
param.get_double_vals(a,b);
arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" );
arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" );
eT val = eT(0);
@@ -119,7 +119,7 @@ randu(const uword n_elem, const distr_param& param = distr_param())
param.get_double_vals(a,b);
arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" );
arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" );
arma_rng::randu<double>::fill(out.memptr(), n_elem, a, b);
}
@@ -156,7 +156,7 @@ randu(const uword n_elem, const distr_param& param = distr_param(), const typena
param.get_double_vals(a,b);
arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" );
arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" );
arma_rng::randu<eT>::fill(out.memptr(), out.n_elem, a, b);
}
@@ -188,7 +188,7 @@ randu(const uword n_rows, const uword n_cols, const distr_param& param = distr_p
param.get_double_vals(a,b);
arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" );
arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" );
arma_rng::randu<double>::fill(out.memptr(), out.n_elem, a, b);
}
@@ -237,7 +237,7 @@ randu(const uword n_rows, const uword n_cols, const distr_param& param = distr_p
param.get_double_vals(a,b);
arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" );
arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" );
arma_rng::randu<eT>::fill(out.memptr(), out.n_elem, a, b);
}
@@ -284,7 +284,7 @@ randu(const uword n_rows, const uword n_cols, const uword n_slices, const distr_
param.get_double_vals(a,b);
arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" );
arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" );
arma_rng::randu<double>::fill(out.memptr(), out.n_elem, a, b);
}
@@ -330,7 +330,7 @@ randu(const uword n_rows, const uword n_cols, const uword n_slices, const distr_
param.get_double_vals(a,b);
arma_conform_check( (a >= b), "randu(): incorrect distribution parameters; a must be less than b" );
arma_conform_check( ((a < b) == false), "randu(): incorrect distribution parameters; a must be less than b" );
arma_rng::randu<eT>::fill(out.memptr(), out.n_elem, a, b);
}
+3 -3
View File
@@ -55,7 +55,7 @@ spsolve_helper
const superlu_opts& opts = (settings.id == 1) ? static_cast<const superlu_opts&>(settings) : superlu_opts_default;
arma_conform_check( ( (opts.pivot_thresh < double(0)) || (opts.pivot_thresh > double(1)) ), "spsolve(): pivot_thresh must be in the [0,1] interval" );
arma_conform_check( ( ((opts.pivot_thresh >= double(0)) == false) || ((opts.pivot_thresh <= double(1)) == false) ), "spsolve(): pivot_thresh must be in the [0,1] interval" );
if(sig == 's') // SuperLU solver
{
@@ -110,12 +110,12 @@ spsolve_helper
if( (status == false) && (rcond > T(0)) )
{
arma_warn(2, "spsolve(): system is singular (rcond: ", rcond, ")");
arma_warn(2, "spsolve(): system is singular; rcond: ", rcond);
}
if( (status == true) && (rcond > T(0)) && (rcond < std::numeric_limits<T>::epsilon()) )
{
arma_warn(2, "solve(): solution computed, but system is singular to working precision (rcond: ", rcond, ")");
arma_warn(2, "spsolve(): solution computed, but system is singular to working precision; rcond: ", rcond);
}
return status;
+2 -2
View File
@@ -47,7 +47,7 @@ svds_helper
"svds(): two or more output objects are the same object"
);
arma_conform_check( (tol < T(0)), "svds(): tol must be >= 0" );
arma_conform_check( ((tol >= T(0)) == false), "svds(): tol must be >= 0" );
const unwrap_spmat<T1> tmp(X.get_ref());
const SpMat<eT>& A = tmp.M;
@@ -171,7 +171,7 @@ svds_helper
"svds(): two or more output objects are the same object"
);
arma_conform_check( (tol < T(0)), "svds(): tol must be >= 0" );
arma_conform_check( ((tol >= T(0)) == false), "svds(): tol must be >= 0" );
const unwrap_spmat<T1> tmp(X.get_ref());
const SpMat<eT>& A = tmp.M;
+3 -3
View File
@@ -97,9 +97,9 @@ sylvester
typedef typename T1::elem_type eT;
const unwrap<T1> tmp_A( in_A.get_ref() );
const unwrap<T2> tmp_B( in_B.get_ref() );
const unwrap<T3> tmp_C( in_C.get_ref() );
const plain_unwrap<T1> tmp_A( in_A.get_ref() );
const plain_unwrap<T2> tmp_B( in_B.get_ref() );
const plain_unwrap<T3> tmp_C( in_C.get_ref() );
const Mat<eT>& A = tmp_A.M;
const Mat<eT>& B = tmp_B.M;
+6 -6
View File
@@ -48,7 +48,7 @@ trimatl(const Base<typename T1::elem_type,T1>& X)
template<typename T1>
arma_warn_unused
arma_inline
inline
const SpOp<T1, spop_trimat>
trimatu(const SpBase<typename T1::elem_type,T1>& X)
{
@@ -61,7 +61,7 @@ trimatu(const SpBase<typename T1::elem_type,T1>& X)
template<typename T1>
arma_warn_unused
arma_inline
inline
const SpOp<T1, spop_trimat>
trimatl(const SpBase<typename T1::elem_type,T1>& X)
{
@@ -78,7 +78,7 @@ trimatl(const SpBase<typename T1::elem_type,T1>& X)
template<typename T1>
arma_warn_unused
arma_inline
inline
const Op<T1, op_trimatl_ext>
trimatl(const Base<typename T1::elem_type,T1>& X, const sword k)
{
@@ -94,7 +94,7 @@ trimatl(const Base<typename T1::elem_type,T1>& X, const sword k)
template<typename T1>
arma_warn_unused
arma_inline
inline
const Op<T1, op_trimatu_ext>
trimatu(const Base<typename T1::elem_type,T1>& X, const sword k)
{
@@ -110,7 +110,7 @@ trimatu(const Base<typename T1::elem_type,T1>& X, const sword k)
template<typename T1>
arma_warn_unused
arma_inline
inline
const SpOp<T1, spop_trimatu_ext>
trimatu(const SpBase<typename T1::elem_type,T1>& X, const sword k)
{
@@ -126,7 +126,7 @@ trimatu(const SpBase<typename T1::elem_type,T1>& X, const sword k)
template<typename T1>
arma_warn_unused
arma_inline
inline
const SpOp<T1, spop_trimatl_ext>
trimatl(const SpBase<typename T1::elem_type,T1>& X, const sword k)
{
+2 -2
View File
@@ -103,8 +103,8 @@ glue_atan2::apply_noalias(Mat<typename T1::elem_type>& out, const Proxy<T1>& P1,
{
if(use_mp)
{
const unwrap<typename Proxy<T1>::stored_type> U1(P1.Q);
const unwrap<typename Proxy<T2>::stored_type> U2(P2.Q);
const plain_unwrap<typename Proxy<T1>::stored_type> U1(P1.Q);
const plain_unwrap<typename Proxy<T2>::stored_type> U2(P2.Q);
out = arma::atan2(U1.M, U2.M);
}
+2 -2
View File
@@ -32,8 +32,8 @@ glue_cor::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_cor>& X)
const uword norm_type = X.aux_uword;
const unwrap<T1> UA(X.A);
const unwrap<T2> UB(X.B);
const plain_unwrap<T1> UA(X.A);
const plain_unwrap<T2> UB(X.B);
const Mat<eT>& A = UA.M;
const Mat<eT>& B = UB.M;
+2 -2
View File
@@ -32,8 +32,8 @@ glue_cov::apply(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_cov>& X)
const uword norm_type = X.aux_uword;
const unwrap<T1> UA(X.A);
const unwrap<T2> UB(X.B);
const plain_unwrap<T1> UA(X.A);
const plain_unwrap<T2> UB(X.B);
const Mat<eT>& A = UA.M;
const Mat<eT>& B = UB.M;
+33 -5
View File
@@ -75,13 +75,41 @@ glue_max::apply(Mat<eT>& out, const Proxy<T1>& PA, const Proxy<T2>& PB)
const uword N = PA.get_n_elem();
for(uword i=0; i<N; ++i)
#if defined(ARMA_SIMPLE_LOOPS)
{
const eT Ai = A[i];
const eT Bi = B[i];
out_mem[i] = comparator(Ai,Bi) ? Ai : Bi;
for(uword i=0; i<N; ++i)
{
const eT Ai = A[i];
const eT Bi = B[i];
out_mem[i] = comparator(Ai,Bi) ? Ai : Bi;
}
}
#else
{
uword i,j;
for(i=0, j=1; j < N; i+=2, j+=2)
{
const eT Ai = A[i];
const eT Aj = A[j];
const eT Bi = B[i];
const eT Bj = B[j];
(*out_mem) = comparator(Ai,Bi) ? Ai : Bi; ++out_mem;
(*out_mem) = comparator(Aj,Bj) ? Aj : Bj; ++out_mem;
}
if(i < N)
{
const eT Ai = A[i];
const eT Bi = B[i];
(*out_mem) = comparator(Ai,Bi) ? Ai : Bi;
}
}
#endif
}
else
{
+33 -5
View File
@@ -75,13 +75,41 @@ glue_min::apply(Mat<eT>& out, const Proxy<T1>& PA, const Proxy<T2>& PB)
const uword N = PA.get_n_elem();
for(uword i=0; i<N; ++i)
#if defined(ARMA_SIMPLE_LOOPS)
{
const eT Ai = A[i];
const eT Bi = B[i];
out_mem[i] = comparator(Ai,Bi) ? Ai : Bi;
for(uword i=0; i<N; ++i)
{
const eT Ai = A[i];
const eT Bi = B[i];
out_mem[i] = comparator(Ai,Bi) ? Ai : Bi;
}
}
#else
{
uword i,j;
for(i=0, j=1; j < N; i+=2, j+=2)
{
const eT Ai = A[i];
const eT Aj = A[j];
const eT Bi = B[i];
const eT Bj = B[j];
(*out_mem) = comparator(Ai,Bi) ? Ai : Bi; ++out_mem;
(*out_mem) = comparator(Aj,Bj) ? Aj : Bj; ++out_mem;
}
if(i < N)
{
const eT Ai = A[i];
const eT Bi = B[i];
(*out_mem) = comparator(Ai,Bi) ? Ai : Bi;
}
}
#endif
}
else
{
@@ -30,6 +30,7 @@ struct glue_powext
template<typename eT> inline static void apply(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B);
// TODO: deprecated; remove in next major version
template<typename parent, unsigned int mode, typename T2> inline static Mat<typename parent::elem_type> apply(const subview_each1<parent,mode>& X, const Base<typename parent::elem_type,T2>& Y);
//
@@ -38,6 +39,7 @@ struct glue_powext
template<typename eT> inline static void apply(Cube<eT>& out, const Cube<eT>& A, const Cube<eT>& B);
// TODO: deprecated; remove in next major version
template<typename eT, typename T2> inline static Cube<eT> apply(const subview_cube_each1<eT>& X, const Base<eT,T2>& Y);
};
@@ -50,6 +52,7 @@ struct glue_powext_cx
template<typename T> inline static void apply(Mat< std::complex<T> >& out, const Mat< std::complex<T> >& A, const Mat<T>& B);
// TODO: deprecated; remove in next major version
template<typename parent, unsigned int mode, typename T2> inline static Mat<typename parent::elem_type> apply(const subview_each1<parent,mode>& X, const Base<typename T2::elem_type,T2>& Y);
//
@@ -58,6 +61,7 @@ struct glue_powext_cx
template<typename T> inline static void apply(Cube< std::complex<T> >& out, const Cube< std::complex<T> >& A, const Cube<T>& B);
// TODO: deprecated; remove in next major version
template<typename T, typename T2> inline static Cube< std::complex<T> > apply(const subview_cube_each1< std::complex<T> >& X, const Base<T,T2>& Y);
};
@@ -97,6 +97,7 @@ glue_powext::apply(Mat<eT>& out, const Mat<eT>& A, const Mat<eT>& B)
// TODO: deprecated; remove in next major version
template<typename parent, unsigned int mode, typename T2>
inline
Mat<typename parent::elem_type>
@@ -280,6 +281,7 @@ glue_powext::apply(Cube<eT>& out, const Cube<eT>& A, const Cube<eT>& B)
// TODO: deprecated; remove in next major version
template<typename eT, typename T2>
inline
Cube<eT>
@@ -426,6 +428,7 @@ glue_powext_cx::apply(Mat< std::complex<T> >& out, const Mat< std::complex<T> >&
// TODO: deprecated; remove in next major version
template<typename parent, unsigned int mode, typename T2>
inline
Mat<typename parent::elem_type>
@@ -603,6 +606,7 @@ glue_powext_cx::apply(Cube< std::complex<T> >& out, const Cube< std::complex<T>
// TODO: deprecated; remove in next major version
template<typename T, typename T2>
inline
Cube< std::complex<T> >
+3 -3
View File
@@ -380,7 +380,7 @@ glue_solve_gen_full::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, const
}
else
{
arma_warn(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution");
arma_warn(2, "solve(): system is singular; rcond: ", rcond, "; attempting approx solution");
}
// TODO: conditionally recreate A: have a separate state flag which indicates whether A was previously overwritten
@@ -472,7 +472,7 @@ glue_solve_tri_default::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, co
}
else
{
arma_warn(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution");
arma_warn(2, "solve(): system is singular; rcond: ", rcond, "; attempting approx solution");
}
Mat<eT> triA = (triu) ? trimatu(A) : trimatl(A); // trimatu() and trimatl() return the same type
@@ -598,7 +598,7 @@ glue_solve_tri_full::apply(Mat<eT>& actual_out, const Base<eT,T1>& A_expr, const
}
else
{
arma_warn(2, "solve(): system is singular (rcond: ", rcond, "); attempting approx solution");
arma_warn(2, "solve(): system is singular; rcond: ", rcond, "; attempting approx solution");
}
Mat<eT> triA = (triu) ? trimatu(A) : trimatl(A); // trimatu() and trimatl() return the same type
+4 -4
View File
@@ -109,11 +109,11 @@ glue_times_redirect2_helper<true, check_alias>::apply(Mat<typename T1::elem_type
if( (is_cx<eT>::no) && (strip_inv<T1>::do_inv_gen) && (is_Mat<T1_stripped>::value) && (is_Mat<T2>::value) )
{
const unwrap<T1_stripped> UA(A_strip.M);
const unwrap<T2 > UB(X.B);
const plain_unwrap<T1_stripped> UA(A_strip.M);
const plain_unwrap<T2 > UB(X.B);
const typename unwrap<T1_stripped>::stored_type& A = UA.M;
const typename unwrap<T2 >::stored_type& B = UB.M;
const typename plain_unwrap<T1_stripped>::stored_type& A = UA.M;
const typename plain_unwrap<T2 >::stored_type& B = UB.M;
const uword N = A.n_rows;
+17 -17
View File
@@ -137,9 +137,9 @@ gmm_diag<eT>::set_params(const Base<eT,T1>& in_means_expr, const Base<eT,T2>& in
{
arma_debug_sigprint();
const unwrap<T1> tmp1(in_means_expr.get_ref());
const unwrap<T2> tmp2(in_dcovs_expr.get_ref());
const unwrap<T3> tmp3(in_hefts_expr.get_ref());
const plain_unwrap<T1> tmp1(in_means_expr.get_ref());
const plain_unwrap<T2> tmp2(in_dcovs_expr.get_ref());
const plain_unwrap<T3> tmp3(in_hefts_expr.get_ref());
const Mat<eT>& in_means = tmp1.M;
const Mat<eT>& in_dcovs = tmp2.M;
@@ -179,7 +179,7 @@ gmm_diag<eT>::set_means(const Base<eT,T1>& in_means_expr)
{
arma_debug_sigprint();
const unwrap<T1> tmp(in_means_expr.get_ref());
const plain_unwrap<T1> tmp(in_means_expr.get_ref());
const Mat<eT>& in_means = tmp.M;
@@ -199,7 +199,7 @@ gmm_diag<eT>::set_dcovs(const Base<eT,T1>& in_dcovs_expr)
{
arma_debug_sigprint();
const unwrap<T1> tmp(in_dcovs_expr.get_ref());
const plain_unwrap<T1> tmp(in_dcovs_expr.get_ref());
const Mat<eT>& in_dcovs = tmp.M;
@@ -222,7 +222,7 @@ gmm_diag<eT>::set_hefts(const Base<eT,T1>& in_hefts_expr)
{
arma_debug_sigprint();
const unwrap<T1> tmp(in_hefts_expr.get_ref());
const plain_unwrap<T1> tmp(in_hefts_expr.get_ref());
const Mat<eT>& in_hefts = tmp.M;
@@ -602,8 +602,8 @@ gmm_diag<eT>::raw_hist(const Base<eT,T1>& expr, const gmm_dist_mode& dist_mode)
{
arma_debug_sigprint();
const unwrap<T1> tmp(expr.get_ref());
const Mat<eT>& X = tmp.M;
const plain_unwrap<T1> tmp(expr.get_ref());
const Mat<eT>& X = tmp.M;
arma_conform_check( (X.n_rows != means.n_rows), "gmm_diag::raw_hist(): incompatible dimensions" );
@@ -626,8 +626,8 @@ gmm_diag<eT>::norm_hist(const Base<eT,T1>& expr, const gmm_dist_mode& dist_mode)
{
arma_debug_sigprint();
const unwrap<T1> tmp(expr.get_ref());
const Mat<eT>& X = tmp.M;
const plain_unwrap<T1> tmp(expr.get_ref());
const Mat<eT>& X = tmp.M;
arma_conform_check( (X.n_rows != means.n_rows), "gmm_diag::norm_hist(): incompatible dimensions" );
@@ -683,12 +683,12 @@ gmm_diag<eT>::learn
|| (seed_mode == random_subset)
|| (seed_mode == random_spread);
arma_conform_check( (dist_mode_ok == false), "gmm_diag::learn(): dist_mode must be eucl_dist or maha_dist" );
arma_conform_check( (seed_mode_ok == false), "gmm_diag::learn(): unknown seed_mode" );
arma_conform_check( (var_floor < eT(0) ), "gmm_diag::learn(): variance floor is negative" );
arma_conform_check( (dist_mode_ok == false), "gmm_diag::learn(): dist_mode must be eucl_dist or maha_dist" );
arma_conform_check( (seed_mode_ok == false), "gmm_diag::learn(): unknown seed_mode" );
arma_conform_check( ((var_floor >= eT(0)) == false), "gmm_diag::learn(): variance floor must be > 0" );
const unwrap<T1> tmp_X(data.get_ref());
const Mat<eT>& X = tmp_X.M;
const plain_unwrap<T1> tmp_X(data.get_ref());
const Mat<eT>& X = tmp_X.M;
if(X.is_empty() ) { arma_warn(3, "gmm_diag::learn(): given matrix is empty" ); return false; }
if(X.internal_has_nonfinite()) { arma_warn(3, "gmm_diag::learn(): given matrix has non-finite values"); return false; }
@@ -815,8 +815,8 @@ gmm_diag<eT>::kmeans_wrapper
arma_conform_check( (seed_mode_ok == false), "kmeans(): unknown seed_mode" );
const unwrap<T1> tmp_X(data.get_ref());
const Mat<eT>& X = tmp_X.M;
const plain_unwrap<T1> tmp_X(data.get_ref());
const Mat<eT>& X = tmp_X.M;
if(X.is_empty() ) { arma_warn(3, "kmeans(): given matrix is empty" ); return false; }
if(X.internal_has_nonfinite()) { arma_warn(3, "kmeans(): given matrix has non-finite values"); return false; }
+14 -14
View File
@@ -137,9 +137,9 @@ gmm_full<eT>::set_params(const Base<eT,T1>& in_means_expr, const BaseCube<eT,T2>
{
arma_debug_sigprint();
const unwrap <T1> tmp1(in_means_expr.get_ref());
const unwrap_cube<T2> tmp2(in_fcovs_expr.get_ref());
const unwrap <T3> tmp3(in_hefts_expr.get_ref());
const plain_unwrap <T1> tmp1(in_means_expr.get_ref());
const unwrap_cube<T2> tmp2(in_fcovs_expr.get_ref());
const plain_unwrap <T3> tmp3(in_hefts_expr.get_ref());
const Mat <eT>& in_means = tmp1.M;
const Cube<eT>& in_fcovs = tmp2.M;
@@ -183,7 +183,7 @@ gmm_full<eT>::set_means(const Base<eT,T1>& in_means_expr)
{
arma_debug_sigprint();
const unwrap<T1> tmp(in_means_expr.get_ref());
const plain_unwrap<T1> tmp(in_means_expr.get_ref());
const Mat<eT>& in_means = tmp.M;
@@ -230,7 +230,7 @@ gmm_full<eT>::set_hefts(const Base<eT,T1>& in_hefts_expr)
{
arma_debug_sigprint();
const unwrap<T1> tmp(in_hefts_expr.get_ref());
const plain_unwrap<T1> tmp(in_hefts_expr.get_ref());
const Mat<eT>& in_hefts = tmp.M;
@@ -641,8 +641,8 @@ gmm_full<eT>::raw_hist(const Base<eT,T1>& expr, const gmm_dist_mode& dist_mode)
{
arma_debug_sigprint();
const unwrap<T1> tmp(expr.get_ref());
const Mat<eT>& X = tmp.M;
const plain_unwrap<T1> tmp(expr.get_ref());
const Mat<eT>& X = tmp.M;
arma_conform_check( (X.n_rows != means.n_rows), "gmm_full::raw_hist(): incompatible dimensions" );
@@ -665,8 +665,8 @@ gmm_full<eT>::norm_hist(const Base<eT,T1>& expr, const gmm_dist_mode& dist_mode)
{
arma_debug_sigprint();
const unwrap<T1> tmp(expr.get_ref());
const Mat<eT>& X = tmp.M;
const plain_unwrap<T1> tmp(expr.get_ref());
const Mat<eT>& X = tmp.M;
arma_conform_check( (X.n_rows != means.n_rows), "gmm_full::norm_hist(): incompatible dimensions" );
@@ -722,12 +722,12 @@ gmm_full<eT>::learn
|| (seed_mode == random_subset)
|| (seed_mode == random_spread);
arma_conform_check( (dist_mode_ok == false), "gmm_full::learn(): dist_mode must be eucl_dist or maha_dist" );
arma_conform_check( (seed_mode_ok == false), "gmm_full::learn(): unknown seed_mode" );
arma_conform_check( (var_floor < eT(0) ), "gmm_full::learn(): variance floor is negative" );
arma_conform_check( (dist_mode_ok == false), "gmm_full::learn(): dist_mode must be eucl_dist or maha_dist" );
arma_conform_check( (seed_mode_ok == false), "gmm_full::learn(): unknown seed_mode" );
arma_conform_check( ((var_floor >= eT(0)) == false), "gmm_full::learn(): variance floor must be > 0" );
const unwrap<T1> tmp_X(data.get_ref());
const Mat<eT>& X = tmp_X.M;
const plain_unwrap<T1> tmp_X(data.get_ref());
const Mat<eT>& X = tmp_X.M;
if(X.is_empty() ) { arma_warn(3, "gmm_full::learn(): given matrix is empty" ); return false; }
if(X.internal_has_nonfinite()) { arma_warn(3, "gmm_full::learn(): given matrix has non-finite values"); return false; }
+5 -5
View File
@@ -22,9 +22,8 @@
struct memory
{
template<typename eT> arma_malloc inline static eT* acquire(const uword n_elem);
template<typename eT> arma_inline static void release(eT* mem);
template<typename eT> arma_inline static eT* acquire(const uword n_elem);
template<typename eT> arma_inline static void release( eT* mem );
template<typename eT> arma_inline static bool is_aligned(const eT* mem);
template<typename eT> arma_inline static void mark_as_aligned( eT*& mem);
@@ -33,9 +32,10 @@ struct memory
// NOTE: arma_inline is used as a partial workaround for bugs in GCC 15:
// NOTE: false positive warnings from -Wmismatched-new-delete and -Wmaybe-uninitialized
template<typename eT>
arma_malloc
inline
arma_inline
eT*
memory::acquire(const uword n_elem)
{
+2 -2
View File
@@ -22,7 +22,7 @@
template<typename eT, const bool use_smaller_thresh = false>
template<typename eT, const bool use_half_threshold = false>
struct mp_gate
{
arma_inline
@@ -32,7 +32,7 @@ struct mp_gate
{
#if defined(ARMA_USE_OPENMP)
{
const bool length_ok = (is_cx<eT>::yes || use_smaller_thresh) ? (n_elem >= (arma_config::mp_threshold/uword(2))) : (n_elem >= arma_config::mp_threshold);
const bool length_ok = (is_cx<eT>::yes || use_half_threshold) ? (n_elem >= (arma_config::mp_threshold/uword(2))) : (n_elem >= arma_config::mp_threshold);
return (length_ok) ? (bool(omp_in_parallel()) == false) : false;
}
@@ -27,6 +27,8 @@ struct mtGlueCube : public BaseCube< out_eT, mtGlueCube<out_eT, T1, T2, glue_typ
typedef out_eT elem_type;
typedef typename get_pod_type<out_eT>::result pod_type;
static constexpr bool has_subview = T1::has_subview || T2::has_subview;
arma_inline mtGlueCube(const T1& in_A, const T2& in_B);
arma_inline mtGlueCube(const T1& in_A, const T2& in_B, const uword in_aux_uword);
arma_inline ~mtGlueCube();
+2
View File
@@ -31,6 +31,8 @@ struct mtGlue : public Base< out_eT, mtGlue<out_eT, T1, T2, glue_type> >
static constexpr bool is_col = glue_type::template traits<T1,T2>::is_col;
static constexpr bool is_xvec = glue_type::template traits<T1,T2>::is_xvec;
static constexpr bool has_subview = T1::has_subview || T2::has_subview;
arma_inline mtGlue(const T1& in_A, const T2& in_B);
arma_inline mtGlue(const T1& in_A, const T2& in_B, const uword in_aux_uword);
arma_inline ~mtGlue();
@@ -32,6 +32,8 @@ struct mtOpCube : public BaseCube< out_eT, mtOpCube<out_eT, T1, op_type> >
typedef typename T1::elem_type in_eT;
static constexpr bool has_subview = T1::has_subview;
inline explicit mtOpCube(const T1& in_m);
inline mtOpCube(const T1& in_m, const in_eT in_aux);
inline mtOpCube(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b, const uword in_aux_uword_c);
+2
View File
@@ -35,6 +35,8 @@ struct mtOp : public Base< out_eT, mtOp<out_eT, T1, op_type> >
static constexpr bool is_col = op_type::template traits<T1>::is_col;
static constexpr bool is_xvec = op_type::template traits<T1>::is_xvec;
static constexpr bool has_subview = T1::has_subview;
inline explicit mtOp(const T1& in_m);
inline mtOp(const T1& in_m, const in_eT in_aux);
inline mtOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
@@ -31,6 +31,8 @@ struct mtSpGlue : public SpBase< out_eT, mtSpGlue<out_eT, T1, T2, spglue_type> >
static constexpr bool is_col = spglue_type::template traits<T1,T2>::is_col;
static constexpr bool is_xvec = spglue_type::template traits<T1,T2>::is_xvec;
static constexpr bool has_subview = T1::has_subview || T2::has_subview;
inline mtSpGlue(const T1& in_A, const T2& in_B);
inline ~mtSpGlue();
+2
View File
@@ -36,6 +36,8 @@ struct mtSpOp : public SpBase< out_eT, mtSpOp<out_eT, T1, spop_type> >
static constexpr bool is_col = spop_type::template traits<T1>::is_col;
static constexpr bool is_xvec = spop_type::template traits<T1>::is_xvec;
static constexpr bool has_subview = T1::has_subview;
inline explicit mtSpOp(const T1& in_m);
inline mtSpOp(const T1& in_m, const in_eT in_aux);
inline mtSpOp(const T1& in_m, const uword aux_uword_a, const uword aux_uword_b);
+1 -1
View File
@@ -94,7 +94,7 @@ arma_inline
bool
mtSpOp<out_eT, T1, op_type>::is_alias(const SpMat<eT2>& X) const
{
return (void_ptr(&X) == void_ptr(&m));
return m.is_alias(X);
}
@@ -46,10 +46,15 @@ struct mtSpReduceOp : public SpBase< out_eT, mtSpReduceOp<out_eT, T1, op_type> >
static constexpr bool is_col = op_type::template traits<T1>::is_col;
static constexpr bool is_xvec = op_type::template traits<T1>::is_xvec;
static constexpr bool has_subview = T1::has_subview;
inline explicit mtSpReduceOp(const T1& in_m);
inline mtSpReduceOp(const T1& in_m, const uword in_aux_uword_a, const uword in_aux_uword_b);
inline ~mtSpReduceOp();
template<typename eT2>
arma_inline bool is_alias(const SpMat<eT2>& X) const;
const T1& m; //!< the operand; must be derived from SpBase
uword aux_uword_a; //!< auxiliary data, uword format
uword aux_uword_b; //!< auxiliary data, uword format
@@ -52,4 +52,15 @@ mtSpReduceOp<out_eT, T1, op_type>::~mtSpReduceOp()
template<typename out_eT, typename T1, typename op_type>
template<typename eT2>
arma_inline
bool
mtSpReduceOp<out_eT, T1, op_type>::is_alias(const SpMat<eT2>& X) const
{
return m.is_alias(X);
}
//! @}
@@ -77,8 +77,8 @@ SparseGenRealShiftSolve<eT>::SparseGenRealShiftSolve(const SpMat<eT>& mat_obj, c
if( (x_rcond < std::numeric_limits<eT>::epsilon()) || arma_isnan(x_rcond) )
{
if(x_rcond == eT(0)) { arma_warn(2, "matrix is singular to working precision"); }
else { arma_warn(2, "matrix is singular to working precision (rcond: ", x_rcond, ")"); }
if(x_rcond == eT(0)) { arma_warn(2, "matrix is singular to working precision"); }
else { arma_warn(2, "matrix is singular to working precision; rcond: ", x_rcond); }
return;
}
+8
View File
@@ -80,6 +80,8 @@ op_accu_mat::apply_proxy_at(const Proxy<T1>& P)
const uword n_rows = P.get_n_rows();
const uword n_cols = P.get_n_cols();
if(n_rows == 0) { return eT(0); }
eT val = eT(0);
if(n_rows != 1)
@@ -146,6 +148,8 @@ op_accu_mat::apply_omit_helper(const Proxy<T1>& P, functor is_omitted)
const uword n_rows = P.get_n_rows();
const uword n_cols = P.get_n_cols();
if(n_rows == 0) { return eT_zero; }
for(uword c=0; c < n_cols; ++c)
for(uword r=0; r < n_rows; ++r)
{
@@ -602,6 +606,8 @@ op_accu_mat::apply(const subview<eT>& X)
const uword X_n_rows = X.n_rows;
const uword X_n_cols = X.n_cols;
if( (X_n_rows == 0) || (X_n_cols == 0) ) { return eT(0); }
if(X_n_rows == 1)
{
const uword X_m_n_rows = X.m.n_rows;
@@ -750,6 +756,8 @@ op_accu_cube::apply_proxy_at(const ProxyCube<T1>& P)
const uword n_cols = P.get_n_cols();
const uword n_slices = P.get_n_slices();
if( (n_rows == 0) || (n_cols == 0) ) { return eT(0); }
eT val1 = eT(0);
eT val2 = eT(0);
+13 -13
View File
@@ -34,11 +34,11 @@ op_clamp::apply(Mat<typename T1::elem_type>& out, const mtOp<typename T1::elem_t
const eT min_val = in.aux;
const eT max_val = in.aux_out_eT;
arma_conform_check( (min_val > max_val), "clamp(): min_val must be less than max_val" );
arma_conform_check( ((min_val <= max_val) == false), "clamp(): min_val must be less than max_val" );
if(is_Mat<T1>::value)
{
const unwrap<T1> U(in.m);
const plain_unwrap<T1> U(in.m);
// detect in-place operation
if(&out == &(U.M))
@@ -83,7 +83,7 @@ op_clamp::apply(Mat_noalias<typename T1::elem_type>& out, const mtOp<typename T1
const eT min_val = in.aux;
const eT max_val = in.aux_out_eT;
arma_conform_check( (min_val > max_val), "clamp(): min_val must be less than max_val" );
arma_conform_check( ((min_val <= max_val) == false), "clamp(): min_val must be less than max_val" );
if((quasi_unwrap<T1>::has_orig_mem) || (is_Mat<typename Proxy<T1>::stored_type>::value) || (arma_config::openmp && Proxy<T1>::use_mp))
{
@@ -186,7 +186,7 @@ op_clamp::apply(Cube<typename T1::elem_type>& out, const mtOpCube<typename T1::e
const eT min_val = in.aux;
const eT max_val = in.aux_out_eT;
arma_conform_check( (min_val > max_val), "clamp(): min_val must be less than max_val" );
arma_conform_check( ((min_val <= max_val) == false), "clamp(): min_val must be less than max_val" );
if(is_Cube<T1>::value)
{
@@ -310,7 +310,7 @@ op_clamp_cx::apply(Mat<typename T1::elem_type>& out, const mtOp<typename T1::ele
if(is_Mat<T1>::value)
{
const unwrap<T1> U(in.m);
const plain_unwrap<T1> U(in.m);
op_clamp_cx::apply_direct(out, U.M, in.aux, in.aux_out_eT);
}
@@ -350,8 +350,8 @@ op_clamp_cx::apply_direct(Mat<eT>& out, const Mat<eT>& X, const eT min_val, cons
const T max_val_real = std::real(max_val);
const T max_val_imag = std::imag(max_val);
arma_conform_check( (min_val_real > max_val_real), "clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( (min_val_imag > max_val_imag), "clamp(): imag(min_val) must be less than imag(max_val)" );
arma_conform_check( ((min_val_real <= max_val_real) == false), "clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( ((min_val_imag <= max_val_imag) == false), "clamp(): imag(min_val) must be less than imag(max_val)" );
if(&out != &X)
{
@@ -401,8 +401,8 @@ op_clamp_cx::apply_proxy_noalias(Mat<typename T1::elem_type>& out, const Proxy<T
const T max_val_real = std::real(max_val);
const T max_val_imag = std::imag(max_val);
arma_conform_check( (min_val_real > max_val_real), "clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( (min_val_imag > max_val_imag), "clamp(): imag(min_val) must be less than imag(max_val)" );
arma_conform_check( ((min_val_real <= max_val_real) == false), "clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( ((min_val_imag <= max_val_imag) == false), "clamp(): imag(min_val) must be less than imag(max_val)" );
const uword n_rows = P.get_n_rows();
const uword n_cols = P.get_n_cols();
@@ -503,8 +503,8 @@ op_clamp_cx::apply_direct(Cube<eT>& out, const Cube<eT>& X, const eT min_val, co
const T max_val_real = std::real(max_val);
const T max_val_imag = std::imag(max_val);
arma_conform_check( (min_val_real > max_val_real), "clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( (min_val_imag > max_val_imag), "clamp(): imag(min_val) must be less than imag(max_val)" );
arma_conform_check( ((min_val_real <= max_val_real) == false), "clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( ((min_val_imag <= max_val_imag) == false), "clamp(): imag(min_val) must be less than imag(max_val)" );
if(&out != &X)
{
@@ -554,8 +554,8 @@ op_clamp_cx::apply_proxy_noalias(Cube<typename T1::elem_type>& out, const ProxyC
const T max_val_real = std::real(max_val);
const T max_val_imag = std::imag(max_val);
arma_conform_check( (min_val_real > max_val_real), "clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( (min_val_imag > max_val_imag), "clamp(): imag(min_val) must be less than imag(max_val)" );
arma_conform_check( ((min_val_real <= max_val_real) == false), "clamp(): real(min_val) must be less than real(max_val)" );
arma_conform_check( ((min_val_imag <= max_val_imag) == false), "clamp(): imag(min_val) must be less than imag(max_val)" );
const uword n_rows = P.get_n_rows();
const uword n_cols = P.get_n_cols();
+4 -4
View File
@@ -33,8 +33,8 @@ op_cor::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cor>& in)
const uword norm_type = in.aux_uword_a;
const unwrap<T1> U(in.m);
const Mat<eT>& A = U.M;
const plain_unwrap<T1> U(in.m);
const Mat<eT>& A = U.M;
if(A.n_elem == 0)
{
@@ -87,8 +87,8 @@ op_cor::apply(Mat<typename T1::elem_type>& out, const Op< Op<T1,op_htrans>, op_c
}
else
{
const unwrap<T1> U(in.m.m);
const Mat<eT>& A = U.M;
const plain_unwrap<T1> U(in.m.m);
const Mat<eT>& A = U.M;
if(A.n_elem == 0)
{
+4 -4
View File
@@ -33,8 +33,8 @@ op_cov::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_cov>& in)
const uword norm_type = in.aux_uword_a;
const unwrap<T1> U(in.m);
const Mat<eT>& A = U.M;
const plain_unwrap<T1> U(in.m);
const Mat<eT>& A = U.M;
if(A.n_elem == 0)
{
@@ -76,8 +76,8 @@ op_cov::apply(Mat<typename T1::elem_type>& out, const Op< Op<T1,op_htrans>, op_c
}
else
{
const unwrap<T1> U(in.m.m);
const Mat<eT>& A = U.M;
const plain_unwrap<T1> U(in.m.m);
const Mat<eT>& A = U.M;
if(A.n_elem == 0)
{
@@ -27,12 +27,20 @@ struct op_diagmat
template<typename T1>
inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_diagmat>& X);
template<typename T1>
inline static void apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1,op_diagmat>& X);
template<typename T1>
inline static void apply(Mat<typename T1::elem_type>& out, const Proxy<T1>& P);
//
template<typename T1, typename T2>
inline static void apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagmat>& X);
template<typename T1, typename T2>
inline static void apply(Mat_noalias<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagmat>& X);
template<typename T1, typename T2>
inline static void apply_times(Mat<typename T1::elem_type>& out, const T1& X, const T2& Y, const typename arma_not_cx<typename T1::elem_type>::result* junk = nullptr);
@@ -48,6 +56,9 @@ struct op_diagmat2
template<typename T1>
inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_diagmat2>& X);
template<typename T1>
inline static void apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1,op_diagmat2>& X);
template<typename T1>
inline static void apply(Mat<typename T1::elem_type>& out, const Proxy<T1>& P, const uword row_offset, const uword col_offset);
};
+76 -34
View File
@@ -34,8 +34,8 @@ op_diagmat::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagmat>& X)
{
// allow detection of in-place operation
const unwrap<T1> U(X.m);
const Mat<eT>& A = U.M;
const plain_unwrap<T1> U(X.m);
const Mat<eT>& A = U.M;
if(&out != &A) // no aliasing
{
@@ -104,6 +104,20 @@ op_diagmat::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagmat>& X)
template<typename T1>
inline
void
op_diagmat::apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1, op_diagmat>& X)
{
arma_debug_sigprint();
const Proxy<T1> P(X.m);
op_diagmat::apply(out, P);
}
template<typename T1>
inline
void
@@ -160,6 +174,31 @@ op_diagmat::apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_ti
{
arma_debug_sigprint();
typedef typename T1::elem_type eT;
if(X.m.is_alias(out))
{
Mat<eT> tmp;
op_diagmat::apply_times(tmp, X.m.A, X.m.B);
out.steal_mem(tmp);
}
else
{
op_diagmat::apply_times(out, X.m.A, X.m.B);
}
}
template<typename T1, typename T2>
inline
void
op_diagmat::apply(Mat_noalias<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagmat>& X)
{
arma_debug_sigprint();
op_diagmat::apply_times(out, X.m.A, X.m.B);
}
@@ -168,7 +207,7 @@ op_diagmat::apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_ti
template<typename T1, typename T2>
inline
void
op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, const T2& Y, const typename arma_not_cx<typename T1::elem_type>::result* junk)
op_diagmat::apply_times(Mat<typename T1::elem_type>& out, const T1& X, const T2& Y, const typename arma_not_cx<typename T1::elem_type>::result* junk)
{
arma_debug_sigprint();
arma_ignore(junk);
@@ -204,9 +243,9 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
const eT* C_mem = C.memptr();
const uword N = C.n_elem;
actual_out.zeros(N,N);
out.zeros(N,N);
for(uword i=0; i<N; ++i) { actual_out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
for(uword i=0; i<N; ++i) { out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
return;
}
@@ -222,9 +261,9 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
const eT* C_mem = C.memptr();
const uword N = C.n_elem;
actual_out.zeros(N,N);
out.zeros(N,N);
for(uword i=0; i<N; ++i) { actual_out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
for(uword i=0; i<N; ++i) { out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
return;
}
@@ -240,9 +279,9 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
const eT* C_mem = C.memptr();
const uword N = C.n_elem;
actual_out.zeros(N,N);
out.zeros(N,N);
for(uword i=0; i<N; ++i) { actual_out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
for(uword i=0; i<N; ++i) { out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
return;
}
@@ -258,20 +297,15 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
const eT* C_mem = C.memptr();
const uword N = C.n_elem;
actual_out.zeros(N,N);
out.zeros(N,N);
for(uword i=0; i<N; ++i) { actual_out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
for(uword i=0; i<N; ++i) { out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
return;
}
}
// if we got to this point, the multiplication results in a matrix
const bool is_alias = (UA.is_alias(actual_out) || UB.is_alias(actual_out));
Mat<eT> tmp;
Mat<eT>& out = (is_alias) ? tmp : actual_out;
if( (partial_unwrap<T1>::do_trans == false) && (partial_unwrap<T2>::do_trans == false) )
{
@@ -384,8 +418,6 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
out.at(k,k) = (use_alpha) ? eT(alpha * acc) : eT(acc);
}
}
if(is_alias) { actual_out.steal_mem(tmp); }
}
@@ -393,7 +425,7 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
template<typename T1, typename T2>
inline
void
op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, const T2& Y, const typename arma_cx_only<typename T1::elem_type>::result* junk)
op_diagmat::apply_times(Mat<typename T1::elem_type>& out, const T1& X, const T2& Y, const typename arma_cx_only<typename T1::elem_type>::result* junk)
{
arma_debug_sigprint();
arma_ignore(junk);
@@ -430,9 +462,9 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
const eT* C_mem = C.memptr();
const uword N = C.n_elem;
actual_out.zeros(N,N);
out.zeros(N,N);
for(uword i=0; i<N; ++i) { actual_out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
for(uword i=0; i<N; ++i) { out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
return;
}
@@ -448,9 +480,9 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
const eT* C_mem = C.memptr();
const uword N = C.n_elem;
actual_out.zeros(N,N);
out.zeros(N,N);
for(uword i=0; i<N; ++i) { actual_out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
for(uword i=0; i<N; ++i) { out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
return;
}
@@ -466,9 +498,9 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
const eT* C_mem = C.memptr();
const uword N = C.n_elem;
actual_out.zeros(N,N);
out.zeros(N,N);
for(uword i=0; i<N; ++i) { actual_out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
for(uword i=0; i<N; ++i) { out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
return;
}
@@ -484,20 +516,15 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
const eT* C_mem = C.memptr();
const uword N = C.n_elem;
actual_out.zeros(N,N);
out.zeros(N,N);
for(uword i=0; i<N; ++i) { actual_out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
for(uword i=0; i<N; ++i) { out.at(i,i) = (use_alpha) ? eT(alpha * C_mem[i]) : eT(C_mem[i]); }
return;
}
}
// if we got to this point, the multiplication results in a matrix
const bool is_alias = (UA.is_alias(actual_out) || UB.is_alias(actual_out));
Mat<eT> tmp;
Mat<eT>& out = (is_alias) ? tmp : actual_out;
if( (partial_unwrap<T1>::do_trans == false) && (partial_unwrap<T2>::do_trans == false) )
{
@@ -659,8 +686,6 @@ op_diagmat::apply_times(Mat<typename T1::elem_type>& actual_out, const T1& X, co
out.at(k,k) = (use_alpha) ? eT(alpha * acc) : eT(acc);
}
}
if(is_alias) { actual_out.steal_mem(tmp); }
}
@@ -701,6 +726,23 @@ op_diagmat2::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagmat2>&
template<typename T1>
inline
void
op_diagmat2::apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1, op_diagmat2>& X)
{
arma_debug_sigprint();
const uword row_offset = X.aux_uword_a;
const uword col_offset = X.aux_uword_b;
const Proxy<T1> P(X.m);
op_diagmat2::apply(out, P, row_offset, col_offset);
}
template<typename T1>
inline
void
+17 -3
View File
@@ -27,14 +27,25 @@ struct op_diagvec
template<typename T1>
inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_diagvec>& X);
template<typename T1>
inline static void apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1,op_diagvec>& X);
template<typename T1>
inline static void apply_proxy(Mat<typename T1::elem_type>& out, const Proxy<T1>& P);
template<typename T1, typename T2>
inline static void apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagvec>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = nullptr);
//
template<typename T1, typename T2>
inline static void apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagvec>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk = nullptr);
inline static void apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagvec>& X);
template<typename T1, typename T2>
inline static void apply(Mat_noalias<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagvec>& X);
template<typename T1, typename T2>
inline static void apply_glue_times(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk = nullptr);
template<typename T1, typename T2>
inline static void apply_glue_times(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk = nullptr);
};
@@ -45,6 +56,9 @@ struct op_diagvec2
template<typename T1>
inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_diagvec2>& X);
template<typename T1>
inline static void apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1,op_diagvec2>& X);
template<typename T1>
inline static void apply_proxy(Mat<typename T1::elem_type>& out, const Proxy<T1>& P, const uword row_offset, const uword col_offset);
};
+79 -22
View File
@@ -48,6 +48,20 @@ op_diagvec::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagvec>& X)
template<typename T1>
inline
void
op_diagvec::apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1, op_diagvec>& X)
{
arma_debug_sigprint();
const Proxy<T1> P(X.m);
op_diagvec::apply_proxy(out, P);
}
template<typename T1>
inline
void
@@ -87,31 +101,63 @@ op_diagvec::apply_proxy(Mat<typename T1::elem_type>& out, const Proxy<T1>& P)
template<typename T1, typename T2>
inline
void
op_diagvec::apply(Mat<typename T1::elem_type>& actual_out, const Op< Glue<T1,T2,glue_times>, op_diagvec>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk)
op_diagvec::apply(Mat<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagvec>& X)
{
arma_debug_sigprint();
typedef typename T1::elem_type eT;
if(X.m.is_alias(out))
{
Mat<eT> tmp;
op_diagvec::apply_glue_times(tmp, X.m);
out.steal_mem(tmp);
}
else
{
op_diagvec::apply_glue_times(out, X.m);
}
}
template<typename T1, typename T2>
inline
void
op_diagvec::apply(Mat_noalias<typename T1::elem_type>& out, const Op< Glue<T1,T2,glue_times>, op_diagvec>& X)
{
arma_debug_sigprint();
op_diagvec::apply_glue_times(out, X.m);
}
template<typename T1, typename T2>
inline
void
op_diagvec::apply_glue_times(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X, const typename arma_not_cx<typename T1::elem_type>::result* junk)
{
arma_debug_sigprint();
arma_ignore(junk);
typedef typename T1::elem_type eT;
const partial_unwrap<T1> UA(X.m.A);
const partial_unwrap<T2> UB(X.m.B);
const partial_unwrap<T1> UA(X.A);
const partial_unwrap<T2> UB(X.B);
const typename partial_unwrap<T1>::stored_type& A = UA.M;
const typename partial_unwrap<T2>::stored_type& B = UB.M;
arma_conform_assert_trans_mul_size< partial_unwrap<T1>::do_trans, partial_unwrap<T2>::do_trans >(A.n_rows, A.n_cols, B.n_rows, B.n_cols, "matrix multiplication");
if( (A.n_elem == 0) || (B.n_elem == 0) ) { actual_out.reset(); return; }
if( (A.n_elem == 0) || (B.n_elem == 0) ) { out.reset(); return; }
constexpr bool use_alpha = partial_unwrap<T1>::do_times || partial_unwrap<T2>::do_times;
const eT alpha = use_alpha ? (UA.get_val() * UB.get_val()) : eT(0);
const bool is_alias = (UA.is_alias(actual_out) || UB.is_alias(actual_out));
Mat<eT> tmp;
Mat<eT>& out = (is_alias) ? tmp : actual_out;
const uword A_n_rows = A.n_rows;
const uword A_n_cols = A.n_cols;
@@ -237,8 +283,6 @@ op_diagvec::apply(Mat<typename T1::elem_type>& actual_out, const Op< Glue<T1,T2,
out_mem[k] = (use_alpha) ? eT(alpha * acc) : eT(acc);
}
}
if(is_alias) { actual_out.steal_mem(tmp); }
}
@@ -246,7 +290,7 @@ op_diagvec::apply(Mat<typename T1::elem_type>& actual_out, const Op< Glue<T1,T2,
template<typename T1, typename T2>
inline
void
op_diagvec::apply(Mat<typename T1::elem_type>& actual_out, const Op< Glue<T1,T2,glue_times>, op_diagvec>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk)
op_diagvec::apply_glue_times(Mat<typename T1::elem_type>& out, const Glue<T1,T2,glue_times>& X, const typename arma_cx_only<typename T1::elem_type>::result* junk)
{
arma_debug_sigprint();
arma_ignore(junk);
@@ -254,24 +298,19 @@ op_diagvec::apply(Mat<typename T1::elem_type>& actual_out, const Op< Glue<T1,T2,
typedef typename T1::pod_type T;
typedef typename T1::elem_type eT;
const partial_unwrap<T1> UA(X.m.A);
const partial_unwrap<T2> UB(X.m.B);
const partial_unwrap<T1> UA(X.A);
const partial_unwrap<T2> UB(X.B);
const typename partial_unwrap<T1>::stored_type& A = UA.M;
const typename partial_unwrap<T2>::stored_type& B = UB.M;
arma_conform_assert_trans_mul_size< partial_unwrap<T1>::do_trans, partial_unwrap<T2>::do_trans >(A.n_rows, A.n_cols, B.n_rows, B.n_cols, "matrix multiplication");
if( (A.n_elem == 0) || (B.n_elem == 0) ) { actual_out.reset(); return; }
if( (A.n_elem == 0) || (B.n_elem == 0) ) { out.reset(); return; }
constexpr bool use_alpha = partial_unwrap<T1>::do_times || partial_unwrap<T2>::do_times;
const eT alpha = use_alpha ? (UA.get_val() * UB.get_val()) : eT(0);
const bool is_alias = (UA.is_alias(actual_out) || UB.is_alias(actual_out));
Mat<eT> tmp;
Mat<eT>& out = (is_alias) ? tmp : actual_out;
const uword A_n_rows = A.n_rows;
const uword A_n_cols = A.n_cols;
@@ -446,8 +485,6 @@ op_diagvec::apply(Mat<typename T1::elem_type>& actual_out, const Op< Glue<T1,T2,
out_mem[k] = (use_alpha) ? eT(alpha * acc) : eT(acc);
}
}
if(is_alias) { actual_out.steal_mem(tmp); }
}
@@ -491,6 +528,26 @@ op_diagvec2::apply(Mat<typename T1::elem_type>& out, const Op<T1, op_diagvec2>&
template<typename T1>
inline
void
op_diagvec2::apply(Mat_noalias<typename T1::elem_type>& out, const Op<T1, op_diagvec2>& X)
{
arma_debug_sigprint();
const uword a = X.aux_uword_a;
const uword b = X.aux_uword_b;
const uword row_offset = (b > 0) ? a : 0;
const uword col_offset = (b == 0) ? a : 0;
const Proxy<T1> P(X.m);
op_diagvec2::apply_proxy(out, P, row_offset, col_offset);
}
template<typename T1>
inline
void
+2 -2
View File
@@ -601,8 +601,8 @@ op_cdot::apply_unwrap(const T1& X, const T2& Y)
typedef typename T1::elem_type eT;
const unwrap<T1> tmp1(X);
const unwrap<T2> tmp2(Y);
const plain_unwrap<T1> tmp1(X);
const plain_unwrap<T2> tmp2(Y);
const Mat<eT>& A = tmp1.M;
const Mat<eT>& B = tmp2.M;

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