Compare commits

...
53 Commits
Author SHA1 Message Date
conrad 62d42aa54b note data race bug 2022-10-06 16:04:07 +10:00
conrad bb4d5a2a26 ensure sparse matrix arrays are valid 2022-07-22 13:17:19 +10:00
conrad 6d672b3d27 fix: zero out accumulation arrays at start of each iteration 2022-07-03 13:58:45 +10:00
conrad 107955b829 fix aliasing bug 2021-12-17 09:19:09 +10:00
conrad c42f1695db fix 2021-10-05 15:29:58 +10:00
conrad a523df82d2 recommend upgrading to Armadillo 10.6 2021-08-19 11:19:03 +10:00
conrad cd4e997759 clean up example 2021-08-18 11:00:11 +10:00
conrad ef22f9e5d7 patch bump 2021-08-17 12:26:31 +10:00
conrad 17e8ba2389 update catch (including backports) 2021-08-17 12:25:22 +10:00
conrad bbe6bf36f3 rename tests directory 2021-08-17 12:24:31 +10:00
conrad 202ec18f84 recommend upgrading to Armadillo 10.x 2021-08-11 14:05:40 +10:00
conrad d56779313b recommend upgrading to Armadillo 10.x 2021-08-09 14:44:24 +10:00
conrad df9c800bff fix error message 2021-08-03 20:54:41 +10:00
conrad 9b11ff441a better wording 2021-07-30 11:34:15 +10:00
conrad 595394b225 use quotes 2021-07-29 16:29:16 +10:00
conrad ec74c7f923 better wording 2021-07-29 16:27:35 +10:00
conrad 57d0ac754a fix comment 2021-07-05 23:25:02 +10:00
conrad 3a168fb11a fix for handling sparse matrices with no non-zero elements 2021-06-25 14:26:04 +10:00
conrad 0b95585c5e move check to avoid potential breakage 2021-05-26 12:17:13 +10:00
conrad 106cafdae4 fix for handling zeros on the diagonal 2021-05-12 18:11:15 +10:00
conrad 3253b180f1 fix 2021-04-08 17:07:16 +10:00
conrad 4f0db314d0 compile time warning about unsupported option 2021-04-01 17:07:55 +10:00
conrad a7408c2d59 fix 2021-03-30 17:20:32 +10:00
conrad 990654a040 fix warning message 2021-03-05 11:05:14 +10:00
conrad e7323b5426 avoid division by zero 2021-02-23 15:27:23 +10:00
conrad 24f62d1104 fix handling of compound expressions by rcond() 2021-02-17 10:41:22 +10:00
conrad cdd88d887c mention PyArmadillo 2021-02-15 12:30:13 +10:00
conrad 16340526fc remove unnecessary compiler warnings on unused results 2021-02-12 16:08:43 +10:00
conrad d426e49032 backport fix for median() 2021-02-04 11:54:37 +10:00
conrad 978b3b8419 backport workaround for hist() 2021-02-04 11:45:46 +10:00
conrad b9ed5bb03b remove unnecessary indentation 2021-01-28 13:31:58 +10:00
conrad 4531c83a7b patch bump 2021-01-25 15:15:11 +10:00
conrad 82c1f7ae44 backport workaround for pow() 2021-01-20 14:02:18 +10:00
conrad 7eda5dccfe spelling fix 2021-01-13 12:49:44 +10:00
conrad 6faee3565b update year 2021-01-13 11:47:54 +10:00
conrad fb8618dd7c update solver paper 2021-01-12 15:44:58 +10:00
conrad 77ca1c4d6c fix for princomp(cx_mat,cx_mat) 2021-01-09 18:19:08 +10:00
conrad 6f33da31c6 fix for cx_mat.elem().randn() 2021-01-09 15:59:42 +10:00
conrad 3d442ab0c3 update comments 2021-01-03 15:36:28 +10:00
conrad 33de4b2f4e warn on unused result 2021-01-03 14:27:30 +10:00
conrad 3bedbfb369 clarifications on use of NEWARP and ARPACK 2021-01-02 02:05:10 +10:00
conrad 0f3bee4183 use arma_abs() instead of std::abs() 2020-12-24 00:56:32 +10:00
conrad 8c6131d0ff use arma_abs() instead of std::abs() 2020-12-24 00:41:21 +10:00
conrad 9278f25e1a fix 2020-12-23 01:18:40 +10:00
conrad b3e6e8e33f use arma_abs() instead of std::abs() to handle unsigned integers 2020-12-08 12:56:38 +10:00
conrad c50076eeee expand sign() to handle nan 2020-12-05 13:11:17 +10:00
conrad 53ab9704f7 warn on unused result from .i() 2020-12-02 12:09:19 +10:00
conrad 0a6d648fe9 warn on unused result from .as_col() and .as_row() 2020-12-02 11:59:35 +10:00
conrad 9800fe428e fix 2020-11-13 14:01:34 +10:00
conrad 7381d1b255 remove no longer used variables 2020-11-13 13:53:50 +10:00
conrad 1f1c1ae725 fix 2020-11-02 12:03:14 +10:00
conrad 4595e66b89 fix 2020-10-26 13:16:07 +10:00
conrad 172df33aeb fix 2020-10-21 01:58:24 +10:00
123 changed files with 590 additions and 372 deletions
+1 -5
View File
@@ -196,8 +196,6 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake_au
if(APPLE)
message(STATUS "Detected macOS")
set(ARMA_OS macos)
set(ARMA_USE_LAPACK true)
set(ARMA_USE_BLAS true)
set(ARMA_USE_ACCELERATE true)
@@ -258,8 +256,6 @@ if(APPLE)
else()
set(ARMA_OS unix)
include(ARMA_FindMKL)
include(ARMA_FindACMLMP)
include(ARMA_FindACML)
@@ -651,5 +647,5 @@ install(FILES "${PROJECT_BINARY_DIR}/tmp/misc/armadillo.pc" DESTINATION ${CMAKE_
if(BUILD_SMOKE_TEST)
message(STATUS "*** configuring smoke_test")
enable_testing()
add_subdirectory(smoke_test)
add_subdirectory(tests1)
endif()
+170 -165
View File
@@ -22,7 +22,7 @@ Copyright 2017-2020 Data61, CSIRO
2. [Citation Details](#2-citation-details)
3. [Distribution License](#3-distribution-license)
4. [Compilers and External Dependencies](#4-compilers-and-external-dependencies)
4. [Prerequisites](#4-prerequisites)
5. [Linux and macOS: Installation](#5-linux-and-macos-installation)
6. [Linux and macOS: Compiling and Linking](#6-linux-and-macos-compiling-and-linking)
@@ -35,7 +35,7 @@ Copyright 2017-2020 Data61, CSIRO
11. [Support for C++11 / C++14 Features](#11-support-for-c11-c14-features)
12. [Support for OpenMP](#12-support-for-openmp)
13. [Documentation](#13-documentation)
13. [Documentation of Functions and Classes](#13-documentation-of-functions-and-classes)
14. [API Stability and Versioning](#14-api-stability-and-versioning)
15. [Bug Reports and Frequently Asked Questions](#15-bug-reports-and-frequently-asked-questions)
@@ -57,8 +57,8 @@ The library provides efficient classes for vectors, matrices and cubes,
as well as 200+ associated functions covering essential and advanced functionality
for data processing and manipulation of matrices.
Various matrix decompositions are provided through integration with LAPACK,
or one of its high performance drop-in replacements
Various matrix decompositions (eigen, SVD, QR, etc) are provided through
integration with LAPACK, or one of its high performance drop-in replacements
(eg. OpenBLAS, Intel MKL, Apple Accelerate framework, etc).
A sophisticated expression evaluator (via C++ template meta-programming)
@@ -104,154 +104,163 @@ informational purposes only and do not modify the License.
---
### 4: Compilers and External Dependencies
### 4: Prerequisites
A compiler that properly supports the C++98/C++03 standards is required,
as Armadillo makes extensive use of template meta-programming.
Armadillo 9.900 requires a C++ compiler with proper support for at least the C++98/C++03 standards.
Upgrading to Armadillo 10.6 is recommended to make best use of C++11/C++14 features.
On Linux-based systems, install the GCC C++ compiler, which is available as a pre-built package.
The package name might be `g++` or `gcc-c++` depending on your system.
On macOS systems, a C++ compiler can be obtained by first installing Xcode (version 8 or later)
and then running the following command in a terminal window:
xcode-select --install
On Windows systems, the MinGW toolset or Visual Studio C++ 2012 (MSVC) can be used.
The functionality of Armadillo is partly dependent on other libraries:
LAPACK, BLAS (preferably OpenBLAS), ARPACK and SuperLU.
LAPACK and BLAS are used for dense matrices,
while ARPACK and SuperLU are used for sparse matrices.
OpenBLAS (or standard BLAS) and LAPACK (for dense matrices),
as well as ARPACK and SuperLU (for sparse matrices).
Caveat: only SuperLU versions 5.2.x can be used.
On macOS, the Accelerate framework can be used for BLAS and LAPACK functions.
Armadillo can work without the above libraries, but its functionality will be reduced.
Basic functionality will be available (eg. matrix addition and multiplication),
but operations like eigen decomposition or matrix inversion will not be.
Matrix multiplication (mainly for big matrices) may not be as fast.
As Armadillo is a template library, we recommended that optimisation
is enabled during compilation of programs that use Armadillo.
For example, for GCC and Clang compilers use -O2 or -O3
but operations such as eigen decomposition and system solvers will not be.
Matrix multiplication may not be as fast (mainly for large matrices).
---
### 5: Linux and macOS: Installation
* Step 1:
Ensure a C++ compiler is installed on your system.
Armadillo can be installed in several ways: either manually or via cmake, with or without root access.
The cmake based installation is preferred.
The cmake tool can be downloaded from http://www.cmake.org
or (preferably) installed using the package manager on your system;
on macOS systems, cmake can be installed through MacPorts or Homebrew.
- On macOS systems install Xcode (version 8 or later)
and then type the following command in a terminal window:
Before installing Armadillo, first install OpenBLAS and LAPACK, and optionally ARPACK and SuperLU.
It is also necessary to install the corresponding development files for each library.
For example, when installing the `libopenblas` package, also install the `libopenblas-dev` package.
xcode-select --install
* Step 2:
Ensure the CMake tool is installed on your system.
#### 5a: Installation via CMake
- Cmake can be downloaded from http://www.cmake.org
or (preferably) installed using the package manager on your system.
The cmake based installer detects which relevant libraries
are installed on your system (eg. OpenBLAS, LAPACK, SuperLU, ARPACK, etc)
and correspondingly modifies Armadillo's configuration.
The installer also generates the Armadillo runtime library,
which is a wrapper for all the detected libraries,
and provides a thread-safe random number generator.
- On Linux-based systems, CMake can be installed using dnf, yum, apt, aptitude, ...
- On macOS systems, CMake can be installed through MacPorts or Homebrew.
* Step 3:
Ensure that OpenBLAS (or standard BLAS and LAPACK) is installed on your system.
On macOS, the Accelerate framework can be used for BLAS/LAPACK.
- On macOS, optionally install OpenBLAS for better performance.
- If support for sparse matrices is required, also install ARPACK and SuperLU.
Caveat: only SuperLU version 5.2 can be used!
- On Linux-based systems, the following libraries are recommended
to be present: OpenBLAS, LAPACK, SuperLU and ARPACK.
It is also necessary to install the corresponding development
files for each library. For example, when installing the "lapack"
package, also install the "lapack-devel" or "lapack-dev" package.
* Step 4:
Run the cmake installer.
- Open a terminal window and change into the directory that was created
by unpacking the armadillo archive.
- The simplest case is to run cmake using:
Change into the directory that was created by unpacking the armadillo archive
(eg. `cd armadillo-9.900.5`) and then run cmake using:
cmake .
- NOTE: the full stop separated from "cmake" by a space is important.
- Options to the cmake installer:
- On Linux, to enable the detection of FlexiBLAS,
use the additional ALLOW_FLEXIBLAS_LINUX option when running cmake:
**NOTE:** the full stop (.) separated from `cmake` by a space is important.
cmake -DALLOW_FLEXIBLAS_LINUX=ON .
On macOS, to enable the detection of OpenBLAS,
use the additional `ALLOW_OPENBLAS_MACOS` option when running cmake:
- On macOS, to enable the detection of OpenBLAS,
use the additional ALLOW_OPENBLAS_MACOS option when running cmake:
cmake -DALLOW_OPENBLAS_MACOS=ON .
cmake -DALLOW_OPENBLAS_MACOS=ON .
Depending on your installation, OpenBLAS may masquerade as standard BLAS.
To detect standard BLAS and LAPACK, use the `ALLOW_BLAS_LAPACK_MACOS` option:
Note: depending on your installation, OpenBLAS may masquerade as standard BLAS.
To detect standard BLAS and LAPACK, use the ALLOW_BLAS_LAPACK_MACOS option:
cmake -DALLOW_BLAS_LAPACK_MACOS=ON .
cmake -DALLOW_BLAS_LAPACK_MACOS=ON .
By default, cmake assumes that the Armadillo runtime library and the corresponding header files
will be installed in the default system directory (eg. in the `/usr` hierarchy in Linux-based systems).
To install the library and headers in an alternative directory,
use the additional option `CMAKE_INSTALL_PREFIX` in this form:
- By default, cmake assumes that the Armadillo library and the
corresponding header files will be installed in the default
system directory (eg. in the /usr hierarchy in Linux-based systems).
To install the library and headers in an alternative directory,
use the additional option CMAKE_INSTALL_PREFIX in this form:
cmake . -DCMAKE_INSTALL_PREFIX:PATH=alternative_directory
cmake . -DCMAKE_INSTALL_PREFIX:PATH=alternative_directory
If cmake needs to be re-run, it's a good idea to first delete the `CMakeCache.txt` file
(not `CMakeLists.txt`).
- CMake will detect which relevant libraries are installed on your system
(eg. OpenBLAS, LAPACK, SuperLU, ARPACK, etc)
and will modify Armadillo's configuration correspondingly.
CMake will also generate the Armadillo run-time library,
which is a wrapper for all the detected libraries.
**Caveat:** if Armadillo is installed in a non-system directory,
make sure that the C++ compiler is configured to use the `lib` and `include`
sub-directories present within this directory.
Note that the `lib` directory might be named differently on your system.
On recent 64 bit Debian & Ubuntu systems it is `lib/x86_64-linux-gnu`.
On recent 64 bit Fedora & RHEL systems it is `lib64`.
- If cmake needs to re-run, it's a good idea to first delete the
"CMakeCache.txt" file (not "CMakeLists.txt").
- Caveat: if Armadillo is installed in a non-system directory,
make sure that the C++ compiler is configured to use the "lib" and "include"
sub-directories present within this directory. Note that the "lib"
directory might be named differently on your system.
On recent 64 bit Debian & Ubuntu systems it is "lib/x86_64-linux-gnu".
On recent 64 bit Fedora & RHEL systems it is "lib64".
* Step 5:
If you and have access to root/administrator/superuser privileges
(ie. able to use "sudo") and didn't use the CMAKE_INSTALL_PREFIX option,
type the following command:
If you have sudo access (ie. root/administrator/superuser privileges)
and didn't use the `CMAKE_INSTALL_PREFIX` option, run the following command:
sudo make install
If you don't have root/administrator/superuser privileges,
make sure that you use the CMAKE_INSTALL_PREFIX option in Step 4,
and type the following command:
If you don't have sudo access, make sure to use the `CMAKE_INSTALL_PREFIX` option
and run the following command:
make install
#### 5b: Manual Installation
Manual installation involves simply copying the `include/armadillo` header
**and** the associated `include/armadillo_bits` directory to a location
such as `/usr/include/` which is searched by your C++ compiler.
If you don't have sudo access or don't have write access to `/usr/include/`,
use a directory within your own home directory (eg. `/home/blah/include/`).
If required, modify `include/armadillo_bits/config.hpp`
to indicate which libraries are currently available on your system.
Comment or uncomment the following lines:
#define ARMA_USE_LAPACK
#define ARMA_USE_BLAS
#define ARMA_USE_ARPACK
#define ARMA_USE_SUPERLU
If support for sparse matrices is not needed, ARPACK and SuperLU are not necessary.
Note that the manual installation will not generate the Armadillo runtime library,
and hence you will need to link your programs directly with OpenBLAS, LAPACK, etc.
---
### 6: Linux and macOS: Compiling and Linking
If you have installed Armadillo via the CMake installer,
use the following command:
If you have installed Armadillo via the cmake installer,
use the following command to compile your programs:
g++ prog.cpp -o prog -O2 -larmadillo
Otherwise, if you want to use Armadillo without installation
(ie. without the Armadillo runtime library), use the following command:
g++ prog.cpp -o prog.cpp -O2 -I /home/blah/armadillo-7.200.3/include -DARMA_DONT_USE_WRAPPER -lopenblas
If you have installed Armadillo manually, link with OpenBLAS and LAPACK
instead of the Armadillo runtime library:
The above command assumes that the armadillo archive was unpacked into /home/blah/
The command needs to be adjusted if the archive was unpacked into a different directory
and/or for each specific version of Armadillo (ie. "7.200.3" needs to be changed).
If you don't have OpenBLAS, on Linux change -lopenblas to -lblas -llapack
and on macOS change -lopenblas to -framework Accelerate
g++ prog.cpp -o prog -O2 -lopenblas -llapack
See the Questions page for more info on linking:
If you have manually installed Armadillo in a non-standard location,
such as `/home/blah/include/`, you will need to make sure
that your C++ compiler searches `/home/blah/include/`
by explicitly specifying the directory as an argument/option.
For example, using the `-I` switch in GCC and Clang:
g++ prog.cpp -o prog -O2 -I /home/blah/include/ -lopenblas -llapack
If you're getting linking issues (unresolved symbols),
enable the `ARMA_DONT_USE_WRAPPER` option:
g++ prog.cpp -o prog -O2 -I /home/blah/include/ -DARMA_DONT_USE_WRAPPER -lopenblas -llapack
If you don't have OpenBLAS, on Linux change `-lopenblas` to `-lblas`;
on macOS change `-lopenblas -llapack` to `-framework Accelerate`
The `examples` directory contains a short example program that uses Armadillo.
We recommend that compilation is done with optimisation enabled,
in order to make best use of the extensive template meta-programming
techniques employed in Armadillo.
For GCC and Clang compilers use `-O2` or `-O3` to enable optimisation.
For more information on compiling and linking, see the Questions page:
http://arma.sourceforge.net/faq.html
The "examples" directory contains a short example program that uses the Armadillo library.
---
### 7: Windows: Installation
@@ -259,43 +268,43 @@ The "examples" directory contains a short example program that uses the Armadill
The installation is comprised of 3 steps:
* Step 1:
Copy the entire "include" folder to a convenient location
Copy the entire `include` folder to a convenient location
and tell your compiler to use that location for header files
(in addition to the locations it uses already).
Alternatively, the "include" folder can be used directly.
Alternatively, the `include` folder can be used directly.
* Step 2:
Modify "include/armadillo_bits/config.hpp" to indicate which
libraries are currently available on your system. For example,
if LAPACK, BLAS (or OpenBLAS), ARPACK and SuperLU present,
uncomment the following lines:
If required, modify `include/armadillo_bits/config.hpp`
to indicate which libraries are currently available on your system:
#define ARMA_USE_LAPACK
#define ARMA_USE_BLAS
#define ARMA_USE_ARPACK
#define ARMA_USE_SUPERLU
If support for sparse matrices is not required,
don't worry about ARPACK or SuperLU.
If support for sparse matrices is not needed, ARPACK or SuperLU are not necessary.
* Step 3:
Configure your compiler to link with LAPACK and BLAS
(and optionally ARPACK and SuperLU).
Note that OpenBLAS can be used as a high-performance substitute
for both LAPACK and BLAS.
---
### 8: Windows: Compiling and Linking
Within the "examples" folder, there is an MSVC project named "example1_win64"
which can be used to compile "example1.cpp". The project needs to be compiled as a
64 bit program: the active solution platform must be set to x64, instead of win32.
Within the `examples` folder, the MSVC project named `example1_win64`
can be used to compile `example1.cpp`.
The project needs to be compiled as a 64 bit program:
the active solution platform must be set to x64, instead of win32.
The MSVC project was tested on Windows 7 (64 bit) with Visual Studio C++ 2012.
Adaptations may need to be made for 32 bit systems, later versions of Windows
and/or the compiler. For example, options such as ARMA_BLAS_LONG and ARMA_BLAS_UNDERSCORE,
defined in "armadillo_bits/config.hpp", may need to be either enabled or disabled.
Adaptations may be required for 32 bit systems, later versions of Windows and/or the compiler.
For example, options such as `ARMA_BLAS_LONG` and `ARMA_BLAS_UNDERSCORE`,
defined in `include/armadillo_bits/config.hpp`, may need to be either enabled or disabled.
The folder "examples/lib_win64" contains baseline (unoptimised) LAPACK and BLAS
The folder `examples/lib_win64` contains baseline (unoptimised) LAPACK and BLAS
libraries compiled for 64 bit Windows. The compilation was done by a third party.
USE AT YOUR OWN RISK. The compiled versions of LAPACK and BLAS were obtained from:
http://ylzhao.blogspot.com.au/2013/10/blas-lapack-precompiled-binaries-for.html
@@ -309,7 +318,7 @@ OpenBLAS and Intel MKL are generally the fastest replacements for both BLAS and
**Caveat:**
for any high performance scientific/engineering workloads,
we strongly recommend using a Linux based operating system:
we strongly recommend using a Linux-based operating system:
* Fedora http://fedoraproject.org/
* Ubuntu http://www.ubuntu.com/
* CentOS http://centos.org/
@@ -322,7 +331,7 @@ Armadillo can use OpenBLAS or Intel Math Kernel Library (MKL) as high-speed
replacements for BLAS and LAPACK. In essence this involves linking with the
replacement libraries instead of BLAS and LAPACK.
Minor modifications to include/armadillo_bits/config.hpp may be required
Minor modifications to `include/armadillo_bits/config.hpp` may be required
to ensure Armadillo uses the same integer sizes and style of function names
as used by the replacement libraries. Specifically, the following defines
may need to be enabled or disabled:
@@ -335,26 +344,27 @@ may need to be enabled or disabled:
See the documentation for more information on the above defines.
On Linux-based systems, MKL might be installed in a non-standard location
such as /opt which can cause problems during linking. Before installing
Armadillo, the system should know where the MKL libraries are located.
For example, /opt/intel/mkl/lib/intel64/. This can be achieved by setting
the LD_LIBRARY_PATH environment variable, or for a more permanent solution,
adding the directory locations to /etc/ld.so.conf. It may also be possible
to store a text file with the locations in the /etc/ld.so.conf.d directory.
For example, /etc/ld.so.conf.d/mkl.conf. If /etc/ld.so.conf is modified
or /etc/ld.so.conf.d/mkl.conf is created, /sbin/ldconfig must be run afterwards.
On Linux-based systems, MKL might be installed in a non-standard location such as `/opt`
which can cause problems during linking.
Before installing Armadillo, the system should know where the MKL libraries are located.
For example, `/opt/intel/mkl/lib/intel64/`.
This can be achieved by setting the `LD_LIBRARY_PATH` environment variable,
or for a more permanent solution, adding the directory locations to `/etc/ld.so.conf`.
It may also be possible to store a text file with the locations
in the `/etc/ld.so.conf.d` directory. For example, `/etc/ld.so.conf.d/mkl.conf`.
If `/etc/ld.so.conf` is modified or `/etc/ld.so.conf.d/mkl.conf` is created,
`/sbin/ldconfig` must be run afterwards.
Below is an example of /etc/ld.so.conf.d/mkl.conf
where Intel MKL is installed in /opt/intel
Below is an example of `/etc/ld.so.conf.d/mkl.conf`
where Intel MKL is installed in `/opt/intel`
/opt/intel/lib/intel64
/opt/intel/mkl/lib/intel64
If MKL is installed and it is persistently giving problems during linking,
Support for MKL can be disabled by editing the CMakeLists.txt file,
deleting CMakeCache.txt and re-running the CMake based installation.
Comment out the lines containing:
deleting CMakeCache.txt and re-running the cmake based installation.
Comment out the line containing:
INCLUDE(ARMA_FindMKL)
INCLUDE(ARMA_FindACMLMP)
@@ -364,32 +374,26 @@ Comment out the lines containing:
### 10: Support for ATLAS
Armadillo can use the ATLAS library for faster versions of a subset
of LAPACK and BLAS functions. LAPACK should still be installed to
obtain full functionality.
Caveat: the minimum recommended version of ATLAS is 3.10;
earlier versions (such as 3.6 and 3.8) can produce incorrect
results and/or corrupt memory, leading to random crashes.
If OpenBLAS is not available, Armadillo can use the ATLAS library for faster versions
of a subset of LAPACK and BLAS functions.
LAPACK should still be installed to obtain full functionality.
The minimum recommended version of ATLAS is 3.10.
---
### 11: Support for C++11 / C++14 Features
Armadillo works with compilers supporting the older C++98 and C++03 standards,
as well as the newer C++11 and C++14 standards.
Armadillo 9.900 will enable extra features when a C++11/C++14 compiler is detected.
You can also force Armadillo to make use of C++11 features by defining
`ARMA_USE_CXX11` before `#include <armadillo>` in your code.
Note that you may need to explicitly enable C++11 mode in your compiler.
For example, use the `-std=c++11` or `-std=c++14` options in gcc & clang.
Armadillo will enable extra features (such as move constructors)
when a C++11/C++14 compiler is detected. You can also force Armadillo
to make use of C++11 features by defining ARMA_USE_CXX11 before
`#include <armadillo>` in your code.
**Caveat:** to make best use of C++11/C++14 features, upgrading to Armadillo 10.6 is recommended.
You may need to explicitly enable C++11 mode in your compiler.
For example, use the -std=c++11 or -std=c++14 options in gcc & clang.
**Caveat:** use of the C++11 "auto" keyword is not recommended with Armadillo
**Caveat:** use of the C++11 `auto` keyword is not recommended with Armadillo
objects and expressions. Armadillo has a template meta-programming framework
which creates lots of short lived temporaries that are not handled by auto.
which creates lots of short lived temporaries that are not handled by `auto`.
---
@@ -399,21 +403,18 @@ Armadillo can use OpenMP to automatically speed up computationally
expensive element-wise functions such as exp(), log(), cos(), etc.
This requires a C++11/C++14 compiler with OpenMP 3.1+ support.
When using gcc or clang, use the following options to enable both
C++11 and OpenMP: -std=c++11 -fopenmp
Caveat: when using gcc, use of -march=native in conjunction with -fopenmp
may lead to speed regressions on recent processors.
For GCC and Clang compilers, use the following options to enable both C++11 and OpenMP:
`-std=c++11 -fopenmp`
---
### 13: Documentation
### 13: Documentation of Functions and Classes
The documentation for Armadillo functions and classes is available at:
The documentation of Armadillo functions and classes is available at:
http://arma.sourceforge.net/docs.html
The documentation is also in the "docs.html" file in this folder,
which can be viewed with a web browser.
The documentation is also in the `docs.html` file distributed with Armadillo.
Use a web browser to view it.
---
@@ -474,7 +475,7 @@ http://arma.sourceforge.net/faq.html
### 16: MEX Interface to Octave/Matlab
The "mex_interface" folder contains examples of how to interface
The `mex_interface` folder contains examples of how to interface
Octave/Matlab with C++ code that uses Armadillo matrices.
---
@@ -492,3 +493,7 @@ Octave/Matlab with C++ code that uses Armadillo matrices.
* RcppArmadillo: integration of Armadillo with the R system and environment
http://dirk.eddelbuettel.com/code/rcpp.armadillo.html
* PyArmadillo: linear algebra library for Python
https://pyarma.sourceforge.io
Binary file not shown.
@@ -0,0 +1,16 @@
# - Config file for the Armadillo package
# It defines the following variables
# ARMADILLO_INCLUDE_DIRS - include directories for Armadillo
# ARMADILLO_LIBRARY_DIRS - library directories for Armadillo (normally not used!)
# ARMADILLO_LIBRARIES - libraries to link against
# Tell the user project where to find our headers and libraries
set(ARMADILLO_INCLUDE_DIRS "@ARMADILLO_INCLUDE_DIRS@")
set(ARMADILLO_LIBRARY_DIRS "@ARMADILLO_LIB_DIR@")
# Our library dependencies (contains definitions for IMPORTED targets)
include("@ARMADILLO_CMAKE_DIR@/ArmadilloLibraryDepends.cmake")
# These are IMPORTED targets created by ArmadilloLibraryDepends.cmake
set(ARMADILLO_LIBRARIES armadillo)
@@ -0,0 +1,11 @@
set(PACKAGE_VERSION "@ARMA_VERSION_MAJOR@.@ARMA_VERSION_MINOR@.@ARMA_VERSION_PATCH@")
# Check whether the requested PACKAGE_FIND_VERSION is compatible
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()
+7 -5
View File
@@ -10643,7 +10643,7 @@ See also:
<li><a href="#polyfit">polyfit()</a></li>
<li><a href="#imag_real">real()</a></li>
<li><a href="#solve">solve()</a></li>
<li><a href="https://en.wikipedia.org/wiki/Zero_of_a_function">zero of a function in Wikpedia</a></li>
<li><a href="https://en.wikipedia.org/wiki/Zero_of_a_function">zero of a function in Wikipedia</a></li>
</ul>
</li>
<br>
@@ -11762,7 +11762,7 @@ fn(A) is one of:
&nbsp;
</td>
<td style="vertical-align: top;">
natural log of the gamma function &nbsp; <font size=-1>(only for <i>float</i> and <i>double</i> elements)</font>
natural log of the absolute value of gamma function &nbsp; <font size=-1>(only for <i>float</i> and <i>double</i> elements)</font>
</td>
</tr>
<tr>
@@ -18005,9 +18005,10 @@ Disable use of BLAS; overrides <i>ARMA_USE_BLAS</i>
&nbsp;
</td>
<td style="vertical-align: top;">
Enable use of the built-in reimplementation of ARPACK (Armadillo 7.x and later versions).
Enable use of NEWARP (built-in alternative to ARPACK).
This is used for the eigen decomposition of real (non-complex) sparse matrices, ie. <a href="#eigs_gen">eigs_gen()</a>, <a href="#eigs_sym">eigs_sym()</a> and <a href="#svds">svds().</a>
Requires ARMA_USE_LAPACK to be enabled.
If use of both NEWARP and ARPACK is enabled, NEWARP will be preferred.
</td>
</tr>
<tr>
@@ -18029,7 +18030,7 @@ Requires ARMA_USE_LAPACK to be enabled.
&nbsp;
</td>
<td style="vertical-align: top;">
Disable use of the built-in reimplementation of ARPACK; overrides <i>ARMA_USE_NEWARP</i>
Disable use of NEWARP (built-in alternative to ARPACK); overrides <i>ARMA_USE_NEWARP</i>
</td>
</tr>
<tr>
@@ -18052,7 +18053,8 @@ Disable use of the built-in reimplementation of ARPACK; overrides <i>ARMA_USE_NE
</td>
<td style="vertical-align: top;">
Enable use of ARPACK, or a high-speed replacement for ARPACK.
Armadillo requires ARPACK for the eigen decomposition of complex sparse matrices, ie. <a href="#eigs_gen">eigs_gen()</a>, <a href="#eigs_sym">eigs_sym()</a> and <a href="#svds">svds()</a>
Armadillo requires ARPACK for the eigen decomposition of complex sparse matrices, ie. <a href="#eigs_gen">eigs_gen()</a>, <a href="#eigs_sym">eigs_sym()</a> and <a href="#svds">svds()</a>.
If use of NEWARP is disabled, ARPACK will also be used for the eigen decomposition of real sparse matrices.
</td>
</tr>
<tr>
+14 -14
View File
@@ -1,24 +1,24 @@
How to compile example1.cpp
* Linux and macOS
If you have installed Armadillo via the CMake installer:
** Linux and macOS **
If you have installed Armadillo via the CMake installer:
g++ example1.cpp -o example1 -O2 -larmadillo
Otherwise, if you want to use Armadillo without installation:
Otherwise, if you want to use Armadillo without installation:
g++ example1.cpp -o example1 -O2 -I /home/blah/armadillo-7.200.3/include -DARMA_DONT_USE_WRAPPER -lopenblas
The above command assumes that the armadillo archive was unpacked into /home/blah/
The command needs to be adjusted if the archive was unpacked into a different directory
and/or for each specific version of Armadillo (ie. "7.200.3" needs to be changed)
The above command assumes that the armadillo archive was unpacked into /home/blah/
The command needs to be adjusted if the archive was unpacked into a different directory
and/or for each specific version of Armadillo (ie. "7.200.3" needs to be changed)
If you don't have OpenBLAS, on Linux change -lopenblas to -lblas -llapack
and on macOS change -lopenblas to -framework Accelerate
If you don't have OpenBLAS, on Linux change -lopenblas to -lblas -llapack
and on macOS change -lopenblas to -framework Accelerate
* Windows
Open "example1_win64.sln" or "example1_win64.vcxproj" with Visual Studio.
The example1_win64 project needs to be compiled as a 64 bit program.
Make sure the active solution platform is set to x64, instead of win32.
** Windows **
Open "example1_win64.sln" or "example1_win64.vcxproj" with Visual Studio.
The example1_win64 project needs to be compiled as a 64 bit program.
Make sure the active solution platform is set to x64, instead of win32.
+6 -4
View File
@@ -14,12 +14,14 @@ main(int argc, char** argv)
{
cout << "Armadillo version: " << arma_version::as_string() << endl;
mat A(2,3); // directly specify the matrix size (elements are uninitialised)
// construct a matrix according to given size and form of element initialisation
mat A(2,3,fill::zeros);
cout << "A.n_rows: " << A.n_rows << endl; // .n_rows and .n_cols are read only
// .n_rows and .n_cols are read only
cout << "A.n_rows: " << A.n_rows << endl;
cout << "A.n_cols: " << A.n_cols << endl;
A(1,2) = 456.0; // directly access an element (indexing starts at 0)
A(1,2) = 456.0; // access an element (indexing starts at 0)
A.print("A:");
A = 5.0; // scalars are treated as a 1x1 matrix
@@ -27,7 +29,7 @@ main(int argc, char** argv)
A.set_size(4,5); // change the size (data is not preserved)
A.fill(5.0); // set all elements to a particular value
A.fill(5.0); // set all elements to a specific value
A.print("A:");
// endr indicates "end of row"
+3 -3
View File
@@ -187,15 +187,15 @@ BaseCube<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::res
const T val_real = access::tmp_real(val);
const T val_imag = access::tmp_imag(val);
if(std::abs(val_real) > tol) { return false; }
if(std::abs(val_imag) > tol) { return false; }
if(eop_aux::arma_abs(val_real) > tol) { return false; }
if(eop_aux::arma_abs(val_imag) > tol) { return false; }
}
}
else // not complex
{
for(uword i=0; i < n_elem; ++i)
{
if(std::abs(Pea[i]) > tol) { return false; }
if(eop_aux::arma_abs(Pea[i]) > tol) { return false; }
}
}
+3 -3
View File
@@ -22,7 +22,7 @@
template<typename elem_type, typename derived>
struct Base_extra_yes
{
arma_inline const Op<derived,op_inv> i() const; //!< matrix inverse
inline arma_warn_unused const Op<derived,op_inv> i() const; //!< matrix inverse
arma_deprecated inline const Op<derived,op_inv> i(const bool ) const; //!< kept only for compatibility with old user code
arma_deprecated inline const Op<derived,op_inv> i(const char*) const; //!< kept only for compatibility with old user code
@@ -154,8 +154,8 @@ struct Base
inline arma_warn_unused bool has_inf() const;
inline arma_warn_unused bool has_nan() const;
arma_inline const Op<derived,op_vectorise_col> as_col() const;
arma_inline const Op<derived,op_vectorise_row> as_row() const;
inline arma_warn_unused const Op<derived,op_vectorise_col> as_col() const;
inline arma_warn_unused const Op<derived,op_vectorise_row> as_row() const;
};
+9 -6
View File
@@ -411,15 +411,15 @@ Base<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::result
const T val_real = access::tmp_real(val);
const T val_imag = access::tmp_imag(val);
if(std::abs(val_real) > tol) { return false; }
if(std::abs(val_imag) > tol) { return false; }
if(eop_aux::arma_abs(val_real) > tol) { return false; }
if(eop_aux::arma_abs(val_imag) > tol) { return false; }
}
}
else // not complex
{
for(uword i=0; i<n_elem; ++i)
{
if(std::abs(Pea[i]) > tol) { return false; }
if(eop_aux::arma_abs(Pea[i]) > tol) { return false; }
}
}
@@ -723,7 +723,8 @@ Base<elem_type,derived>::has_nan() const
template<typename elem_type, typename derived>
arma_inline
inline
arma_warn_unused
const Op<derived,op_vectorise_col>
Base<elem_type, derived>::as_col() const
{
@@ -733,7 +734,8 @@ Base<elem_type, derived>::as_col() const
template<typename elem_type, typename derived>
arma_inline
inline
arma_warn_unused
const Op<derived,op_vectorise_row>
Base<elem_type, derived>::as_row() const
{
@@ -746,7 +748,8 @@ Base<elem_type, derived>::as_row() const
// extra functions defined in Base_extra_yes
template<typename elem_type, typename derived>
arma_inline
inline
arma_warn_unused
const Op<derived,op_inv>
Base_extra_yes<elem_type, derived>::i() const
{
+4
View File
@@ -1034,6 +1034,8 @@ Cube<eT>::slice(const uword in_slice)
arma_debug_check( (in_slice >= n_slices), "Cube::slice(): index out of bounds" );
// BUG: data race when accessed from multiple threads; causes memory leakage
if(mat_ptrs[in_slice] == NULL)
{
const eT* ptr = (n_elem_slice > 0) ? slice_memptr(in_slice) : NULL;
@@ -1056,6 +1058,8 @@ Cube<eT>::slice(const uword in_slice) const
arma_debug_check( (in_slice >= n_slices), "Cube::slice(): index out of bounds" );
// BUG: data race when accessed from multiple threads; causes memory leakage
if(mat_ptrs[in_slice] == NULL)
{
const eT* ptr = (n_elem_slice > 0) ? slice_memptr(in_slice) : NULL;
+3 -3
View File
@@ -2671,12 +2671,12 @@ Mat<eT>::operator/=(const SpBase<eT, T1>& m)
{
arma_extra_debug_sigprint();
// NOTE: use of this function is not advised; it is implemented only for completeness
const SpProxy<T1> p(m.get_ref());
arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise division");
// If you use this method, you are probably stupid or misguided, but for completeness it is implemented.
// Unfortunately the best way to do this is loop over every element.
for(uword c = 0; c < n_cols; ++c)
for(uword r = 0; r < n_rows; ++r)
{
@@ -6902,7 +6902,7 @@ Mat<eT>::fill(const eT val)
//! fill the matrix with the specified value
//! fill the matrix with the specified pattern
template<typename eT>
template<typename fill_type>
inline
+2 -3
View File
@@ -100,9 +100,8 @@ struct SpBase
inline arma_warn_unused bool has_inf() const;
inline arma_warn_unused bool has_nan() const;
inline const SpOp<derived,spop_vectorise_col> as_col() const;
inline const SpOp<derived,spop_vectorise_row> as_row() const;
inline arma_warn_unused const SpOp<derived,spop_vectorise_col> as_col() const;
inline arma_warn_unused const SpOp<derived,spop_vectorise_row> as_row() const;
};
+5 -3
View File
@@ -435,8 +435,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(std::abs(val_real) > tol) { return false; }
if(std::abs(val_imag) > tol) { return false; }
if(eop_aux::arma_abs(val_real) > tol) { return false; }
if(eop_aux::arma_abs(val_imag) > tol) { return false; }
++it;
}
@@ -445,7 +445,7 @@ SpBase<elem_type,derived>::is_zero(const typename get_pod_type<elem_type>::resul
{
while(it != it_end)
{
if(std::abs(*it) > tol) { return false; }
if(eop_aux::arma_abs(*it) > tol) { return false; }
++it;
}
@@ -714,6 +714,7 @@ SpBase<elem_type,derived>::has_nan() const
template<typename elem_type, typename derived>
inline
arma_warn_unused
const SpOp<derived,spop_vectorise_col>
SpBase<elem_type, derived>::as_col() const
{
@@ -724,6 +725,7 @@ SpBase<elem_type, derived>::as_col() const
template<typename elem_type, typename derived>
inline
arma_warn_unused
const SpOp<derived,spop_vectorise_row>
SpBase<elem_type, derived>::as_row() const
{
+4 -6
View File
@@ -782,16 +782,14 @@ SpMat<eT>::operator/=(const SpMat<eT>& x)
{
arma_extra_debug_sigprint();
// NOTE: use of this function is not advised; it is implemented only for completeness
arma_debug_assert_same_size(n_rows, n_cols, x.n_rows, x.n_cols, "element-wise division");
// If you use this method, you are probably stupid or misguided,
// but for compatibility with Mat, we have implemented it anyway.
for(uword c = 0; c < n_cols; ++c)
for(uword r = 0; r < n_rows; ++r)
{
for(uword r = 0; r < n_rows; ++r)
{
at(r, c) /= x.at(r, c);
}
at(r, c) /= x.at(r, c);
}
return *this;
+3 -2
View File
@@ -475,7 +475,6 @@ SpSubview<eT>::operator%=(const SpBase<eT, T1>& x)
//! If you are using this function, you are probably misguided.
template<typename eT>
template<typename T1>
inline
@@ -484,6 +483,8 @@ SpSubview<eT>::operator/=(const SpBase<eT, T1>& x)
{
arma_extra_debug_sigprint();
// NOTE: use of this function is not advised; it is implemented only for completeness
SpProxy<T1> p(x.get_ref());
arma_debug_assert_same_size(n_rows, n_cols, p.get_n_rows(), p.get_n_cols(), "element-wise division");
@@ -1017,7 +1018,7 @@ inline
bool
SpSubview<eT>::check_overlap(const SpSubview<eT>& x) const
{
const subview<eT>& t = *this;
const SpSubview<eT>& t = *this;
if(&t.m != &x.m)
{
+1 -1
View File
@@ -358,7 +358,7 @@ arma_inline
typename arma_real_only<eT>::result
arma_sign(const eT x)
{
return (x > eT(0)) ? eT(+1) : ( (x < eT(0)) ? eT(-1) : eT(0) );
return (x > eT(0)) ? eT(+1) : ( (x < eT(0)) ? eT(-1) : ((x == eT(0)) ? eT(0) : x) );
}
+22 -1
View File
@@ -342,7 +342,7 @@ struct arma_rng::randn
}
arma_inline
inline
static
void
dual_val(eT& out1, eT& out2)
@@ -457,6 +457,27 @@ struct arma_rng::randn< std::complex<T> >
}
inline
static
void
dual_val(std::complex<T>& out1, std::complex<T>& out2)
{
#if defined(_MSC_VER)
T a;
T b;
#else
T a(0);
T b(0);
#endif
arma_rng::randn<T>::dual_val(a,b);
out1 = std::complex<T>(a,b);
arma_rng::randn<T>::dual_val(a,b);
out2 = std::complex<T>(a,b);
}
inline
static
void
+1 -1
View File
@@ -21,7 +21,7 @@
#define ARMA_VERSION_MAJOR 9
#define ARMA_VERSION_MINOR 900
#define ARMA_VERSION_PATCH 4
#define ARMA_VERSION_PATCH 6
#define ARMA_VERSION_NAME "Nocturnal Misbehaviour"
+2 -2
View File
@@ -135,7 +135,7 @@ arrayops::clean(eT* mem, const uword n_elem, const eT abs_limit, const typename
{
eT& val = mem[i];
val = (std::abs(val) <= abs_limit) ? eT(0) : val;
val = (eop_aux::arma_abs(val) <= abs_limit) ? eT(0) : val;
}
}
@@ -1028,7 +1028,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(std::abs(mem[i]) > abs_limit) { return false; }
if(eop_aux::arma_abs(mem[i]) > abs_limit) { return false; }
}
}
+4
View File
@@ -307,6 +307,10 @@
#undef ARMA_CRIPPLED_LAPACK
#endif
#if defined(ARMA_WARN_LEVEL)
#pragma message ("WARNING: the ARMA_WARN_LEVEL option is not supported in this version of Armadillo")
#endif
// if Armadillo was installed on this system via CMake and ARMA_USE_WRAPPER is not defined,
// ARMA_AUX_LIBS lists the libraries required by Armadillo on this system, and
+4
View File
@@ -307,6 +307,10 @@
#undef ARMA_CRIPPLED_LAPACK
#endif
#if defined(ARMA_WARN_LEVEL)
#pragma message ("WARNING: the ARMA_WARN_LEVEL option is not supported in this version of Armadillo")
#endif
// if Armadillo was installed on this system via CMake and ARMA_USE_WRAPPER is not defined,
// ARMA_AUX_LIBS lists the libraries required by Armadillo on this system, and
+1 -1
View File
@@ -113,7 +113,7 @@ namespace priv
//! various constants.
//! Physical constants taken from NIST 2014 CODATA values, and some from WolframAlpha (values provided as of 2009-06-23)
//! Physical constants taken from NIST 2018 CODATA values, and some from WolframAlpha (values provided as of 2009-06-23)
//! http://physics.nist.gov/cuu/Constants
//! http://www.wolframalpha.com
//! See also http://en.wikipedia.org/wiki/Physical_constant
+1 -1
View File
@@ -90,7 +90,7 @@ class diagmat_proxy_default
}
arma_inline bool is_alias(const Mat<elem_type>&) const { return false; }
inline bool is_alias(const Mat<elem_type>& X) const { return P.is_alias(X); }
const Proxy<T1> P;
const bool P_is_vec;
+2 -2
View File
@@ -4377,7 +4377,7 @@ diskio::load_ppm_binary(Cube<eT>& x, std::istream& f, std::string& err_msg)
f >> f_maxval;
f.get();
if( (f_maxval > 0) || (f_maxval <= 65535) )
if( (f_maxval > 0) && (f_maxval <= 65535) )
{
x.set_size(f_n_rows, f_n_cols, 3);
@@ -4566,7 +4566,7 @@ diskio::load_ppm_binary(field<T1>& x, std::istream& f, std::string& err_msg)
f >> f_maxval;
f.get();
if( (f_maxval > 0) || (f_maxval <= 65535) )
if( (f_maxval > 0) && (f_maxval <= 65535) )
{
x.set_size(3);
Mat<eT>& R = x(0);
+1 -1
View File
@@ -198,7 +198,7 @@ class eop_aux
template<typename T1, typename T2> arma_inline static typename arma_integral_only<T1>::result pow (const T1 base, const T2 exponent) { return T1( std::pow( double(base), double(exponent) ) ); }
template<typename T1, typename T2> arma_inline static typename arma_real_or_cx_only<T1>::result pow (const T1 base, const T2 exponent) { return std::pow(base, exponent); }
template<typename T1, typename T2> arma_inline static typename arma_real_or_cx_only<T1>::result pow (const T1 base, const T2 exponent) { return T1( std::pow( base, exponent ) ); }
template<typename eT>
+1 -1
View File
@@ -44,7 +44,7 @@ log_det
out_val = eT(Datum<T>::nan);
out_sign = T(0);
arma_warn("log_det(): failed to find determinant");
arma_debug_warn("log_det(): failed to find determinant");
}
}
-2
View File
@@ -56,7 +56,6 @@ mvnrnd(const Base<typename T1::elem_type, T1>& M, const Base<typename T1::elem_t
template<typename T1, typename T2>
arma_warn_unused
inline
typename
enable_if2
@@ -82,7 +81,6 @@ mvnrnd(Mat<typename T1::elem_type>& out, const Base<typename T1::elem_type, T1>&
template<typename T1, typename T2>
arma_warn_unused
inline
typename
enable_if2
+1 -1
View File
@@ -157,7 +157,7 @@ svd_econ
U.soft_reset();
S.soft_reset();
V.soft_reset();
arma_debug_warn("svd(): decomposition failed");
arma_debug_warn("svd_econ(): decomposition failed");
}
return status;
-2
View File
@@ -82,7 +82,6 @@ wishrnd(Mat<typename T1::elem_type>& W, const Base<typename T1::elem_type, T1>&
template<typename T1, typename T2>
arma_warn_unused
inline
typename
enable_if2
@@ -167,7 +166,6 @@ iwishrnd(Mat<typename T1::elem_type>& W, const Base<typename T1::elem_type, T1>&
template<typename T1, typename T2>
arma_warn_unused
inline
typename
enable_if2
+4 -4
View File
@@ -58,7 +58,7 @@ glue_max::apply(Mat<eT>& out, const Proxy<T1>& PA, const Proxy<T2>& PB)
const uword n_rows = PA.get_n_rows();
const uword n_cols = PA.get_n_cols();
arma_debug_assert_same_size(n_rows, n_cols, PB.get_n_rows(), PB.get_n_cols(), "element-wise maximum");
arma_debug_assert_same_size(n_rows, n_cols, PB.get_n_rows(), PB.get_n_cols(), "element-wise max()");
out.set_size(n_rows, n_cols);
@@ -102,7 +102,7 @@ glue_max::apply(Mat< std::complex<T> >& out, const Proxy<T1>& PA, const Proxy<T2
const uword n_rows = PA.get_n_rows();
const uword n_cols = PA.get_n_cols();
arma_debug_assert_same_size(n_rows, n_cols, PB.get_n_rows(), PB.get_n_cols(), "element-wise maximum");
arma_debug_assert_same_size(n_rows, n_cols, PB.get_n_rows(), PB.get_n_cols(), "element-wise max()");
out.set_size(n_rows, n_cols);
@@ -179,7 +179,7 @@ glue_max::apply(Cube<eT>& out, const ProxyCube<T1>& PA, const ProxyCube<T2>& PB)
const uword n_cols = PA.get_n_cols();
const uword n_slices = PA.get_n_slices();
arma_debug_assert_same_size(n_rows, n_cols, n_slices, PB.get_n_rows(), PB.get_n_cols(), PB.get_n_slices(), "element-wise maximum");
arma_debug_assert_same_size(n_rows, n_cols, n_slices, PB.get_n_rows(), PB.get_n_cols(), PB.get_n_slices(), "element-wise max()");
out.set_size(n_rows, n_cols, n_slices);
@@ -225,7 +225,7 @@ glue_max::apply(Cube< std::complex<T> >& out, const ProxyCube<T1>& PA, const Pro
const uword n_cols = PA.get_n_cols();
const uword n_slices = PA.get_n_slices();
arma_debug_assert_same_size(n_rows, n_cols, n_slices, PB.get_n_rows(), PB.get_n_cols(), PB.get_n_slices(), "element-wise maximum");
arma_debug_assert_same_size(n_rows, n_cols, n_slices, PB.get_n_rows(), PB.get_n_cols(), PB.get_n_slices(), "element-wise max()");
out.set_size(n_rows, n_cols, n_slices);
+4 -4
View File
@@ -58,7 +58,7 @@ glue_min::apply(Mat<eT>& out, const Proxy<T1>& PA, const Proxy<T2>& PB)
const uword n_rows = PA.get_n_rows();
const uword n_cols = PA.get_n_cols();
arma_debug_assert_same_size(n_rows, n_cols, PB.get_n_rows(), PB.get_n_cols(), "element-wise minimum");
arma_debug_assert_same_size(n_rows, n_cols, PB.get_n_rows(), PB.get_n_cols(), "element-wise min()");
out.set_size(n_rows, n_cols);
@@ -102,7 +102,7 @@ glue_min::apply(Mat< std::complex<T> >& out, const Proxy<T1>& PA, const Proxy<T2
const uword n_rows = PA.get_n_rows();
const uword n_cols = PA.get_n_cols();
arma_debug_assert_same_size(n_rows, n_cols, PB.get_n_rows(), PB.get_n_cols(), "element-wise minimum");
arma_debug_assert_same_size(n_rows, n_cols, PB.get_n_rows(), PB.get_n_cols(), "element-wise min()");
out.set_size(n_rows, n_cols);
@@ -179,7 +179,7 @@ glue_min::apply(Cube<eT>& out, const ProxyCube<T1>& PA, const ProxyCube<T2>& PB)
const uword n_cols = PA.get_n_cols();
const uword n_slices = PA.get_n_slices();
arma_debug_assert_same_size(n_rows, n_cols, n_slices, PB.get_n_rows(), PB.get_n_cols(), PB.get_n_slices(), "element-wise minimum");
arma_debug_assert_same_size(n_rows, n_cols, n_slices, PB.get_n_rows(), PB.get_n_cols(), PB.get_n_slices(), "element-wise min()");
out.set_size(n_rows, n_cols, n_slices);
@@ -225,7 +225,7 @@ glue_min::apply(Cube< std::complex<T> >& out, const ProxyCube<T1>& PA, const Pro
const uword n_cols = PA.get_n_cols();
const uword n_slices = PA.get_n_slices();
arma_debug_assert_same_size(n_rows, n_cols, n_slices, PB.get_n_rows(), PB.get_n_cols(), PB.get_n_slices(), "element-wise minimum");
arma_debug_assert_same_size(n_rows, n_cols, n_slices, PB.get_n_rows(), PB.get_n_cols(), PB.get_n_slices(), "element-wise min()");
out.set_size(n_rows, n_cols, n_slices);
+4
View File
@@ -2157,6 +2157,10 @@ gmm_diag<eT>::km_iterate(const Mat<eT>& X, const uword max_iter, const bool verb
}
#else
{
acc_hefts.zeros();
acc_means.zeros();
last_indx.zeros();
uword* acc_hefts_mem = acc_hefts.memptr();
uword* last_indx_mem = last_indx.memptr();
+4
View File
@@ -2186,6 +2186,10 @@ gmm_full<eT>::km_iterate(const Mat<eT>& X, const uword max_iter, const bool verb
}
#else
{
acc_hefts.zeros();
acc_means.zeros();
last_indx.zeros();
uword* acc_hefts_mem = acc_hefts.memptr();
uword* last_indx_mem = last_indx.memptr();
+4 -2
View File
@@ -58,11 +58,13 @@ op_cond::rcond(const Base<typename T1::elem_type, T1>& X)
{
const strip_trimat<T1> S(X.get_ref());
arma_debug_check( (S.M.is_square() == false), "rcond(): matrix must be square sized" );
const quasi_unwrap<typename strip_trimat<T1>::stored_type> U(S.M);
arma_debug_check( (U.M.is_square() == false), "rcond(): matrix must be square sized" );
const uword layout = (S.do_triu) ? uword(0) : uword(1);
return auxlib::rcond_trimat(S.M, layout);
return auxlib::rcond_trimat(U.M, layout);
}
Mat<eT> A = X.get_ref();
+23 -8
View File
@@ -58,6 +58,12 @@ op_hist::apply_noalias(Mat<uword>& out, const Mat<eT>& A, const uword n_bins, co
if(max_val < val_i) { max_val = val_i; }
}
if(min_val == max_val)
{
min_val -= (n_bins/2);
max_val += (n_bins/2);
}
if(arma_isfinite(min_val) == false) { min_val = priv::most_neg<eT>(); }
if(arma_isfinite(max_val) == false) { max_val = priv::most_pos<eT>(); }
@@ -66,7 +72,7 @@ op_hist::apply_noalias(Mat<uword>& out, const Mat<eT>& A, const uword n_bins, co
for(uword ii=0; ii < n_bins; ++ii)
{
c_mem[ii] = (0.5 + ii) / double(n_bins); // TODO: may need to be modified for integer matrices
c_mem[ii] = (0.5 + ii) / double(n_bins);
}
c = ((max_val - min_val) * c) + min_val;
@@ -89,17 +95,26 @@ op_hist::apply(Mat<uword>& out, const mtOp<uword, T1, op_hist>& X)
const uword dim = (T1::is_xvec) ? uword(U.M.is_rowvec() ? 1 : 0) : uword((T1::is_row) ? 1 : 0);
if(U.is_alias(out))
if(is_non_integral<typename T1::elem_type>::value)
{
Mat<uword> tmp;
op_hist::apply_noalias(tmp, U.M, n_bins, dim);
out.steal_mem(tmp);
if(U.is_alias(out))
{
Mat<uword> tmp;
op_hist::apply_noalias(tmp, U.M, n_bins, dim);
out.steal_mem(tmp);
}
else
{
op_hist::apply_noalias(out, U.M, n_bins, dim);
}
}
else
{
op_hist::apply_noalias(out, U.M, n_bins, dim);
Mat<double> converted = conv_to< Mat<double> >::from(U.M);
op_hist::apply_noalias(out, converted, n_bins, dim);
}
}
+2 -2
View File
@@ -98,7 +98,7 @@ op_index_max::apply_noalias(Mat<uword>& out, const Mat<eT>& X, const uword dim)
for(uword row=0; row < X_n_rows; ++row)
{
tmp_mem[row] = std::abs(col_mem[row]);
tmp_mem[row] = eop_aux::arma_abs(col_mem[row]);
}
}
else
@@ -113,7 +113,7 @@ op_index_max::apply_noalias(Mat<uword>& out, const Mat<eT>& X, const uword dim)
for(uword row=0; row < X_n_rows; ++row)
{
T& max_val = tmp_mem[row];
T col_val = (is_cx<eT>::yes) ? T(std::abs(col_mem[row])) : T(access::tmp_real(col_mem[row]));
T col_val = (is_cx<eT>::yes) ? T(eop_aux::arma_abs(col_mem[row])) : T(access::tmp_real(col_mem[row]));
if(max_val < col_val)
{
+2 -2
View File
@@ -98,7 +98,7 @@ op_index_min::apply_noalias(Mat<uword>& out, const Mat<eT>& X, const uword dim)
for(uword row=0; row < X_n_rows; ++row)
{
tmp_mem[row] = std::abs(col_mem[row]);
tmp_mem[row] = eop_aux::arma_abs(col_mem[row]);
}
}
else
@@ -113,7 +113,7 @@ op_index_min::apply_noalias(Mat<uword>& out, const Mat<eT>& X, const uword dim)
for(uword row=0; row < X_n_rows; ++row)
{
T& min_val = tmp_mem[row];
T col_val = (is_cx<eT>::yes) ? T(std::abs(col_mem[row])) : T(access::tmp_real(col_mem[row]));
T col_val = (is_cx<eT>::yes) ? T(eop_aux::arma_abs(col_mem[row])) : T(access::tmp_real(col_mem[row]));
if(min_val > col_val)
{
+4 -4
View File
@@ -43,11 +43,11 @@ class op_median
{
public:
template<typename T1>
inline static void apply(Mat<typename T1::elem_type>& out, const Op<T1,op_median>& in);
template<typename eT, typename T1>
inline static void apply(Mat<eT>& out, const Op<T1,op_median>& in, const typename arma_not_cx<eT>::result* junk = 0);
template<typename T, typename T1>
inline static void apply(Mat< std::complex<T> >& out, const Op<T1,op_median>& in);
template<typename eT, typename T1>
inline static void apply(Mat<eT>& out, const Op<T1,op_median>& in, const typename arma_cx_only<eT>::result* junk = 0);
//
//
+11 -8
View File
@@ -23,14 +23,15 @@
//! For each row or for each column, find the median value.
//! The result is stored in a dense matrix that has either one column or one row.
//! The dimension, for which the medians are found, is set via the median() function.
template<typename T1>
template<typename eT, typename T1>
inline
void
op_median::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_median>& in)
op_median::apply(Mat<eT>& out, const Op<T1,op_median>& in, const typename arma_not_cx<eT>::result* junk)
{
arma_extra_debug_sigprint();
arma_ignore(junk);
typedef typename T1::elem_type eT;
// typedef typename T1::elem_type eT;
const uword dim = in.aux_uword_a;
arma_debug_check( (dim > 1), "median(): parameter 'dim' must be 0 or 1" );
@@ -41,7 +42,7 @@ op_median::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_median>& in)
const bool is_alias = P.is_alias(out);
if( (is_Mat<P_stored_type>::value == true) || is_alias )
if(is_Mat<P_stored_type>::value || is_alias)
{
const unwrap_check<P_stored_type> tmp(P.Q, is_alias);
@@ -134,14 +135,16 @@ op_median::apply(Mat<typename T1::elem_type>& out, const Op<T1,op_median>& in)
//! Implementation for complex numbers
template<typename T, typename T1>
template<typename eT, typename T1>
inline
void
op_median::apply(Mat< std::complex<T> >& out, const Op<T1,op_median>& in)
op_median::apply(Mat<eT>& out, const Op<T1,op_median>& in, const typename arma_cx_only<eT>::result* junk)
{
arma_extra_debug_sigprint();
arma_ignore(junk);
typedef typename std::complex<T> eT;
// typedef typename std::complex<T> eT;
typedef typename get_pod_type<eT>::result T;
arma_type_check(( is_same_type<eT, typename T1::elem_type>::no ));
@@ -242,7 +245,7 @@ op_median::median_vec
std::vector<eT> tmp_vec(n_elem);
if(is_Mat<P_stored_type>::value == true)
if(is_Mat<P_stored_type>::value)
{
const unwrap<P_stored_type> tmp(P.Q);
+1 -1
View File
@@ -119,7 +119,7 @@ op_pinv::apply_direct(Mat<typename T1::elem_type>& out, const Base<typename T1::
{
const T val = s_mem[i];
if(val >= tol) { s2_mem[count2] = T(1) / val; ++count2; }
if(val >= tol) { s2_mem[count2] = (val > T(0)) ? T(T(1) / val) : T(0); ++count2; }
}
+2 -1
View File
@@ -264,6 +264,7 @@ op_princomp::direct_princomp
arma_extra_debug_sigprint();
typedef typename T1::elem_type eT;
typedef typename T1::pod_type T;
const unwrap<T1> Y( X.get_ref() );
const Mat<eT>& in = Y.M;
@@ -274,7 +275,7 @@ op_princomp::direct_princomp
// singular value decomposition
Mat<eT> U;
Col<eT> s;
Col< T> s;
const bool svd_ok = (in.n_rows >= in.n_cols) ? svd_econ(U, s, coeff_out, tmp) : svd(U, s, coeff_out, tmp);
+2 -2
View File
@@ -351,7 +351,7 @@ sp_auxlib::eigs_gen_newarp(Col< std::complex<T> >& eigval, Mat< std::complex<T>
const newarp::SparseGenMatProd<T> op(X);
arma_debug_check( (op.n_rows != op.n_cols), "eigs_sym(): given matrix must be square sized" );
arma_debug_check( (op.n_rows != op.n_cols), "eigs_gen(): given matrix must be square sized" );
arma_debug_check( (n_eigvals + 1 >= op.n_rows), "eigs_gen(): n_eigvals + 1 must be less than the number of rows in the matrix" );
@@ -1146,7 +1146,7 @@ sp_auxlib::spsolve_refine(Mat<typename T1::elem_type>& X, typename T1::pod_type&
// We have to actually create the object which stores the data.
// This gets cleaned by destroy_supermatrix().
// We have to use SuperLU's stupid memory allocation routines since they are
// We have to use SuperLU's problematic memory allocation routines since they are
// not guaranteed to be new and delete. See the comments in def_superlu.hpp
superlu::NCformat* nc = (superlu::NCformat*)superlu::malloc(sizeof(superlu::NCformat));
+16 -13
View File
@@ -473,6 +473,8 @@ spglue_merge::diagview_merge(SpMat<eT>& out, const SpMat<eT>& A, const SpMat<eT>
{
arma_extra_debug_sigprint();
// NOTE: assuming that B has non-zero elements only on the main diagonal
out.reserve(A.n_rows, A.n_cols, A.n_nonzero + B.n_nonzero); // worst case scenario
typename SpMat<eT>::const_iterator x_it = A.begin();
@@ -485,7 +487,7 @@ spglue_merge::diagview_merge(SpMat<eT>& out, const SpMat<eT>& A, const SpMat<eT>
while( (x_it != x_end) || (y_it != y_end) )
{
eT out_val;
eT out_val = eT(0);
const uword x_it_col = x_it.col();
const uword x_it_row = x_it.row();
@@ -508,28 +510,29 @@ spglue_merge::diagview_merge(SpMat<eT>& out, const SpMat<eT>& A, const SpMat<eT>
{
if((x_it_col < y_it_col) || ((x_it_col == y_it_col) && (x_it_row < y_it_row))) // if y is closer to the end
{
out_val = (*x_it);
if(x_it_col != x_it_row) { out_val = (*x_it); } // don't take values from the main diagonal of A
++x_it;
}
else
{
out_val = (*y_it);
if(y_it_col == y_it_row) { out_val = (*y_it); use_y_loc = true; } // take values only from the main diagonal of B
++y_it;
use_y_loc = true;
}
}
access::rw(out.values[count]) = out_val;
const uword out_row = (use_y_loc == false) ? x_it_row : y_it_row;
const uword out_col = (use_y_loc == false) ? x_it_col : y_it_col;
access::rw(out.row_indices[count]) = out_row;
access::rw(out.col_ptrs[out_col + 1])++;
++count;
if(out_val != eT(0))
{
access::rw(out.values[count]) = out_val;
const uword out_row = (use_y_loc == false) ? x_it_row : y_it_row;
const uword out_col = (use_y_loc == false) ? x_it_col : y_it_col;
access::rw(out.row_indices[count]) = out_row;
access::rw(out.col_ptrs[out_col + 1])++;
++count;
}
}
const uword out_n_cols = out.n_cols;
@@ -50,7 +50,7 @@ spop_normalise::apply_direct(SpMat<eT>& out, const SpMat<eT>& X, const uword p,
X.sync();
if( X.is_empty() || (X.n_nonzero == 0) ) { return; }
if( X.is_empty() || (X.n_nonzero == 0) ) { out.zeros(X.n_rows, X.n_cols); return; }
if(dim == 0)
{
+6 -2
View File
@@ -708,7 +708,9 @@ armaSetSparsePr(mxArray *matlabMatrix, const SpMat<double>& armaMatrix)
double *sr = mxGetPr(matlabMatrix);
mwIndex *irs = mxGetIr(matlabMatrix);
mwIndex *jcs = mxGetJc(matlabMatrix);
armaMatrix.sync();
mwSize n_nonzero = armaMatrix.n_nonzero;
mwSize n_cols = armaMatrix.n_cols;
@@ -732,7 +734,9 @@ armaSetSparsePi(mxArray *matlabMatrix, const SpMat<double>& armaMatrix)
double *si = mxGetPi(matlabMatrix);
mwIndex *irs = mxGetIr(matlabMatrix);
mwIndex *jcs = mxGetJc(matlabMatrix);
armaMatrix.sync();
mwSize n_nonzero = armaMatrix.n_nonzero;
mwSize n_cols = armaMatrix.n_cols;
+27
View File
@@ -0,0 +1,27 @@
LIB_FLAGS = -larmadillo
#LIB_FLAGS = -lblas -llapack
#LIB_FLAGS = -lopenblas -llapack
CXX_FLAGS = -std=c++11 -Wshadow -Wall -pedantic -O0
#CXX_FLAGS = -std=c++11 -Wshadow -Wall -pedantic -O0 -fopenmp
#CXX_FLAGS = -std=c++11 -Wshadow -Wall -pedantic -O0 -DARMA_DONT_USE_WRAPPER
#CXX_FLAGS = -std=c++11 -Wshadow -Wall -pedantic -O0 -fsanitize=address -fsanitize=leak -fsanitize=undefined -fsanitize=bounds -fsanitize=bounds-strict -g
#CXX_FLAGS = -std=c++11 -Wshadow -Wall -pedantic -O2
OBJECTS = $(patsubst %.cpp,%.o,$(wildcard *.cpp))
%.o: %.cpp $(DEPS)
$(CXX) $(CXX_FLAGS) -o $@ -c $<
main: $(OBJECTS)
$(CXX) $(CXX_FLAGS) -o $@ $(OBJECTS) $(LIB_FLAGS)
all: main
.PHONY: clean
clean:
rm -f main *.o
+171 -80
View File
@@ -1,6 +1,6 @@
/*
* Catch v1.10.0
* Generated: 2017-08-26 15:16:46.676990
* Catch v1.12.2
* Generated: 2018-05-14 15:10:01.112442
* ----------------------------------------------------------
* This file has been merged from multiple headers. Please don't edit it directly
* Copyright (c) 2012 Two Blue Cubes Ltd. All rights reserved.
@@ -8,6 +8,11 @@
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
// NOTE: added backport of fix for macOS on ARM, as per https://github.com/catchorg/Catch2/commit/bb6d08323f23a39eb65dd86671e68f4f5d3f2d6c
// NOTE: SIGSTKSZ is no longer a constant in glibc 2.34; see https://github.com/catchorg/Catch2/issues/2178
#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED
@@ -228,7 +233,12 @@
( defined __GNUC__ && ( __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3 )) ) || \
( defined __clang__ && __clang_major__ >= 3 )
#define CATCH_INTERNAL_CONFIG_COUNTER
// Use of __COUNTER__ is suppressed during code analysis in CLion/AppCode 2017.2.x and former,
// because __COUNTER__ is not properly handled by it.
// This does not affect compilation
#if ( !defined __JETBRAINS_IDE__ || __JETBRAINS_IDE__ >= 20170300L )
#define CATCH_INTERNAL_CONFIG_COUNTER
#endif
#endif
@@ -309,10 +319,7 @@
#if defined(CATCH_INTERNAL_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_NO_UNIQUE_PTR) && !defined(CATCH_CONFIG_CPP11_UNIQUE_PTR) && !defined(CATCH_CONFIG_NO_CPP11)
# define CATCH_CONFIG_CPP11_UNIQUE_PTR
#endif
// Use of __COUNTER__ is suppressed if __JETBRAINS_IDE__ is #defined (meaning we're being parsed by a JetBrains IDE for
// analytics) because, at time of writing, __COUNTER__ is not properly handled by it.
// This does not affect compilation
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) && !defined(__JETBRAINS_IDE__)
#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER)
# define CATCH_CONFIG_COUNTER
#endif
#if defined(CATCH_INTERNAL_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_NO_SHUFFLE) && !defined(CATCH_CONFIG_CPP11_SHUFFLE) && !defined(CATCH_CONFIG_NO_CPP11)
@@ -1318,10 +1325,12 @@ namespace Internal {
template<> struct OperatorTraits<IsGreaterThanOrEqualTo>{ static const char* getName(){ return ">="; } };
template<typename T>
T& removeConst(T const &t) { return const_cast<T&>(t); }
T& opCast(T const& t) { return const_cast<T&>(t); }
// nullptr_t support based on pull request #154 from Konstantin Baumann
#ifdef CATCH_CONFIG_CPP11_NULLPTR
inline std::nullptr_t removeConst(std::nullptr_t) { return nullptr; }
#endif
inline std::nullptr_t opCast(std::nullptr_t) { return nullptr; }
#endif // CATCH_CONFIG_CPP11_NULLPTR
// So the compare overloads can be operator agnostic we convey the operator as a template
// enum, which is used to specialise an Evaluator for doing the comparison.
@@ -1331,90 +1340,161 @@ namespace Internal {
template<typename T1, typename T2>
struct Evaluator<T1, T2, IsEqualTo> {
static bool evaluate( T1 const& lhs, T2 const& rhs) {
return bool(removeConst(lhs) == removeConst(rhs) );
return bool( opCast( lhs ) == opCast( rhs ) );
}
};
template<typename T1, typename T2>
struct Evaluator<T1, T2, IsNotEqualTo> {
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
return bool(removeConst(lhs) != removeConst(rhs) );
return bool( opCast( lhs ) != opCast( rhs ) );
}
};
template<typename T1, typename T2>
struct Evaluator<T1, T2, IsLessThan> {
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
return bool(removeConst(lhs) < removeConst(rhs) );
return bool( opCast( lhs ) < opCast( rhs ) );
}
};
template<typename T1, typename T2>
struct Evaluator<T1, T2, IsGreaterThan> {
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
return bool(removeConst(lhs) > removeConst(rhs) );
return bool( opCast( lhs ) > opCast( rhs ) );
}
};
template<typename T1, typename T2>
struct Evaluator<T1, T2, IsGreaterThanOrEqualTo> {
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
return bool(removeConst(lhs) >= removeConst(rhs) );
return bool( opCast( lhs ) >= opCast( rhs ) );
}
};
template<typename T1, typename T2>
struct Evaluator<T1, T2, IsLessThanOrEqualTo> {
static bool evaluate( T1 const& lhs, T2 const& rhs ) {
return bool(removeConst(lhs) <= removeConst(rhs) );
return bool( opCast( lhs ) <= opCast( rhs ) );
}
};
// Special case for comparing a pointer to an int (deduced for p==0)
template<typename T>
struct Evaluator<int const&, T* const&, IsEqualTo> {
static bool evaluate( int lhs, T* rhs) {
return reinterpret_cast<void const*>( lhs ) == rhs;
}
};
template<typename T>
struct Evaluator<T* const&, int const&, IsEqualTo> {
static bool evaluate( T* lhs, int rhs) {
return lhs == reinterpret_cast<void const*>( rhs );
}
};
template<typename T>
struct Evaluator<int const&, T* const&, IsNotEqualTo> {
static bool evaluate( int lhs, T* rhs) {
return reinterpret_cast<void const*>( lhs ) != rhs;
}
};
template<typename T>
struct Evaluator<T* const&, int const&, IsNotEqualTo> {
static bool evaluate( T* lhs, int rhs) {
return lhs != reinterpret_cast<void const*>( rhs );
}
};
template<Operator Op, typename T1, typename T2>
bool applyEvaluator( T1 const& lhs, T2 const& rhs ) {
return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
}
template<typename T>
struct Evaluator<long const&, T* const&, IsEqualTo> {
static bool evaluate( long lhs, T* rhs) {
return reinterpret_cast<void const*>( lhs ) == rhs;
}
};
template<typename T>
struct Evaluator<T* const&, long const&, IsEqualTo> {
static bool evaluate( T* lhs, long rhs) {
return lhs == reinterpret_cast<void const*>( rhs );
}
};
template<typename T>
struct Evaluator<long const&, T* const&, IsNotEqualTo> {
static bool evaluate( long lhs, T* rhs) {
return reinterpret_cast<void const*>( lhs ) != rhs;
}
};
template<typename T>
struct Evaluator<T* const&, long const&, IsNotEqualTo> {
static bool evaluate( T* lhs, long rhs) {
return lhs != reinterpret_cast<void const*>( rhs );
}
};
// This level of indirection allows us to specialise for integer types
// to avoid signed/ unsigned warnings
// "base" overload
template<Operator Op, typename T1, typename T2>
bool compare( T1 const& lhs, T2 const& rhs ) {
return Evaluator<T1, T2, Op>::evaluate( lhs, rhs );
}
// unsigned X to int
template<Operator Op> bool compare( unsigned int lhs, int rhs ) {
return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
}
template<Operator Op> bool compare( unsigned long lhs, int rhs ) {
return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
}
template<Operator Op> bool compare( unsigned char lhs, int rhs ) {
return applyEvaluator<Op>( lhs, static_cast<unsigned int>( rhs ) );
}
// unsigned X to long
template<Operator Op> bool compare( unsigned int lhs, long rhs ) {
return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
}
template<Operator Op> bool compare( unsigned long lhs, long rhs ) {
return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
}
template<Operator Op> bool compare( unsigned char lhs, long rhs ) {
return applyEvaluator<Op>( lhs, static_cast<unsigned long>( rhs ) );
}
// int to unsigned X
template<Operator Op> bool compare( int lhs, unsigned int rhs ) {
return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
}
template<Operator Op> bool compare( int lhs, unsigned long rhs ) {
return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
}
template<Operator Op> bool compare( int lhs, unsigned char rhs ) {
return applyEvaluator<Op>( static_cast<unsigned int>( lhs ), rhs );
}
// long to unsigned X
template<Operator Op> bool compare( long lhs, unsigned int rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
template<Operator Op> bool compare( long lhs, unsigned long rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
template<Operator Op> bool compare( long lhs, unsigned char rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
// pointer to long (when comparing against NULL)
template<Operator Op, typename T> bool compare( long lhs, T* rhs ) {
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
}
template<Operator Op, typename T> bool compare( T* lhs, long rhs ) {
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
}
// pointer to int (when comparing against NULL)
template<Operator Op, typename T> bool compare( int lhs, T* rhs ) {
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
}
template<Operator Op, typename T> bool compare( T* lhs, int rhs ) {
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
}
#ifdef CATCH_CONFIG_CPP11_LONG_LONG
// long long to unsigned X
template<Operator Op> bool compare( long long lhs, unsigned int rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
template<Operator Op> bool compare( long long lhs, unsigned long rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
template<Operator Op> bool compare( long long lhs, unsigned long long rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
template<Operator Op> bool compare( long long lhs, unsigned char rhs ) {
return applyEvaluator<Op>( static_cast<unsigned long>( lhs ), rhs );
}
// unsigned long long to X
template<Operator Op> bool compare( unsigned long long lhs, int rhs ) {
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
}
template<Operator Op> bool compare( unsigned long long lhs, long rhs ) {
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
}
template<Operator Op> bool compare( unsigned long long lhs, long long rhs ) {
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
}
template<Operator Op> bool compare( unsigned long long lhs, char rhs ) {
return applyEvaluator<Op>( static_cast<long>( lhs ), rhs );
}
// pointer to long long (when comparing against NULL)
template<Operator Op, typename T> bool compare( long long lhs, T* rhs ) {
return Evaluator<T*, T*, Op>::evaluate( reinterpret_cast<T*>( lhs ), rhs );
}
template<Operator Op, typename T> bool compare( T* lhs, long long rhs ) {
return Evaluator<T*, T*, Op>::evaluate( lhs, reinterpret_cast<T*>( rhs ) );
}
#endif // CATCH_CONFIG_CPP11_LONG_LONG
#ifdef CATCH_CONFIG_CPP11_NULLPTR
// pointer to nullptr_t (when comparing against nullptr)
template<Operator Op, typename T> bool compare( std::nullptr_t, T* rhs ) {
return Evaluator<T*, T*, Op>::evaluate( nullptr, rhs );
}
template<Operator Op, typename T> bool compare( T* lhs, std::nullptr_t ) {
return Evaluator<T*, T*, Op>::evaluate( lhs, nullptr );
}
#endif // CATCH_CONFIG_CPP11_NULLPTR
} // end of namespace Internal
} // end of namespace Catch
@@ -1835,7 +1915,7 @@ public:
void endExpression() const {
m_rb
.setResultType( Internal::Evaluator<LhsT, RhsT, Op>::evaluate( m_lhs, m_rhs ) )
.setResultType( Internal::compare<Op>( m_lhs, m_rhs ) )
.endExpression( *this );
}
@@ -2054,6 +2134,9 @@ namespace Catch{
#define CATCH_TRAP() \
__asm__("li r0, 20\nsc\nnop\nli r0, 37\nli r4, 2\nsc\nnop\n" \
: : : "memory","r0","r3","r4" ) /* NOLINT */
#elif defined(__aarch64__)
// Backport of https://github.com/catchorg/Catch2/commit/a25c1a24af8bffd35727a888a307ff0280cf9387
#define CATCH_TRAP() __asm__(".inst 0xd4200000")
#else
#define CATCH_TRAP() __asm__("int $3\n" : : /* NOLINT */ )
#endif
@@ -2756,7 +2839,8 @@ namespace Detail {
if (relativeOK) {
return true;
}
return std::fabs(lhs_v - rhs.m_value) < rhs.m_margin;
return std::fabs(lhs_v - rhs.m_value) <= rhs.m_margin;
}
template <typename T, typename = typename std::enable_if<std::is_constructible<double, T>::value>::type>
@@ -2828,7 +2912,7 @@ namespace Detail {
if (relativeOK) {
return true;
}
return std::fabs(lhs - rhs.m_value) < rhs.m_margin;
return std::fabs(lhs - rhs.m_value) <= rhs.m_margin;
}
friend bool operator == ( Approx const& lhs, double rhs ) {
@@ -5279,10 +5363,6 @@ namespace Catch {
.describe( "should output be colourised" )
.bind( &setUseColour, "yes|no" );
cli["--use-colour"]
.describe( "should output be colourised" )
.bind( &setUseColour, "yes|no" );
cli["--libidentify"]
.describe( "report name and version according to libidentify standard" )
.bind( &ConfigData::libIdentify );
@@ -6527,6 +6607,7 @@ namespace Catch {
#endif // not Windows
#include <cassert>
#include <set>
#include <string>
@@ -7215,14 +7296,14 @@ namespace Catch {
namespace Catch {
struct RandomNumberGenerator {
typedef std::ptrdiff_t result_type;
typedef unsigned int result_type;
result_type operator()( result_type n ) const { return std::rand() % n; }
#ifdef CATCH_CONFIG_CPP11_SHUFFLE
static constexpr result_type min() { return 0; }
static constexpr result_type max() { return 1000000; }
result_type operator()() const { return std::rand() % max(); }
static constexpr result_type (min)() { return 0; }
static constexpr result_type (max)() { return 1000000; }
result_type operator()() const { return std::rand() % (max)(); }
#endif
template<typename V>
static void shuffle( V& vector ) {
@@ -8136,7 +8217,7 @@ namespace Catch {
std::string AssertionResult::getExpression() const {
if( isFalseTest( m_info.resultDisposition ) )
return '!' + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg);
return "!(" + capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg) + ")";
else
return capturedExpressionWithSecondArgument(m_info.capturedExpression, m_info.secondArg);
}
@@ -8394,7 +8475,7 @@ namespace Catch {
}
inline Version libraryVersion() {
static Version version( 1, 10, 0, "", 0 );
static Version version( 1, 12, 2, "", 0 );
return version;
}
@@ -8429,11 +8510,18 @@ namespace Catch {
: m_info( other.m_info )
{}
#if defined(_MSC_VER)
#pragma warning(push)
#pragma warning(disable:4996) // std::uncaught_exception is deprecated in C++17
#endif
ScopedMessage::~ScopedMessage() {
if ( !std::uncaught_exception() ){
getResultCapture().popScopedMessage(m_info);
}
}
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
} // end namespace Catch
@@ -9092,6 +9180,8 @@ std::string toString( std::nullptr_t ) {
// #included from: catch_result_builder.hpp
#define TWOBLUECUBES_CATCH_RESULT_BUILDER_HPP_INCLUDED
#include <cassert>
namespace Catch {
ResultBuilder::ResultBuilder( char const* macroName,
@@ -10208,12 +10298,12 @@ namespace Catch {
bool includeResults = m_config->includeSuccessfulResults() || !result.isOk();
if( includeResults ) {
if( includeResults || result.getResultType() == ResultWas::Warning ) {
// Print any info messages in <Info> tags.
for( std::vector<MessageInfo>::const_iterator it = assertionStats.infoMessages.begin(), itEnd = assertionStats.infoMessages.end();
it != itEnd;
++it ) {
if( it->type == ResultWas::Info ) {
if( it->type == ResultWas::Info && includeResults ) {
m_xml.scopedElement( "Info" )
.writeText( it->message );
} else if ( it->type == ResultWas::Warning ) {
@@ -10585,6 +10675,7 @@ namespace Catch {
// #included from: ../reporters/catch_reporter_console.hpp
#define TWOBLUECUBES_CATCH_REPORTER_CONSOLE_HPP_INCLUDED
#include <cassert>
#include <cfloat>
#include <cstdio>

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